• 【bzoj1014】: [JSOI2008]火星人prefix 平衡树-字符串-hash-二分


    【bzoj1014】: [JSOI2008]火星人

    用平衡树维护字符串的hash

    然后询问的时候二分一下就好了

      1 /* http://www.cnblogs.com/karl07/ */
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <algorithm>
      7 using namespace std;
      8 #define ull unsigned long long
      9 
     10 const int N=1000005;
     11 const int P=131;
     12 struct tre{
     13     int key,sz,t;
     14     ull hash;
     15     tre *ls,*rs;
     16 }t[N*3],*NEW=t,*null=t,*root,*r1,*r2,*r3;
     17 ull base[N];
     18 char s[N];
     19 int n;
     20 
     21 inline tre *new1(int x){
     22     NEW++;
     23     NEW->t=x;
     24     NEW->key=rand();
     25     NEW->sz=1;
     26     NEW->hash=x;
     27     NEW->ls=NEW->rs=null;
     28     return NEW;
     29 }
     30 
     31 inline void update(tre *p){
     32     p->sz=p->ls->sz+1+p->rs->sz;
     33     p->hash=p->ls->hash*base[p->rs->sz+1]+p->t*base[p->rs->sz]+p->rs->hash;
     34 }
     35 
     36 void merge(tre *&p,tre *x,tre *y){
     37     if (x==null) { p=y; return; }
     38     if (y==null) { p=x; return; }
     39     if (x->key>y->key){
     40         p=x;
     41         merge(p->rs,p->rs,y);
     42     }else{
     43         p=y;
     44         merge(p->ls,x,p->ls);
     45     }
     46     update(p);
     47 }
     48 
     49 void split(tre *p,tre *&x,tre *&y,int k){
     50     if (k==0) { x=null,y=p; return; }
     51     if (k==p->sz) { y=null,x=p; return; }
     52     if (k>=p->ls->sz+1){
     53         x=p;
     54         split(p->rs,p->rs,y,k-p->ls->sz-1);
     55     }else{
     56         y=p;
     57         split(p->ls,x,p->ls,k);
     58     }
     59     update(p);
     60 }
     61 
     62 void HASH(){
     63     null->ls=null->rs=null;
     64     null->hash=0;
     65     null->sz=null->t=0;
     66     null->key=-1;
     67     root=null;
     68     base[0]=1;
     69     for (int i=1;i<N;i++) base[i]=base[i-1]*P; 
     70 }
     71 
     72 inline ull Q(tre *p,int l,int x){
     73     ull ans;
     74     split(root,r1,r2,l-1);
     75     split(r2,r2,r3,x);
     76     ans=r2->hash;
     77     merge(r2,r2,r3);
     78     merge(root,r1,r2);
     79     return ans;
     80 }
     81 
     82 inline void R(int l,int x){
     83     split(root,r1,r2,l-1);
     84     split(r2,r2,r3,1);
     85     merge(r1,r1,new1(x));
     86     merge(root,r1,r3);
     87 }
     88 
     89 inline void I(int l,int x){
     90     split(root,r1,r2,l);
     91     merge(r1,r1,new1(x));
     92     merge(root,r1,r2);
     93 }
     94 
     95 inline int query(int x,int y){
     96     if (x>y) swap(x,y); 
     97     int l=0,r=root->sz-y+1,ans=0;
     98     while (l<=r){
     99         int mid=(l+r)/2;
    100         ull a1=Q(root,x,mid),a2=Q(root,y,mid);
    101         if (a1==a2){
    102             ans=mid;
    103             l=mid+1;
    104         }else{
    105             r=mid-1;
    106         }
    107     }
    108     return ans;
    109 }
    110 
    111 int main(){
    112     HASH();
    113     scanf("%s",s);
    114     scanf("%d",&n);
    115     for (int i=0,l=strlen(s);i<=l-1;i++){
    116         merge(root,root,new1(s[i]));
    117     }
    118     for (int i=1,x,y;i<=n;i++){
    119         char ss[10],s1[10];
    120         scanf("%s",ss);
    121         if (ss[0]=='Q') { scanf("%d%d",&x,&y); printf("%d
    ",query(x,y)); }
    122         if (ss[0]=='R') { scanf("%d%s",&x,s1); R(x,s1[0]);}
    123         if (ss[0]=='I') { scanf("%d%s",&x,s1); I(x,s1[0]);}     
    124     }
    125     return 0;
    126 }
    View Code

    并不会splay。。只会非旋转treap。。10s正好卡过去。。药丸

  • 相关阅读:
    如何判断PHP 是ts还是nts版的
    让IE支持placeholder属性
    解决点击浏览器后退按钮页面过期的问题
    git记住用户名密码
    php保存base64数据
    azure注册码
    SQL Server 2008 R2密钥序列号
    SQL允许远程访问
    PHP生成表格
    PHP发起get post put delete请求
  • 原文地址:https://www.cnblogs.com/karl07/p/6746239.html
Copyright © 2020-2023  润新知