Before long a question, or write about, this question is a tree cross-section do not say it, but it is to support both the interval assignment and addition operation, so we definitely need two tags, but at the same time when the assignment and addition flag below when we need details of the deal, the initial value of first assignment should be assigned to -1, and when the bottom of the first release of a high-priority assignment mark. Plus mark before the interval when the assignment must be emptied! When the time is because of this examination of the burst zero, painful lesson.
code show as below:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+7; 4 const int N=1e7+7; 5 struct seg{ 6 int l,r,lazy1,lazy2; 7 long long sum; 8 }tree[maxn*10]; 9 struct node{ 10 int nxt,to; 11 }edge[maxn*2]; 12 int n,m; 13 int a[maxn]; 14 int dep[maxn],fa[maxn],size[maxn],id[maxn],son[maxn],rev[maxn],top[maxn]; 15 bool not_zhishu[N]; 16 int prime[maxn]; 17 int Time,cnt; 18 int head[maxn]; 19 int opt,x,y,k; 20 int st,ed; 21 int jmr; 22 bool flag; 23 inline void Euler(){ 24 for( register int i=2;i<=10000000;i++){ 25 if(!not_zhishu[i]) prime[++prime[0]] = i; 26 for(register int j=1;j<=prime[0]&&i*prime[j]<=10000000;j++){ 27 not_zhishu[i*prime[j]]=true; 28 if(i%prime[j]==0) break; 29 } 30 } 31 } 32 inline void add(int u,int v){ 33 edge[++cnt].nxt=head[u]; 34 edge[cnt].to=v; 35 head[u]=cnt; 36 } 37 inline void dfs1(int x,int f){ 38 dep[x]=dep[f]+1; 39 fa[x]=f; 40 size[x]=1; 41 int maxson=-1; 42 for(int i=head[x];i;i=edge[i].nxt){ 43 int v=edge[i].to; 44 if(v==f) continue; 45 dfs1(v,x); 46 size[x]+=size[v]; 47 if(size[v]>maxson||son[x]==-1){ 48 maxson=size[v]; 49 son[x]=v; 50 } 51 } 52 } 53 inline void dfs2(int x,int topf){ 54 top[x]=topf; 55 id[x]=++Time; 56 rev[id[x]]=x; 57 if(son[x]==-1) return; 58 dfs2(son[x],topf); 59 for(int i=head[x];i;i=edge[i].nxt){ 60 int v=edge[i].to; 61 if(v==son[x]||v==fa[x]) continue; 62 dfs2(v,v); 63 } 64 } 65 inline void pushup(int x){ 66 tree[x].sum=tree[x*2].sum+tree[x*2+1].sum; 67 } 68 inline void pushdown(int x){ 69 if(tree[x].lazy2!=-1){ 70 tree[x*2].sum=tree[x].lazy2*(tree[x*2].r-tree[x*2].l+1); 71 tree[x*2+1].sum=tree[x].lazy2*(tree[x*2+1].r-tree[x*2+1].l+1); 72 tree[x*2].lazy2=tree[x].lazy2; 73 tree[x*2+1].lazy2=tree[x].lazy2; 74 tree[x].lazy2=-1; 75 tree[x*2+1].lazy1=tree[x*2].lazy1=0; 76 } 77 if(tree[x].lazy1){ 78 tree[x*2].sum+=tree[x].lazy1*(tree[x*2].r-tree[x*2].l+1); 79 tree[x*2+1].sum+=tree[x].lazy1*(tree[x*2+1].r-tree[x*2+1].l+1); 80 tree[x*2].lazy1+=tree[x].lazy1; 81 tree[x*2+1].lazy1+=tree[x].lazy1; 82 tree[x].lazy1=0; 83 } 84 } 85 inline void build(int now,int l,int r){ 86 tree[now].l=l; 87 tree[now].r=r; 88 tree[now].lazy1=0; 89 tree[now].lazy2=-1; 90 if(l==r){ 91 tree[now].sum=a[rev[l]]; 92 return; 93 } 94 int mid=(l+r)>>1; 95 build(now*2,l,mid); 96 build(now*2+1,mid+1,r); 97 pushup(now); 98 } 99 inline void modify1(int now,int l,int r,int v){ 100 if(tree[now].l>=l&&tree[now].r<=r){ 101 tree[now].sum+=(tree[now].r-tree[now].l+1)*v; 102 tree[now].lazy1+=v; 103 return; 104 } 105 pushdown(now); 106 int mid=(tree[now].l+tree[now].r)>>1; 107 if(l<=mid) modify1(now*2,l,r,v); 108 if(r>mid) modify1(now*2+1,l,r,v); 109 pushup(now); 110 } 111 inline void modify2(int now,int l,int r,int v){ 112 if(tree[now].l>=l&&tree[now].r<=r){ 113 tree[now].lazy2=v; 114 tree[now].sum=(tree[now].r-tree[now].l+1)*v; 115 tree[now].lazy1=0; 116 return; 117 } 118 pushdown(now); 119 int mid=(tree[now].l+tree[now].r)>>1; 120 if(l<=mid) modify2(now*2,l,r,v); 121 if(r>mid) modify2(now*2+1,l,r,v); 122 pushup(now); 123 } 124 inline int query(int now,int l,int r){ 125 if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum; 126 int mid=(tree[now].l+tree[now].r)>>1; 127 pushdown(now); 128 int val=0; 129 if(l<=mid) val+=query(now*2,l,r); 130 if(r>mid) val+=query(now*2+1,l,r); 131 return val; 132 } 133 inline void link1(int x,int y,int v){ 134 while(top[x]!=top[y]){ 135 if(dep[top[x]]<dep[top[y]]) swap(x,y); 136 modify1(1,id[top[x]],id[x],v); 137 x=fa[top[x]]; 138 } 139 if(dep[x]<dep[y]) swap(x,y); 140 modify1(1,id[y],id[x],v); 141 } 142 inline void link2(int x,int y,int v){ 143 while(top[x]!=top[y]){ 144 if(dep[top[x]]<dep[top[y]]) swap(x,y); 145 modify2(1,id[top[x]],id[x],v); 146 x=fa[top[x]]; 147 } 148 if(dep[x]<dep[y]) swap(x,y); 149 modify2(1,id[y],id[x],v); 150 } 151 inline void linkquery(int x,int y){ 152 int ans=0; 153 while(top[x]!=top[y]){ 154 if(dep[top[x]]<dep[top[y]]) swap(x,y); 155 ans+=query(1,id[top[x]],id[x]); 156 x=fa[top[x]]; 157 } 158 if(dep[x]<dep[y]) swap(x,y); 159 ans+=query(1,id[y],id[x]); 160 if(ans<=3){printf("TANOSHI\n");return;} 161 if(ans%2==0){printf("SUGOI\n");return;} 162 int tmp=ans-2; 163 if(not_zhishu[tmp]){printf("TANOSHI\n");return;} 164 else{printf("SUGOI\n");return;} 165 } 166 int main(){ 167 // freopen("japari.in","r",stdin); 168 // freopen("japari.out","w",stdout); 169 memset(son,-1,sizeof(son)); 170 Euler(); 171 scanf("%d%d",&n,&m); 172 for(register int i=1;i<=n;i++){ 173 scanf("%d",&a[i]); 174 } 175 for(register int i=1;i<n;i++){ 176 scanf("%d%d",&st,&ed); 177 add(st,ed);add(ed,st); 178 } 179 dfs1(1,0); 180 dfs2(1,1); 181 build(1,1,n); 182 for(register int i=1;i<=m;i++){ 183 scanf("%d",&opt); 184 if(opt==1){ 185 scanf("%d%d%d",&x,&y,&k); 186 link1(x,y,k); 187 } 188 else if(opt==2){ 189 scanf("%d%d%d",&x,&y,&k); 190 link2(x,y,k); 191 } 192 else{ 193 scanf("%d%d",&x,&y); 194 linkquery(x,y); 195 } 196 } 197 return 0; 198 }