Gym - 102307D Do Not Try This Problem

Posted lmcc1108

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym - 102307D Do Not Try This Problem相关的知识,希望对你有一定的参考价值。

 Do Not Try This Problem Gym - 102307D 

题意:给个长度为len的字符串(len<=1e5),然后q次操作(q<=1e5),每次给出i,a,k,c,(i+k*a<=len)也就是把字符串位置为i,i+a,i+2*a...,i+k*a的改成c字符,输出q次操作后的字符串。

首先暴力做法肯定是遍历字符串的每个位置,然后从后往前遍历,找到最后一个修改到这个位置的操作,但这样的时间复杂度是n*q,是1e10级别的,很明显不行。然后看提交里一位大佬的代码,才明白是怎么个做法。

我们的入手点就在i+k*a<=len这里,i基本没啥影响我们不管i,直接看k*a,设n为√len,那么如果k<=n,我们就直接更新,此时是n*q,是3e7级别的。

那么对于k>n的,此时a<=n,我们就遍历a从1到n,对每个a进行考虑,相同a的按照操作次序从后往前的顺序进行遍历,因为是相同的a,那么同一个位置的下一个位置也是一样的,

所以我们可以用一个并查集的区间合并进行跳转,这样对于相同的a,字符串的每个位置只会被遍历到一个,此时是n*len*并查集find小于log的一个复杂度。

技术图片
 1 #include<cstdio>
 2 #include<cmath> 
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int N=1e5+11;
 9 struct Node{
10     int p,a,k,id;
11     Node(){}
12     Node(int p,int a,int k,int id):p(p),a(a),k(k),id(id){}
13 };
14 char mmp[N],mmk[N];
15 int ans[N],fa[N];
16 vector<Node> vv;
17 void init(int n){
18     vv.clear();
19     for(int i=0;i<=n;i++) ans[i]=0;
20 } 
21 int find(int x){
22     return fa[x]==x ? x : fa[x]=find(fa[x]); 
23 }
24 int main(){
25     int lens,n,q,p,a,kk;
26     while(~scanf("%s%d",mmp+1,&q)){
27         lens=strlen(mmp+1);
28         n=sqrt(lens);
29         init(lens);
30         for(int i=1;i<=q;i++){
31             scanf("%d%d%d %c",&p,&a,&kk,&mmk[i]);
32             if(kk<=n){
33                 for(int j=0;j<=kk;j++) ans[p+j*a]=max(ans[p+j*a],i);
34                 continue;
35             }
36             vv.push_back(Node(p,a,kk,i));
37         }
38         for(int i=1;i<=n;i++){
39             for(int j=1;j<=lens+1;j++) fa[j]=j;
40             for(int j=(int)vv.size()-1;j>=0;j--){
41                 if(vv[j].a!=i) continue;
42                 for(int k=find(vv[j].p),lim=vv[j].p+vv[j].k*vv[j].a;k<=lim;k=find(k)){
43                     ans[k]=max(ans[k],vv[j].id);
44                     fa[k]=k+i<=lens ? find(k+i) : lens+1; 
45                 }
46             }
47         }
48         for(int i=1;i<=lens;i++) if(ans[i]) mmp[i]=mmk[ans[i]];
49         printf("%s
",mmp+1);
50     }
51     return 0;
52 }
分类讨论

 

以上是关于Gym - 102307D Do Not Try This Problem的主要内容,如果未能解决你的问题,请参考以下文章

(寒假开黑gym)2018 USP Try-outs

Gym .101879 USP Try-outs (寒假自训第七场)

try? try! try do catch try 使用详解

do, not do

PSI and index do not match: PSI and index do not match

Gym - 100989B