题意:
中文
思路:
线段树基础题当然亦可以分块做
代码:
线段树:
#include <bits/stdc++.h>
using namespace std;
#define ls l,mid,rt*2
#define rs mid+1,r,rt*2+1
#define mi (l+r)/2
const int MAXN=1e5+7;
int n,m;
long long sum[MAXN*4];
int lazy[MAXN*4],st,en,v;
void push_down(int l,int r,int rt){
if(lazy[rt]){
int mid=mi;
lazy[rt*2+1]+=lazy[rt];
lazy[rt*2]+=lazy[rt];
sum[rt*2+1]+=(long long)lazy[rt]*(r-mid);
sum[rt*2]+=(long long)lazy[rt]*(mid-l+1);
lazy[rt]=0;
}
}
void push_up(int rt){
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
void build(int l,int r,int rt){
sum[rt]=lazy[rt]=0;
if(l==r){
return ;
}
int mid=mi;
build(ls);
build(rs);
}
long long update_and_query(int l,int r,int rt){
if(r<st||l>en) return 0;
if(st<=l&&r<=en){
lazy[rt]+=v;
sum[rt]+=(long long)v*(r-l+1);
return sum[rt];
}
push_down(l,r,rt);
int mid=mi;
long long ans=update_and_query(ls)+update_and_query(rs);
push_up(rt);
return ans;
}
int main(){
freopen("data.in","r",stdin);
freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&m)!=-1){
build(1,n,1);
while(m--){scanf("%d%d%d",&st,&en,&v);
printf("%lld\n",update_and_query(1,n,1));
}
}
}
分块:
#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN=1e5+7;
int n,m;
int blen,belong[MAXN],r[MAXN],l[MAXN],num;
long long sum[MAXN],a[MAXN];
int lazy[MAXN];
void build(){
blen=sqrt(n);
num=n/blen;
if(n%blen) n++;
for(int i=1;i<=num;i++) l[i]=blen*(i-1)+1,r[i]=blen*i;
r[num]=n;
for(int i=1;i<=num;i++){
sum[i]=lazy[i]=0;
for(int j=l[i];j<=r[i];j++){
belong[j]=i;
a[j]=0;
}
}
}
long long update_and_query(int st,int en,int v){
long long ans=0;
if(belong[st]==belong[en]){
for(int i=st;i<=en;i++){
a[i]+=v;
ans+=a[i]+lazy[belong[st]];
}
sum[belong[st]]+=(long long)v*(en-st+1);
}else{
for(int i=st;i<=r[belong[st]];i++){
a[i]+=v;
ans+=a[i]+lazy[belong[st]];
}
sum[belong[st]]+=(long long)v*(r[belong[st]]-st+1);
for(int i=belong[st]+1;i<belong[en];i++){
sum[i]+=(long long)v*(r[i]-l[i]+1);
lazy[i]+=v;
ans+=sum[i];
}
for(int i=l[belong[en]];i<=en;i++){
a[i]+=v;
ans+=a[i]+lazy[belong[en]];
}
sum[belong[en]]+=(long long)v*(en-l[belong[en]]+1);
}
return ans;
}
int main(){
//freopen("data.in","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&m)!=-1){
build();
while(m--){int st,en,v;
scanf("%d%d%d",&st,&en,&v);
printf("%lld\n",update_and_query(st,en,v));
}
}
}