CF 232 div2 E On Changing Tree 树状数组

来源:互联网 发布:机甲英雄淘宝 编辑:程序博客网 时间:2024/06/05 05:19

dfs把树上的节点映射到[1,n],l[u]到r[u]表示节点u的儿子的范围,然后用树状数组搞。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<queue>#include<map>#include<set>using namespace std;#define inf 0x3f3f3f3f#define eps 1e-8#define LL long long #define ULL unsigned long long#define MP make_pair#define PB push_back#define For( i, x, y ) for( int i = x; i <= y; ++i )#define mxn 300030const LL mod = 1000000000 + 7;LL add[mxn], sub[mxn];int l[mxn], r[mxn], d[mxn];vector<int>g[mxn];int n, dfs_clock = 0;void dfs( int i, int deep ) {l[i] = ++ dfs_clock;d[i] = deep;for( int j = 0; j < g[i].size(); ++j ) {dfs( g[i][j], deep + 1 );}r[i] = dfs_clock;}int lowbit( int i ) {return i & ( - i );}void ad( LL *bit, int i, LL val ) {while( i <= n ) {bit[i] = ( bit[i] + val ) % mod;i += lowbit( i );}}LL getsum( int i ) {LL ret = 0, t = 0;int k = l[i];while( k ) {ret = ( ret + add[k] ) % mod;t = ( t + sub[k] ) % mod;k -= lowbit( k );}return ( ( ret - t * d[i] ) % mod + mod ) % mod;}void init() {memset( add, 0, sizeof( add ) );memset( sub, 0, sizeof( sub ) );For( i, 0, 300030 )g[i].clear();dfs_clock = 0;}int main() {while( cin >> n ) {init();For( i, 2, n ) {int u;cin >> u;g[u].PB( i );}dfs( 1, 1 );int m;cin >> m;while( m-- ) {LL type, u, x, k;cin >> type >> u;if( type == 1 ) {cin >> x >> k;LL val = ( x + d[u] * k ) % mod;ad( add, l[u], val );ad( add, r[u] + 1, - val );ad( sub, l[u], k );ad( sub, r[u] + 1, - k );}else {cout << getsum( u ) << endl;}}}return 0;}



0 0
原创粉丝点击