线段树太难写了。。。
线段树
#include<stdio.h>
#include<string.h>
const int inf=0x3f3f3f3f;
typedef long long ll;
int a[100005];
struct node{
ll l,r,sum,add;
}t[100005*4];
void build(int v,int x,int y){
t[v].l=x;t[v].r=y;
if(x==y){
t[v].sum=a[x];
return ;
}
int mid=(x+y)/2;
build(v*2,x,mid);
build(v*2+1,mid+1,y);
t[v].sum=t[v*2].sum+t[v*2+1].sum;
}
void spread(int v){
if(t[v].add){
t[v*2].sum+=t[v].add*(t[v*2].r-t[v*2].l+1);
t[v*2+1].sum+=t[v].add*(t[v*2+1].r-t[v*2+1].l+1);
t[v*2].add+=t[v].add;
t[v*2+1].add+=t[v].add;
t[v].add=0;
}
}
void updata(int v,int x,int y,int z){
if(x<=t[v].l&&y>=t[v].r){
t[v].sum+=z*(t[v].r-t[v].l+1);
t[v].add+=z;
return ;
}
spread(v);
int mid=t[v].l+t[v].r>>1;
if(x<=mid) updata(v*2,x,y,z);
if(y>mid) updata(v*2+1,x,y,z);
t[v].sum=t[v*2].sum+t[v*2+1].sum;
}
ll query(int v,int x,int y){
if(x<=t[v].l&&y>=t[v].r)
return t[v].sum;
spread(v);
long long ans=0;
int mid=t[v].l+t[v].r>>1;
if(x<=mid) ans+=query(v*2,x,y);
if(y>mid) ans+=query(v*2+1,x,y);
return ans;
}
int main()
{
int i,j,x,y,t,m,n,f;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
while(m--){
scanf("%d",&t);
if(t==1){
scanf("%d %d %d",&x,&y,&f);
updata(1,x,y,f);
}
else if(t==2){
scanf("%d %d",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}
树状数组
#include<stdio.h>
#include<string.h>
#include<math.h>
#define maxn 105
int n,a[maxn]={0},ans,c[maxn]={0};
int lowbit(int x){//lowbit(i)的意思是将i转化成二进制数之后,只保留最低位的1及其后面的0,截断前面的内容,然后再转成10进制数
return x&(-x);
}
int sum(int x){
int s=0;
while(x>0){
s+=c[x];
x-=lowbit(x);
}
return s;
}
void updata(int i,int x){
int j;
for(j=i;j<=n;j+=lowbit(j)){
c[j]+=x;
}
}
void add(int i,int x){
while(i<=n){
c[i]+=x;
i+=lowbit(x);
}
}
int query(int x,int y){
return sum(y)-sum(x-1);
}
int main()
{
int i,j,t;
n=10;
for(i=1;i<=10;i++){
a[i]=i;
updata(i,a[i]);
}
add(1,2);//在1的位置上加上2
ans=query(1,2);
printf("%d\n",ans);
return 0;
}
一下午收获还行。