qoj 10306. 黄焖鸡 solution
对于一个数列,最大独立集的下界是和的一半,可以取奇数和与偶数和中较大的一方达到这个下界。因此坏数列的必要条件是奇数和等于偶数和。
从调整的角度,可以发现 \(a_1\leq a_2\),否则偶数集合可以把 \(2\) 调成 \(1\)。\(n=5\) 要考虑 ACE 调成 BE 不优,变化量是 \(A+C-B\)。就可以感觉到这个东西和交替和有一些联系的。
拓展到更长的情况:由于最终 \(n,n-1\) 至少有一个在集合中,不妨设 \(n\) 在集合中,考虑初始与 \(n\) 同奇偶的都选上,初始集合为 \(S\),进行调整的方式是选取若干不交区间 \([l,r],l\in S,r\in S\),将 \([l,r]\) 所有元素是否在 \(S\) 中的情况反转,将 \(l,r\) 调整可以对 \([1,r],[1,l-1]\) 分开做一次。\([1,x]\) 操作的变化量是与 \(x\) 同奇偶位置的和减去不同奇偶的,记录变化量为 \(d_x\)。如果有 \(d_x<0\) 一定不合法,剩下的话每一步调整都严格不优。因此最终结论是:令 \(d_x=\sum_{i\leq x}[i\bmod 2=x\bmod 2]a_i-\sum[i\bmod 2\ne x\bmod2]a_i\),一个数列是坏的当且仅当:所有 \(d_x\) 非负,并且偶数位置和等于奇数位置和。
将判定拓展到所有子区间的情况。从左往右加入 \(r\),维护所有 \(l\) 的信息。转移是所有存活的 \(l\) 进行 \(d_l=a_r-d_l\),如果 \(<0\) 那么在以后就不考虑(已经违反全部非负限制);如果 \(=0\) 那么就爆了。然后加入 \(d_r=a_r\)。发现 \(d\) 的值域只在于 \([1,m]\),因此看成维护一个不可重集 \(S\)(如果重复那么操作都是一样的):删除所有 \(>a_r\) 的,检查不存在 \(a_r\),整体令 \(i=a_r-i\),加入 \(a_r\)。其实可以看成一种 dp 套 dp。预处理 \(tr_{S,i}\) 表示 \(S\) 经过 \(i\) 转移到的 \(T\),或者宣告不合法。每次枚举 \(S\) 以及 \(i\) 暴力转移,这样就是 \(\mathcal O(nm2^m)\) 的复杂度。
进一步优化,性质在于 \(tr_{S,i}\) 中 \(S\) 在 \(\{i+1,\cdots,n\}\) 的情况完全不在意,所以只需要关心 \(S\cap\{1,2,\cdots,i\}=S'\),而 \(S'\) 的枚举量是 \(\sum 2^i=\mathcal O(2^m)\)。并且 \(tr_{S,i}=T\) 若合法则 \(T\) 也是 \(\{1,2,\cdots,i\}\) 的子集,且必然含 \(i\)。结合上面的那个复杂度,启发我们每次枚举最高位消除掉它的影响,也就是枚举插入的元素 \(x\),由 \(n\) 枚举到 \(1\)。将上一轮得到的 \(dp_S\) 下传到 \(\{1,2,\cdots,x-1\}\) 的子问题,同时考虑求插入 \(x\) 的影响,枚举 \(\{1,2,\cdots,x-1\}\) 的子集即可。这样就保证了 \(\sum 2^i=\mathcal O(2^m)\) 的总枚举量,总时间复杂度 \(\mathcal O(n2^m)\),可以通过。
void solve(){
cin>>zsy>>n;
const int mx=(1<<n)-1;
F(i,0,n-1)F(s,0,(1<<i)-1){
int t=(1<<i);
F(j,0,i-1)if((s>>j)&1)t^=(1<<(i-1-j));
tr[s][i]=t;
}
f[0]=1;
F(_,1,zsy){
F(i,0,n-1)cin>>vis[i];
dF(x,n-1,0){
if(vis[x])F(s,0,(1<<x)-1)if(~tr[s][x])inc(g[tr[s][x]],f[s]);
F(s,1<<x,(1<<(x+1))-1)inc(f[s^(1<<x)],f[s]);
}
F(s,0,mx)f[s]=g[s],g[s]=0;
}
int ans=0;
F(s,0,mx)inc(ans,f[s]);
cout<<ans<<'\n';
}
posted on 2025-08-29 20:25 nullptr_qwq 阅读(37) 评论(0) 收藏 举报
浙公网安备 33010602011771号