【考试总结】2022-05-06
魔法球
不难发现是否合法具有单调性,同时保留的一定是权值最大的若干个
通过贪心也可以得到删去球的顺序一定是将待删去的球从大到小操作,并且在保留球之外被加的是最小的若干个
考察一个 \(\Theta(n)\) 判定方式,即从后向前找到每个球的每个权值的出路:被保留的球和没被删去的球,如果出现没有出路的情况就是非法的
注意相对大小关系发生改变时权值一定是不变的(因为每次添加的是 \(1\)),所以直接从后往前循环找到的就是待找出路权值的增量
Code Display
const int N=1e6+10;
int n,a[N];
inline bool check(int mid){
int sum=0;
for(int i=n-mid;i>=1;--i){
sum+=a[i];
if(sum>(mid+i-1)*(n-mid-i+1)) return 0;
}
return 1;
}
signed main(){
freopen("magic.in","r",stdin); freopen("magic.out","w",stdout);
int T=read();
while(T--){
n=read();
rep(i,1,n) a[i]=read();
sort(a+1,a+n+1);
int l=1,r=n-1,ans=n;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
print(ans);
}
return 0;
}
基因切割
使用 std::bitset
维护每个字母出现的位置,那么求出来每个 \(T\) 的无交的出现位置就变成了对应字母左移之后进行按位与
那么找到无交的区间可以使用 bitset->_Find_next(x)
来每次暴跳并删去
时间复杂度是 \(\Theta\left(\dfrac{n^2}{\omega}\right)\)
题解提供的一种 \(\Theta(n^{\frac{5}3})\) 的做法是维护长度不超过 \(n^{\frac13}\) 的子串的哈希值,如果 \(T_i\) 超过阀值就暴力扫描
删去串时有 \(\Theta(B^2)\) 个哈希值被改变了,所以暴力删去即可
Code Display
const int N=1e5+10;
int n,Q;
bitsetapp[4];
inline int turn(char s){
if(s=='A') return 0;
if(s=='C') return 1;
if(s=='G') return 2;
return 3;
}
char s[N],t[N];
inline void del(bitset&now,int l,int r){
now^=(now>>(r+1)^(now>>l))< now=app[turn(t[1])];
for(int i=2;i<=m;++i) now&=app[turn(t[i])]>>(i-1);
vector > vec;
for(int i=now._Find_first();i!=N;i=now._Find_next(i+m-1)) vec.emplace_back(i,i+m-1);
reverse(vec.begin(),vec.end());
for(auto inter:vec){
rep(i,0,3) del(app[i],inter.fir,inter.sec);
}
n-=m*vec.size();
}
for(int i=1;i<=n;++i){
if(app[0][i]) putchar('A');
if(app[1][i]) putchar('C');
if(app[2][i]) putchar('G');
if(app[3][i]) putchar('T');
} putchar('\n');
return 0;
}
细菌培养
将所有的 \(0\) 覆盖的区间进行标记,然后将其视为任意数进行处理其它部分的计算
使用原根处理乘法操作,不难发现本质上就是进行一个 \(a'_i\leftarrow (a_i+a_{i-1}+a_{i+1})\%4\) 的操作
将其写作 \(\rm OGF\) 即为 \(A\leftarrow A\frac{x^2+x+1}{x}\mod (x^{n}-1)\)
不难发现 \((x^2+x+1)^{2^k}\) 在模 \(4\) 意义下系数有值的位置只有 \(3\) 或 \(5\) 项,对每个 \(k\) 处理即可
Code Display
const int N=1e6+10;
int n,T,a[N],b[N],c[N];
int pwg[5];
signed main(){
freopen("bacteria.in","r",stdin); freopen("bacteria.out","w",stdout);
n=read(); T=read();
auto ins=[&](int l,int r){c[l]++; c[r+1]--;};
pwg[1]=0; pwg[2]=1; pwg[3]=3; pwg[4]=2;
rep(i,0,n-1){
a[i]=read()%5;
if(a[i]==0){
if(T>=n/2){
rep(i,0,n-1) print(0);
putchar('\n');
exit(0);
}else{
if(i-T>=0) ins(i-T,i);
else{
ins(i+n-T,n-1);
ins(0,i);
}
if(i+T<=n) ins(i,i+T);
else{
ins(i,n-1);
ins(0,(i+T)%n);
}
}
}else a[i]=pwg[a[i]];
}
if(T&1){
rep(i,0,n-1) b[i]=a[i];
rep(i,0,n-1) a[i]=(b[i]+b[(i+n-1)%n]+b[(i+1)%n])&3;
}
for(int d=1;(1ll<>d&1){
rep(i,0,n-1) b[i]=a[i];
int len=1ll<