对于 100% 的数据,1 <= n;m <= 300000; 1 <= fi<i; 1 <= ci <= n; -10^18 <= hi,vi,si <= 10^18;ai等于1或者2;当 ai =1 时,vi > 0;保证任何时候骑士战斗力值的绝对值不超过 10^18。
考虑我们需要一些什么操作。由于每个节点可能有多个骑士,每次都要把不符合条件的骑士踢出去,于是需要查询最小值。由于需要改变能力值,于是需要打标记。由于需要往上合并,需要支持合并。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<cmath>
6 #define maxn 300010
7
8 using namespace std;
9 typedef long long llg;
10
11 struct data{
12 llg x,ch,jia;
13 data(llg a=0,llg bb=0,llg c=0):x(a),ch(bb),jia(c){}
14 void gi(){x=jia=0;ch=1;}
15 bool operator < (const data &h)const{return x<h.x;}
16 }ss[maxn];
17 int rt[maxn],s[maxn][2],gua[maxn],ci[maxn],dep[maxn];
18 int n,m,head[maxn],next[maxn],to[maxn],tt,dis[maxn];
19 llg h[maxn],a[maxn]; bool w[maxn];
20
21 void pushdown(int u){
22 int l=s[u][0],r=s[u][1];
23 if(ss[u].ch!=1){
24 ss[l].x*=ss[u].ch; ss[r].x*=ss[u].ch;
25 ss[l].ch*=ss[u].ch; ss[r].ch*=ss[u].ch;
26 ss[l].jia*=ss[u].ch; ss[r].jia*=ss[u].ch;
27 }
28 if(ss[u].jia){
29 ss[l].x+=ss[u].jia; ss[r].x+=ss[u].jia;
30 ss[l].jia+=ss[u].jia; ss[r].jia+=ss[u].jia;
31 }
32 ss[u].jia=0; ss[u].ch=1; ss[0].gi();
33 }
34
35 int merge(int a,int b){
36 if(!a || !b) return a+b;
37 if(ss[b]<ss[a]) swap(a,b);
38 pushdown(a);
39 s[a][1]=merge(s[a][1],b);
40 if(dis[s[a][1]]>dis[s[a][0]]) swap(s[a][1],s[a][0]);
41 dis[a]=dis[s[a][1]]+1; return a;
42 }
43
44 void dfs(int u){
45 for(int i=head[u];i;i=next[i])
46 dfs(to[i]),rt[u]=merge(rt[u],rt[to[i]]);
47 int nn=rt[u];
48 while(nn && ss[nn].x<h[u]){
49 gua[u]++; ci[nn]-=dep[u]; pushdown(nn);
50 nn=rt[u]=merge(s[nn][0],s[nn][1]);
51 }
52 if(nn){
53 if(!w[u]) ss[nn].x+=a[u],ss[nn].jia+=a[u];
54 else ss[nn].x*=a[u],ss[nn].ch*=a[u],ss[nn].jia*=a[u];
55 }
56 }
57
58 int main(){
59 scanf("%d %d",&n,&m); dep[1]=1; dis[0]=-1;
60 for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
61 for(int i=2,x,xx;i<=n;i++){
62 scanf("%d %d %lld",&x,&xx,&a[i]);
63 w[i]=xx; dep[i]=dep[x]+1;
64 to[++tt]=i;next[tt]=head[x];head[x]=tt;
65 }
66 for(int i=1,u;i<=m;i++){
67 scanf("%lld %d",&ss[i].x,&u);
68 ss[i].ch=1; ci[i]=dep[u];
69 if(!rt[u]) rt[u]=i;
70 else rt[u]=merge(rt[u],i);
71 }
72 dfs(1);
73 for(int i=1;i<=n;i++) printf("%d\n",gua[i]);
74 for(int i=1;i<=m;i++) printf("%d\n",ci[i]);
75 return 0;
76 }