模板题,不过好像卡常?
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int SIZE=500010;
typedef long long LL;
struct seg{
int l,r;
LL sum,add;
}tree[SIZE*4];
void update(int p)
{
tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
}
void build(int p,int l,int r)
{
tree[p].l=l; tree[p].r=r;
if(l==r)
{
tree[p].sum=tree[p].add=0;
return ;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
update(p);
}
void spread(int p)
{
if(tree[p].add)
{
LL d=tree[p].add;
tree[p<<1].sum+=d*(tree[p<<1].r-tree[p<<1].l+1);
tree[p<<1|1].sum+=d*(tree[p<<1|1].r-tree[p<<1|1].l+1);
tree[p<<1].add+=d;
tree[p<<1|1].add+=d;
tree[p].add=0;
}
}
void change(int p,int l,int r,LL d)
{
if(l<=tree[p].l&&tree[p].r<=r)
{
tree[p].add+=d;
tree[p].sum+=d*(tree[p].r-tree[p].l+1);
return ;
}
spread(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid) change(p<<1,l,r,d);
if(mid<r) change(p<<1|1,l,r,d);
update(p);
}
LL ask(int p,int l,int r)
{
if(l<=tree[p].l&&tree[p].r<=r)
{
return tree[p].sum;
}
spread(p);
int mid=(tree[p].l+tree[p].r)>>1;
LL ans=0;
if(l<=mid) ans+=ask(p<<1,l,r);
if(mid<r) ans+=ask(p<<1|1,l,r);
return ans;
}
void scanf(int &n)
{
n=0;
bool flag=0;
char a=getchar();
while(a<'0'||a>'9') {if(a=='-') flag=1;a=getchar();}
while(a>='0'&&a<='9') n=(n<<3)+(n<<1)+a-'0',a=getchar();
if(flag) n=-n;
}
void scanf(LL &n)
{
n=0;
bool flag=0;
char a=getchar();
while(a<'0'||a>'9') {if(a=='-') flag=1;a=getchar();}
while(a>='0'&&a<='9') n=(n<<3)+(n<<1)+a-'0',a=getchar();
if(flag) n=-n;
}
int main()
{
int n,m;
scanf(n); scanf(m);
build(1,1,n);
while(m--)
{
LL s;
scanf(s);
switch(s)
{
case 1:
int l,r;
scanf(l);scanf(r);
printf("%lld\n",ask(1,l,r));
break;
case 2:
int a,b;
LL c;
scanf(a); scanf(b); scanf(c);
change(1,a,b,c);
break;
}
}
return 0;
}