分块求调,本地ac,提交全wa

P3372 【模板】线段树 1

SunsetLake @ 2023-07-15 07:54:06

rt,有没有大佬知道这是什么情况,或者帮我找一下代码哪里写错了,感激不尽!

Input
8 10
640 591 141 307 942 58 775 133 
2 1 5
2 3 8
2 3 6
2 5 8
2 4 8
1 4 8 60
2 1 6
2 5 8
1 3 7 15
1 2 6 86
Output
2621
2356
1448
1908
2215
2859
2148

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,op,t,x,y,k;
ll a[100005],l[100005],r[100005],sum[100005],ad[100005],pos[100005];//l,r是每个块的左右端点;sum区间和,ad懒标记,pos是块号 
void update(int x,int y,ll d){
    int p=pos[x],q=pos[y];
    if(p==q){
        for(int i=x;i<=y;++i)a[i]+=d;
        sum[p]+=d*(ll)(y-x+1);
        return;
    }
    for(int i=p+1;i<=q-1;++i)ad[i]+=d;

    for(int i=x;i<=r[p];++i)a[i]+=d;
    sum[p]+=d*(r[p]-x+1);
    for(int i=l[q];i<=y;++i)a[i]+=d;
    sum[q]+=d*(y-l[q]+1);
}
ll query(int x,int y){
    int p=pos[x],q=pos[y];
    ll res=0;
    if(p==q){
        for(int i=x;i<=y;++i)res+=a[i];
        res+=ad[p]*(y-x+1);
        return res;
    }
    for(int i=p+1;i<=q-1;++i)res+=sum[i]+ad[i]*(r[i]-l[i]+1);
    for(int i=x;i<=r[p];++i)res+=a[i];
    res+=ad[p]*(r[p]-x+1);
    for(int i=l[q];i<=y;++i)res+=a[i];
    res+=ad[q]*(y-l[q]+1);
    return res;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
    t=sqrt(n);
    for(int i=1;i<=t;++i){
        l[i]=(i-1)*t+1;
        r[i]=i*t;
    }
    if(r[t]<n){
        l[++t]=r[t-1]+1;
        r[t]=n;
    }
    for(int i=1;i<=t;++i){
        for(int j=l[i];j<=r[i];++j){
            sum[i]+=a[j];
            pos[j]=i;
        }
    }
    while(m--){
        scanf("%d%d%d",&op,&x,&y);
        if(op==1){
            scanf("%lld",&k);
            update(x,y,k);
        }
        else printf("%lld\n",query(x,y));
    }
    return 0;
}

by Struct_Sec @ 2023-07-15 07:55:04

orz%%%


by ATZdhjeb @ 2023-07-15 08:09:19

@CW_gjy 询问的时候 scanf("%lld") 试试?


by Deleted304 @ 2023-07-15 09:52:50

@CW_gjy orz


by Deleted304 @ 2023-07-15 09:54:20

@CW_gjy 推荐loj数列分块入门1-9捏


by imsaileach @ 2023-07-15 10:04:28

@CW_gjy 建议先做loj数列分块入门1-9和这个题,这些是分块里比较基础的题。推荐做完了再来做线段树一这种世纪难题。


by Deleted304 @ 2023-07-15 10:04:51

分块大佬甲克阳。


by BINYU @ 2023-07-15 10:05:49

@CW_gjy orz


by Deleted304 @ 2023-07-15 10:06:11

@ALnAYuLvM 分块大佬RongC。


by Opuntia9622 @ 2023-07-15 10:10:49

@BINYU 6


by imsaileach @ 2023-07-15 11:04:30

@CW_gjy 亲测把

 if(r[t]<n){
        l[++t]=r[t-1]+1;
        r[t]=n;
    }

改成

 if (r[t] < n){
        ++ t;
        l[t] = r[t - 1] + 1;
        r[t] = n;
    }

就能过。

不谢。


| 下一页