您的位置:首页 > 其它

线段树练习2

2017-08-04 20:44 260 查看
这一篇也没什么难度,就直接写代码吧,

题目:> http://codevs.cn/problem/1081/

单点查询,区间修改:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 2e5 + 5;
struct zt
{
int sum,l,r,sz;
zt *right,*lift;
};
zt tree[MAXN];
int n,q,a,b,c,cnt = 0;
void build(zt *root,int l,int r)
{
root->l = l;root->r = r;root->sum = 0;root->sz = r - l + 1;
if(l == r)
return;
int mid = (l + r)>>1;
root->lift = &tree[++cnt];
root->right = &tree[++cnt];
build(root->lift,l,mid);
build(root->right,mid + 1,r);
}
void add(zt *root,int l,int r,int ql,int qr,int x)
{
if(l >= ql&&qr >= r&&l == r)
{
root->sum+=x*root->sz;
return;
}
int mid = (l + r)>>1;
if(ql <= mid)
add(root->lift,l,mid,ql,qr,x);
if(qr > mid)
add(root->right,mid + 1,r,ql,qr,x);
}
int query(zt *root,int x)
{
if(root->l == x&&root->r == x)
return root->sum;
int mid = (root->l + root->r)>>1;
if(x > mid)
return query(root->right,x);
return query(root->lift,x);
}
int main()
{
scanf("%d",&n);
build(tree,1,n);
for(int i = 1;i <= n;i ++)
{
scanf("%d",&a);
add(tree,1,n,i,i,a);
}
scanf("%d",&q);
for(int i = 1;i <= q;i ++)
{
scanf("%d",&a);
if(a == 1)
{
scanf("%d %d %d",&a,&b,&c);
add(tree,1,n,a,b,c);
}
else
{
scanf("%d",&a);
printf("%d\n",query(tree,a));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: