bzoj4448 [Scoi2015]情报传递
第一问不解释,对于第二问的处理,可以使用cdq分治,假设分治的询问区间是[L,R],那么我们对于标号在[L,mid]的修改操作赋予一个权值,因为在当前[L,R]中[L,mid]的修改操作只会对[mid+1,R]的询问操作,所以第i修改操作至少经过m-i的时间,因此赋予的权值是m-i,而对于[mid+1,R]区间中的询问操作,也赋予一个权值w-m,这里w为询问的数值,我们可以预处理出树的dfs序并维护一个树状数组,这样我们就可以把这些操作按权值从大到小插入或者询问,时间复杂度O(nlognlogn)。
代码,运行时间差不多垫底。。(看了其他博主的题解貌似我想的复杂了。。。)
1 #include<cstdio> 2 #include<algorithm> 3 #define N 500010 4 #define lb(x) (x&-x) 5 using namespace std; 6 int dp,p[N],pre[N],tt[N],n,a,i,m,o,c[N],deep[N],fa[N]; 7 int L[N],R[N],ans[N]; 8 int s[N][20]; 9 struct g{ 10 int typ,l,r,w; 11 }b[N]; 12 struct gg{ 13 int id,v; 14 }w[N]; 15 void cc(int x,int w) 16 { 17 while (x<=o) 18 { 19 c[x]+=w; 20 x+=lb(x); 21 } 22 } 23 void dfs(int x) 24 { 25 int i=p[x]; 26 L[x]=++o; 27 while (i) 28 { 29 fa[tt[i]]=x; 30 deep[tt[i]]=deep[x]+1; 31 dfs(tt[i]); 32 i=pre[i]; 33 } 34 R[x]=++o; 35 } 36 int lca(int x,int y) 37 { 38 if(deep[x]>deep[y])x^=y^=x^=y; 39 int i; 40 for(i=19;i>=0;i--) 41 { 42 if(deep[y]-deep[x]>=(1<<i)) 43 { 44 y=s[y][i]; 45 } 46 } 47 if(x==y)return x; 48 for(i=19;i>=0;i--) 49 { 50 if(s[x][i]!=s[y][i]) 51 { 52 x=s[x][i]; 53 y=s[y][i]; 54 } 55 } 56 return fa[x]; 57 } 58 int sum(int x) 59 { 60 int ans=0; 61 while (x) 62 { 63 ans+=c[x]; 64 x-=lb(x); 65 } 66 return ans; 67 } 68 void link(int x,int y) 69 { 70 dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; 71 } 72 bool cmp(gg a,gg b) 73 { 74 if (a.v==b.v) 75 return a.id>b.id; 76 return a.v>b.v; 77 } 78 void solve(int l,int r) 79 { 80 int m,i,tot=0; 81 if (l>=r) return; 82 m=(l+r)>>1; 83 for (i=l;i<=m;i++) 84 if (b[i].typ==2) 85 { 86 w[++tot].id=i; 87 w[tot].v=m-i; 88 } 89 for (i=m+1;i<=r;i++) 90 if (b[i].typ==1) 91 { 92 w[++tot].id=i; 93 w[tot].v=b[i].w-(i-m); 94 } 95 sort(w+1,w+1+tot,cmp); 96 97 for (i=1;i<=tot;i++) 98 if (w[i].id<=m) 99 { 100 cc(L[b[w[i].id].w],1); 101 cc(R[b[w[i].id].w],-1); 102 } 103 else 104 { 105 int u=b[w[i].id].l; 106 int v=b[w[i].id].r; 107 int LCA=lca(u,v); 108 ans[w[i].id]+=sum(L[u])+sum(L[v])-sum(L[LCA])-sum(L[LCA]-1); 109 } 110 for (i=1;i<=tot;i++) 111 if (w[i].id<=m) 112 { 113 cc(L[b[w[i].id].w],-1); 114 cc(R[b[w[i].id].w],1); 115 } 116 117 solve(l,m);solve(m+1,r); 118 } 119 120 int main() 121 { 122 scanf("%d",&n); 123 for (i=1;i<=n;i++) 124 { 125 scanf("%d",&a); 126 if (a) link(a,i); 127 } 128 scanf("%d",&m); 129 for (i=1;i<=m;i++) 130 { 131 scanf("%d",&b[i].typ); 132 if (b[i].typ==1) 133 scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].w); 134 else scanf("%d",&b[i].w); 135 } 136 dfs(1); 137 for(i=1;i<=n;i++)s[i][0]=fa[i]; 138 for(int h=1;h<20;h++) 139 { 140 for(i=1;i<=n;i++) 141 { 142 s[i][h]=s[s[i][h-1]][h-1]; 143 } 144 } 145 solve(1,m); 146 for (i=1;i<=m;i++) 147 if (b[i].typ==1) 148 { 149 int Ans=lca(b[i].l,b[i].r); 150 Ans=deep[b[i].l]+deep[b[i].r]-2*deep[Ans]+1; 151 printf("%d %d\n",Ans,ans[i]); 152 } 153 }