• bzoj1014 火星人 (hash+splay+二分答案)


    求公共前缀的问题可以用hash+二分来解决,但这个是动态的,所以我们用平衡树来维护区间的hash值

    复杂度$O(mlog^2n)$

      1 #include<bits/stdc++.h>
      2 #define CLR(a,x) memset(a,x,sizeof(a))
      3 using namespace std;
      4 typedef long long ll;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> pa;
      7 const int maxn=1e5+10,P=131;
      8 const ull RUA=1145141919810ll;
      9 
     10 inline ll rd(){
     11     ll x=0;char c=getchar();int neg=1;
     12     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     13     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     14     return x*neg;
     15 }
     16 
     17 int ch[maxn][2],pct,fa[maxn],siz[maxn];
     18 char v[maxn],s[maxn];
     19 ull sum[maxn],bin[maxn];
     20 int M,rt;
     21 
     22 inline void print(int x){
     23     if(!x) return;
     24     print(ch[x][0]);
     25     // printf("!%d %d %d %d
    ",x,ch[x][0],ch[x][1],fa[x]);
     26     print(ch[x][1]);
     27 }
     28 
     29 inline bool isrc(int x){return x==ch[fa[x]][1];}
     30 
     31 inline void update(int x){
     32     siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
     33     sum[x]=(sum[ch[x][0]]*bin[1]+v[x])*bin[siz[ch[x][1]]]+sum[ch[x][1]];
     34 }
     35 
     36 inline void rotate(int x){
     37     int f=fa[x],ff=fa[f];bool b=isrc(x);
     38     if(ff) ch[ff][isrc(f)]=x; fa[x]=ff;
     39     if(ch[x][!b]) fa[ch[x][!b]]=f; ch[f][b]=ch[x][!b];
     40     fa[f]=x;ch[x][!b]=f;
     41     update(f),update(x);
     42 }
     43 
     44 inline void splay(int x,int tar){
     45     while(fa[x]!=tar&&fa[fa[x]]!=tar){
     46         if(isrc(x)==isrc(fa[x])) rotate(fa[x]);
     47         else rotate(x);rotate(x);
     48     }if(fa[x]!=tar) rotate(x);
     49     if(!tar) rt=x;
     50 }
     51 
     52 inline int findkth(int k){
     53     if(k>pct) return 0;
     54     int x=rt;
     55     while(1){
     56         int w=siz[ch[x][0]];
     57         if(k<=w) x=ch[x][0];
     58         else if(k==w+1) return x;
     59         else k-=w+1,x=ch[x][1];
     60     }
     61 }
     62 
     63 inline void insert(int x,char y){
     64     int p=findkth(x+1);
     65     splay(p,0);
     66     int q=findkth(x+2);
     67     splay(q,p);
     68     int n=++pct;
     69     sum[n]=v[n]=y,siz[n]=1;fa[n]=q,ch[q][0]=n;
     70     splay(n,0);
     71 }
     72 
     73 inline void change(int x,char y){
     74     int p=findkth(x+1);
     75     v[p]=y;update(p);
     76     splay(p,0);
     77 }
     78 
     79 inline ull query(int x,int y){
     80     int p=findkth(x);
     81     if(!p) return RUA;
     82     splay(p,0);
     83     int q=findkth(y+2);
     84     if(!q) return RUA;
     85     splay(q,p);
     86     return sum[ch[q][0]];
     87 }
     88 
     89 int main(){
     90     //freopen("","r",stdin);
     91     int i,j,k;
     92     bin[0]=1;for(i=1;i<=1e5;i++) bin[i]=bin[i-1]*P;
     93     ch[rt=1][1]=2;siz[1]=2;
     94     fa[pct=2]=1;siz[2]=1;
     95     scanf("%s",s+1);int len=strlen(s+1);
     96     for(i=1;i<=len;i++){
     97         insert(i-1,s[i]);
     98     }
     99     M=rd();
    100     for(i=1;i<=M;i++){
    101         char op[5];scanf("%s",op);
    102         if(op[0]=='Q'){
    103             int x=rd(),y=rd();
    104             int l=1,r=pct-2,ans=0;
    105             while(l<=r){
    106                 int m=l+r>>1;
    107                 ull a=query(x,x+m-1),b=query(y,y+m-1);
    108                 if(a==b&&a!=RUA) ans=m,l=m+1;
    109                 else r=m-1;
    110             }
    111             printf("%d
    ",ans);
    112         }else if(op[0]=='I'){
    113             int x=rd();scanf("%s",op);
    114             insert(x,op[0]);
    115         }else{
    116             int x=rd();scanf("%s",op);
    117             change(x,op[0]);
    118         }
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    eclipse FilteredTree
    Windows API高精度计时 C#版
    循环中响应消息,避免循环时UI线程被阻塞
    Linux rpm 包制作 使用 rpmbuild
    利用Windows API实现精确计时
    C++显示选择文件夹对话框
    android AsyncTask
    [转]Android 动画学习笔记
    eclipse 中导入android 工程时出错:The method of type must override a superclass method 解决方式
    Android 自定义对话框
  • 原文地址:https://www.cnblogs.com/Ressed/p/9957317.html
Copyright © 2020-2023  润新知