ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

gym 102586 B Evacuation

2021-11-09 21:02:02  阅读:193  来源: 互联网

标签:val int gym 102586 mid rb Evacuation now LL


gym 102586 B Evacuation

首先先考虑\(O(NQ)\)的做法:

可以发现最坏情况一定是放在同一点,然后在此基础上,最终分布的区间两边长度的绝对值不能超过1 。

这个可以\(O(NlogN)\)预处理每一个点,询问\([1,n]\)的答案,这样查询任意\(x,l,r\)可以做到\(O(1)\)。

下面的优化就比较神仙了,需要发现当\(x\leq\frac{l+r}{2}\)时,只和\(l\)有关,然后随着\(l\)递增,最优的\(x\)也是递增的。

然后利用决策单调性,分治+线段树分治进行优化,时间复杂度为\(O(Nlog^2N)\)。

#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define rep(a,b) for(int a=0;a<b;++a)
#define LL long long
#define PB push_back
#define POB pop_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
const int MAXN=2e5+5;
int n;
LL s;
LL a[MAXN];
LL prefix[MAXN];
LL prefix2[MAXN];
LL ans[MAXN];
const int N=1<<18;
vector<pair<int,int > > seg[N+N];
void addi(int a,int b,mp val,int now=1,int l=1,int r=N+1){
    if(r<=a||l>=b) return ;
    if(r<=b&&l>=a) {
        seg[now].PB(val);
        return ;
    }
    int mid=(l+r)>>1;
    addi(a,b,val,now<<1,l,mid);
    addi(a,b,val,now<<1|1,mid,r);
}
int save[MAXN];
int init(int x){
    int L=0,R=min(x-1,n-x)+1;
    while(L<R-1){
        int mid=(L+R)>>1;
        mp lg,rg;
        lg=II(x-mid,x);
        rg=II(x+1,x+mid);
        LL tot=0;
        if(lg.FIR<=lg.SEC) tot+=prefix[lg.SEC]-prefix[lg.FIR-1];
        if(rg.FIR<=rg.SEC) tot+=prefix[rg.SEC]-prefix[rg.FIR-1];
        if(tot>s) R=mid;
        else L=mid;
    }
    return L;
}
LL query(int x,int l,int r){
    int L=min(save[x],min(x-l,r-x));
    mp lg,rg;
    lg=II(x-L,x);
    check_max(lg.FIR,1);
    rg=II(x+1,x+L);
    check_min(rg.SEC,n);
    LL lp,rp;
    lp=rp=0;
    if(lg.FIR<=lg.SEC) lp=prefix[lg.SEC]-prefix[lg.FIR-1];
    if(rg.FIR<=rg.SEC) rp=prefix[rg.SEC]-prefix[rg.FIR-1];
    LL rst=s-lp-rp;
    LL dis=0;
    
    dis=lp*x-rp*x+rst*(L+1);
    if(lp) dis-=prefix2[lg.SEC]-prefix2[lg.FIR-1];
    if(rp) dis+=prefix2[rg.SEC]-prefix2[rg.FIR-1];
    
    return dis;
}
void dvdL(vector<mp> v,int l,int r){
    if(v.empty()) return ;
    int mid=v.size()/2;
    vector<mp> L,R;
    rep(i,mid) L.PB(v[i]);
    rb(i,mid+1,v.size()-1) R.PB(v[i]);
    int p=-1;
    LL val=-1e18;
    auto now=v[mid];
    rb(i,l,r){
        LL tmp=query(i,now.FIR,n);
        if(tmp>val){
            tie(val,p)=II(tmp,i);
        }
    }
    check_max(ans[now.SEC],val);
    dvdL(L,l,p);
    dvdL(R,p,r);
}
void dvdR(vector<mp> v,int l,int r){
    if(v.empty()) return ;
    int mid=v.size()/2;
    vector<mp> L,R;
    rep(i,mid) L.PB(v[i]);
    rb(i,mid+1,v.size()-1) R.PB(v[i]);
    int p=-1;
    LL val=-1e18;
    auto now=v[mid];
    rb(i,l,r){
        LL tmp=query(i,1,now.FIR);
        if(tmp>val){
            tie(val,p)=II(tmp,i);
        }
    }
    check_max(ans[now.SEC],val);
    dvdR(L,l,p);
    dvdR(R,p,r);
}
void run(int now=1,int l=1,int r=N+1){
    vector<mp> L,R;
    for(auto it:seg[now]){
        if(it.SEC<0){
            R.PB(II(it.FIR,-it.SEC));
        }
        else{
            L.PB(it);
        }
    }
    sort(ALL(L));
    sort(ALL(R));
    dvdL(L,l,r-1);
    dvdR(R,l,r-1);
    if(l==r-1) return ;
    int mid=(l+r)>>1;
    run(now<<1,l,mid);
    run(now<<1|1,mid,r);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>s;
    rb(i,1,n) cin>>a[i];
    rb(i,1,n) prefix[i]=prefix[i-1]+a[i],prefix2[i]=prefix2[i-1]+a[i]*i;
    rb(i,1,n) save[i]=init(i);
    int q;
    cin>>q;
    rb(i,1,q){
        int l,r;
        cin>>l>>r;
        int mid=(l+r)>>1;
        addi(l,mid+1,II(l,i));
        if(mid!=r)
            addi(mid+1,r+1,II(r,-i));
    }
    rb(i,1,q) ans[i]=-1e18;
    run();
    rb(i,1,q) cout<<ans[i]<<endl;
    return 0;
}

标签:val,int,gym,102586,mid,rb,Evacuation,now,LL
来源: https://www.cnblogs.com/QQQ0000/p/15530887.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有