diff --git a/src/11/6/P14358.cpp b/src/11/6/P14358.cpp new file mode 100644 index 0000000..5d68124 --- /dev/null +++ b/src/11/6/P14358.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +using ll = int64_t; +#define printf + +const ll maxn = 17; +ll isd=1; +ll n,m,x=1,y=1,ansx,ansy,ansn,a[maxn*maxn]; + +int main(){ + std::iostream::sync_with_stdio(false); + std::cin.tie(nullptr); + + std::cin>>n>>m; + for(ll i=1;i<=n*m;i++){ + std::cin>>a[i]; + } + ansn=a[1]; + std::sort(a+1,a+1+n*m,std::greater<>()); + ll tot=1; + while(y<=m){ + printf("x=%lld, y=%lld\n",x,y); + if(x==n+1||x==0){ + y++; + isd=isd*-1; + x+=isd; + continue; + } + ll tmp=a[tot++]; + printf("tmp=%lld\n",tmp); + if(tmp==ansn){ + ansx=x,ansy=y,ansn=tmp; + break; + } + x+=isd; + } + std::cout< +#include +#include +#include + +using ll = int64_t; +#define printf +const ll p220=1048576,maxa=p220+7; +ll n,k,f[maxa],now,tmp,ans,last; +struct S{ + ll l,r; +}; + +int main(){ + std::iostream::sync_with_stdio(false); + std::cin.tie(nullptr); + + for(ll i=0;i>n>>k; + f[0]=1; + last=0; + for(ll i=1;i<=n;i++){ + std::cin>>tmp; + now^=tmp; + printf("i=%lld, now=%lld\n",i,now); + printf("f[%lld]=%lld\n",now^k,f[now^k]); + if(f[now^k]!=-1){ + if(f[now^k]>last){ + ans++; + last=i; + } + printf("add %lld, %lld\n",f[now^k],i); + f[now^k]=-1; + } + f[now]=i+1; + } + std::cout< +#include +#include +#include + +// 使用标准 long long 类型,并定义常量 +using ll = long long; +const int MOD = 998244353; +const int MAXN = 5005; + +// 预计算2的幂,用于快速得到子集总数 +ll p2[MAXN]; + +void precompute_powers(int n) { + p2[0] = 1; + for (int i = 1; i <= n; ++i) { + p2[i] = (p2[i - 1] * 2) % MOD; + } +} + +int main() { + // OI/ACM 风格的快速输入输出 + std::ios_base::sync_with_stdio(false); + std::cin.tie(nullptr); + + int n; + std::cin >> n; + + std::vector a(n); + int total_sum = 0; + for (int i = 0; i < n; ++i) { + std::cin >> a[i]; + total_sum += a[i]; + } + + // 1. 排序:这是算法的关键前提 + std::sort(a.begin(), a.end()); + + // 预计算2的幂 + precompute_powers(n); + + // 2. DP 数组设置 + // dp[j] 表示从当前已处理的木棍中选出若干根,使其和为 j 的方案数。 + // 背包容量上界是所有木棍的总和。 + std::vector dp(total_sum + 1, 0); + dp[0] = 1; // 和为0的方案只有一种:不选任何木棍 + + ll totans = 0; + int cursum = 0; // 记录当前处理过的木棍的总和,作为DP容量的上界 + + // 3. 主循环:依次处理每根木棍 + for (int i = 0; i < n; ++i) { + // a[i] 是当前木棍的长度 + + // 3.1 统计答案: + // 假设 a[i] 是最长边,从前面的 a[0]...a[i-1] 中选边。 + // 此时 dp 数组存储的是从 {a[0], ..., a[i-1]} 中选择的方案。 + // 我们需要找到满足 sum(S) > a[i] 的子集 S 的数量。 + + // 计算 sum(S) <= a[i] 的方案数 + ll nans = 0; + // 注意 j 的上界是 cursum 和 a[i] 的较小值 + for (int j = 0; j <= std::min(cursum, a[i]); ++j) { + nans = (nans + dp[j]) % MOD; + } + + // 从 {a[0], ..., a[i-1]} 中选子集,总方案数是 2^i + ll totpre = p2[i]; + + // 合法方案数 = 总方案数 - 不合法方案数 (sum(S) <= a[i]) + ll ok = (totpre - nans + MOD) % MOD; + + // 累加到最终答案 + totans = (totans + ok) % MOD; + + // 3.2 更新DP数组 + // 将 a[i] 加入可选木棍池,为后续 a[i+1], a[i+2]... 作为最长边时做准备。 + cursum += a[i]; + // 0/1 背包,必须逆序遍历以保证每个物品只被选一次 + for (int j = cursum; j >= a[i]; --j) { + dp[j] = (dp[j] + dp[j - a[i]]) % MOD; + } + } + + std::cout << totans << std::endl; +}