zoukankan      html  css  js  c++  java
  • BZOJ4448 SCOI2015情报传递(离线+树链剖分+树状数组)

      即滋磁单点修改,询问路径上小于某数的值有多少个。暴力树剖套个主席树(或者直接树上主席树,似乎就1个log了?感觉不一定比两个log快)即可,然而不太优美。

      开始觉得可以cdq,然而就变成log^3了。冷静一下感觉简直是个弱智,修改本身就是单调的,只要对询问离线即可。树剖+BIT即可维护。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 200010
    int n,m,root,fa[N],deep[N],p[N],t=0,cnt,cntu,cntq;
    int top[N],id[N],son[N],size[N],tree[N];
    struct data{int to,nxt;
    }edge[N];
    struct data2{int x,i;
    }u[N];
    struct data3{int x,y,z,i,ans;
    }q[N];
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    bool cmp(const data3&a,const data3&b)
    {
        return a.z<b.z;
    }
    bool cmp1(const data3&a,const data3&b)
    {
        return a.i<b.i;
    }
    void dfs1(int k)
    {
        size[k]=1;
        for (int i=p[k];i;i=edge[i].nxt)
        {
            deep[edge[i].to]=deep[k]+1;
            dfs1(edge[i].to);
            size[k]+=size[edge[i].to];
            if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;
        }
    }
    void dfs2(int k,int from)
    {
        top[k]=from;id[k]=++cnt;
        if (son[k]) dfs2(son[k],from);
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=son[k]) dfs2(edge[i].to,edge[i].to);
    }
    void mbit(int k){while (k<=n) tree[k]++,k+=k&-k;}
    int qbit(int k){int s=0;while (k) s+=tree[k],k-=k&-k;return s;}
    int lca(int x,int y) 
    {
        while (top[x]!=top[y])
        {
            if (deep[top[x]]<deep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        return deep[x]<deep[y]?x:y;
    }
    int query(int x,int y)
    {
        int s=0;
        while (top[x]!=top[y])
        {
            if (deep[top[x]]<deep[top[y]]) swap(x,y);
            s+=qbit(id[x])-qbit(id[top[x]]-1);
            x=fa[top[x]];
        }
        if (deep[x]<deep[y]) swap(x,y);
        s+=qbit(id[x])-qbit(id[y]-1);
        return s;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4448.in","r",stdin);
        freopen("bzoj4448.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++)
        {
            fa[i]=read();
            if (fa[i]==0) root=i,fa[i]=i;
            else addedge(fa[i],i);
        }
        dfs1(root);
        dfs2(root,root);
        m=read();
        for (int i=1;i<=m;i++)
        {
            int op=read();
            if (op==1) cntq++,q[cntq].x=read(),q[cntq].y=read(),q[cntq].z=i-read()-1,q[cntq].i=i;
            else cntu++,u[cntu].x=read(),u[cntu].i=i;
        }
        sort(q+1,q+cntq+1,cmp);
        int x=0;
        for (int i=1;i<=cntq;i++)
        if (q[i].z>0)
        {
            while (x<cntu&&u[x+1].i<=q[i].z) mbit(id[u[++x].x]);
            q[i].ans=query(q[i].x,q[i].y);
        }
        sort(q+1,q+cntq+1,cmp1);
        for (int i=1;i<=cntq;i++)
        printf("%d %d
    ",deep[q[i].x]+deep[q[i].y]-(deep[lca(q[i].x,q[i].y)]<<1)+1,q[i].ans);
        return 0;
    }
  • 相关阅读:
    枚举三部曲之一
    Java的版本历史与特性
    Oracle备份恢复之冷备份恢复与异机还原
    Oracle性能优化之普通用户使用dbms_xplan包需要有的权限
    一个简单的RMAN自动备份脚本
    Oracle体系结构之Oracle基本数据字典:v$database、v$instance、v$version、dba_objects
    转载:oracle null处理
    Oracle SQL之 序列使用限制
    Oracle的update语句优化研究
    oracle在impdp时报ORA-31655和ORA-39154
  • 原文地址:https://www.cnblogs.com/Gloid/p/9876560.html
Copyright © 2011-2022 走看看