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 }
以上是关于FZU 2277Change的主要内容,如果未能解决你的问题,请参考以下文章