bzoj 4003

     左偏树。。。

     打两个标记。。。和线段树一样,先下放cheng再下放*。

     每回合并子树就行了。

    

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #define N 300010
  7 #define int long long
  8 using namespace std;
  9 int n,m,h[N];
 10 int b[N],v[N];
 11 int s[N],root[N];
 12 vector<int>qi[N];
 13 int c[N],ans[N],ans2[N];
 14 int head[N],nxt[N],ver[N],tot;
 15 void add(int a,int d)
 16 {
 17     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=d;return ;
 18 }
 19 struct node
 20 {
 21     int l,r,w,d,lazy1,lazy2;
 22     int pre;
 23     node()
 24     {
 25         lazy2=1;
 26     }
 27 }a[N*4];int cnt;
 28 int dep[N];
 29 void push_down(int x)
 30 {
 31     int t1=a[x].l;int t2=a[x].r;
 32     if(t1)
 33     {
 34         a[t1].w*=a[x].lazy2,a[t1].lazy1*=a[x].lazy2,a[t1].lazy2*=a[x].lazy2;
 35         a[t1].w+=a[x].lazy1;
 36         a[t1].lazy1+=a[x].lazy1;
 37     }
 38     if(t2)
 39     {
 40         a[t2].w*=a[x].lazy2,a[t2].lazy1*=a[x].lazy2,a[t2].lazy2*=a[x].lazy2;
 41         a[t2].w+=a[x].lazy1;
 42         a[t2].lazy1+=a[x].lazy1;
 43     }
 44     a[x].lazy1=0;
 45     a[x].lazy2=1;
 46     return ;
 47 }
 48 int merge(int x,int y)
 49 {
 50     if(!x||!y)return x+y;
 51     if(a[x].w>a[y].w)swap(x,y);
 52     push_down(x);
 53     a[x].r=merge(a[x].r,y);
 54     if(a[a[x].l].d<a[a[x].r].d)swap(a[x].l,a[x].r);
 55     a[x].d=a[a[x].r].d+1;
 56     return x;
 57 }
 58 void dfs(int x)
 59 {
 60     root[x]=0;
 61     for(int i=0;i<qi[x].size();i++)
 62     {
 63         a[++cnt].pre=qi[x][i];a[cnt].w=s[qi[x][i]];root[x]=merge(root[x],cnt);
 64     }
 65     for(int i=head[x];i;i=nxt[i])
 66     {
 67         dep[ver[i]]=dep[x]+1;
 68         dfs(ver[i]);
 69         root[x]=merge(root[x],root[ver[i]]);
 70     }
 71     while(root[x]&&a[root[x]].w<h[x])
 72     {
 73         ans[x]++;
 74         int y=a[root[x]].pre;
 75         ans2[y]=dep[c[y]]-dep[x];
 76         push_down(root[x]);
 77         root[x]=merge(a[root[x]].l,a[root[x]].r);
 78     }
 79     if(root[x])
 80     {
 81         if(!b[x])
 82         {
 83             a[root[x]].w+=v[x];
 84             a[root[x]].lazy1+=v[x];
 85         }
 86         else
 87         {
 88             a[root[x]].w*=v[x];
 89             a[root[x]].lazy1*=v[x];
 90             a[root[x]].lazy2*=v[x];
 91         }
 92     }
 93     return ;
 94 }
 95 signed main()
 96 {
 97     scanf("%lld%lld",&n,&m);
 98     for(int i=1;i<=n;i++)scanf("%lld",&h[i]);
 99     int t1;
100     for(int i=2;i<=n;i++)
101     {
102         scanf("%lld",&t1);
103         add(t1,i);
104         scanf("%lld%lld",&b[i],&v[i]);
105     }
106     for(int i=1;i<=m;i++)
107     {
108         scanf("%lld%lld",&s[i],&t1);
109         qi[t1].push_back(i);c[i]=t1;
110     }
111     dep[1]=1;
112     dfs(1);
113     while(root[1]!=0)
114     {
115         int y=a[root[1]].pre;
116         ans2[y]=dep[c[y]]-dep[1]+1;
117         push_down(root[1]);
118         root[1]=merge(a[root[1]].l,a[root[1]].r);
119     }
120     for(int i=1;i<=n;i++)printf("%lld\n",ans[i]);
121     for(int i=1;i<=m;i++)printf("%lld\n",ans2[i]);
122     return 0;
123 }

 

posted @ 2016-12-21 09:33  SD_le  阅读(163)  评论(0编辑  收藏  举报
重置按钮