poj3468 A Simple Problem with Integers (线段树段修改)
2017-11-16 14:34
274 查看
题意:线段树段修改的板子题
思路:套板子,注意mark _down和值都要用longlong
#include <cstdio>
#include<iostream>
typedef long long ll;
using namespace std;
const int maxn=100000*5+100;
struct segn
{
ll su,mark_add;
}segt[maxn];
void push_dowm_segadd(int root,int st,int en)
{
if(segt[root].mark_add!=0)
{
segt[root*2+1].su+=((st+en)/2-st+1)*segt[root].mark_add;
segt[root*2+2].su+=(en-(st+en)/2)*segt[root].mark_add;
segt[root*2+1].mark_add+=segt[root].mark_add;
segt[root*2+2].mark_add+=segt[root].mark_add;
segt[root].mark_add=0;
}
}
void build(ll *arr,int root,int st,int en)
{
if(st==en)
{
segt[root].mark_add=0;
segt[root].su=arr[st];
return;
}
int mid=(st+en)/2;
build(arr,root*2+1,st,mid);
build(arr,root*2+2,mid+1,en);
segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
}
void segadd(int qst,int qen,int tst,int ten,int root,ll addnum)
{
if(qst>ten||qen<tst)//不符合的区间
{
return ;
}
if(tst>=qst&&ten<=qen)//找到要加的区间
{
segt[root].mark_add+=addnum;
segt[root].su+=addnum*(ten-tst+1);
return ;
}
int mid =(tst+ten)/2;
push_dowm_segadd(root,tst,ten);
segadd(qst,qen,tst,mid,root*2+1,addnum);
segadd(qst,qen,mid+1,ten,root*2+2,addnum);
if(tst!=ten)segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
}
ll query(int root,int qst,int qen,int tst,int ten)
{
if(segt[root].mark_add!=0&&tst!=ten)push_dowm_segadd(root,tst,ten);
if(qst>ten||qen<tst)return 0;
if(qst<=tst&&qen>=ten)return segt[root].su;
ll mm= query(2*root+1,qst,qen,tst,(tst+ten)/2)+query(2*root+2,qst,qen,(tst+ten)/2+1,ten);
if(tst!=ten)segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
return mm;
}
int main()
{
int n,qn;
ll arr[100100];
while(~scanf("%d%d",&n,&qn))
{
for(int i=0;i<n;i++)
{
// scanf("%d",&arr[i]);
cin>>arr[i];
}
build(arr,0,0,n-1);
char gr[3];
int st,en;ll num;
while(qn--)
{
scanf("%s",gr);
if(gr[0]=='C')
{
cin>>st>>en>>num;
segadd(st-1,en-1,0,n-1,0,num);
}
else if(gr[0]=='Q')
{
scanf("%d%d",&st,&en);
cout<<query(0,st-1,en-1,0,n-1)<<endl;
} //for(int i=0;i<2*n;i++)cout<<segt[i].su<<" ";cout<<endl;
}
}
}
思路:套板子,注意mark _down和值都要用longlong
#include <cstdio>
#include<iostream>
typedef long long ll;
using namespace std;
const int maxn=100000*5+100;
struct segn
{
ll su,mark_add;
}segt[maxn];
void push_dowm_segadd(int root,int st,int en)
{
if(segt[root].mark_add!=0)
{
segt[root*2+1].su+=((st+en)/2-st+1)*segt[root].mark_add;
segt[root*2+2].su+=(en-(st+en)/2)*segt[root].mark_add;
segt[root*2+1].mark_add+=segt[root].mark_add;
segt[root*2+2].mark_add+=segt[root].mark_add;
segt[root].mark_add=0;
}
}
void build(ll *arr,int root,int st,int en)
{
if(st==en)
{
segt[root].mark_add=0;
segt[root].su=arr[st];
return;
}
int mid=(st+en)/2;
build(arr,root*2+1,st,mid);
build(arr,root*2+2,mid+1,en);
segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
}
void segadd(int qst,int qen,int tst,int ten,int root,ll addnum)
{
if(qst>ten||qen<tst)//不符合的区间
{
return ;
}
if(tst>=qst&&ten<=qen)//找到要加的区间
{
segt[root].mark_add+=addnum;
segt[root].su+=addnum*(ten-tst+1);
return ;
}
int mid =(tst+ten)/2;
push_dowm_segadd(root,tst,ten);
segadd(qst,qen,tst,mid,root*2+1,addnum);
segadd(qst,qen,mid+1,ten,root*2+2,addnum);
if(tst!=ten)segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
}
ll query(int root,int qst,int qen,int tst,int ten)
{
if(segt[root].mark_add!=0&&tst!=ten)push_dowm_segadd(root,tst,ten);
if(qst>ten||qen<tst)return 0;
if(qst<=tst&&qen>=ten)return segt[root].su;
ll mm= query(2*root+1,qst,qen,tst,(tst+ten)/2)+query(2*root+2,qst,qen,(tst+ten)/2+1,ten);
if(tst!=ten)segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
return mm;
}
int main()
{
int n,qn;
ll arr[100100];
while(~scanf("%d%d",&n,&qn))
{
for(int i=0;i<n;i++)
{
// scanf("%d",&arr[i]);
cin>>arr[i];
}
build(arr,0,0,n-1);
char gr[3];
int st,en;ll num;
while(qn--)
{
scanf("%s",gr);
if(gr[0]=='C')
{
cin>>st>>en>>num;
segadd(st-1,en-1,0,n-1,0,num);
}
else if(gr[0]=='Q')
{
scanf("%d%d",&st,&en);
cout<<query(0,st-1,en-1,0,n-1)<<endl;
} //for(int i=0;i<2*n;i++)cout<<segt[i].su<<" ";cout<<endl;
}
}
}
相关文章推荐
- POJ3468_A Simple Problem with Integers_树状数组区间和::区间修改
- POJ3468 A Simple Problem with Integers(数状数组||区间修改的RMQ问题)
- poj3468 A Simple Problem with Integers(zkw区间修改模板)
- POJ3468 A Simple Problem with Integers(线段树区间修改--动态实现)
- poj3468 A Simple Problem with Integers(线段树区间修改)
- 【POJ3468】【树状数组区间修改】A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers 线段树|树状数组BIT(区间增减,求和)
- (线段树、树状数组)poj3468-A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers(线段树成段增减,区间求和)
- POJ3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- [POJ 2368 A Simple Problem with Integers] 树状数组区间修改、区间查询
- poj3468--A Simple Problem with Integers(树状数组解法)
- poj3468 A Simple Problem with Integers(线段树)
- POJ3468_A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers 树状数组 区间修改 区间查询
- POJ3468 A Simple Problem with Integers
- POJ3468:A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- POJ3468-A Simple Problem with Integers