A little girl loves problems on trees very much. Here ' s one of them.
A Tree is an undirected connected graph, not containing cycles. The degree of node x in the tree are the number of nodes y of the tree, such that's them is connect ed with node x by some edge of the tree.
Let's consider a tree that consists of n nodes. We'll consider the tree ' s nodes indexed from 1 to N. The cosidered tree has the following Property:each node except for node number 1 have the degree of at most 2.
Initially, each node of the tree contains number 0. Your task is to quickly process the requests of the types:
- Request of form:0 vxD. In reply to the request you should addxTo all numbers is written in the nodes is located at the distance ofDFrom nodev. The distance between and nodes are the number of edges on the shortest path between them.
- Request of form: 1 v. In reply to the request you should print the current number, which is written in node v.
Input
The first line contains integers n (2?≤? N? ≤?105) and Q (1?≤? Q. ≤?105)-the number of tree nodes and the number of requests, correspondingly.
Each of the next n?? -?? 1lines contains, integers ui and vi (1?≤? u i,? v i? ≤? N , ui? ≠? v I ), that show this there is an edge between nodes ui and vi . Each edge's description occurs in the input exactly once. It is guaranteed, the given graph is a tree, with the property, that's described in the statement.
Next Q Lines describe the requests.
- The request to add has the following format:0vxD(1?≤? v≤? N ,1?≤? x? ≤?104 ,1?≤? d. <? N ).
- The request to print the node value has the following format: 1 v (1?≤? V≤? n).
The numbers in the lines is separated by a single spaces.
Output
For each request to print the node value print a integer-the reply to the request.
Sample Test (s) input
3 61 21 30 3 1 20 2 3 10 1 5 21 11 21 3
Output
996
Input
6 111 22 55 41 61 30 3 1 30 3 4 50 2 1 40 1 5 50 4 6 21 11 21 31 41 51 6
Output
111711161711
Test instructions: A tree has only one vertex, which is then derived from the vertex of the chain, for input 0 v X D, represents the distance v node distance within d of all nodes to increase x, for input 1 V, the value of the query v node
Ideas: This problem refers to other people's code, found that the use of a tree array, but did not do a tree array, although the tree can be used to do the problem can be done with a line tree, but the tree array is quite ingenious, so temporarily to look at the principle of tree-like array, and finally combined with other people's thinking of the problem a
First of all we for a chain, when the node in the chain, the distance to update D is very good, but to update to 1 nodes, we assume that there is no update of the distance of D, if we go to the update is easy to time out, so we can update the whole tree directly, That is, all nodes with a distance of 1 to D are updated in the same state.
Use new to dynamically allocate memory to place hyper-memory
#include <iostream> #include <stdio.h> #include <string.h> #include <stack> #include <queue > #include <map> #include <set> #include <vector> #include <math.h> #include <algorithm >using namespace std, #define LS 2*i#define rs 2*i+1#define up (i,x,y) for (i=x;i<=y;i++) #define DOWN (i,x,y) for (i=x; i>=y;i--) #define MEM (a,x) memset (A,x,sizeof (a)) #define W (a) while (a) #define LL long longconst double pi = acos (-1.0); # Define N 100005#define mod 19999997const int INF = 0x3f3f3f3f, the number of the chain where the exp 1e-8//v point is located, the number of layers, V is labeled on the chain, each chain length. int mark[n],level[n],pos[n],length[n],id,deep;vector<int> vec[n];struct node{int *sum,n; void init (int len) {n = len; sum = new Int[n+1]; Memset (sum,0, (n+1) *sizeof (int)); } int query (int i) {int ans = 0; for (; i<=n; i+=i&-i) ans+=sum[i]; return ans; } void Add (int i,int x) {for (; i>0; i-=i&-i) sum[i]+=x; } void Updata (int l,int r,int x)//update l~r interval {add (r,x); Add (l-1,-x);//extra Update minus}} tree,*chain;int dfs (int step,int u,int pre) {int i,n = Vec[u].size (), V; LEVEL[U] = step+1;//layer to add 1 where the layer mark[u] = ID; Pos[u] = step;//The label on the chain does not count 1 nodes, so do not add 1 up (i,0,n-1) {v = vec[u][i]; if (v = = pre) continue; Return Dfs (STEP+1,V,U); } return step; void init () {int i,n=vec[1].size (), len,v; Chain = new Node[n]; Level[1]=1; Up (i,0,n-1)//initialization of each chain {id = i; v = vec[1][i]; Len = DFS (1,v,1); Length[i]=len; Deep = max (len,deep);//Find the longest chain depth chain[i].init (len);//update the depth of each chain} tree.init (++deep);//depth of the whole tree}int query (int v) { int ans = 0; Ans = tree.query (level[v]); if (v!=1) {ans+=chain[mark[v]].query (pos[v]); } return ans; void Updata (int v,int x,int d) {int l,r; if (v = = 1) {if (deep>=1+d) R = 1+d;//compares the depth of the tree depth to D to determine the update depth else r = Deep; Tree.uPdata (1,R,X); Return }//For each chain, R represents the depth of the update down, and L represents the depth of the update, first updating to the 1 node so far if (length[mark[v]]>=pos[v]+d) r = pos[v]+d; else R = Length[mark[v]]; if (1<=pos[v]-d) L = pos[v]-d; else L = 1; Chain[mark[v]].updata (L,R,X); D-=level[v]-1; if (d>=0)//to 1 nodes there is still {if (deep>=1+d) R = 1+d;//with 1 Nodes as origin, update all chains, depth r else R = deep; Tree.updata (1,R,X); if (r>=2)//For the required point, due to the update two times, subtract this update {if (length[mark[v]]>=r-1) r = r-1; else R = Length[mark[v]]; Chain[mark[v]].updata (1,r,-x); }}}int Main () {int i,n,q,x,y; scanf ("%d%d", &n,&q); Up (i,1,n-1) {scanf ("%d%d", &x,&y); Vec[x].push_back (y); Vec[y].push_back (x); } init (); int cas,v,d; W (q--) {scanf ("%d%d", &cas,&v); if (!cas) {scanf ("%d%d", &x,&d); Updata (V,X,D); } else printf ("%d\n", Query (v)); }return 0;}
Codeforces276e:little Girl and problem on Trees