A Simple Problem with Integers
题意:线段数区间修改和区间查询,线段树节点代表区间的和。
值得注意数据范围:-1000000000 ≤ Ai ≤ 1000000000,以及数组界限:开4*n大小
节点存取的是一段区间内数的和需要开longlong型,防爆
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
int a[N],lazy[4*N];
ll sum[4*N];
void build(int k,int l,int r)
{
if(l==r)
{
sum[k]=a[l];
return;
}
int mid=(l+r)/2;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
sum[k]=sum[k<<1]+sum[k<<1|1];
}
void add(int k,int l,int r,int v)
{
lazy[k]+=v;
sum[k]+=(ll)v*(r-l+1);
}
void push(int k,int l,int r,int mid)
{
if(lazy[k])
{
add(k<<1,l,mid,lazy[k]);
add(k<<1|1,mid+1,r,lazy[k]);
lazy[k]=0;
}
}
void modify(int k,int l,int r,int x,int y,int v)
{
if(l>=x&&r<=y) return add(k,l,r,v);
int mid=l+r>>1;
push(k,l,r,mid);
if(x<=mid)modify(k<<1,l,mid,x,y,v);
if(y>mid)modify(k<<1|1,mid+1,r,x,y,v);
sum[k]=sum[k<<1]+sum[k<<1|1];
}
ll query(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y)return sum[k];
int mid=l+r>>1;
ll res=0;
push(k,l,r,mid);
if(x<=mid)res+=query(k<<1,l,mid,x,y);
if(y>mid)res+=query(k<<1|1,mid+1,r,x,y);
return res;
}
int main()
{
char c;
int n,m;
scanf("%d%d",&n,&m);
memset(lazy,0,sizeof(lazy));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
int t1,t2,t3;
while(m--){
getchar();
scanf("%c",&c);
if(c=='C'){
scanf("%d%d%d",&t1,&t2,&t3);
modify(1,1,n,t1,t2,t3);
}
if(c=='Q'){
scanf("%d%d",&t1,&t2);
printf("%lld\n",query(1,1,n,t1,t2));
}
}
return 0;
}
I Hate It
题意:裸题,单点修改,单点查询。
注意输入是多组数据
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200010
ll sum[4*N],a[N];
void build(int k,int l,int r)
{
if(l==r)
{
sum[k]=a[l];
return;
}
int mid=(l+r)/2;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
sum[k]=max(sum[k<<1],sum[k<<1|1]);
}
ll query_max(int k,int l,int r,int x,int y)
{
if(r<x||l>y)return -1;
if(x<=l&&r<=y)return sum[k];
int mid=(l+r)/2;
return max(query_max(k<<1,l,mid,x,y),query_max(k<<1|1,mid+1,r,x,y));
}
void change(int k,int l,int r,int x,int v)
{
if(l>x||r<x) return;
if(l==r&&l==x)
{
sum[k]=v;
return;
}
int mid=(l+r)/2;
change(k<<1,l,mid,x,v);
change(k<<1|1,mid+1,r,x,v);
sum[k]=max(sum[k<<1],sum[k<<1|1]);
}
int main()
{
char c;
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(sum,0,sizeof(sum));
for(int i=1; i<=n; i++)
scanf("%lld",&a[i]);
build(1,1,n);
int t1,t2;
while(m--){
getchar();
scanf("%c%d%d",&c,&t1,&t2);
if(c=='U')
change(1,1,n,t1,t2);
else if(c=='Q')
printf("%lld\n",query_max(1,1,n,t1,t2));
}
}
return 0;
}