BZOJ4293: [PA2015]Siano

发现大小顺序不变,因为都是从0开始长,生长速度快的肯定不会落后

所以排下序,二分就可以找到一段连续的需要cov的区间

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define INF 0x7f7f7f7f
  6 #define MAXN 500010 
  7 #define rint register int 
  8 #define ll long long
  9 using namespace std;
 10 ll read(){
 11     ll x=0,f=1;char ch=getchar();
 12     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
 13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 14     return x*f;
 15 }
 16 #define lc k<<1
 17 #define rc k<<1|1
 18 struct SegmentTree{
 19     struct Node{
 20         ll mn,mt;
 21         ll sn,st;
 22         ll tg,tgt;
 23         int L,R;
 24     }st[MAXN<<2];
 25     ll a[MAXN],s[MAXN];
 26     ll T;
 27     int n;
 28     Node Merge(Node A,Node B){
 29         Node r;
 30         r.L=A.L,r.R=B.R; 
 31         r.mn=B.mn,r.mt=B.mt;
 32         r.sn=A.sn+(T-A.st)*(s[A.R]-s[A.L-1])+B.sn+(T-B.st)*(s[B.R]-s[B.L-1]);
 33         r.st=T;
 34         r.tg=0LL,r.tgt=0LL;
 35         return r;
 36     }
 37     void workcov(int k,ll v,ll t){
 38         int L=st[k].L,R=st[k].R;
 39         st[k].mn=v,st[k].mt=t;
 40         st[k].sn=v*(R-L+1),st[k].st=t;
 41         st[k].tg=v,st[k].tgt=t;
 42     }    
 43     void pushdown(int k){
 44         if(st[k].tgt){
 45             for(rint i=0;i<=1;i++){
 46                 int c=k<<1|i;
 47                 if(st[c].tgt<st[k].tgt)workcov(c,st[k].tg,st[k].tgt);
 48             }
 49             st[k].tg=0LL;
 50             st[k].tgt=0LL;
 51         }
 52     }
 53     ll query(int k,int a,int b,ll v){
 54         int L=st[k].L,R=st[k].R;
 55         ll r=0LL;
 56         if(a<=L&&R<=b){
 57             r=st[k].sn+(T-st[k].st)*(s[R]-s[L-1]);
 58             workcov(k,v,T);    
 59         }
 60         else{    
 61             int mid=(L+R)>>1;
 62             pushdown(k);
 63             if(a<=mid)r+=query(lc,a,b,v);
 64             if(b>mid)r+=query(rc,a,b,v);
 65             st[k]=Merge(st[lc],st[rc]);        
 66         }
 67         return r;
 68     }
 69     int getp(int k,ll v){
 70         int L=st[k].L,R=st[k].R;
 71         if(L==R){
 72             if(st[k].mn+(T-st[k].mt)*a[L]>=v)return L;
 73             else return L+1;
 74         }
 75         pushdown(k);
 76         if(st[lc].mn+(T-st[lc].mt)*a[st[lc].R]>=v){
 77             return getp(lc,v);
 78         }
 79         else{
 80             return getp(rc,v);
 81         }
 82     }
 83     void build(int k,int L,int R){
 84         st[k].L=L,st[k].R=R;
 85         if(L==R){
 86             st[k].mn=0LL,st[k].mt=0LL;
 87             st[k].sn=0LL,st[k].st=0LL;
 88             st[k].tgt=0LL;
 89         }
 90         else{
 91             int mid=(L+R)>>1;
 92             build(lc,L,mid);
 93             build(rc,mid+1,R);
 94             st[k]=Merge(st[lc],st[rc]);
 95         }
 96     }
 97     ll ask(ll v,ll t){
 98         T=t;
 99         int p=getp(1,v);
100         if(p<=n)return query(1,p,n,v)-(n-p+1)*v;
101         else return 0LL;
102     }
103 }ST;
104 int n;
105 int main()
106 {
107 //    freopen("data.in","r",stdin);
108     int T;
109     n=read(),T=read();ST.n=n;
110     for(rint i=1;i<=n;i++)ST.a[i]=read();
111     sort(ST.a+1,ST.a+n+1);
112     for(rint i=1;i<=n;i++)ST.s[i]=ST.s[i-1]+ST.a[i];
113     ST.build(1,1,n); 
114     ll t,v,ans;
115     while(T--){
116         t=read(),v=read();
117         ans=ST.ask(v,t);
118         printf("%lld\n",ans);
119     }
120     return 0;
121 }

 

posted @ 2018-03-07 20:05  white_hat_hacker  阅读(278)  评论(0编辑  收藏  举报