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

    题目链接:戳我

    树链剖分把树上问题转换成序列上的问题qwq,然后求链上小于i-k的节点个数。

    可以离线做,先把所有操作读入,这样就不需要中间的修改了qwq

    然后就是大力主席树了qwqwq

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<ctime>
    #include<cmath>
    #define MAXN 400010
    
    using namespace std;
    int n,m,tt,tot,root,cnt;
    int head[MAXN<<1],fa[MAXN],st[MAXN],rt[MAXN],sum[MAXN<<4],lc[MAXN<<4],rc[MAXN<<4];
    int dep[MAXN],top[MAXN],siz[MAXN],son[MAXN],id[MAXN];
    struct Node{int u,v,k,op;}node[MAXN];
    struct Edge{int nxt,to;}edge[MAXN<<1];
    
    inline void add(int from,int to){edge[++tt].nxt=head[from],edge[tt].to=to,head[from]=tt;}
    
    inline void insert(int &x,int f,int l,int r,int pos)
    {
        x=++tot;
        //printf("x=%d p=%d l=%d r=%d pos=%d
    ",x,f,l,r,pos);
        lc[x]=lc[f],rc[x]=rc[f],sum[x]=sum[f]+1;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(pos<=mid) insert(lc[x],lc[f],l,mid,pos);
        else insert(rc[x],rc[f],mid+1,r,pos);
    }
    
    inline int query(int l,int r,int ll,int rr,int k)
    {
        if(l==r) return sum[rr]-sum[ll];
        int mid=(l+r)>>1;
        if(k<=mid) return query(l,mid,lc[ll],lc[rr],k);
        else return sum[lc[rr]]-sum[lc[ll]]+query(mid+1,r,rc[ll],rc[rr],k);
    }
    
    inline void build(int x)
    {
        insert(rt[x],rt[fa[x]],1,m,st[x]);
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            build(v);
        }
    }
    
    inline void dfs1(int x)
    {
        siz[x]=1;
        int maxx=-1;
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            dep[v]=dep[x]+1;
            dfs1(v);
            siz[x]+=siz[v];
            if(siz[v]>maxx) maxx=siz[v],son[x]=v;
        }
    }
    
    inline void dfs2(int x,int topf)
    {
        top[x]=topf;
        id[x]=++cnt;
        if(son[x]) dfs2(son[x],topf);
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v==son[x]) continue;
            dfs2(v,v);
        }
    }
    
    inline int LCA(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if(dep[x]<dep[y]) return x;
        else return y;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        freopen("ce.out","w",stdout);
        #endif
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&fa[i]);
            if(fa[i]==0) root=i; 
            add(fa[i],i);
        }
        scanf("%d",&m);
        for(int i=1;i<=n;i++) st[i]=m;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&node[i].op);
            if(node[i].op==1) scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].k);
            else scanf("%d",&node[i].u),st[node[i].u]=i;
        }
        dep[root]=1;
        dfs1(root);
        dfs2(root,root);
        build(root);
        //for(int i=1;i<=n;i++) printf("rt[%d]=%d
    ",i,rt[i]); puts("");
        //for(int i=1;i<=n;i++) printf("dep[%d]=%d
    ",i,dep[i]); puts("");
        //for(int i=1;i<=n;i++) printf("fa[%d]=%d
    ",i,fa[i]);
        for(int i=1;i<=m;i++)
        {
            int op=node[i].op,u,v,k;
            if(op==1)
            {
                u=node[i].u,v=node[i].v,k=node[i].k;
                int lca=LCA(u,v);
                int cur_ans=0;
                if(i-k<=1) 
                {
                    printf("%d 0
    ",dep[u]+dep[v]-2*dep[lca]+1);
                    continue;
                }
                cur_ans+=query(1,m,rt[lca],rt[u],i-k-1);
                cur_ans+=query(1,m,rt[lca],rt[v],i-k-1);
                cur_ans+=(st[lca]<(i-k));
                printf("%d %d
    ",dep[u]+dep[v]-2*dep[lca]+1,cur_ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Java 回调函数的理解
    Java对象初始化
    Hibernate中get方法和load方法的区别
    Java 如何判断导入表格某列是否有重复数据
    Java学习之Java的单例模式
    Java中怎么设置文件权限
    div居中问题
    JSON
    js
    ajax
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10445317.html
Copyright © 2011-2022 走看看