• LOJ #6280. 数列分块入门 4


    (color{#0066ff}{题目描述})

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

    (color{#0066ff}{输入格式})

    第一行输入一个数字 n。

    第二行输入 n 个数字,第 i 个数字为 (a_i),以空格隔开。

    接下来输入 n 行询问,每行输入四个数字 (mathrm{opt}、l、r、c),以空格隔开。

    (mathrm{opt} = 0),表示将位于 ([l,r]) 的之间的数字都加 c。

    (mathrm{opt} = 1),表示询问位于 ([l,r]) 的所有数字的和 (mod (c+1))

    (color{#0066ff}{输出格式})

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

    (color{#0066ff}{输入样例})

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

    (color{#0066ff}{输出样例})

    1
    4
    

    (color{#0066ff}{题解})

    对于区间加,如果是整块,打标记,并修改区间的和

    如果是散块,暴力修改,别忘了所属块的修改

    对于区间查询,对于整块,直接加维护的和

    对于散块,直接加对应位置的值+标记!

    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #define _ 0
    #define LL long long
    #define Space putchar(' ')
    #define Enter putchar('
    ')
    #define fuu(x,y,z) for(int x=(y),x##end=z;x<=x##end;x++)
    #define fu(x,y,z)  for(int x=(y),x##end=z;x<x##end;x++)
    #define fdd(x,y,z) for(int x=(y),x##end=z;x>=x##end;x--)
    #define fd(x,y,z)  for(int x=(y),x##end=z;x>x##end;x--)
    #define mem(x,y)   memset(x,y,sizeof(x))
    #ifndef olinr
    inline char getc()
    {
    	static char buf[100001],*p1=buf,*p2=buf;
    	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100001,stdin),p1==p2)? EOF:*p1++;
    }
    #else
    #define getc() getchar()
    #endif
    template<typename T>inline void in(T &x)
    {
    	int f=1; char ch; x=0;
    	while(!isdigit(ch=getc()))(ch=='-')&&(f=-f);
    	while(isdigit(ch)) x=x*10+(ch^48),ch=getc();
    	x*=f;
    }
    const int inf=0x7fffffff;
    int n,num;
    struct K
    {
    	int l,r;
    	LL tag,val;
    	K() {l=inf,r=-inf;}
    }e[50505];
    struct seq
    {
    	int bel;
    	LL val;
    }a[50550];
    inline void init()
    {
    	num=std::sqrt(n);
    	fuu(i,1,n)
    	{
    		in(a[i].val),a[i].bel=(i-1)/num+1;
    		e[a[i].bel].l=std::min(e[a[i].bel].l,i);
    		e[a[i].bel].r=std::max(e[a[i].bel].r,i);
    		e[a[i].bel].val+=a[i].val;
    	}
    }
    inline void add(int l,int r,LL c)
    {
    	fuu(i,a[l].bel+1,a[r].bel-1) e[i].tag+=c,e[i].val+=((LL)(e[i].r-e[i].l+1)*c);
    	fuu(i,l,std::min(r,e[a[l].bel].r)) a[i].val+=c,e[a[i].bel].val+=c;
    	if(a[l].bel!=a[r].bel) fuu(i,std::max(l,e[a[r].bel].l),r) a[i].val+=c,e[a[i].bel].val+=c;
    }
    inline LL query(int l,int r,LL c)
    {
    	int mod=c+1;
    	LL ans=0;
    	fuu(i,a[l].bel+1,a[r].bel-1) (ans+=e[i].val)%=mod;
    	fuu(i,l,std::min(r,e[a[l].bel].r)) (ans+=a[i].val+e[a[i].bel].tag)%=mod;
    	if(a[l].bel!=a[r].bel) fuu(i,std::max(l,e[a[r].bel].l),r) (ans+=a[i].val+e[a[i].bel].tag)%=mod;
    	return ans;
    }
    int main()
    {
    	in(n);
    	init();
    	int p,l,r,c;
    	while(n--)
    	{
    		in(p),in(l),in(r),in(c);
    		if(p==0) add(l,r,c);
    		else printf("%lld
    ",query(l,r,c));
    	}
    	return ~~(0^_^0);
    }
    
  • 相关阅读:
    【模板】Sparse-Table
    UVa 11235 Frequent values
    【模板】树状数组
    UVa 1428 Ping pong
    数学技巧
    UVa 11300 Spreading the Wealth
    UVa 11729 Commando War
    UVa 11292 Dragon of Loowater
    POJ 3627 Bookshelf
    POJ 1056 IMMEDIATE DECODABILITY
  • 原文地址:https://www.cnblogs.com/olinr/p/10066863.html
Copyright © 2020-2023  润新知