LibreOj6280数列分块入门 4 区间加法+区间和

    xiaoxiao2023-11-01  34

    数列分块入门 4

    链接:LibreOj6280

    题目描述

    给出一个长为n的数列,以及n个操作,操作涉及区间加法,区间求和。

    输入格式

    第一行输入一个数字n。

    第二行输入n个数字,第i个数字为 a[i],以空格隔开。

    接下来输入n行询问,每行输入四个数字op、l、r、c,以空格隔开。

    若 op==0,将[l,r]之间的数字都加上c

    若 op==1,表示询问[l,r]所有数字的和%(c+1)

    输出格式

    对于每次询问,输出一行一个数字表示答案。

    样例输入

    4 1 2 2 3 0 1 3 1 1 1 4 4 0 1 2 2 1 1 2 4

    样例输出

    1 4

    分析:

    除了维护区间加法标记add,额外维护一个区间和sum

    ps:但是这题用longlong的话,输出不能用I64d必须用lld,心态被这个搞炸了(难受)

    我的代码:

    #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> #include<vector> #include<set> #include<queue> #include<stack> #include<map> #include<string> #include<algorithm> #include<sstream> #include<memory> #include<utility> #include<functional> #include<iterator> typedef long long ll; const int inf=0x3f3f3f3f; const int inn=0x80808080; using namespace std; const int maxm=5e4+5; int n; int l[maxm],r[maxm]; ll a[maxm],sum[maxm],add[maxm]; int belong[maxm]; int block,num; void build(){ block=sqrt(n); num=n/block; if(n%block){ num++; } for(int i=1;i<=num;i++){ l[i]=(i-1)*block+1; r[i]=i*block; add[i]=0; sum[i]=0; } r[num]=n; } void update(int x,int y,int val){ if(belong[x]==belong[y]){ for(int i=x;i<=y;i++){ a[i]+=val; sum[belong[i]]+=val; } return ; } for(int i=x;i<=r[belong[x]];i++){ a[i]+=val; sum[belong[i]]+=val; } for(int i=l[belong[y]];i<=y;i++){ a[i]+=val; sum[belong[i]]+=val; } for(int i=belong[x]+1;i<belong[y];i++){ add[i]+=val; sum[i]+=block*val; } } long long ffind(int x,int y){ long long ans=0; if(belong[x]==belong[y]){ for(int i=x;i<=y;i++){ ans+=(a[i]+add[belong[i]]); } return ans; } for(int i=x;i<=r[belong[x]];i++){ ans+=(a[i]+add[belong[i]]); } for(int i=l[belong[y]];i<=y;i++){ ans+=(a[i]+add[belong[i]]); } for(int i=belong[x]+1;i<belong[y];i++){ ans+=sum[i]; } return ans; } int main(){ scanf("%d",&n); build(); for(int i=1;i<=n;i++){ belong[i]=(i-1)/block+1; scanf("%lld",&a[i]); sum[belong[i]]+=a[i]; } for(int i=1;i<=n;i++){ int d,x,y; ll c; scanf("%d%d%d%lld",&d,&x,&y,&c); if(d==0){ update(x,y,c); }else{ printf("%lld\n",ffind(x,y)%(c+1)); } } return 0; }
    最新回复(0)