zoukankan      html  css  js  c++  java
  • 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix

    1014: [JSOI2008]火星人prefix

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 4164  Solved: 1277
    [Submit][Status][Discuss]

    Description

    火星人最近研究了一种操作:求一个字串两个后缀的公共前缀。比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字符 m a d a m i m a d a m 现在,火星人定义了一个函数LCQ(x, y),表示:该字符串中第x个字符开始的字串,与该字符串中第y个字符开始的字串,两个字串的公共前缀的长度。比方说,LCQ(1, 7) = 5, LCQ(2, 10) = 1, LCQ(4, 7) = 0 在研究LCQ函数的过程中,火星人发现了这样的一个关联:如果把该字符串的所有后缀排好序,就可以很快地求出LCQ函数的值;同样,如果求出了LCQ函数的值,也可以很快地将该字符串的后缀排好序。 尽管火星人聪明地找到了求取LCQ函数的快速算法,但不甘心认输的地球人又给火星人出了个难题:在求取LCQ函数的同时,还可以改变字符串本身。具体地说,可以更改字符串中某一个字符的值,也可以在字符串中的某一个位置插入一个字符。地球人想考验一下,在如此复杂的问题中,火星人是否还能够做到很快地求取LCQ函数的值。

    Input

    第一行给出初始的字符串。第二行是一个非负整数M,表示操作的个数。接下来的M行,每行描述一个操作。操作有3种,如下所示: 1、 询问。语法:Q x y,x, y均为正整数。功能:计算LCQ(x, y) 限制:1 <= x, y <= 当前字符串长度。 2、 修改。语法:R x d,x是正整数,d是字符。功能:将字符串中第x个数修改为字符d。限制:x不超过当前字符串长度。 3、 插入:语法:I x d,x是非负整数,d是字符。功能:在字符串第x个字符之后插入字符d,如果x = 0,则在字符串开头插入。限制:x不超过当前字符串长度。

    Output

    对于输入文件中每一个询问操作,你都应该输出对应的答案。一个答案一行。

    Sample Input

    madamimadam
    7
    Q 1 7
    Q 4 8
    Q 10 11
    R 3 a
    Q 1 7
    I 10 a
    Q 2 11

    Sample Output

    5
    1
    0
    2
    1

    HINT

    数据规模:

    对于100%的数据,满足:

    1、 所有字符串自始至终都只有小写字母构成。

    2、 M <= 150,000

    3、 字符串长度L自始至终都满足L <= 100,000

    4、 询问操作的个数不超过10,000个。

    对于第1,2个数据,字符串长度自始至终都不超过1,000

    对于第3,4,5个数据,没有插入操作。


    Source

    弃疗!!!!

    拿hzwer学长的程序拍了一天啊!!!屁都没拍出来!!!!!

    hash函数改了千百遍,照样在一个奇葩点跪。。。、

    还请大神们帮我啃啃好嘛。。。。。。。。。。。。

    我的:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 #define CH for(int d=0;d<2;d++) if(ch[d])
     10 #define lson x->ch[0],L,M-1
     11 #define rson x->ch[1],M+1,R
     12 using namespace std;
     13 const int maxn=200000+10,inf=-1u>>1,hash=27;int n,Q;
     14 const long long mod=98799321;
     15 long long p[maxn];
     16 struct node{
     17     node*ch[2],*fa;int siz;long long h,x;
     18     void update(){
     19         siz=1;
     20         if(ch[0]&&ch[1]){
     21             siz+=ch[0]->siz+ch[1]->siz;
     22             h=ch[0]->h+(long long)x*p[ch[0]->siz]%mod+(long long)ch[1]->h*p[ch[0]->siz+1]%mod;
     23         }else if(ch[0]){
     24             siz+=ch[0]->siz;
     25             h=ch[0]->h+(long long)x*p[ch[0]->siz]%mod;
     26         }else if(ch[1]){
     27             siz+=ch[1]->siz;
     28             h=x+(long long)ch[1]->h*p[1]%mod;
     29         }else{
     30             h=x;
     31         } h%=mod;return;
     32     }
     33 }Splay[maxn],*nodecnt=Splay,*root;
     34 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;}
     35 void rotate(node*x){
     36     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
     37     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
     38     y->fa=x;x->fa=z;x->ch[d1^1]=y;
     39     if(d2!=-1) z->ch[d2]=x;
     40     y->update();return;
     41 }
     42 node*splay(node*x){
     43     node*y,*z;int d1,d2;
     44     while(true){
     45         if((d1=parent(x,y))<0) break;
     46         if((d2=parent(y,z))<0){rotate(x);break;}
     47         if(d1==d2) rotate(y),rotate(x);
     48         else rotate(x),rotate(x);
     49     } x->update();return x;
     50 }
     51 char A[maxn];
     52 void build(node*&x,int L,int R){
     53     if(L>R)return;x=nodecnt++;
     54     int M=L+R>>1;x->x=A[M]-'a';build(lson);build(rson);
     55     if(x->ch[0]) x->ch[0]->fa=x;
     56     if(x->ch[1]) x->ch[1]->fa=x;x->update();return;
     57 }
     58 node*find(node*x,int k){
     59     int kth=x->ch[0]?x->ch[0]->siz+1:1;
     60     if(k==kth)return x;
     61     if(k<kth)return find(x->ch[0],k);return find(x->ch[1],k-kth);
     62 }
     63 node*findlast(node*x){
     64     while(x->ch[1]) x=x->ch[1];return x;
     65 }
     66 void split(node*&x,node*&y,int a){
     67     if(!a){y=x;x=NULL;return;}
     68     x=splay(find(x,a));y=x->ch[1];x->ch[1]=NULL;
     69     if(y)y->fa=NULL;x->update();return;
     70 }
     71 void split(node*&x,node*&y,node*&z,int a,int b){
     72     split(x,z,b);split(x,y,a-1);return;
     73 }
     74 void join(node*&x,node*y){
     75     if(!x){x=y;return;}if(!y)return;
     76     x=splay(findlast(x));x->ch[1]=y;
     77     if(y)y->fa=x;x->update();return;
     78 }
     79 void join(node*&x,node*y,node*z){
     80     join(y,z);join(x,y);return;
     81 }
     82 void print(node*x){
     83     if(!x)return;
     84     print(x->ch[0]);
     85     printf("%c",x->x+'a');
     86     print(x->ch[1]);
     87     return;
     88 }
     89 void insert(int k){
     90     node*x,*y;split(root,x,k);
     91     //puts("insert:");print(root);PAU;print(x);ENT;
     92     scanf("%s",A);build(y,0,strlen(A)-1);
     93     join(root,y,x);n++;
     94 }
     95 int query(int k1,int k2){
     96     node*x,*y;split(root,x,y,k1,k2);int ans=splay(x)->h;join(root,x,y);return ans;
     97 }
     98 int solve(int k1,int k2){
     99     if(k1>k2)swap(k1,k2);
    100     if(k1==k2)return n-k1+1;
    101     int L=0,R=min(n-k1,n-k2)+1,ans=-1,M;
    102     //printf("L:%d R:%d erfen_L:%d erfen_R:%d
    ",k1,k2,L,R);
    103     while(L<R){
    104         M=L+R>>1;
    105         if(query(k1,k1+M)==query(k2,k2+M)) L=M+1;
    106         else R=M;
    107         //printf("ing:[%d %d]
    ",L,R);
    108     }
    109     //printf("ans:%d
    ",L);
    110     return L;
    111 }
    112 void update(int k,int c){
    113     node*x,*y;split(root,x,y,k,k);
    114     /*puts("root!");print(root);
    115     puts("x!");print(x);
    116     puts("y!");print(y);*/
    117     x->x=c;x->update();join(root,x,y);/*puts("zyq:");print(root);*/return;
    118 }
    119 inline int read(){
    120     int x=0,sig=1;char ch=getchar();
    121     while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();}
    122     while(isdigit(ch)) x=10*x+ch-'0',ch=getchar();
    123     return x*=sig;
    124 }
    125 inline void write(int x){
    126     if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x;
    127     int len=0,buf[15];while(x) buf[len++]=x%10,x/=10;
    128     for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return;
    129 }
    130 inline char readc(){
    131     char ch=getchar();while(!isalpha(ch))ch=getchar();return ch;
    132 }
    133 void init(){
    134     //freopen("std01.in","r",stdin);
    135     //freopen("chxer.out","w",stdout);
    136     scanf("%s",A);n=strlen(A);
    137     p[0]=1;for(int i=1;i<=n;i++) p[i]=p[~-i]*hash%mod;
    138     build(root,0,n-1);
    139     //print(root);
    140     return;
    141 }
    142 void work(){
    143     int ql,qr;char tp;
    144     Q=read();
    145     while(Q--){
    146         tp=readc();
    147         if(tp=='Q'){
    148             ql=read();qr=read();write(solve(ql,qr));ENT;
    149         }
    150         else if(tp=='R') ql=read(),update(ql,readc()-'a');
    151         else insert(read());
    152         //printf("printroot:");print(root);puts("");
    153     }
    154     return;
    155 }
    156 void print(){
    157     write(-1);
    158     return;
    159 }
    160 int main(){
    161     init();work();print();return 0;
    162 }
    163 
    164 /*
    165 asdfasdasd
    166 1000
    167 I 10 f
    168 Q 4 11
    169 */

    hzwer学长的:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #define ll long long
      6 #define mod 9875321
      7 using namespace std;
      8 int c[150005][2],fa[150005],id[150005];
      9 int size[150005],v[150005],h[150005],p[150005];
     10 int n,m,rt,sz;
     11 char ch[150005];
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     16     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 void update(int k)
     20 {
     21     int l=c[k][0],r=c[k][1];
     22     size[k]=size[l]+size[r]+1;
     23     h[k]=h[l]+(ll)v[k]*p[size[l]]%mod+(ll)p[size[l]+1]*h[r]%mod;
     24     h[k]%=mod;
     25 }
     26 void rotate(int x,int &k)
     27 {
     28     int y=fa[x],z=fa[y],l,r;
     29     if(c[y][0]==x)l=0;else l=1;r=l^1;
     30     if(y==k)k=x;
     31     else {if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;}
     32     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
     33     c[y][l]=c[x][r];c[x][r]=y;
     34     update(y);update(x);
     35 }
     36 void splay(int x,int &k)
     37 {
     38     while(x!=k)
     39     {
     40         int y=fa[x],z=fa[y];
     41         if(y!=k)
     42         {
     43             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
     44             else rotate(y,k);
     45         }
     46         rotate(x,k);
     47     }
     48 }
     49 int find(int k,int rk)
     50 {
     51     int l=c[k][0],r=c[k][1];
     52     if(size[l]+1==rk)return k;
     53     else if(size[l]>=rk)return find(l,rk);
     54     else return find(r,rk-size[l]-1);
     55 }
     56 void insert(int k,int val)
     57 {
     58     int x=find(rt,k+1),y=find(rt,k+2);
     59     splay(x,rt);splay(y,c[x][1]);
     60     int z=++sz;c[y][0]=z;fa[z]=y;v[z]=val;
     61     update(z);update(y);update(x);
     62 }
     63 int query(int k,int val)
     64 {
     65     int x=find(rt,k),y=find(rt,k+val+1);
     66     splay(x,rt);splay(y,c[x][1]);
     67     int z=c[y][0];
     68     return h[z];
     69 }
     70 int solve(int x,int y)
     71 {
     72     int l=1,r=min(sz-x,sz-y)-1,ans=0;
     73     while(l<=r)
     74     {
     75         int mid=(l+r)>>1;
     76         if(query(x,mid)==query(y,mid))l=mid+1,ans=mid;
     77         else r=mid-1;
     78     }
     79     return ans;
     80 }
     81 void build(int l,int r,int f)
     82 {
     83     if(l>r)return;
     84     int now=id[l],last=id[f];
     85     if(l==r)
     86     {
     87         v[now]=h[now]=ch[l]-'a'+1;
     88         fa[now]=last;size[now]=1;
     89         if(l<f)c[last][0]=now;
     90         else c[last][1]=now;
     91         return;
     92     }
     93     int mid=(l+r)>>1;now=id[mid];
     94     build(l,mid-1,mid);build(mid+1,r,mid);
     95     v[now]=ch[mid]-'a'+1;fa[now]=last;update(now);
     96     if(mid<f)c[last][0]=now;
     97     else c[last][1]=now;
     98 }
     99 int main()
    100 {
    101     //freopen("std01.in","r",stdin);
    102     //freopen("hzwer.out","w",stdout);
    103     scanf("%s",ch+2);
    104     n=strlen(ch+2);
    105     p[0]=1;for(int i=1;i<=150004;i++)p[i]=p[i-1]*27%mod;
    106     for(int i=1;i<=n+2;i++)id[i]=i;
    107     build(1,n+2,0);sz=n+2;rt=(n+3)>>1;
    108     m=read();
    109     int x,y;
    110     char s[2],d[2];
    111     for(int i=1;i<=m;i++)
    112     {
    113         scanf("%s",s+1);
    114         x=read();
    115         switch(s[1])
    116         {
    117         case 'Q':y=read();printf("%d
    ",solve(x,y));break;
    118         case 'R':
    119         {
    120             scanf("%s",d+1);x=find(rt,x+1);splay(x,rt);
    121             v[rt]=d[1]-'a'+1;update(rt);break;
    122         }
    123         case 'I':scanf("%s",d+1);insert(x,d[1]-'a'+1);break;
    124         }
    125     }
    126     return 0;
    127 }
    128 /*
    129 abaabbbbbbbbbaaaabba
    130 1000
    131 Q 1 9
    132 Q 6 6
    133 Q 2 9
    134 Q 7 13
    135 Q 14 18
    136 Q 18 18
    137 Q 5 6
    138 */

    生成数据:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <time.h>
      5 #include <cstring>
      6 #include <windows.h>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 using namespace std;
     10 inline int read(){
     11     int x=0,sig=1;char ch=getchar();
     12     while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();}
     13     while(isdigit(ch)) x=10*x+ch-'0',ch=getchar();
     14     return x*=sig;
     15 }
     16 inline void write(int x){
     17     if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x;
     18     int len=0,buf[15];while(x) buf[len++]=x%10,x/=10;
     19     for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return;
     20 }
     21 const int maxl=99999;
     22 
     23 char in[15] = "std00.in";
     24 char out[15] = "std00.out";
     25 const int L_file = 1;
     26 const int R_file = 2;
     27 
     28 void _init()   //每次循环的数值清空
     29 {
     30     //此处清零 
     31 
     32     return ;
     33 }
     34 
     35 void _in()
     36 {
     37     in[8] = '';
     38     out[9] = '';
     39     for(int __i = L_file; __i <= R_file; __i ++)
     40     {
     41          in[3] = __i / 10 + '0', in[4] = __i % 10 + '0';
     42         if(freopen(in, "w", stdout) == NULL) system("in失败");
     43         
     44         //此处开始打印测试数据 
     45         int Q=100000;
     46         for(int i=1;i<=20;i++){
     47             putchar(rand()%3+'a');
     48         }
     49         int len=20;
     50         puts("");
     51         write(Q);ENT;int tp;
     52         for(int i=1;i<=Q;i++){
     53             tp=rand()%2;
     54             if(!tp){
     55                 putchar('Q');PAU;int t,t2;
     56                 write(t=rand()%(len-1)+1);PAU;
     57                 while(t>(t2=rand()%len+1));
     58                 write(t2);ENT;
     59             }
     60             else if(tp==1){
     61                 putchar('I');PAU;write(rand()%len);PAU;putchar(rand()%2+'a');ENT;len++;
     62             }
     63             else {
     64                 putchar('R');PAU;write(rand()%len+1);PAU;putchar(rand()%2+'a');ENT;
     65             }
     66         }
     67         
     68         system("已处理完一项输入数据");
     69     }
     70     return ;
     71 }
     72 
     73 void _out()
     74 {
     75     int n, m;
     76     for(int __i = L_file; __i <= R_file; __i ++)
     77     {
     78         _init();
     79          in[3] = __i / 10 + '0', in[4] = __i % 10 + '0';
     80         if(freopen(in, "r", stdin) == NULL) system("in2失败");
     81             
     82         out[3] = __i / 10 + '0', out[4] = __i % 10 + '0';
     83         if(freopen(out, "w", stdout) == NULL) system("out失败");
     84         
     85         //此处放代码
     86         
     87         system("已处理完一项输出数据");
     88     } 
     89     return ;
     90 }
     91 
     92 int main()
     93 {
     94     srand((unsigned)time(0));
     95     
     96     _in();
     97     //_out();
     98     
     99     fclose(stdin);
    100     fclose(stdout);
    101     
    102     return 0;
    103 }

    对拍程序:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #include<fstream>
     8 #define PAU putchar(' ')
     9 #define ENT putchar('
    ')
    10 using namespace std;
    11 ifstream fin1 ("CHXER.out");
    12 ifstream fin2 ("HZWER.out");
    13 inline int read(){
    14     int x=0,sig=1;char ch=getchar();
    15     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    16     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    17     return x*=sig;
    18 }
    19 inline void write(int x){
    20     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    21     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    22     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    23 }
    24 char a1,a2;int len=0;
    25 bool check(){
    26     fin1>>a1;
    27     fin2>>a2;
    28     //printf("%c %c
    ",a1,a2);
    29     if(a1==a2)return true;
    30     else return false;
    31 }
    32 void init(){
    33     while(check())len++;
    34     printf("%c %c %d
    ",a1,a2,len);
    35     while(check())len++;
    36     printf("%c %c %d
    ",a1,a2,len);
    37     while(check())len++;
    38     printf("%c %c %d
    ",a1,a2,len);
    39     while(check())len++;
    40     printf("%c %c %d
    ",a1,a2,len);
    41     while(check())len++;
    42     printf("%c %c %d
    ",a1,a2,len);
    43     while(check())len++;
    44     printf("%c %c %d
    ",a1,a2,len);
    45     while(check())len++;
    46     printf("%c %c %d
    ",a1,a2,len);
    47     while(check())len++;
    48     printf("%c %c %d
    ",a1,a2,len);
    49     while(check())len++;
    50     printf("%c %c %d
    ",a1,a2,len);
    51     return;
    52 }
    53 void work(){
    54     return;
    55 }
    56 void print(){
    57     return;
    58 }
    59 int main(){init();work();print();return 0;}
  • 相关阅读:
    js例子
    js表单验证
    Python之Numpy的基础及进阶函数(图文)
    Numpy库的下载及安装(吐血总结)
    世界,你好!
    用逻辑回归模型解决互联网金融信用风险问题
    用逻辑回归模型解决互联网金融信用风险问题
    如何建立投资模型
    如何建立投资模型
    秒懂数据类型的真谛—Python基础前传(4)
  • 原文地址:https://www.cnblogs.com/chxer/p/4647958.html
Copyright © 2011-2022 走看看