NOIP大纲整理:(九)树结构的模板*3

1、树状数组

暂时代码是转载的,以后有机会会更新,看不懂请跳过

例:HDU 1166
#include<stdio.h>
#include<math.h>
const intMAX = 50010 * 4;
intsegment[MAX];
voidpushUp(int root)
{
    segment[root] = segment[root * 2] + segment[root* 2 + 1];
}
voidbuildTree(int root, int left, int right)
{
    if(left == right)
    {
        scanf("%d",&segment[root]);
        return;
    }
    int mid = (left + right) / 2;
    buildTree(root * 2, left, mid);
    buildTree(root * 2 + 1, mid + 1, right);
    pushUp(root);
}
voidupdate(int root, int pos, int add_num, int left, int right)
{
    if (left == right)
    {
        segment[root] += add_num;
        return;
    }
    int mid = (left + right) / 2;
    if (pos <= mid)
        update(root * 2, pos, add_num, left,mid);
    else
        update(root * 2 + 1, pos, add_num, mid+ 1, right);
    pushUp(root);
}
intgetSum(int root, int left, int right, int L, int R)
{
    if(left == L && right == R)
    {
        return segment[root];
    }
    int mid = (L + R) / 2;
    int res = 0;
    if(left > mid)
    {
        res += getSum(root * 2 + 1, left,right, mid + 1, R);
    }
    else if(right <= mid)
    {
        res += getSum(root * 2, left, right, L,mid);
    }
    else
    {
        res += getSum(root * 2, left, mid, L,mid);
        res += getSum(root * 2 + 1, mid + 1,right, mid + 1, R);
    }
    return res;
}
int main()
{
    int T;
    scanf("%d", &T);
    for(int kase = 1; kase <= T; kase++)
    {
 
        int n;
        scanf("%d", &n);
        buildTree(1, 1, n);
        char op[10];
        int t1, t2;
        printf("Case %d:\n", kase);
        while(scanf("%s", op))
        {
            if(op[0] == 'E')
                break;
            scanf("%d %d", &t1,&t2);
            if(op[0] == 'A')
            {
                update(1, t1, t2, 1, n);
            }
            else if(op[0] == 'S')
            {
                update(1, t1, -t2, 1, n);
            }
            else
            {
                printf("%d\n",getSum(1, t1, t2, 1, n));
            }
        }
    }
    return 0;
}

2、线段树

例:HDU 1542
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
usingnamespace std;
constint SIZE=505;
intadd[SIZE<<2];           
doublex[SIZE<<2],sum[SIZE<<2];
structnode{
    int ss;                                   
    double l,r,h;        
    node(){}
    node(double a,double b,double c,intd):l(a),r(b),h(c),ss(d){}
    friend bool operator<(node p,node q){
        return p.h<q.h;
    }
}s[SIZE];
voidpushup(int rt,int l,int r){
    if(add[rt]) 
    sum[rt]=x[r+1]-x[l];
    else if(l==r)
    sum[rt]=0;
    else
   sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
voidupdate(int L,int R,int c,int l,int r,int rt){
    int m;
    if(L<=l&&r<=R){
        add[rt]+=c;
        pushup(rt,l,r);
        return;
    }
    m=(l+r)>>1;
    if(L<=m)
    update(L,R,c,l,m,rt<<1);
    if(R>m)
    update(L,R,c,m+1,r,rt<<1|1);
    pushup(rt,l,r);
}
intmain(){
    int n,i,k,l,m,r,cas;
    double a,b,c,d,ans;
    cas=1;       
   while(scanf("%d",&n)!=EOF&&n){
        k=1,ans=m=0;
        for(i=0;i<n;i++){
           scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
            x[m]=a;
            s[m++]=node(a,c,b,1);
            x[m]=c;
            s[m++]=node(a,c,d,-1);
        }
        sort(x,x+m);
        sort(s,s+m);
        for(i=1;i<m;i++) 
        if(x[i]!=x[i-1])
        x[k++]=x[i];
        memset(add,0,sizeof(add));
        memset(sum,0,sizeof(sum));
        for(i=0;i<m-1;i++){
            l=lower_bound(x,x+k,s[i].l)-x;
            r=lower_bound(x,x+k,s[i].r)-x-1;
            update(l,r,s[i].ss,0,k-1,1);
            ans+=(sum[1]*(s[i+1].h-s[i].h));
        }
        printf("Test case #%d\nTotalexplored area: %.2lf\n\n",cas++,ans);
    } 
    return 0;
}

3、并查集

暂时代码是转载的,以后有机会会更新,看不懂请跳过

例:POJ 2492
#include<stdio.h>
#define N 2002
int fa[N],rank[N],resex[N];
void init(int len)
{
           int i;
           for(i=1;i<=len;i++)
           {
                     fa[i]=i;
                     rank[i]=0;
                     resex[i]=0;
           }
}
int find(int x)
{
           if(fa[x]!=x)
           {
                     fa[x]=find(fa[x]);//路径压缩
           }
           return fa[x];
}
void Union(int a,int b)
{
           int x=find(a);
           int y=find(b);
           if(rank[x]>rank[y])//按秩合并
                     fa[y]=x;
           else
           {
                     fa[x]=y;
                     if(rank[x]==rank[y])
                                rank[y]++;
           }
}
int main()
{
           int T,n,m,i,a,b,num=0,flag;
           scanf("%d",&T);
           while(num<T)
           {
                     flag=1;
                     num++;
                     scanf("%d%d",&n,&m);
                     init(n);
                     for(i=1;i<=m;i++)
                     {
                                scanf("%d%d",&a,&b);
                                if(!flag)continue;
                                int x=find(a);
                                int y=find(b);
                                if(x==y)flag=0;
                                if(resex[a]!=0)Union(resex[a],b);
                                else resex[a]=b;
                                if(resex[b]!=0)Union(resex[b],a);
                                else resex[b]=a;
                     }
                     printf("Scenario#%d:\n",num);
                     if(!flag)
                                printf("Suspiciousbugs found!\n\n");
                     else
                                printf("Nosuspicious bugs found!\n\n");
           }
           return 0;
}

4、后缀树

暂时代码是转载的,以后有机会会更新,看不懂请跳过

例:CodeForces 128B
#include<stdio.h>  
#include<string.h>  
#include<algorithm>  
#include<math.h>  
#include<iostream>  
#include<stdlib.h>  
#include<set>  
#include<map>  
#include<queue>  
#include<vector>  
#include<bitset>  
#pragma comment(linker, "/STACK:1024000000,1024000000")  
template <class T>  
bool scanff(T &ret){ //Faster Input  
    char c; int sgn; T bit=0.1;  
    if(c=getchar(),c==EOF) return 0;  
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();  
    sgn=(c=='-')?-1:1;  
    ret=(c=='-')?0:(c-'0');  
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');  
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }  
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;  
    ret*=sgn;  
    return 1;  
}  
#define inf 1073741823  
#define llinf 4611686018427387903LL  
#define PI acos(-1.0)  
#define lth (th<<1)  
#define rth (th<<1|1)  
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)  
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)  
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)  
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)  
#define mem(x,val) memset(x,val,sizeof(x))  
#define mkp(a,b) make_pair(a,b)  
#define findx(x) lower_bound(b+1,b+1+bn,x)-b  
#define pb(x) push_back(x)  
using namespace std;  
typedef long long ll;  
typedef pair<int,int> pii;  
#define SIZE 27  
struct suffixtree{  
        struct node{  
        int l,r,point,a[SIZE];  
        void init(){  
            mem(a,0);  
            point=l=0;  
            r=-1;  
        }  
    }T[400011];  
    char s[400011];  
    int actnode,actride,actline;  
    int rest,total,temp,linker,len;  
    void builtleaf(int root,int line){  
        total++;  
        T[total].init();  
        T[total].l=len;  
        T[total].r=100000001;  
        T[root].a[line]=total;  
        rest--;  
    }  
    bool pd_ride(int next){  
        temp=T[next].r-T[next].l+1;  
        if(actride>=temp){  
            actride-=temp;  
            actnode=next;  
            actline+=temp;  
            return true;  
        }  
        return false;  
    }  
    void link(int x){  
        if(linker>0)T[linker].point=x;  
        linker=x;  
    }  
    void insert(int wait){  
        s[++len]=wait;  
        rest++;  
        linker=0;  
        while(rest>0){  
            if(actride==0)actline=len;  
            if(T[actnode].a[s[actline]]==0){   
                builtleaf(actnode,s[actline]);  
                link(actnode);  
            }  
            else{  
                int next=T[actnode].a[s[actline]];  
                if(pd_ride(next))continue;  
                if(s[T[next].l+actride]==wait){  
                    actride++;  
                    link(actnode);  
                    break;  
                }    
                total++;  
                T[total].init();  
                T[actnode].a[s[actline]]=total;  
                T[total].l=T[next].l;  
                T[total].r=T[next].l+actride-1;  
                T[next].l+=actride;  
                T[total].a[s[T[next].l]]=next;  
                link(total);  
                builtleaf(total,wait);  
            }  
            if(actnode==0&&actride>0){  
                actride--;  
                actline=len-rest+1;  
            }  
            else actnode=T[actnode].point;  
        }  
    }  
    void clear(){  
        total=0;  
        len=0;  
        T[0].init();  
        actnode=actride=actline=0;  
    }  
    void debug(){  
        rep(i,0,total){  
            printf("T[%d] (%d %d)\n",i,T[i].l,T[i].r);  
        }  
    }  
}st;     
#define NN 400400  
char s[NN];  
ll cot[NN];  
ll sum;  
ll k;  
int len;  
ll getcot(int x){  
    ll temp=0;  
    ll bj=1;  
    rep(i,0,26){  
        if(st.T[x].a[i]){  
            bj=0;  
            temp+=getcot(st.T[x].a[i]);  
        }  
    }  
    cot[x]=temp+bj;  
    return cot[x];  
}  
ll edr,edx;  
int alen=0;  
char ans[NN];  
void dfs(int x){  
    sum+=(ll)(min(st.T[x].r,len)-st.T[x].l+1)*cot[x];  
    if(sum>=k){  
        edx=x;  
        edr=min(ll(st.T[x].r),ll(len));  
        while(sum-cot[x]>=k){  
            sum-=cot[x];  
            edr--;  
        }  
        //printf("%lld %lld\n",edx,edr);  
        //return;  
    }  
    rep(i,0,26){  
        if(st.T[x].a[i]&&sum<k){  
            dfs(st.T[x].a[i]);  
        }  
    }  
    if(sum>=k){  
        drep(i,min(edr,ll(st.T[x].r)),st.T[x].l){  
            ans[alen++]=s[i];  
        }  
    }  
}    
main(){  
    st.clear();  
    scanf("%s",s+1);  
    len=strlen(s+1);  
    rep(i,1,len)st.insert(s[i]-'a');  
    st.insert(26);  
    scanf("%lld",&k);  
    if(ll(len)*ll(len+1)/2LL<k){  
        printf("No such line.\n");  
        return 0;  
    }  
    getcot(0);  
    dfs(0);  
    ans[alen]=0;  
    reverse(ans,ans+alen);  
    printf("%s\n",ans);  
}  

猜你喜欢

转载自blog.csdn.net/liusu201601/article/details/81435508
今日推荐