萌新不知道什么是线段树二分
查看原帖
萌新不知道什么是线段树二分
766675
da_ke楼主2024/10/20 20:51
// 线段树二分
int query(int o,int l,int r,int w,int e)
{
    if(l==r) return l; 
    if(tag[o]) push_down(o,l,r);
    int mid=l+((r-l)>>1);
    if(v[o<<1]*e>=w) return query(o<<1,l,mid,w,e);
    else return query(o<<1|1,mid+1,r,w-v[o<<1]*e,e);
}

求挑错!

完整代码:

#include <bits/stdc++.h>

#define int long long
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define fdn(i,r,l) for(int i=(r);i>=(l);i--)
#define pii pair<int,int>
using namespace std;

typedef long long ll;
typedef double db;
typedef __int128 i128;

std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
std::mt19937_64 rnd64(std::chrono::steady_clock::now().time_since_epoch().count());

const int N=2e5+23;

int n,Q;
ll W,a[N];
ll v[N<<2],tag[N<<2];

void build(int o,int l,int r)
{
    if(l==r){v[o]=a[l];return ;}
    int mid=l+((r-l)>>1);
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    v[o]=v[o<<1]+v[o<<1|1];
}

void push_down(int o,int l,int r)
{
    int mid=l+((r-l)>>1);
    v[o<<1]+=tag[o]*(mid-l+1),v[o<<1|1]+=tag[o]*(r-mid);
    tag[o<<1]+=tag[o],tag[o<<1|1]+=tag[o],tag[o]=0;
}

void update(int o,int l,int r,int s,int t,int k)
{
    if(s<=l&&r<=t){tag[o]+=k,v[o]+=(r-l+1)*k;return ;}
    if(tag[o]) push_down(o,l,r);
    int mid=l+((r-l)>>1);
    if(s<=mid) update(o<<1,l,mid,s,t,k);
    if(t>mid) update(o<<1|1,mid+1,r,s,t,k);
    v[o]=v[o<<1]+v[o<<1|1];
}

// 线段树二分
int query(int o,int l,int r,int w,int e)
{
    if(l==r) return l; 
    if(tag[o]) push_down(o,l,r);
    int mid=l+((r-l)>>1);
    if(v[o<<1]*e>=w) return query(o<<1,l,mid,w,e);
    else return query(o<<1|1,mid+1,r,w-v[o<<1]*e,e);
}

signed main()
{
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    cin>>n>>Q>>W;
    rep(i,1,n) cin>>a[i];
    build(1,1,n);
    while(Q--)
    {
        ll w=W;
        int l,r,k;
        cin>>l>>r>>k;
        update(1,1,n,l,r,k);
        ll sum=query(1,1,n,1,n);
        ll e=sum,Rd; // e 表示幂,Rd 表示对数
        rep(i,1,59)
        {
            w-=e;
            if(w<=0) /*死了*/{w+=e,Rd=i-1;break;}
            e*=2;
        }
        e/=sum;
        cout<<Rd*n+query(1,1,n,w,e)<<endl;
    }
}
2024/10/20 20:51
加载中...