• spoj COT2(树上莫队)


    模板。树上莫队的分块就是按dfn分,然后区间之间转移时注意一下就好。有个图方便理解http://blog.csdn.net/thy_asdf/article/details/47377709;

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=50010;
    int ccc[maxn],col[maxn],n,m,last[maxn],pre[maxn*2],other[maxn*2],d[maxn],bel[maxn],f[maxn][25];
    int res,bo,ind,dfn[maxn],ans[maxn*2],t,cnt,sta[maxn],top,vis[maxn],tong[maxn],ttt[maxn];
    struct que{
        int u,v,id;
        bool operator<(const que&tmp)const{
            if(bel[u]==bel[tmp.u])return dfn[v]<dfn[tmp.v];
            return bel[u]<bel[tmp.u];
        }
    }q[maxn*2];
    void add(int x,int y){++t;pre[t]=last[x];last[x]=t;other[t]=y;}
    int dfs(int x){
        int siz=0;
        dfn[x]=++ind;
        for(int i=last[x];i;i=pre[i]){
            int v=other[i];
            if(v==f[x][0])continue;
            d[v]=d[x]+1;f[v][0]=x;
            siz+=dfs(v);
            if(siz>=bo){
                ++cnt;
                for(int j=1;j<=siz;++j)
                bel[sta[top--]]=cnt;
                siz=0;
            }
        }
        sta[++top]=x;
        return siz+1;
    }
    void change(int x){
        if(!vis[x]){vis[x]=1;tong[col[x]]++;if(tong[col[x]]==1)res++;}
        else{vis[x]=0;tong[col[x]]--;if(tong[col[x]]==0)res--;}
    }
    void solve(int u,int v){
        while(u!=v){
            if(d[u]>d[v])change(u),u=f[u][0];
            else change(v),v=f[v][0];
        }
    }
    int lca(int x,int y){
        if(d[x]<d[y])swap(x,y);
        for(int i=20;i>=0;--i)
        if(d[f[x][i]]>=d[y])x=f[x][i];
        if(x==y)return x;
        for(int i=20;i>=0;--i)
        if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    int main(){
        cin>>n>>m;
        int x,y;bo=sqrt(n+0.5);
        for(int i=1;i<=n;++i){
            scanf("%d",&ccc[i]);
            ttt[i]=ccc[i];
        }
        sort(ttt+1,ttt+n+1);
        int len=unique(ttt+1,ttt+n+1)-ttt-1;
        for(int i=1;i<=n;++i){
            col[i]=lower_bound(ttt+1,ttt+len+1,ccc[i])-ttt;
        }
        for(int i=1;i<n;++i){
            scanf("%d%d",&x,&y);
            add(x,y);add(y,x);
        }
        d[1]=1;dfs(1);
        ++cnt;
        while(top)bel[sta[top--]]=cnt;
        for(int j=1;j<=20;++j)
          for(int i=1;i<=n;++i)
            f[i][j]=f[f[i][j-1]][j-1];
        for(int i=1;i<=m;++i){
            q[i].id=i;
            scanf("%d%d",&q[i].u,&q[i].v);
            if(dfn[q[i].u]>dfn[q[i].v])swap(q[i].u,q[i].v);
        }
        sort(q+1,q+m+1);
        int op=lca(q[1].u,q[1].v);
        solve(q[1].u,q[1].v);
        change(op);ans[q[1].id]=res;change(op);
        for(int i=2;i<=m;++i){
            solve(q[i-1].u,q[i].u);solve(q[i-1].v,q[i].v);
            op=lca(q[i].u,q[i].v);
            change(op);ans[q[i].id]=res;change(op);
        }
        for(int i=1;i<=m;++i){
            printf("%d
    ",ans[i]);
        }
        //system("pause");
        return 0;
    }
  • 相关阅读:
    [问题2014A13] 解答
    [问题2014A12] 解答
    [问题2014A13] 复旦高等代数 I(14级)每周一题(第十五教学周)
    [问题2014A10] 解答
    php使用amqplib方式使用rabbitmq
    Ubuntu 16.04 源码编译安装PHP7+swoole
    Ubuntu apt-get更换阿里云源
    微信企业号网页授权
    nginx转发swoole以及nginx负载
    PHP 命名空间
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8353227.html
Copyright © 2020-2023  润新知