为什么??!
查看原帖
为什么??!
552255
aleph_楼主2024/10/21 21:19

求调! 二分线段树,思路大概就是先二分找到能抗住的最大的那个2的次幂,再二分前缀和,时间复杂度 O(loglogn)O(\log \log n)

大样例3最后跑出非常逆天的结果,有一段应该全是49648的,结果我跑出:

49648
49648
120000
105001
105001
102375
102001
102001
171011
99001
150000
96005
96005
96004
96004
96004
96004
96003
96003
96003
150000 ???
96003
49648
49648

code如下。

#include <bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int N=200005;
int n,q,W;
int a[N],pow2[64];
#define lson (x<<1)
#define rson (x<<1|1)
#define mid ((l+r)>>1)
#define ls l,mid,lson
#define rs mid+1,r,rson
int seg[N<<2],tag[N<<2];
void update(int x){
    seg[x]=seg[lson]+seg[rson];
}
void build(int l,int r,int x){
    tag[x]=0;
    if(l==r){
        seg[x]=a[l];
        return;
    }
    build(ls);
    build(rs);
    update(x);
}
void pushdown(int l,int r,int x){
    if(!tag[x]) return;
    seg[lson]+=(mid-l+1)*tag[x];
    seg[rson]+=(r-mid)*tag[x];
    tag[lson]+=tag[x];
    tag[rson]+=tag[x];
    tag[x]=0;
}
void modify(int l,int r,int x,int L,int R,int k){
    if(l>R||r<L) return;
    if(L<=l&&r<=R){
        seg[x]+=(r-l+1)*k;
        tag[x]+=k;
        return;
    }
    pushdown(l,r,x);
    modify(ls,L,R,k);
    modify(rs,L,R,k);
    update(x);
}
int query(int l,int r,int x,int L,int R){
    if(l>R||r<L) return 0;
    if(L<=l&&r<=R){
        return seg[x];
    }
    pushdown(l,r,x);
    int ans=0;
    ans+=query(ls,L,R);
    ans+=query(rs,L,R);
    return ans;
}
signed main(){
    freopen("wxyt3.in","r",stdin);
    freopen("wxyt.out","w",stdout);
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    pow2[0]=1;
    for(int i=1;i<=63;i++){
        pow2[i]=pow2[i-1]*2;
    }
    //cout<<pow2[63]<<endl;
    cin>>n>>q>>W;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,n,1);
    int rec=1e18;
    while(q--){
        int L,R,d;
        cin>>L>>R>>d;
        modify(1,n,1,L,R,d);
        int l=1,r=63,k=0;
        int sum=query(1,n,1,1,n);
        while(l<=r){
            int mi=(l+r)>>1;
            if(W>sum*(pow2[mi]-1)){
                l=mi+1;
                k=mi;
            }
            else{
                r=mi-1;
            }
        }
        int w=W-sum*(pow2[k]-1);
        l=1,r=n;
        int pos=0;
        while(l<=r){
            int mi=(l+r)>>1;
            int tmp=query(1,n,1,1,mi);
            if(w>pow2[k]*tmp){
                l=mi+1;
                pos=mi;
            }
            else{
                r=mi-1;
            }
        }
        cout<<n*k+pos<<'\n';
    }
}
2024/10/21 21:19
加载中...