您的位置:首页 > 其它

POJ3468 线段树模板

2017-11-16 20:05 302 查看
Description

You have N integers, A1, A2, ... ,
AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.

The second line contains N numbers, the initial values of A1,
A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.

Each of the next Q lines represents an operation.

"C abc" means adding c to each of Aa, Aa+1, ... ,
Ab. -10000 ≤ c ≤ 10000.

"Q ab" means querying the sum of Aa, Aa+1, ... ,
Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4


Sample Output

4
55
9
15


Hint

The sums may exceed the range of 32-bit integers.

这个题之前做过,模板题

郁闷的是今天找了一晚上,自己写的也没找出WA在哪。。。。

今天的WA

#include <iostream>
#include<stdio.h>
using namespace std;
const int N=1e5;
typedef long long ll;
struct node{
int left,right;
ll weight;
int flag;
}tree[4*N+500];
ll sum;
void build(int k,int ll,int rr)
{
tree[k].left=ll;
tree[k].right=rr;
tree[k].flag=0;
if(tree[k].left==tree[k].right)
{
scanf("%lld",&tree[k].weight);
tree[k].flag=0;
return ;
}
int mid=(ll+rr)/2;
build(2*k,ll,mid);
build(2*k+1,mid+1,rr);
tree[k].weight=tree[2*k].weight+tree[2*k+1].weight;
}
void down(int k)
{
tree[2*k].flag+=tree[k].flag;
tree[2*k+1].flag+=tree[k].flag;
tree[2*k].weight+=tree[k].flag*(tree[2*k].right-tree[2*k].left+1);
tree[2*k+1].weight+=tree[k].flag*(tree[2*k+1].right-tree[2*k+1].left+1);
tree[k].flag=0;
}
void ask_interval(int k,int a,int b)
{
if(tree[k].left>=a&&tree[k].right<=b)
{
sum+=tree[k].weight;
return ;
}
if(tree[k].flag)
down(k);
int mid=(tree[k].left+tree[k].right)/2;
if(a<=mid)
ask_interval(2*k,a,b);
if(b>mid)
ask_interval(2*k+1,a,b);
}
void change_interval(int k,int a,int b,int add)
{
if(tree[k].left>=a&&tree[k].right<=b)
{
tree[k].weight+=(tree[k].right-tree[k].left+1)*add;
tree[k].flag+=add;
return ;
}
if(tree[k].flag)
down(k);
int mid=(tree[k].left+tree[k].right)/2;
if(a<=mid)
change_interval(2*k,a,b,add);
if(b>mid)
change_interval(2*k+1,a,b,add);
tree[k].weight=tree[2*k].weight+tree[2*k+1].weight;
}
int main()
{
int m,n;
while(scanf("%d%d",&n,&m)==2&&n+m!=0)
{
build(1,1,n);
int u,v;
char c;
int add;
while(m--)
{
getchar();
c=getchar();
scanf("%d%d",&u,&v);
if(c=='Q')
{
scanf("%d%d",&u,&v);
sum=0;
ask_interval(1,u,v);
printf("%lld\n",sum);
}
if(c=='C')
{
scanf("%d%d%d",&u,&v,&add);
change_interval(1,u,v,add);
}
}
}
return 0;
}


之前的AC
#include <iostream>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
struct node{
ll left,right;
ll weight;
int flag;
}tree[4*N];
ll fn
;
int o,n,q;
ll ans;
void build(ll k,ll l,ll r)
{
tree[k].left=l;
tree[k].right=r;
if(tree[k].left==tree[k].right){
tree[k].weight=fn[o++];
tree[k].flag=0;
return ;
}
ll mid=(l+r)/2;
build(2*k,l,mid);
build(2*k+1,mid+1,r);
tree[k].weight=tree[2*k].weight+tree[2*k+1].weight;
}
void down(ll k)
{
tree[2*k].flag+=tree[k].flag;
tree[2*k+1].flag+=tree[k].flag;
tree[2*k].weight+=tree[k].flag*(tree[2*k].right-tree[2*k].left+1);
tree[2*k+1].weight+=tree[k].flag*(tree[2*k+1].right-tree[2*k+1].left+1);
tree[k].flag=0;
}
void ask_interval(ll k,ll a,ll b)
{
if(tree[k].left>=a&&tree[k].right<=b){
ans+=tree[k].weight;
return ;
}
if(tree[k].flag)
down(k);
ll mid=(tree[k].left+tree[k].right)/2;
if(a<=mid)
ask_interval(2*k,a,b);
if(b>mid)
ask_interval(2*k+1,a,b);
}
void change_interval(ll k,ll a,ll b,int add)
{
if(tree[k].left>=a&&tree[k].right<=b){
tree[k].weight+=(tree[k].right-tree[k].left+1)*add;
tree[k].flag+=add;
return ;
}
if(tree[k].flag)
down(k);
ll mid=(tree[k].left+tree[k].right)/2;
if(a<=mid)
change_interval(2*k,a,b,add);
if(b>mid)
change_interval(2*k+1,a,b,add);
tree[k].weight=tree[k*2].weight+tree[k*2+1].weight;
}
int main()
{
while(scanf("%d%d",&n,&q)==2&&n+q!=0)
{
o=1;
for(int i=1;i<=n;i++)
scanf("%lld",&fn[i]);
build(1,1,n);
ll x,y;
int z;
char c;
while(q--){
getchar();
c=getchar();
if(c=='C'){
scanf("%lld%lld%d",&x,&y,&z);
change_interval(1,x,y,z);
}
if(c=='Q'){
ans=0;
scanf("%lld%lld",&x,&y);
ask_interval(1,x,y);
printf("%lld\n",ans);
}
}
}
return 0;
}


今天先到这吧,不开心~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模板 线段树