题意就不描述啦。
对于第一种操作 1 v x k,我们可以给v的子树全部加上(x+depth[v]*k)的值。
对于第二种操作 2 v。查询每个节点的值之后,只需要在减去depth[v]*K即可得到答案了。里面的K是对v这个节点有影响的k的和。
自己在纸上推推公式,很容易就能知道为何是对的了
这里用两个树状数组即可维护, 当然增加整棵子树的操作就是预先处理dfs序,将树转化为线性,然后在区间操作即可。
这里的区间操作可以用线段树,也可以用树状数组。当然树状数组比较简单。我用的是树状数组。
这题还有一个做法是用树链剖分,如果学过树链剖分的话,可以尝试着做一下~
#include <iostream> #include <cstdio> #include <stack> #include <cstring> #include <queue> #include <algorithm> #include <cmath> //#include <unordered_map> #define N 500010 //#define lson x<<1 //#define rson x<<1|1 //#define mid ((lt[x].l+lt[x].r)/2) //#define ID(x, y) ((x)*m+(y)) //#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m) using namespace std; typedef pair<long long,long long> PII; const long long INF=0x3f3f3f3f; const long long mod = 1e9+7; void Open() { #ifndef ONLINE_JUDGE freopen("D:/in.txt","r",stdin); //freopen("D:/my.txt","w",stdout); #endif // ONLINE_JUDGE } long long n, m, Tn; long long c1[N], c2[N], dep[N], st[N], ed[N]; vector<long long> G[N]; void add(long long c[], long long x, long long val) { for(long long i = x; i <= n+10; i += ((-i) & i)) c[i] = (c[i] + val) % mod; } long long getsum(long long c[], long long x) { long long rnt = 0; for(long long i=x;i>0;i -= ((-i) & i)) rnt = (rnt + c[i])%mod; return rnt; } void dfs(long long u, long long d) { dep[u] = d; st[u] = ++Tn; for(long long i=0;i<G[u].size();i++) dfs(G[u][i], d+1); ed[u] = Tn; } int main() { Open(); Tn = 0; scanf("%I64d", &n); for(long long i=2;i<=n;i++) { long long x; scanf("%I64d", &x); G[x].push_back(i); } dfs(1, 0); scanf("%I64d", &m); while(m--) { long long op; scanf("%I64d", &op); if(op == 1){ long long v, x, k; scanf("%I64d%I64d%I64d", &v, &x, &k); add(c1, st[v], x + k * dep[v] % mod); add(c1, ed[v]+1, - (x + k * dep[v] % mod)); add(c2, st[v], k); add(c2, ed[v]+1, - k); }else { long long v; scanf("%I64d", &v); long long tmp = getsum(c1, st[v]) - getsum(c2, st[v]) * dep[v]; tmp = (tmp%mod + mod)%mod; printf("%I64d\n", tmp); } } return 0; }
#include <iostream> #include <cstdio> #include <stack> #include <cstring> #include <queue> #include <algorithm> #include <cmath> //#include <unordered_map> #define N 5000010 using namespace std; typedef pair<long long,long long> PII; const long long INF=0x3f3f3f3f; void Open() { #ifndef ONLINE_JUDGE freopen("D:/in.txt","r",stdin); //freopen("D:/my.txt","w",stdout); #endif // ONLINE_JUDGE }// long long pn; long long vis[N]; void get_prime() { memset(vis,0,sizeof(vis)); for(long long i=2;i<N;i++) { if(vis[i]!=0) continue; vis[i]=1; for(long long j=i*2;j<N;j+=i) { long long tmp = j; long long rnt=0; while(tmp%i==0) { tmp/=i; rnt++; } vis[j]+=rnt; } } } long long a[N]; int main() { //Open(); get_prime(); a[0]=0; for(long long i=1;i<N;i++) a[i]=vis[i]+a[i-1]; long long T; scanf("%I64d",&T); while(T--) { long long A,B; scanf("%I64d%I64d",&A,&B); printf("%I64d\n",a[A]-a[B]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
BUPT Summer Training #7 for Grade 14 题解
原文地址:http://blog.csdn.net/u013912596/article/details/47259267