【JSOI 2008】【BZOJ 1014】火星人prefix

来源:互联网 发布:iphone6手机壳淘宝 编辑:程序博客网 时间:2024/05/22 05:02

这题其实很奇怪,一眼看出fhq treap+字符串hash。。。
结果在BZOJ被卡常了,结果学长告诉我了一些优化,有些自己还不会写,只写了inline和吧unsigned long long改为unsigned int。。。
结果时间少了一半,谁能告诉我为什么。。。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;int m,len;char s[100000]; unsigned int mi[200000];struct treap_node{    treap_node *left,*right;    int fix,size;    unsigned int hashz;    char val;    treap_node(char val): val(val) {left=right=NULL; fix=rand(); hashz=(int)(val)-96; size=1; }    int lsize()      {        if (left)           return left->size;        else           return 0;      }    int rsize()      {        if (right)          return right->size;        else          return 0;       }    void Maintain()      {        size=1;        size+=lsize()+rsize();        hashz=(int)(val)-96;         if (left&&!right)          hashz=left->hashz+hashz*mi[lsize()];        if (!left&&right)          hashz=hashz+right->hashz*mi[1];         if (left&&right)          hashz=left->hashz+hashz*mi[lsize()]+right->hashz*mi[lsize()+1];      }};treap_node *root;typedef pair<treap_node*,treap_node*> droot;inline treap_node *merge(treap_node *a,treap_node *b){    if (!a) return b; if (!b) return a;    if (a->fix<b->fix)      {        a->right=merge(a->right,b);        a->Maintain();        return a;      }    else      {        b->left=merge(a,b->left);        b->Maintain();        return b;      }}inline droot split(treap_node *x,int k){    if (!x) return droot(NULL,NULL);    droot y;    if (k<=x->lsize())      {        y=split(x->left,k);        x->left=y.second;        x->Maintain();        y.second=x;      }    else      {        y=split(x->right,k-x->lsize()-1);        x->right=y.first;        x->Maintain();        y.first=x;      }    return y;}inline void insert(int xi,char ch){    droot x;    treap_node *temp;    x=split(root,xi);    temp=new treap_node(ch);    x.first=merge(x.first,temp);    root=merge(x.first,x.second);}inline void del(int xi,int k){    droot x,y;    x=split(root,xi-1);    y=split(x.second,1);    root=merge(x.first,y.second);}inline void work(int x,int y){    int l,r,mid,ans=0;    unsigned int t1,t2;    droot a,b;    l=1; r=min(len-x+1,len-y+1);    while (l<=r)      {        mid=(l+r)/2;          a=split(root,x-1); b=split(a.second,mid);        b.first->Maintain();        t1=b.first->hashz;        a.second=merge(b.first,b.second); root=merge(a.first,a.second);        a=split(root,y-1); b=split(a.second,mid);        b.first->Maintain();        t2=b.first->hashz;         a.second=merge(b.first,b.second); root=merge(a.first,a.second);        if (t1==t2)          l=mid+1,ans=mid;         else          r=mid-1;       }    printf("%d\n",ans);}int main(){    int i,x,y,t=0;    char opt,ch;    treap_node *temp;    scanf("%s",&s);    len=strlen(s);    scanf("%d",&m);    mi[0]=1;    for (i=1;i<=100000;++i)      mi[i]=mi[i-1]*27;     for (i=0;i<=len-1;++i)      {        temp=new treap_node(s[i]);        root=merge(root,temp);      }    for (i=1;i<=m;++i)      {        opt=getchar();        while (opt!='Q'&&opt!='R'&&opt!='I')          opt=getchar();        if (opt=='Q')          {            scanf("%d%d",&x,&y);            work(x,y);          }        if (opt=='I')          {            scanf("%d",&x);            ch=getchar();            while (ch<'a'||ch>'z')              ch=getchar();            insert(x,ch);            len++;          }             if (opt=='R')          {            scanf("%d",&x);            ch=getchar();            while (ch<'a'||ch>'z')              ch=getchar();            del(x,1);            insert(x-1,ch);          }      }}
2 0