• 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
    ",ans[i]);
    121     for(int i=1;i<=m;i++)printf("%lld
    ",ans2[i]);
    122     return 0;
    123 }
  • 相关阅读:
    tkinter 类继承的三种方式
    tkinter 的两个例子
    python 测试驱动开发的简单例子
    python 播放 wav 文件
    Python 操作 MongoDB
    【转】如何拿到半数面试公司Offer——我的Python求职之路
    scrapy 保存到 sqlite3
    scrapy 爬取 useragent
    收集的User-Agent
    scrapy 登录
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6206382.html
Copyright © 2020-2023  润新知