P2357 守墓人
题解
标准的线段树加上一点点题意转化,注意细节
code
#define ll long long
#include<bits/stdc++.h>
using namespace std;
ll tree[810000];
ll wait[810000];
inline void read(ll &x) {
x = 0;
ll flag = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')flag = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
x *= flag;
}
inline void write(ll x)
{
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void build(ll node,ll l,ll r)
{
if(l==r)
{
read(tree[node]);
return;
}
ll mid=(l+r)>>1;
build(node<<1,l,mid);
build((node<<1)+1,mid+1,r);
tree[node]=tree[node<<1]+tree[(node<<1)+1];
}
void fresh(ll node,ll l,ll r)
{
tree[node]+=(r-l+1)*wait[node];
if(l!=r)
{
wait[node<<1]+=wait[node];
wait[(node<<1)+1]+=wait[node];
}
wait[node]=0;
}
void add(ll node,ll l,ll r,ll x,ll y,ll val)
{
fresh(node,l,r);
if(l>y||r<x)return;
if(l>=x&&r<=y)
{
wait[node]+=val;
fresh(node,l,r);
return;
}
ll mid=(l+r)>>1;
add(node<<1,l,mid,x,y,val);
add((node<<1)+1,mid+1,r,x,y,val);
tree[node]=tree[node<<1]+tree[(node<<1)+1];
}
ll query(ll node,ll l,ll r,ll x,ll y)
{
fresh(node,l,r);
if(l>y||r<x)return 0;
if(l>=x&&r<=y) return tree[node];
ll mid=(l+r)>>1;
return query(node<<1,l,mid,x,y)+query((node<<1)+1,mid+1,r,x,y);
}
int main()
{
ll n,m;
read(n); read(m);
memset(tree,0,sizeof tree);
memset(wait,0,sizeof wait);
build(1,1,n);
while(m--)
{
ll op,k,l,r;
read(op);
if(op==1)
{
read(l); read(r); read(k);
add(1,1,n,l,r,k);
}
else if(op==2)
{
read(k);
add(1,1,n,1,1,k);
}
else if(op==3)
{
read(k);
add(1,1,n,1,1,0-k);
}
else if(op==4)
{
read(l); read(r);
write(query(1,1,n,l,r));
putchar('\n');
}
else
{
write(query(1,1,n,1,1));
putchar('\n');
}
}
return 0;
}

浙公网安备 33010602011771号