codeforces.com/gym/102307/problem/D 分块+并查集
分析:
从最后一个单词从后往前修改,且已经修改的不作变动,减少次数
分块,并查集和暴力
对于d 大于 根号n的,用暴力
对于d 小于 根号n的,由于d相等,所以可以将每个点的下一个点用并查集标到还没被修改过的位置
//-------------------------代码---------------------------- //#define int ll const int N = 1e5+10; int n,m; struct UF { int fa[N]; int find(int x) { if(fa[x] == x) return x; return fa[x] = find(fa[x]); } void mer(int x,int y) { fa[find(x)] = find(y); } void init(int n) { fo(i,1,n) fa[i] = i; } }uf[350]; void solve() { // cin>>n>>m; cin>>s;n = s.length(),s = '>' + s; sq = sqrt(n); fo(i,1,sq) uf[i].init(n+1); cin>>m; fo(j,1,m) { cin>>que[j].st>>que[j].d>>que[j].len>>que[j].ch; } of(j,m,1) { int st = que[j].st,d = que[j].d,len = que[j].len; char ch = que[j].ch; if(d > sq) { fo(i,0,len) { int id = st + i * d; if(!vis[id]) { s[id] = ch; vis[id] = 1; } } } else { int id = st; while((id - st) / d <= len && id <= n) { if(!vis[id]) { s[id] = ch; vis[id] = 1; } ud[d].mer(id,min(n + 1,id + d)); id = uf[d].find(id); } } } fo(i,1,n) cout<<s[i]; cout<<<endl; } void main_init() {} signed main(){ AC();clapping();TLE; cout<<fixed<<setprecision(12); main_init(); // while(cin>>n,n) // while(cin>>n>>m,n,m) // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------