• bzoj4293 [PA2015]Siano


      首先需要意识到这一点:生长速度快的植物,无论进行多少次操作,其高度一定大于等于生长速度慢的植物。于是可以先把植物生长速度进行排序,建立线段树,有两种标记,一种标记表示经历了多少时间,另一种为覆盖标记,一开始先把时间标记打上两个询问的时间差,然后用二分查询找到第一个高度>=询问值的位置i,然后使用线段树统计答案,并把i到n覆盖掉,注意标记更新顺序。

      

      代码

      

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #define N 5000010
      5 using namespace std;
      6 int l[N],r[N],e[N];
      7 long long v1[N],v2[N],S[N],s[N],a,b,ta,n,m,i,ma[N];
      8 void build(int x,int a,int b)
      9 {
     10     int m;
     11     l[x]=a;r[x]=b;v2[x]=-1;v1[x]=0;
     12     if (b-a>1)
     13     {
     14         m=(a+b)>>1;
     15         build(2*x,a,m);
     16         build(2*x+1,m,b);
     17         s[x]=s[2*x]+s[2*x+1];
     18     }
     19     else
     20         s[x]=e[b];
     21 } 
     22 void clean(int x)
     23 {
     24     if (v2[x]>=0)
     25     {
     26         ma[x]=v2[x];
     27         S[x]=(r[x]-l[x])*v2[x];
     28         v2[2*x]=v2[x];v1[2*x]=0;
     29         v2[2*x+1]=v2[x];v1[2*x+1]=0;
     30         v2[x]=-1;
     31     }
     32     if (v1[x])
     33     {
     34         ma[x]+=v1[x]*e[r[x]];
     35         S[x]=S[x]+v1[x]*s[x];
     36         v1[2*x]+=v1[x];
     37         v1[2*x+1]+=v1[x];
     38         v1[x]=0;
     39     }
     40 }
     41 void gao(int x,int a,int b,long long c)
     42 {
     43     int m;
     44     clean(x);
     45     if ((a<=l[x])&&(r[x]<=b))
     46     {
     47         v2[x]=c;
     48         return;
     49     }
     50     m=(l[x]+r[x])>>1;
     51     if (a<m) gao(2*x,a,b,c);
     52     if (m<b) gao(2*x+1,a,b,c);
     53     clean(2*x);clean(2*x+1);
     54     S[x]=S[2*x]+S[2*x+1];
     55     ma[x]=ma[2*x+1];
     56 }
     57 long long query(int x,int a,int b)
     58 {
     59     long long ans=0;
     60     int m;
     61     clean(x);
     62     if ((a<=l[x])&&(r[x]<=b))
     63         return S[x];
     64     m=(l[x]+r[x])>>1;
     65     if (a<m) ans+=query(2*x,a,b);
     66     if (m<b) ans+=query(2*x+1,a,b);
     67     return ans;
     68 }
     69 int find(int x,long long y)
     70 {
     71     clean(x);
     72     if (r[x]-l[x]==1)
     73     {
     74         if (ma[x]>=y)
     75         return r[x]-1;
     76         else
     77         return r[x];
     78     }
     79     clean(2*x);clean(2*x+1);
     80     if (ma[2*x]>=y)
     81     return find(2*x,y);
     82     else
     83     return find(2*x+1,y);
     84 }
     85 int main()
     86 {
     87     scanf("%lld%lld",&n,&m);
     88     for (i=1;i<=n;i++)
     89         scanf("%d",&e[i]);
     90     sort(e+1,e+1+n);
     91     build(1,0,n);
     92     
     93     for (i=1;i<=m;i++)
     94     {
     95         scanf("%lld%lld",&a,&b);
     96         v1[1]+=a-ta;
     97         int L=1,R=n,mid;
     98         
     99         R=find(1,b);
    100     //    printf("%d
    ",R);
    101         
    102         if (R<n)
    103         {
    104             printf("%lld
    ",query(1,R,n)-b*(n-R));
    105             gao(1,R,n,b);
    106         }
    107         else
    108             printf("0
    ");
    109         ta=a;
    110     }    
    111 }
  • 相关阅读:
    Linux内核中的信号机制--一个简单的例子【转】
    国际C语言混乱代码大赛代码赏析(一)【转】
    宏内核与微内核【转】
    Linux内核USB驱动【转】
    USB驱动开发大全【转】
    Linux驱动程序学习【转】
    GPIO口及中断API函数【转】
    Linux的fasync驱动异步通知详解【转】
    request_irq() | 注册中断服务函数【转】
    混杂设备动态次设备号分析【转】
  • 原文地址:https://www.cnblogs.com/fzmh/p/5384685.html
Copyright © 2020-2023  润新知