警示后人! ! !
查看原帖
警示后人! ! !
312767
Ayin楼主2023/9/26 20:07
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define int long long
using namespace std;
const int N = 2e5+10;
int read(){
    int a=0,b=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') b=-1;
    for(;isdigit(ch);ch=getchar()) a=a*10+(ch-48);
    return a*b;
}
template<typename T>inline void read(T &x){x=read();}
template<typename T,typename ...Args>inline void read(T &x,Args &...args){read(x);read(args...);}
int n,L,R,ans;
int num[N],pre[N];
void solve(int ll,int rr){
    if(ll==rr) { if(num[ll]>=L&&num[rr]<=R) { ++ans; } return; }
    int mid=(ll+rr)>>1; solve(ll,mid); solve(mid+1,rr);
    int sum[N]={0},len=0;
    for(int i=ll;i<=mid;i++) sum[++len]=pre[mid]-pre[i-1];
    sort(sum+1,sum+len+1);
    for(int i=mid+1;i<=rr;i++){
        int val=pre[i]-pre[mid];
        int ans1=-1,ans2=-1;
        int l=1,r=len; L=L-val; R=R-val;
        while(l<=r){
            int mit=(l+r)>>1;
            if(sum[mit]>=L){
                ans1=mit;
                r=mit-1;
            }
            else{
                l=mit+1;
            }
        }
        l=1,r=len;
        while(l<=r){
            int mit=(l+r)>>1;
            if(sum[mit]<=R){
                ans2=mit;
                l=mit+1;
            }
            else{
                r=mit-1;
            }
        }
        L=L+val; R=R+val;
        if(ans1==-1) continue;
        if(ans2==-1) continue;
        ans=ans+(ans2-ans1+1);
    } return;
}
signed main(){
    read(n,L,R); for(int i=1;i<=n;i++) { read(num[i]); pre[i]=pre[i-1]+num[i]; }
    solve(1,n); printf("%lld\n",ans);
    return 0;
}

千万不要在cdq分治里面初始化数组,这会使得你的算法复杂度退化为O(n2n^2) ! ! !

2023/9/26 20:07
加载中...