hdu 5790 prefix 主席树

来源:互联网 发布:新疆公路计价软件 编辑:程序博客网 时间:2024/05/19 07:10

这道题目其实和 spoj上的d-query 差不多  http://blog.csdn.net/mtrix/article/details/52335617,

本质都是统计连续区间不同数个数,本来有 离线+树状数组 和在线主席树 两种做法,

这里强制在线那就主席树,对每个前缀要判断它有没有出现过可以用hash也可以字典树。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>#include <map>#include <cstring>#define mid (l+r>>1)using namespace std;const int maxn=100000+5;int root[maxn];int data[maxn*40],ls[maxn*40],rs[maxn*40];int cnt1;map<int,int> cnt;int Next[maxn][26],tot;int rt;inline void read(int &z)  {    bool sig = false;    char ch = getchar();    while (ch<'0' || ch>'9') {ch=='-'?sig=true:false;ch = getchar();}    int x = ch - '0';    while ((ch = getchar()) >= '0'&&ch <= '9') x = x * 10 + ch - '0';    z = sig ? -x : x;}inline void out(int x){    if ( x > 9 ) out ( x / 10 );    putchar ( x % 10 + '0');}int newnode(){    int t=tot++;    fill(Next[t],Next[t]+26,-1);    return t;}void ini(){    tot=0;    rt=newnode();    cnt.clear();}int build(int l,int r){    int t=cnt1++;    data[t]=0;    if(l==r)return t;    ls[t]=build(l,mid);    rs[t]=build(mid+1,r);    return t;}int update(int p,int l,int r,int v,int w){    int t=cnt1++;    data[t]=data[p]+w;    if(l==r) return t;    if(v<=mid){        rs[t]=rs[p];        ls[t]=update(ls[p],l,mid,v,w);    }    else{        ls[t]=ls[p];        rs[t]=update(rs[p],mid+1,r,v,w);    }    return t;}int query(int t,int l,int r,int v){    if(l==r)return data[t];    if(v<=mid)return query(ls[t],l,mid,v)+data[rs[t]];    else return query(rs[t],mid+1,r,v);}char s[maxn];string a[maxn];int b[maxn];int main(){    int n;    while(~scanf("%d",&n)){        cnt1=1;        ini();        int siz=0;        for(int i=1;i<=n;i++){            scanf("%s",s);            a[i]=string(s);            b[i-1]=siz;            siz+=a[i].length();        }        b[n]=siz;        root[0]=build(1,siz);        for(int i=1;i<=n;i++){            int tmp=rt;            for(int j=0;j<a[i].length();j++){                int &t=Next[tmp][a[i][j]-'a'];                if(t==-1){                    root[b[i-1]+j+1]=update(root[b[i-1]+j],1,siz,b[i-1]+j+1,1);                    t=newnode();                }                else{                    int tmp1=update(root[b[i-1]+j],1,siz,cnt[t],-1);                    root[b[i-1]+j+1]=update(tmp1,1,siz,b[i-1]+j+1,1);                }                cnt[t]=b[i-1]+j+1;                tmp=t;            }        }        int m;        scanf("%d",&m);        int Z=0;        for(int i=0;i<m;i++){            int l,r,L,R;read(l);read(r);            L=min((Z+l)%n,(Z+r)%n)+1;            R=max((Z+l)%n,(Z+r)%n)+1;            Z=query(root[b[R]],1,siz,b[L-1]+1);            out(Z);puts("");        }    }    return 0;}


0 0