zoukankan      html  css  js  c++  java
  • Gym

     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 }
    分类讨论
  • 相关阅读:
    Oracle EBS-SQL (INV-1):库存货位列表.sql
    Oracle EBS-SQL (SYS-24):职责列表
    Oracle EBS-SQL (SYS-23):用户权限查询.sql
    Oracle EBS-SQL (SYS-22):sysadmin_用户职责查询.sql
    Oracle EBS-SQL (SYS-21):sys_用户名与人员对应关系查询.sql
    Oracle EBS-SQL (SYS-20):职责使用菜单2.sql
    Oracle EBS-SQL (SYS-20):OPM接口处理.sql
    Oracle EBS-SQL (SYS-19):sys-用户登陆纪录查询.sql
    Oracle EBS-SQL (SYS-18):检查系统安装的各个表是否打开(PJM%).sql
    Oracle EBS-SQL (SYS-17):查询一张报表在哪个职责下面.sql
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11674619.html
Copyright © 2011-2022 走看看