zoukankan      html  css  js  c++  java
  • cf396C. On Changing Tree

    题解 操作一可以转化成 x+dep[i]*k-dep[j]*k  j是i的子树节点 然后dfs序以后用两个树状数组维护即可

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    const int mod=1e9+7;
    using namespace std;
    struct edge{int t;edge*next;}e[MAXN],*h[MAXN],*o=e;
    void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    ll sum1[MAXN],sum2[MAXN];
    int p[MAXN],cnt,dep[MAXN],num[MAXN];
    void dfs(int x,int fa,int deep){
    	p[x]=++cnt;dep[x]=deep+1;num[x]=1;
    	link(x){
    		if(j->t!=fa){
    			dfs(j->t,x,deep+1);
    			num[x]+=num[j->t];
    		}
    	}
    }
    int n;
    int get_id(int x){return x&(-x);}
    void update1(int x,ll k){
    	for(int i=x;i<=n+1;i+=get_id(i))sum1[i]+=k,sum1[i]%=mod;
    }
    void update2(int x,ll k){
    	for(int i=x;i<=n+1;i+=get_id(i))sum2[i]+=k,sum2[i]%=mod;
    }
    ll Sum1(int x){
    	ll ans=0;
    	for(int i=x;i>0;i-=get_id(i))ans+=sum1[i],ans%=mod;
    	return ans;
    }
    ll Sum2(int x){
    	ll ans=0;
    	for(int i=x;i>0;i-=get_id(i))ans+=sum2[i],ans%=mod;
    	return ans;
    }
    int main(){
    	n=read();
    	int u,v,op;ll x,k;
    	inc(i,2,n)u=read(),add(u,i);
    	dfs(1,0,0);
    	int q=read();
    	while(q--){
    		op=read();
    		if(op==1){
    			v=read();x=read();k=read();
    			ll t1=(x+(1ll*dep[v]*k%mod))%mod;
    			//cout<<t1<<endl;
    			update1(p[v],t1);
    			update1(p[v]+num[v],(mod-t1));
    			update2(p[v],k);
    			update2(p[v]+num[v],mod-k);
    		}
    		else{
    			v=read();
    			ll ans=Sum1(p[v]);
    			//cout<<ans<<"==="<<endl;
    			ll ans2=Sum2(p[v]);
    			ans2=ans2*dep[v]%mod;
    			ans=(ans-ans2+mod)%mod;
    			printf("%lld
    ",ans);
    		}
    	}
    	return 0;
    }
    
    C. On Changing Tree
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given a rooted tree consisting of n vertices numbered from 1 to n. The root of the tree is a vertex number 1.

    Initially all vertices contain number 0. Then come q queries, each query has one of the two types:

    • The format of the query: v x k. In response to the query, you need to add to the number at vertex v number x; to the numbers at the descendants of vertex v at distance 1, add x - k; and so on, to the numbers written in the descendants of vertex v at distance i, you need to add x - (i·k). The distance between two vertices is the number of edges in the shortest path between these vertices.
    • The format of the query: v. In reply to the query you should print the number written in vertex v modulo 1000000007 (109 + 7).

    Process the queries given in the input.

    Input

    The first line contains integer n (1 ≤ n ≤ 3·105) — the number of vertices in the tree. The second line contains n - 1 integers p2, p3, ... pn(1 ≤ pi < i), where pi is the number of the vertex that is the parent of vertex i in the tree.

    The third line contains integer q (1 ≤ q ≤ 3·105) — the number of queries. Next q lines contain the queries, one per line. The first number in the line is type. It represents the type of the query. If type = 1, then next follow space-separated integers v, x, k (1 ≤ v ≤ n0 ≤ x < 109 + 7; 0 ≤ k < 109 + 7). If type = 2, then next follows integer v (1 ≤ v ≤ n) — the vertex where you need to find the value of the number.

    Output

    For each query of the second type print on a single line the number written in the vertex from the query. Print the number modulo 1000000007 (109 + 7).

    Examples
    input
    Copy
    3
    1 1
    3
    1 1 2 1
    2 1
    2 2
    output
    Copy
    2
    1
    Note

    You can read about a rooted tree here: http://en.wikipedia.org/wiki/Tree_(graph_theory).

  • 相关阅读:
    CF 13B Letter A
    CF12D Ball
    题解 CF11C
    CF10E Greedy Change
    CF10D LCIS&&Acwing 272
    CF10C Digital Root
    yLOI2019 青原樱
    js有关时间日期的操作
    js 读取 cookie
    nginx有关.htaccess小结
  • 原文地址:https://www.cnblogs.com/wang9897/p/9909980.html
Copyright © 2011-2022 走看看