左偏树裸题 合并+lazytag即可
每个点合并儿子然后弹出所有<ci的即可
然后每个骑士直接dep[x]-dep[y]挂了的节点和初始节点的深度差即可
样例太水了注意要判每个节点万一骑士挂完了是空的QAQ
//Love and Freedom. #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define ll long long #define inf 20021225 #define N 300010 using namespace std; ll read() { ll s=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return f*s; } struct edge{int to,lt;}e[N]; int in[N],cnt,dep[N]; int rt[N]; void add(int x,int y){e[++cnt].to=y;e[cnt].lt=in[x];in[x]=cnt;} struct node{ll val,mul,add; int fa,son[2],dis;}t[N]; int st[N]; int war[N],city[N]; ll v[N],c[N]; bool kd[N]; void pushdown(int x) { int ls=t[x].son[0],rs=t[x].son[1]; ll mul=t[x].mul,add=t[x].add; if(mul!=1) { t[ls].val*=mul; t[rs].val*=mul; t[ls].mul*=mul; t[rs].mul*=mul; t[ls].add*=mul; t[rs].add*=mul; t[x].mul=1; } if(add) { t[ls].val+=add; t[rs].val+=add; t[ls].add+=add; t[rs].add+=add; t[x].add=0; } } int find(int x){return t[x].fa^x?t[x].fa=find(t[x].fa):x;} int merge(int x,int y) { if(!x||!y) return x|y; if(t[x].val>t[y].val) swap(x,y); pushdown(x); t[x].son[1]=merge(t[x].son[1],y); t[t[x].son[1]].fa=t[t[x].son[0]].fa=x; t[x].fa=x; if(t[t[x].son[1]].dis>t[t[x].son[0]].dis) swap(t[x].son[0],t[x].son[1]); t[x].dis=t[t[x].son[1]].dis+1; return x; } void modify(int x,ll add,ll mul) { if(mul!=1){t[x].val*=mul; t[x].mul*=mul; t[x].add*=mul;} if(add){t[x].val+=add; t[x].add+=add;} } void pop(int &x,int ct) { war[x]=dep[st[x]]-dep[ct]; city[ct]++; pushdown(x); t[t[x].son[0]].fa=t[x].son[0]; t[t[x].son[1]].fa=t[x].son[1]; t[x].fa=merge(t[x].son[0],t[x].son[1]); t[t[x].fa].fa=t[x].fa; x=t[x].fa; } void work(int x) { for(int i=in[x];i;i=e[i].lt) dep[e[i].to]=dep[x]+1,work(e[i].to),rt[x]=merge(rt[x],rt[e[i].to]); while(rt[x]&&t[rt[x]].val<c[x]) pop(rt[x],x); if(kd[x]) modify(rt[x],0,v[x]); else modify(rt[x],v[x],1); } int n,m; int main() { n=read(); m=read(); int fi,ci; for(int i=1;i<=n;i++) c[i]=read(); for(int i=2;i<=n;i++) fi=read(),add(fi,i),kd[i]=read(),v[i]=read(); for(int i=1;i<=m;i++) t[i].val=read(),ci=read(),rt[ci]=merge(rt[ci],i),st[i]=ci; work(1); dep[0]=-1; while(rt[1]) pop(rt[1],0); for(int i=1;i<=n;i++) printf("%d ",city[i]); for(int i=1;i<=m;i++) printf("%d ",war[i]); return 0; }