CF Round 1014 题解合集
E
啥啊,难评。
考虑把所有格子涂成白色,然后考虑将一个格子由白变黑的贡献。
发现只有在边上且不在角上的格子会影响整体的奇偶性,也就是说我们要求这些格子中,黑色格子的数量为偶数。我们把这些位置的格子称为关键格子。
设总体绿色格子数量为 \(sum\),于是考虑:
-
如果关键格子中有绿色格子,那么相当于我们把一个绿色格子留到最后平衡奇偶性,答案为 \(2^{sum-1}\);
-
否则,如果关键格子中黑色格子数量为偶数,那么答案为 \(2^{sum}\),否则答案为 \(0\)。
F
你们有脑子玩家都觉得这个题应该放 2D 吗?
考虑直接做没法做,所以考虑枚举最终划分时,每个字符串的美观度 \(r\),对于 \(r=0\) 的情况特殊考虑。
注意到,对于一个给定的前缀和一个给定的 \(k\),\(r\) 是唯一的。
对于每一个 \(r\),枚举划分的段数 \(k\),考虑能在前缀的哪些位置划分,使得每一段的美观度都为 \(r\)。
我们将 \(z_{i-1} \neq z_i\) 的位置 \(i\) 单独拎出来,形成序列 \(a\)。
对于 \(r,k\),设必须在 \(a_i\) 处截断的位置有 \(cnt\) 个,我们能够划分的前缀位置,处于 \([a_{kr+cnt},a_{k(r+1)})\) 区间内,在这个区间做区间加,表示这个区间中答案可以为 \(k\)。用差分维护。
所谓必须在 \(a_i\) 处截断的位置,也就是 \([a_{kr+cnt},a_{kr+cnt+1})\) 这个区间内只有一个元素时的情况。
对于每一个 \(r\),枚举 \(k\) 的上界为 \(\frac{c}{r}\),所以总体复杂度为 \(O(n \log n)\)。
#include<bits/stdc++.h>
using namespace std;
vector<int> v;
char ch;
int t,n,m,a[1000005],b[1000005],c[1000005];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
cin>>n;
v.push_back(0);
for(int i=1;i<=n;i++){
cin>>ch;
a[i]=ch-'0';
if(i!=1 && a[i]!=a[i-1]) m++,v.push_back(i);
c[i]=m;
}
v.push_back(n+1);
for(int r=1;r<=n;r++){
int cnt=0;
for(int k=1;k*r+cnt<=m;k++){
b[v[k*r+cnt]]++;
b[v[min(k*(r+1),m+1)]]--;
if(v[k*r+cnt]+1==v[min(k*r+cnt+1,m+1)]) cnt++;
}
}
for(int i=1;i<=n;i++){
b[i]+=b[i-1];
}
for(int i=1;i<=n;i++){
b[i]+=i-c[i];
cout<<b[i]<<' ';
}
cout<<'\n';
for(int i=0;i<=n+1;i++){
a[i]=b[i]=c[i]=0;
}
v.clear();
m=0;
}
return 0;
}