zoukankan      html  css  js  c++  java
  • BZOJ 4448 情报传递

    注意到可以转化为静态。直接建树上主席树。

    1A了赞。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 200500
    #define maxe 400500
    using namespace std;
    int n,g[maxv],nume=0,m,val[maxv],anc[maxv][21],dis[maxv],a,b,c,type,cnt=0,rt;
    int root[maxv],tot=0,ls[maxv<<4],rs[maxv<<4],sum[maxv<<4];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    struct query
    {
        int x,y,id,c;
    }q[maxv];
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void modify(int last,int &now,int left,int right,int pos)
    {
        now=++tot;sum[now]=sum[last]+1;
        if (left==right) return;
        ls[now]=ls[last];rs[now]=rs[last];
        int mid=left+right>>1;
        if (pos<=mid) modify(ls[last],ls[now],left,mid,pos);
        else modify(rs[last],rs[now],mid+1,right,pos);
    }
    void dfs1(int x)
    {
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=anc[x][0])
            {
                anc[v][0]=x;dis[v]=dis[x]+1;
                dfs1(v);
            }
        }
    }
    void dfs2(int x)
    {
        if (val[x]) modify(root[anc[x][0]],root[x],1,m,val[x]);
        else root[x]=root[anc[x][0]];
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=anc[x][0])
                dfs2(v);
        }
    }
    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];
    }
    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 build_tree()
    {
        build(root[0],1,m);
        dfs2(rt);
    }
    int lca(int x,int 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 ask(int n1,int n2,int n3,int n4,int left,int right,int l,int r)
    {
        if (l>r) return 0;
        if ((left==l) && (right==r))
            return sum[n3]+sum[n4]-sum[n1]-sum[n2];
        int mid=left+right>>1;
        if (r<=mid) return ask(ls[n1],ls[n2],ls[n3],ls[n4],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[n1],rs[n2],rs[n3],rs[n4],mid+1,right,l,r);
        else return ask(ls[n1],ls[n2],ls[n3],ls[n4],left,mid,l,mid)+ask(rs[n1],rs[n2],rs[n3],rs[n4],mid+1,right,mid+1,r);
    }
    void work(int now)
    {
        int x=q[now].x,y=q[now].y,id=q[now].id,c=q[now].c;
        if (dis[x]<dis[y]) swap(x,y);
        int t=lca(x,y);
        printf("%d %d
    ",dis[x]+dis[y]-dis[t]-dis[anc[t][0]],ask(root[anc[t][0]],root[t],root[x],root[y],1,m,1,id-c-1));
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            if (a) {addedge(a,i);addedge(i,a);}
            else rt=i;
        }
        dis[rt]=1;dfs1(rt);get_table();
        scanf("%d",&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&type);
            if (type==1)
            {
                scanf("%d%d%d",&a,&b,&c);
                cnt++;
                q[cnt].x=a;q[cnt].y=b;q[cnt].id=i;q[cnt].c=c;
            }
            else
            {
                scanf("%d",&a);
                val[a]=i;
            }
        }
        build_tree();
        for (int i=1;i<=cnt;i++)
            work(i);
        return 0;
    }
  • 相关阅读:
    api接口安全
    php读取大文件
    thinkphp5.0的工作流程
    php扩展包索引
    redis学习之持久化与内存淘汰机制
    mysql优化之分区
    简练软考知识点整理-控制干系人参与
    简练软考知识点整理-控制干系人参与
    简练软考知识点整理-管理干系人参与
    简练软考知识点整理-管理干系人参与
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5903551.html
Copyright © 2011-2022 走看看