FZU 2277Change

Posted 蒟蒻LQL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FZU 2277Change相关的知识,希望对你有一定的参考价值。

题意

   有一颗有n个节点的有根树,根节点编号时1,每个结点都有一个值ai,开始的时候,所有节点的值都是0.

   我们有q个操作,操作只有两种类型

   1 v x k,a[v]+=x,a[v‘]+=x-k,a[v"]+=x-2*k... v‘是结点v的孩子 。

  2 v 输出a[v]mod 1e9+7。

分析

dfs序+线段树

下面的代码TLE了,一会再改,感觉没啥毛病哇

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 const int maxn=300000+100;
10 const int MOD=1000000007;
11 int n,T,q,num ;
12 vector<int>child[maxn];
13 LL a[maxn],r[maxn],dep[maxn],val[maxn];
14 void dfs(LL u){
15     num++;
16     a[num]=u;
17     for(int i=0;i<child[u].size();i++){
18         int v=child[u][i];
19         dep[v]=dep[u]+1;
20         dfs(v);
21     }
22     r[u]=a[num];
23     return ;
24 }
25 LL addv[4*maxn],kv[4*maxn];
26 int ql,qr;
27 LL v,k;
28 
29 void update(int o,int L,int R){
30     if(ql<=L&&qr>=R){
31         addv[o]=(add[o]%MOD+v%MOD)%MOD;
32         kv[o]=(kv[o]%MOD+k%MOD)MOD;
33         return;
34     }
35     int M=L+(R-L)/2;
36     if(ql<=M)
37        update(2*o,L,M);
38     if(qr>M)
39        update(2*o+1,M+1,R);
40     return;
41 }
42 //找到v的值
43 LL query(int o,int L,int R,LL adv,LL adk){
44     if(L==R){
45         return addv[o]+adv-dep[val[L]]*(kv[o]+adk);
46     }
47     int M=L+(R-L)/2;
48     if(v<=M)
49         return query(2*o,L,M,(adv%MOD+addv[o]%MOD)%MOD,(adk+kv[o])%MOD);
50     if(v>M)
51         return query(2*o+1,M+1,R,(adv%MOD+addv[o]%MOD)%MOD,(adk%MOD+kv[o]%MOD)%MOD);
52 }
53 int main(){
54     scanf("%d",&T);
55     for(int t=1;t<=T;t++){
56         scanf("%d",&n);
57         for(int i=1;i<=n;i++)child[i].clear();
58         num=0;
59         for(int i=2;i<=n;i++){
60             int x;
61             scanf("%d",&x);
62             child[x].push_back(i);
63         }
64         dep[1]=1;
65         dfs(1);
66         for(int i=1;i<=n;i++)val[a[i]]=i;
67         memset(addv,0,sizeof(addv));
68         memset(kv,0,sizeof(kv));
69         scanf("%d",&q);
70         for(int i=1;i<=q;i++){
71             int ty;
72             scanf("%d",&ty);
73             if(ty==1){
74                int vv;
75                LL x;
76                scanf("%d%lld%lld",&vv,&x,&k);
77                ql=a[vv],qr=r[vv],v=x+dep[vv]*k;
78               // cout<<ql<<" "<<qr<<endl;
79                update(1,1,n);
80             }else{
81                 int vv;
82                 scanf("%d",&vv);
83                 v=a[vv];
84                 cout<<query(1,1,n,0,0)%MOD<<endl;
85             }
86         }
87 
88        /* for(int i=1;i<=num;i++)
89             printf("%d ",a[i]);
90         printf("\n");
91         for(int i=1;i<=n;i++){
92             printf("%d %d\n",i,r[i]);
93         }*/
94     }
95 return 0;
96 }
View Code

 

以上是关于FZU 2277Change的主要内容,如果未能解决你的问题,请参考以下文章

Change FZU - 2277 毒瘤啊 毒瘤题目

FZU 2277 树状数组

HDU 2277 Change the ball

FZU1004-Number Triangle经典动归题,核心思路及代码优化

2017福建省赛 FZU2272~2283

FZU 2169 shadow