链接:https://codeforces.com/contest/1244/problem/F
题意:给出一个每个节点黑色或者白色的环,k次更新,每次更新将所有满足条件的节点颜色反转(同时进行),满足条件:该节点的相邻的2个节点颜色和它不同。求k次后各个节点的颜色。
题解:环的话,序列复制向左右分别扩展一倍数,最后看中间部分,可以发现,颜色相同的连续的节点不会发生变化,颜色不同的序列,直接暴力更新即可,复杂度O(n)
#include <bits/stdc++.h> #define IO_read ios::sync_with_stdio(false);cin.tie(0) #define fre freopen("in.txt", "r", stdin) #define _for(i,a,b) for(int i=a; i< b; i++) #define _rep(i,a,b) for(int i=a; i<=b; i++) #define inf 0x3f3f3f3f #define lowbit(a) ((a)&-(a)) using namespace std; typedef long long ll; template <class T> void read(T &x) { char c; bool op=0; while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1; x=c-'0'; while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0'; if(op) x=-x; } template <class T> void write(T x) { if(x<0) putchar('-'), x=-x; if(x>=10) write(x/10); putchar('0'+x%10); } const int maxn=2e5+5; char s[maxn]; int color[maxn*3]; struct Segment{ int l, r, color; }segment[maxn*3]; int n, k, tot; int main() { IO_read; //fre; cin>>n>>k; cin>>(s+1); for(int i=1; i<=n; i++) color[i]= s[i]=='B'?1:0; for(int i=n+1; i<=3*n; i++) color[i]=color[(i-1)%n+1]; for(int i=1,j=1; i<=3*n; i=j+1) { while(j+1<=3*n&&color[i]==color[j+1]) ++j; if(j-i>=1) segment[++tot]={i, j, color[i]}; } for(int i=1; i<tot; i++) { int l=segment[i].r+1, r=segment[i+1].l-1; int lc=color[l-1], rc=color[r+1]; if(l>r) continue; int len=r-l+1; if(2*k>=len){ if(lc==rc){ for(int j=l; j<=r; j++) color[j]=lc; } else{ for(int j=l; j<=l+len/2-1; j++) color[j]=lc; for(int j=r; j>=r-len/2+1; j--) color[j]=rc; } } else{ for(int j=l; j<=l+k-1; j++) color[j]=lc; for(int j=r; j>=r-k+1; j--) color[j]=rc; for(int j=l+k; j<=r-k; j++) color[j]=!color[j-1]; } } if(tot==0&&k%2) for(int i=n+1; i<=2*n; i++) color[i]=!color[i-1]; //要判断tot为0且k为奇数的时候 for(int i=n+1; i<=2*n; i++) printf("%c", color[i]?'B':'W'); return 0; }