3653: Laughing time limit:20 Sec Memory limit:512 MB
submit:628 solved:245
[Submit] [Status] [Discuss] Description
Set T to a tree with a root tree, we do the following definitions:
• Set A and B as two different nodes in T. If a is the ancestor of B, then it is said that "a than B does not know where the wise goes".
• Set A and B as two different nodes in T. If the distance between A and B does not exceed a given constant x in the tree, then "A and B" is called "laughing".
Given a root tree t of n nodes, the nodes are numbered 1 to n and the root node is node # 1th. You need to answer q questions, ask for a given two integers p and K, and ask how many ordered triples (A;B;C) satisfy:
1. A, B and C are three different points in T, and A is the P node;
2. A and b are better than C to know where the wise go;
3. A and B are laughing. The constant in the laughing here is the given K.
Input
The first line of the input file contains two positive integers n and q, each representing the number of points and queries that have a root tree. Next n-1 lines, each line describes an edge on a tree. Each row contains two integers u and V, which represents an edge between the node U and v.
Next the Q line, each line describes an operation. Line I contains two integers representing the p and K of the I inquiry respectively.
Output
Output Q line, each line corresponding to a query, representative of the answer to the question.
Sample Input5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3
Sample Output3
1
3
HINT
1<=p<=n
1<=k<=n
n<=300000
q<=300000
SourceSolution
The answer is clearly $ (size[x]-1) *min (deep[x],k) +\sum_{dis (x, y) <=k,y\epsilon x}^{y} (size[y]-1) $
Consider looking for those things that can be done using a durable line tree
Use deep as subscript to maintain size.
Code
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespacestd;intRead () {intx=0, f=1;CharCh=GetChar (); while(ch<'0'|| Ch>'9') {if(ch=='-') f=-1; Ch=GetChar ();} while(ch>='0'&& ch<='9') {x=x*Ten+ch-'0'; Ch=GetChar ();} returnx*F;}#defineMAXN 300010#defineLL Long Longintn,q;structedgenode{intNext,to;} edge[maxn<<1];intHead[maxn],cnt=1;voidAddedge (intUintV) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}voidInsertedge (intUintv) {Addedge (u,v); Addedge (v,u);}intDeep[maxn],size[maxn],pl[maxn],pr[maxn],pre[maxn],dfn,maxd;voidDFS (intNowintLast ) {Pl[now]=++DFN; Pre[dfn]=now; size[now]=1; Maxd=Max (Maxd,deep[now]); for(intI=head[now]; I I=edge[i].next)if(edge[i].to!=Last ) {Deep[edge[i].to]=deep[now]+1; DFS (Edge[i].to,now); Size[now]+=Size[edge[i].to]; } Pr[now]=DFN;}structsegmenttreenode{intLs,rs; LL sum;} tree[maxn* -];intRoot[maxn],sz;voidUpdate (int&now,intLastintLintRintPosintval) { Now=++sz; Tree[now].sum=tree[last].sum+Val; if(L==R)return; intMid= (l+r) >>1; Tree[now].ls=tree[last].ls,tree[now].rs=tree[last].rs; if(pos<=mid) Update (tree[now].ls,tree[last].ls,l,mid,pos,val); ElseUpdate (tree[now].rs,tree[last].rs,mid+1, r,pos,val);} LL Query (intNowintLintRintLintR) { if(!now)return0LL; if(L==l && r==r)returntree[now].sum; intMid= (l+r) >>1; if(R<=mid)returnQuery (TREE[NOW].LS,L,MID,L,R); Else if(L>mid)returnQuery (tree[now].rs,mid+1, R,l,r); Else returnQuery (Tree[now].ls,l,mid,l,mid) +query (tree[now].rs,mid+1, r,mid+1, R);}intMain () {N=read (), q=read (); for(intX,y,i=1; i<=n-1; i++) X=read (), y=read (), Insertedge (x, y); DFS (1,0);//for (int i=1; i<=n; i++)//printf ("%d [%d,%d]%d%d\n", Pre[i],pl[pre[i]],pr[pre[i]],size[pre[i]],deep[pre[i]]); for(intI=1; i<=n; i++) Update (root[i],root[i-1],0, maxd,deep[pre[i]],size[pre[i]]-1); for(intI=1; i<=q; i++) { intP=read (), k=read (); LL ans=0LL; Ans= (LL) (size[p]-1) *min (deep[p],k) +query (Root[pr[p]),0, maxd,deep[p]+1, deep[p]+k)-query (root[pl[p]-1],0, maxd,deep[p]+1, deep[p]+K); printf ("%lld\n", ans); } return 0;}
by Char--shot dead.
"BZOJ-3653" Laughing Dfs sequence + persistent segment tree