队列+二分+树状数组75求调
查看原帖
队列+二分+树状数组75求调
920358
kmguochang楼主2024/11/18 21:29

可能思路较奇怪的一种做法

#include<bits/stdc++.h>
#define lowb(x) x&(-x)
using namespace std;
const int N=2e5+666;
typedef long long ll;
struct node{
    ll val,num;
    node(){
    }
    node(ll x,ll y){
        val=x,num=y;
        return;
    }
}now,q[N];
int n,c,top=1,tail;
ll s1[N],mx[N],s2[N];
void add(int x,ll data){//树状数组维护最值
    while(x<=n){
        mx[x]=max(mx[x],data);
        x+=lowb(x);
    }
    return;
}
ll ask(int x,int y){
    ll ans=0ll;
    while(y>=x){
        while(y-lowb(y)>=x){
            ans=max(ans,mx[y]);
            y-=lowb(y);
        }
        if(y<x)
            break;
        ans=max(ans,s2[y]);
        y--;
    }
    return ans;
}
int main(){
    int dx=0,dy=0,loc;
    ll x;
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>c>>n;
    for(int i=1;i<=n;++i){
        cin>>c;
        if(c==1){
            cin>>x;
            q[++tail]=node(x,x);
            s2[++dy]=x;
            s1[dy]=s1[dy-1]+x;//加入双端队列中
            add(dy,x);
        }
        else if(c==2){
            cin>>x;
            now=q[top];
            x+=now.val-now.num+s1[dx];//要在前缀和中二分,先加上前面的
            loc=upper_bound(s1+dx+1,s1+dy+1,x)-s1-1;//二分寻找修改后位置
            top+=(loc-dx);
            dx=loc;
            q[top].num=q[top].val-(x-s1[dx]);
        }
        else if(c==3){
            cin>>x;
            now=q[top];
            x+=(now.val-now.num+s1[dx]);
            loc=lower_bound(s1+dx+1,s1+dy+1,x)-s1-1;//二分同理
            cout<<x-s1[loc]<<endl;
        }
        else
            cout<<ask(dx+1,dy)<<endl;
    }
    return 0;
}

感觉时间复杂度nlog(n),六个输出样例都对

但是TLE 75 #9 #10 #11 #12 #20

https://www.luogu.com.cn/record/189681744

有没有热心大佬帮忙看一下Orz

2024/11/18 21:29
加载中...