奇怪的膜法(magic)——前缀和做法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇怪的膜法(magic)——前缀和做法相关的知识,希望对你有一定的参考价值。

题目描述

Zxyer是M国一个伟大的膜法师,现在他制作出了n个膜法球,每个膜法球有一个初始膜力值,由亍zxyer现在在修炼膜法,因此zxyer现在会对这些按照编号为1~n顺序依次排列的膜法球进行m次操作,每次zxyer会将一个区间的膜法球拿出,然后将他们的膜力值依次增加一个等差数列,现在zxyer想要知道在他施法全部结束后,这些膜法球各自的膜力值。 

 

输入

第一行2个整数,n,m,定义参见问题描述。 

第2行n个整数,ai,表示膜法球各自的初始膜力值。 

第3~m+2行,每行3个整数,Li,Ri,qi,si表示第i次操作区间的左右端点(对应着等差数列的首项与末项),等差数列的公差,首项。 

 

输出

输出n行,每行1个整数,表示施法结束后每个膜法球的膜力值。 

 

样例输入

5 4
1 2 3 4 5
1 3 2 1
4 5 -1 2
1 5 -3 10
2 4 6 -5

样例输出

12
7
13
14
4

提示

 

对于100%的数据,1≤n,m≤200000

 

来源

20170416 NOIP模拟赛 by zxyer

 

这是学长出的一道题。

暴力的做法就只能拿部分分,其实我们大多数人也只有部分分。

线段树的做法就O(nlogn)就可以过了,不过还有更快的O(n+m)的方法。

简单的说就是两次前缀和。

因为题意要求在区间内加上一个差分序列,告诉公差。

我们假设公差是1,那么在前缀和数组a上修改就是a[l]到a[r]加每一位都加1。

因此可以用线段树做。

然而没有多次查询,我们就可以再来一个数组a的前缀和数组b,在b[l]上加1,在b[r]上减1。就可以实现a[l]到a[r]加每一位都加1。

然后就大功告成了。

注意,会爆int。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const long long maxn=200010;
long long read(){
    long long t=1,num=0;
    char c=getchar();
    while(c>9||c<0){if(c==-)t=-1;c=getchar();}
    while(c>=0&&c<=9){num=num*10+c-0;c=getchar();}
    return num*t;
}
long long a[maxn],b[maxn]={0},c[maxn]={0},ans[maxn]={0};
long long n,m,l,r,q,s;
int main()
{
    n=read();m=read();
    for(long long i=1;i<=n;i++)a[i]=read();
    for(long long i=1;i<=m;i++){
        l=read();r=read();q=read();s=read();
        c[l+1]+=q;c[r+1]-=q;
        long long g=(r-l)*q;
        c[l]+=s;c[l+1]-=s;
        c[r+1]-=g+s;c[r+2]+=g+s;
    }
    for(long long i=1;i<=n;i++)b[i]=b[i-1]+c[i];
    for(long long i=1;i<=n;i++)ans[i]=ans[i-1]+b[i];
    for(long long i=1;i<=n;i++)cout<<a[i]+ans[i]<<"\\n";
    return 0;
}

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

以上是关于奇怪的膜法(magic)——前缀和做法的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot2.x 给Controller的RequestMapping添加统一前缀

python jupyter magic命令片段

Android片段底部的奇怪空白?

HDU - 5157 :Harry and magic string (回文树)

一起在指针上使用前缀和后缀时的奇怪输出

BZOJ 4052 Magical GCD