两道模版题 UOj 35 和 bzoj1036

来源:互联网 发布:大数据hadoop分布式 编辑:程序博客网 时间:2024/06/05 03:01

      • 后缀数组排序
      • 树剖

后缀数组排序:

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+10;int n,k,p,q=1;char ch[N];int a[N],v[N],h[N],sa[2][N],rk[2][N];void mul(int *sa,int *rk,int *SA,int *RK){    fo(i,1,n) v[rk[sa[i]]]=i;    for(int i=n;i;i--)         if(sa[i]>k)            SA[v[rk[sa[i]-k]]--]=sa[i]-k;    for(int i=n-k+1;i<=n;i++)        SA[v[rk[i]]--]=i;    fo(i,1,n) RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);}void presa(){    for(int i=1;i<=n;i++)v[a[i]]++;    for(int i=1;i<=30;i++)v[i]+=v[i-1];    for(int i=1;i<=n;i++)        sa[p][v[a[i]]--]=i;    for(int i=1;i<=n;i++)        rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i-1]]!=a[sa[p][i]]);    for(k=1;k<n;k<<=1,swap(p,q))        mul(sa[p],rk[p],sa[q],rk[q]);    for(int i=1,k=0;i<=n;i++)    {        int j=sa[p][rk[p][i]-1];        while(a[i+k]==a[j+k])k++;        h[rk[p][i]]=k;if(k>0)k--;    }}int main(){    scanf("%s",ch+1);    n=strlen(ch+1);    fo(i,1,n) a[i]=ch[i]-'a'+1;    presa();    fo(i,1,n) printf("%d ",sa[p][i]); puts("");    fo(i,2,n) printf("%d ",h[i]); puts("");    return 0;}   

树剖

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=3e4+10,M=6e4+10,inf=(1<<30);int n,q,pos[N],v[N],dep[N],fa[N],size[N],bl[N], head[N],len,sz;struct Edge{int to,next;Edge(int to=0,int next=0):to(to),next(next){}}e[M];void add_edge(int from,int to){ e[++len]=Edge(to,head[from]); head[from]=len;}struct Seg{    int l,r,mx,sum;}t[N<<2];void init(){    scanf("%d",&n);    for(int from,to,i=1;i<n;i++)    {        scanf("%d%d",&from,&to);        add_edge(from,to);        add_edge(to,from);    }    fo(i,1,n) scanf("%d",&v[i]);}void dfs1(int x){    size[x]=1;    for(int i=head[x];i;i=e[i].next) {        int id=e[i].to;        if(id==fa[x]) continue;        fa[id]=x;        dep[id]=dep[x]+1;        dfs1(id);        size[id]+=size[x];    }}void dfs2(int x,int chain){    int k=0; pos[x]=++sz;    bl[x]=chain;    for(int i=head[x];i;i=e[i].next) {        int id=e[i].to;        if(dep[id]>dep[x]&&size[id]>size[k]) k=id;    }    if(k==0) return ;    dfs2(k,chain);    for(int i=head[x];i;i=e[i].next) {        int id=e[i].to;        if(dep[id]>dep[x]&&k!=id)             dfs2(id,id);    }   }void build(int k,int l,int r){    t[k].l=l; t[k].r=r;    if(l==r) return ;    int mid=(l+r)>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);}void change(int k,int x,int y){    int l=t[k].l,r=t[k].r,mid=(l+r)>>1;    if(l==r) {t[k].mx=t[k].sum=y;return ;}    if(x<=mid) change(k<<1,x,y);    else change(k<<1|1,x,y);    t[k].sum=t[k<<1].sum+t[k<<1|1].sum;    t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);}int querysum(int k,int x,int y){    int l=t[k].l,r=t[k].r,mid=(l+r)>>1;    if(l==x&&y==r) return t[k].sum;    if(y<=mid) return querysum(k<<1,x,y);    else if(x>mid) return querysum(k<<1|1,x,y);    else {return querysum(k<<1,x,mid)+querysum(k<<1|1,mid+1,y);}}int querymax(int k,int x,int y){    int l=t[k].l,r=t[k].r,mid=(l+r)>>1;    if(l==x&&y==r) return t[k].mx;    if(y<=mid) return querymax(k<<1,x,y);    else if(x>mid) return querymax(k<<1|1,x,y);    else {return max(querymax(k<<1,x,mid),querymax(k<<1|1,mid+1,y));}}int solvesum(int x,int y){    int sum=0;    while(bl[x]!=bl[y]) {        if(dep[bl[x]]<dep[bl[y]])  swap(x,y);        sum+=querysum(1,pos[bl[x]],pos[x]);        x=fa[bl[x]];    }    if(pos[x]>pos[y]) swap(x,y);    sum+=querysum(1,pos[x],pos[y]);    return sum;}int solvemx(int x,int y){    int mx=-inf;    while(bl[x]!=bl[y]) {        if(dep[bl[x]]<dep[bl[y]]) swap(x,y);        mx=max(querymax(1,pos[bl[x]],pos[x]),mx);        x=fa[bl[x]];    }    if(pos[x]>pos[y]) swap(x,y);    mx=max(mx,querymax(1,pos[x],pos[y]));    return mx;}void solve(){    build(1,1,n);    fo(i,1,n) change(1,pos[i],v[i]);    scanf("%d",&q);    char ch[10];    for(int x,y,i=1;i<=q;i++) {        scanf("%s%d%d",ch,&x,&y);        if(ch[0]=='C') {v[x]=y;change(1,pos[x],y);}        else {            if(ch[1]=='M') printf("%d\n",solvemx(x,y));            else printf("%d\n",solvesum(x,y));        }    }}int main(){    init();    dfs1(1);    dfs2(1,1);    solve();    return 0;}
原创粉丝点击