zoukankan      html  css  js  c++  java
  • BZOJ 4285 使者

    我TM再也不写BIT套主席树了。。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 200500
    #define maxe 200500
    using namespace std;
    int n,m,q,type,x,y,g[maxv],nume=0,dfn[maxv],mx[maxv],fdfn[maxv],dis[maxv],anc[maxv][23],times=0;
    int root[maxv*2],sum[maxv*180],tot=0,ls[maxv*180],rs[maxv*180];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    int lowbit(int x)
    {
        return (x&(-x));
    }
    void dfs(int x,int fath)
    {
        dfn[x]=++times;fdfn[times]=x;mx[x]=dfn[x];
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=fath)
            {
                anc[v][0]=x;dis[v]=dis[x]+1;
                dfs(v,x);
                mx[x]=max(mx[x],mx[v]);
            }
        }
    }
    void build(int &now,int left,int right)
    {
        now=++tot;sum[now]=0;
        if (left==right) return;
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
    }
    void get_table()
    {
        for (int e=1;e<=20;e++)
            for (int i=1;i<=n;i++)
                anc[i][e]=anc[anc[i][e-1]][e-1];
    }
    int lca(int x,int y)
    {
        if (dis[x]<dis[y]) swap(x,y);
        if (dis[x]!=dis[y])
        {
            for (int e=20;e>=0;e--)
            {
                if ((dis[anc[x][e]]>=dis[y]) && (anc[x][e]))
                    x=anc[x][e];
            }
        }
        if (x==y) return x;
        for (int e=20;e>=0;e--)
        {
            if (anc[x][e]!=anc[y][e])
            {
                x=anc[x][e];
                y=anc[y][e];
            }
        }
        return anc[x][0];
    }
    int find(int x,int pos)
    {
        for (int e=20;e>=0;e--)
            if (dis[anc[x][e]]>dis[pos])
                x=anc[x][e];
        return x;
    }
    void modify(int last,int x,int pos,int val)
    {
        root[x]=++tot;
        int now=root[x];sum[now]=sum[last]+val;
        int left=1,right=n;
        while (left<right)
        {
            int mid=(left+right)>>1;
            ls[now]=ls[last];rs[now]=rs[last];
            if (pos<=mid)
            {
                ls[now]=++tot;
                sum[ls[now]]=sum[ls[last]]+val;
                now=ls[now];last=ls[last];right=mid;
            }
            else
            {
                rs[now]=++tot;
                sum[rs[now]]=sum[rs[last]]+val;
                now=rs[now];last=rs[last];left=mid+1;
            }
        }
    }
    void add(int x,int pos,int val)
    {
        for (int i=x;i<=n;i+=lowbit(i))
            modify(root[i],i,pos,val);
    }
    void build_tree()
    {
        build(root[0],1,n);
        for (int i=1;i<=n;i++)
        {
            root[i]=++tot;
            ls[root[i]]=ls[root[i-1]];rs[root[i]]=rs[root[i-1]];
        }
        scanf("%d",&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(dfn[x],dfn[y],1);
            add(dfn[y],dfn[x],1);
        }
    }
    int ask(int now,int left,int right,int l,int r)
    {
        if ((left==l) && (right==r))
            return sum[now];
        int mid=(left+right)>>1;
        if (r<=mid) return ask(ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
        else return ask(ls[now],left,mid,l,mid)+ask(rs[now],mid+1,right,mid+1,r);
    }
    int ask_(int now,int left,int right)
    {
        int ret=0;
        for (int i=now;i>=1;i-=lowbit(i))
            ret+=ask(root[i],1,n,left,right);
        return ret;
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n-1;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);addedge(y,x);
        }
        dfs(1,1);
        get_table();
        build_tree();
        scanf("%d",&q);
        for (int i=1;i<=q;i++)
        {
            scanf("%d%d%d",&type,&x,&y);
            if (type==1)
            {
                add(dfn[x],dfn[y],1);
                add(dfn[y],dfn[x],1);
            }
            else if (type==2)
            {
                add(dfn[x],dfn[y],-1);
                add(dfn[y],dfn[x],-1);
            }
            else
            {
                int t=lca(x,y);
                if (t==y)
                {
                    int r=find(x,y);
                    int ret1=ask_(mx[x],1,n)-ask_(dfn[x]-1,1,n);
                    int ret2=ask_(mx[x],dfn[r],mx[r])-ask_(dfn[x]-1,dfn[r],mx[r]);
                    printf("%d
    ",ret1-ret2);
                }
                else if (t==x)
                {
                    int r=find(y,x);
                    int ret1=ask_(n,dfn[y],mx[y]);
                    int ret2=ask_(mx[r],dfn[y],mx[y])-ask_(dfn[r]-1,dfn[y],mx[y]);
                    printf("%d
    ",ret1-ret2);
                }
                else
                    printf("%d
    ",ask_(mx[x],dfn[y],mx[y])-ask_(dfn[x]-1,dfn[y],mx[y]));
            }
        }
        return 0;
    }
  • 相关阅读:
    ACE反应器(Reactor)模式(1)
    net 命令
    ACE反应器(Reactor)模式(2)
    恢复SQLServer实例连接 (转载)
    在SQL Server Management Studio中可以运行作业但是用TSQL运行则失败 (转载)
    VirtualBox 之 共享磁盘
    从 IClassFactory 为 CLSID 为 {0002450000000000C000000000000046} 的 COM 组件创建实例失败,原因是出现以下错误: 8001010a解决办法 .
    SQLServer数据类型优先级对性能的影响 (转)
    封装getElementsByAttribute
    js中setAttribute 的兼容性
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5865142.html
Copyright © 2011-2022 走看看