您的位置:首页 > 其它

线段树(区间修改,单点查询)

2017-11-03 16:12 429 查看
题目链接:https://vjudge.net/contest/196267#problem/B

题号:zoj-3284

题目大意:就是给你一个矩阵,让你实现一些修改和查询操作

题目思路:建立两个线段树,不细说

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#define ri(n) scanf("%d",&n)
#define oi(n) printf("%d\n",n)
#define rl(n) scanf("%lld",&n)
#define ol(n) printf("%lld\n",n)
#define rep(i,l,r) for(i=l;i<=r;i++)
#define rep1(i,l,r) for(i=l;i<r;i++)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int epg=10-8;
struct node
{
int l,r;
int sum,add;
}p[10010<<2],q[10010<<2];
int a[110][110];
void build(node *t,int L,int R,int pos)//建立线段树
{
t[pos].l=L;
t[pos].r=R;
t[pos].sum=0;
t[pos].add=0;
if(L==R)
{
return ;
}
int mid=(L+R)>>1;
build(t,L,mid,pos<<1);
build(t,mid+1,R,pos<<1|1);
}
void updown(node *t,int pos)//更新延迟标记,就是相当于分块里面标记整个块,这里标记的是整个区间
{
if(t[pos].add!=0)
{
t[pos<<1].add+=t[pos].add;
t[pos<<1|1].add+=t[pos].add;
t[pos<<1].sum+=(t[pos<<1].r-t[pos<<1].l+1)*t[pos].add;
t[pos<<1|1].sum+=(t[pos<<1|1].r-t[pos<<1|1].l+1)*t[pos].add;
t[pos].add=0;
}
}
void upup(node *t,int pos)//回溯求和
{
t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
}
int query(node *t,int x,int pos)//单点查询,查询第x个元素的值
{
if(t[pos].l==t[pos].r)
{
return t[pos].sum;
}
int mid=(t[pos].l+t[pos].r)>>1;
updown(t,pos);
if(x<=mid)
return query(t,x,pos<<1);
//if(R>mid)
else
return query(t,x,pos<<1|1);
}
void updata(node *t,int L,int R,int ad,int pos)//区间修改,L-R区间的所有元素加上ad
{
if(L<=t[pos].l&&t[pos].r<=R)
{
t[pos].sum+=(t[pos].r-t[pos].l+1)*ad;
t[pos].add+=ad;
return ;
}
int mid=(t[pos].l+t[pos].r)>>1;
updown(t,pos);
if(L<=mid)
updata(t,L,R,ad,pos<<1);//这里需要注意一下,容易写错
if(R>mid)
updata(t,L,R,ad,pos<<1|1);//这里需要注意一下,容易写错
upup(t,pos);
}
int main()
{
int n,m;
int kases=0;
while(scanf("%d%d",&n,&m)==2)
{
for(int i=0;i<(10010<<2);i++)
{
p[i].sum=0;p[i].add=0;
q[i].add=0;q[i].sum=0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
build(p,1,n*m,1);
build(q,1,n*m,1);
int t;
scanf("%d",&t);
printf("Case %d\n",++kases);
for(int i=1;i<=t;i++)
{
int x;
scanf("%d",&x);
if(x==0)
{
int r1,c1,r2,c2,ad;
scanf("%d%d%d%d%d",&r1,&c1,&r2,&c2,&ad);
int l=(r1-1)*m+c1,r=(r2-1)*m+c2;
updata(p,l,r,ad,1);
}
else if(x==1)
{
int r1,c1,r2,c2,ad;
scanf("%d%d%d%d%d",&r1,&c1,&r2,&c2,&ad);
int l=(c1-1)*n+r1,r=(c2-1)*n+r2;
updata(q,l,r,ad,1);
}
else if(x==2)
{
int r,c;
scanf("%d%d",&r,&c);
int ans=query(p,(r-1)*m+c,1)+query(q,(c-1)*n+r,1)+a[r][c];
printf("%d\n",ans);
}
}
}
return 0;
}


补充:

区间修改区间求求和:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include
bfef
<algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#define ri(n) scanf("%d",&n)
#define oi(n) printf("%d\n",n)
#define rl(n) scanf("%lld",&n)
#define ol(n) printf("%lld\n",n)
#define rep(i,l,r) for(i=l;i<=r;i++)
#define rep1(i,l,r) for(i=l;i<r;i++)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int epg=10-8;
struct node
{
int l,r;
ll add,sum;
}tr[100010<<2];
ll a[100010<<2];
void build(node *t,int l,int r,int pos)
{
t[pos].l=l;
t[pos].r=r;
t[pos].add=0;
if(l==r)
{
t[pos].sum=a[l];
return;
}
int mid=(t[pos].l+t[pos].r)>>1;
//int mid=(l+r)>>1;
build(t,l,mid,pos<<1);
build(t,mid+1,r,pos<<1|1);
t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
}
void pushdown(node *t,int pos)
{
if(t[pos].add!=0)
{
t[pos<<1].add+=t[pos].add;
t[pos<<1].sum+=(t[pos<<1].r-t[pos<<1].l+1)*t[pos].add;
t[pos<<1|1].add+=t[pos].add;
t[pos<<1|1].sum+=(t[pos<<1|1].r-t[pos<<1|1].l+1)*t[pos].add;
t[pos].add=0;
}
}
ll query(node *t,int l,int r,int pos)
{
if(l<=t[pos].l&&t[pos].r<=r)
{
return t[pos].sum;
}
ll ans=0;
int mid=(t[pos].l+t[pos].r)>>1;
pushdown(t,pos);
if(l<=mid)
ans+=query(t,l,r,pos<<1);
if(r>mid)
ans+=query(t,l,r,pos<<1|1);
return ans;
}
void updata(node *t,int l,int r,int ad,int pos)
{
if(l<=t[pos].l&&t[pos].r<=r)//这里一定要注意是<=和>=
{
t[pos].sum+=(t[pos].r-t[pos].l+1)*ad;
t[pos].add+=ad;
return ;
}
int mid=(t[pos].l+t[pos].r)>>1;
pushdown(t,pos);
if(l<=mid)
updata(t,l,r,ad,pos<<1);//这里是l,r,不是l,mid
if(r>mid)
updata(t,l,r,ad,pos<<1|1);//这里是l,r,不是mid+1,r
t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(tr,1,n,1);
for(int i=1;i<=q;i++)
{
char c;
//scanf("%c",&c);
cin>>c;
if(c=='Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(tr,l,r,1));
}
else
{
int l,r,ad;
scanf("%d%d%d",&l,&r,&ad);
updata(tr,l,r,ad,1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: