标签:线段树
3211: 花神游历各国
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 1144 Solved: 416
[Submit][Status][Discuss]
Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
HINT
对于100%的数据,n
Source
SPOJ2713 gss4 数据已加强
这个题竟然暴力下放标记我也是醉了QUQ
因为每个数开方次数并不是很多,最多开到0/1就不用开了嘛
所以记录max和sum
max
然后就是裸线段树
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100100
#define MAXM 201000
#define lchild rt<<1,l,mid
#define rchild rt<<1|1,mid+1,r
#define ln rt<<1
#define rn rt<<1|1
using namespace std;
struct seg
{
int l,r;
long long sum,maxn;
}tree[MAXN<<4];
int n,m;
int op,l,r;
void push_up(int rt)
{
tree[rt].sum=tree[ln].sum+tree[rn].sum;
tree[rt].maxn=max(tree[ln].maxn,tree[rn].maxn);
}
void build(int rt=1,int l=1,int r=n)
{
int mid=(l+r)>>1;
tree[rt].l=l;tree[rt].r=r;
if (l==r)
{
scanf("%lld",&tree[rt].sum);
tree[rt].maxn=tree[rt].sum;
return;
}
build(lchild);build(rchild);
push_up(rt);
}
void modify(int rt,int l,int r)
{
if (tree[rt].maxn<=1) return;
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (L==R)
{
tree[rt].sum=floor(sqrt(tree[rt].sum));
tree[rt].maxn=tree[rt].sum;
return;
}
if (l<=mid) modify(ln,l,r);
if (r>mid) modify(rn,l,r);
push_up(rt);
}
long long query(int rt,int l,int r)
{
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (L==l&&R==r) return tree[rt].sum;
if (r<=mid) return query(ln,l,r);
else
if (l>mid) return query(rn,l,r);
else return query(ln,l,mid)+query(rn,mid+1,r);
}
int main()
{
scanf("%d",&n);
build();
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&l,&r);
if (l>r) swap(l,r);
if (op==1)
printf("%lld\n",query(1,l,r));
else
modify(1,l,r);
}
}
标签:线段树
原文地址:http://blog.csdn.net/creationaugust/article/details/44974429