zoukankan      html  css  js  c++  java
  • 【bzoj4448】SCOI2015 情报传递

    树剖,可以相当于一个染色问题,以及询问先前节点的染色个数。

    把第二种操作离线掉,然后用线段树模拟即可。

    #include<bits/stdc++.h>
    #define N 800010
    #define lson (o<<1)
    #define rson (o<<1|1)
    using namespace std;
    struct Edge{int u,v,next;}G[N<<1];
    int head[N],tot=0,wson[N],size[N],d[N],fa[N],top[N],tpos[N],pre[N],cnt,n;
    struct Query{int id,t,x,y,opt;}a[N];
    bool operator <(Query a,Query b){return (a.t<b.t)||(a.t==b.t&&a.opt==2&&b.opt==1);}
    int sum[3][N],rt;
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int f[N];
    inline void addedge(int u,int v){
        G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot;
        G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot;
    }
    void dfs1(int u,int f){
        size[u]=1;
        for(int i=head[u];i;i=G[i].next){
            int v=G[i].v;if(v==f)continue;
            fa[v]=u;d[v]=d[u]+1;
            dfs1(v,u);
            size[u]+=size[v];
            if(size[v]>size[wson[u]])wson[u]=v;
        }
    }
    void dfs2(int u,int tp){
        tpos[u]=++cnt;pre[cnt]=u;top[u]=tp;
        if(wson[u])dfs2(wson[u],tp);
        for(int i=head[u];i;i=G[i].next){
            int v=G[i].v;if(v==fa[u]||v==wson[u])continue;
            dfs2(v,v);
        }
    }
    struct Segment_Tree{
        int cntv[N<<2];
        void change(int o,int l,int r,int q){
            cntv[o]++;if(l==r)return;
            int mid=(l+r)>>1;
            if(q<=mid)change(lson,l,mid,q);
            else change(rson,mid+1,r,q);
        }
        int query(int o,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return cntv[o];
            int mid=(l+r)>>1,ans=0;
            if(ql<=mid)ans+=query(lson,l,mid,ql,qr);
            if(qr>mid)ans+=query(rson,mid+1,r,ql,qr);
            return ans;
        }
    }T;
    void query(int u,int v,int id){
        int ans=0;int xx=u,yy=v;f[id]=1;
        while(top[u]!=top[v]){
            if(d[top[u]]<d[top[v]])swap(u,v);
            ans+=T.query(1,1,n,tpos[top[u]],tpos[u]);u=fa[top[u]];
        }
        if(d[u]<d[v])swap(u,v);
        ans+=T.query(1,1,n,tpos[v],tpos[u]);
        sum[1][id]=d[xx]+d[yy]-2*d[v]+1;sum[2][id]=ans;
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++){fa[i]=read();if(!fa[i])rt=i;else addedge(fa[i],i);}
        dfs1(rt,0);dfs2(rt,rt);int m=read();
        for(int i=1;i<=m;i++){
            a[i].opt=read();a[i].id=i;
            if(a[i].opt==2){a[i].x=read();a[i].t=i;}
            else{
                a[i].x=read();a[i].y=read();int tmp=read();
                a[i].t=i-tmp-1;
            }
        }
        sort(a+1,a+m+1);
        for(int i=1;i<=m;i++)if(a[i].opt==2)T.change(1,1,n,tpos[a[i].x]);
        else query(a[i].x,a[i].y,a[i].id);
        for(int i=1;i<=m;i++)if(f[i])printf("%d %d
    ",sum[1][i],sum[2][i]);
    }
  • 相关阅读:
    eclipse不提示
    怎么在eclipse中安装properties插件
    表单验证之validform.js使用方法
    Activiti Service介绍
    activiti插件安装-离线安装
    三分钟明白 Activiti工作流 -- java运用
    Eclipse中快捷键Ctrl + Alt + 向上箭头 或者 Ctrl + Alt + 向下箭头与Windows冲突
    Eclipse 从git导入maven多模块项目
    封印
    教主的花园
  • 原文地址:https://www.cnblogs.com/zcysky/p/7128111.html
Copyright © 2011-2022 走看看