全WA,但是本地运行以后发现只有少数输出是对不上的,不知道为什么,求大佬调试。
样例1挂掉的询问(序号):
109 115 122 126 129 134 139 143
144 145 147 152 163 173 177 185
189 190 197 198 201 207 208
另外,样例2挂在了第4个询问。
代码:
#include <bits/stdc++.h>
using namespace std;
struct edge {
int t, x;
}el[200024];
int n,q,lazy[400024],dfn[100024],eot[100024],cnt,s[100024],ect,a[100024],una[100024],hson[100024],top[100024],fa[100024];
bool haslazy[400024],vis0[100024],vis1[100024];
long long seg[400024];
/*
el : Edge list
eot : the End Of the Tree's DFN
una : If x = dfn[y], that una[x] = a[y]
hson : The heaviest son
vis0, vis1 : "vis"s in dfs0, dfs1
dfs0 : Get HSON
dfs1 : Get DFN, EOT, FA, TOP
Modify1 : Modify a node in Segtree, like binary-search.
onepd : Push-down a "leaf node"
Init : "Build"
*/
int opx,opa,opc;
int dfs0(int x) {
vis0[x]=true;
int max_g = 0xc0c0c0c0, total_g = 1;
int nx=s[x];
hson[x]=-1;
while(~nx) {
if(!vis0[el[nx].t]) {
int g = dfs0(el[nx].t);
total_g += g;
if(g>max_g) {
max_g=g;
hson[x]=el[nx].t;
}
}
nx=el[nx].x;
}
return total_g;
}
void dfs1(int x) {
vis1[x]=true;
dfn[x]=++cnt;
if(~hson[x]) {
top[hson[x]]=top[x];
fa[hson[x]]=x;
dfs1(hson[x]);
}
int nx=s[x];
while(~nx) {
if(!vis1[el[nx].t]) {
if(el[nx].t!=hson[x]){
top[el[nx].t]=el[nx].t;
fa[el[nx].t]=x;
dfs1(el[nx].t);
}
}
nx=el[nx].x;
}
eot[x]=cnt;
}
inline void pushdown(int x, int len) {
lazy[x<<1]+=lazy[x];
lazy[x<<1|1]+=lazy[x];
haslazy[x<<1]=true;
haslazy[x<<1|1]=true;
seg[x]+=1ll*lazy[x]*len;
lazy[x]=0;
haslazy[x]=false;
}
inline void onepd(int x) {
seg[x]+=lazy[x];
lazy[x]=0;
haslazy[x]=false;
}
void Init(int id, int l, int r) {
if(l==r) {
seg[id] = una[l];
return;
}
int mid=(l+r)>>1;
Init(id<<1,l,mid);
Init(id<<1|1,mid+1,r);
seg[id]=seg[id<<1]+seg[id<<1|1];
}
inline void Modify1(int id, int d, int l, int r) {
int mid;
while(l!=r) {
if(haslazy[id]) {
pushdown(id, r-l+1);
}
seg[id]+=opa;
mid=(l+r)>>1;
if(d<=mid) {
r=mid;
id=id<<1;
}else{
l=mid+1;
id=id<<1|1;
}
}
if(haslazy[id]) {
onepd(id);
}
seg[id]+=opa;
}
void Modify(int id, int l, int r, int L, int R) {
if(L==R) {
if(haslazy[id]) {
onepd(id);
}
seg[id]+=opa;
return;
}
if(haslazy[id]) {
pushdown(id, R-L+1);
}
if(l<=L&&R<=r) {
lazy[id]=opa;
pushdown(id, R-L+1);
return;
}
int mid=(L+R)>>1;
if(l<=mid) {
Modify(id<<1,l,r,L,mid);
}
if(r>mid) {
Modify(id<<1|1,l,r,mid+1,R);
}
seg[id]=seg[id<<1]+seg[id<<1|1];
}
long long Query(int id, int l, int r, int L, int R) {
if(L==R) {
if(haslazy[id]) {
onepd(id);
}
}
if(haslazy[id]) {
pushdown(id, R-L+1);
}
if(l<=L&&R<=r) {
return seg[id];
}
int mid=(L+R)>>1;
long long ret = 0;
if(l<=mid) {
ret+=Query(id<<1,l,r,L,mid);
}
if(r>mid) {
ret+=Query(id<<1|1,l,r,mid+1,R);
}
return ret;
}
inline void Read(int& val) {
char ch=getchar();
bool neg=false;
val^=val;
while((ch>'9'||ch<'0')&&ch!='-') {
ch=getchar();
}
if(ch=='-') {
neg=true;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
val = (val<<1) + (val<<3) + (ch&15);
ch=getchar();
}
if(neg) val=-val;
}
int main() {
top[1]=1;
fa[1]=0;
Read(n);
Read(q);
memset(s,-1,sizeof(s));
int f,t;
for(int i=1;i<=n;i++) {
Read(a[i]);
}
for(int i=1;i<n;i++) {
Read(f);
Read(t);
el[ect].t=t;
el[ect].x=s[f];
s[f]=ect;
ect++;
el[ect].t=f;
el[ect].x=s[t];
s[t]=ect;
ect++;
}
dfs0(1);
dfs1(1);
for(int i=1;i<=n;i++) {
una[dfn[i]]=a[i];
}
Init(1,1,n);
while(q--) {
Read(opc);
Read(opx);
if(opc==3) {
long long ans = 0;
int dot=opx;
while(dot!=0) {
ans+=Query(1,dfn[top[dot]],dfn[dot],1,n);
dot=fa[top[dot]];
}
printf("%lld\n",ans);
}
else{
Read(opa);
if(opc==1) {
Modify1(1,dfn[opx],1,n);
}
else {
Modify(1,dfn[opx],eot[opx],1,n);
}
}
}
return 0;
}