zoukankan      html  css  js  c++  java
  • 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门

    我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间

    那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$

    这个只要用主席树上树就可以解决了,顺便用树剖求一下LCA

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     5 char buf[1<<21],*p1=buf,*p2=buf;
     6 inline int read(){
     7     #define num ch-'0'
     8     char ch;bool flag=0;int res;
     9     while(!isdigit(ch=getc()))
    10     (ch=='-')&&(flag=true);
    11     for(res=num;isdigit(ch=getc());res=res*10+num);
    12     (flag)&&(res=-res);
    13     #undef num
    14     return res;
    15 }
    16 char sr[1<<21],z[20];int C=-1,Z;
    17 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    18 inline void print(int x,char ch){
    19     if(C>1<<20)Ot();
    20     while(z[++Z]=x%10+48,x/=10);
    21     while(sr[++C]=z[Z],--Z);sr[++C]=ch;
    22 }
    23 const int N=3e5+5,M=N*32;
    24 struct node{int u,v,c,id;}q[N];
    25 int head[N],Next[N],ver[N],tot;
    26 inline void add(int u,int v){
    27     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
    28 }
    29 int L[M],R[M],sum[M],rt[N],cnt;
    30 void update(int last,int &now,int l,int r,int x){
    31     sum[now=++cnt]=sum[last]+1;
    32     if(l==r) return;
    33     int mid=(l+r)>>1;
    34     if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
    35     else L[now]=L[last],update(R[last],R[now],mid+1,r,x);
    36 }
    37 int fa[N],dep[N],top[N],sz[N],son[N],val[N],root,n,m,k;
    38 void dfs1(int u){
    39     sz[u]=1,dep[u]=dep[fa[u]]+1;
    40     update(rt[fa[u]],rt[u],1,m,val[u]);
    41     for(int i=head[u];i;i=Next[i]){
    42         int v=ver[i];
    43         dfs1(v),sz[u]+=sz[v];
    44         if(sz[son[u]]<sz[v]) son[u]=v;
    45     }
    46 }
    47 void dfs2(int u,int t){
    48     top[u]=t;
    49     if(son[u]){
    50         dfs2(son[u],t);
    51         for(int i=head[u];i;i=Next[i])
    52         if(ver[i]!=son[u]) dfs2(ver[i],ver[i]);
    53     }
    54 }
    55 inline int LCA(int u,int v){
    56     while(top[u]!=top[v])
    57     dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
    58     return dep[u]<dep[v]?u:v;
    59 }
    60 int query(int u,int v,int lca,int lca_fa,int l,int r,int x){
    61     if(r<=x) return sum[u]+sum[v]-sum[lca]-sum[lca_fa];
    62     if(l>x) return 0;
    63     int mid=(l+r)>>1,res=0;
    64     if(x>=l) res+=query(L[u],L[v],L[lca],L[lca_fa],l,mid,x);
    65     if(x>mid) res+=query(R[u],R[v],R[lca],R[lca_fa],mid+1,r,x);
    66     return res;
    67 }
    68 int main(){
    69 //    freopen("testdata.in","r",stdin);
    70     n=read();
    71     for(int i=1;i<=n;++i){fa[i]=read(),add(fa[i],i);if(fa[i]==0) root=i;}
    72     m=read();for(int i=1;i<=n;++i) val[i]=m;
    73     for(int i=1;i<=m;++i){
    74         int op=read(),p;
    75         if(op&1) q[++k].u=read(),q[k].v=read(),q[k].c=read(),q[k].id=i;
    76         else val[p=read()]=i;
    77     }
    78     dfs1(root),dfs2(root,root);
    79     for(int i=1;i<=k;++i){
    80         int u=q[i].u,v=q[i].v,lca=LCA(u,v),lca_fa=fa[lca];
    81         print(dep[u]+dep[v]-2*dep[lca]+1,' ');
    82         int t=q[i].id-q[i].c-1;
    83         print(t>0?query(rt[u],rt[v],rt[lca],rt[lca_fa],1,m,t):0,'
    ');
    84     }
    85     Ot();
    86     return 0;
    87 }
  • 相关阅读:
    IO流
    异常,File,递归,IO流
    Collection接口 map
    使用canvas画出的时钟
    js对象2
    js对象
    js 猜数游戏、斗地主发牌、伪数字
    js函数2
    js函数
    js矩形,数组,杨辉三角
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9797570.html
Copyright © 2011-2022 走看看