标签:
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 1508 Solved: 573
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 ≤ 100000,m≤200000 ,data[i]非负且小于10^9
Source
SPOJ2713 gss4 数据已加强
题解:
区间开根号显然不能打标记,但是对于一个数,多次开根后一定会变成1,所以我们可以标记一下区间是否都是1,修改时暴力下放即可,因为如果一个区间上一次变成了1,那么下一次就不会访问它了,所以复杂度并没有问题。
Code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100100
#define LL long long
#define root 1,1,n
#define lch rt<<1,l,mid
#define rch rt<<1|1,mid+1,r
struct Tree{
LL s; bool f;
}tree[N<<2];
int n,m;
int in(){
int x=0; char ch=getchar();
while (ch<‘0‘ || ch>‘9‘) ch=getchar();
while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
return x;
}
void push_up(int rt){
if (tree[rt<<1].f || tree[rt<<1|1].f)
tree[rt].f=1;
else tree[rt].f=0;
tree[rt].s=tree[rt<<1].s+tree[rt<<1|1].s;
}
void push_down(int rt,int l,int r){
if (!tree[rt].f) return;
if (l==r){
tree[rt].s=sqrt(tree[rt].s);
if (tree[rt].s<=1) tree[rt].f=0;
return;
}
int mid=(l+r)>>1;
push_down(lch); push_down(rch);
push_up(rt);
}
void build(int rt,int l,int r){
if (l==r){
tree[rt].s=(LL)in();
if (tree[rt].s<=1) tree[rt].f=0;
else tree[rt].f=1;
return;
}
int mid=(l+r)>>1;
build(lch); build(rch);
push_up(rt);
}
void change(int rt,int l,int r,int ll,int rr){
if (!tree[rt].f) return;
if (ll<=l && r<=rr){
push_down(rt,l,r);
return;
}
int mid=(l+r)>>1;
if (ll<=mid) change(lch,ll,rr);
if (rr>mid) change(rch,ll,rr);
push_up(rt);
}
LL query(int rt,int l,int r,int ll,int rr){
if (ll<=l && r<=rr) return tree[rt].s;
int mid=(l+r)>>1; LL k=0;
if (ll<=mid) k+=query(lch,ll,rr);
if (rr>mid) k+=query(rch,ll,rr);
return k;
}
int main(){
n=in(); build(root); m=in();
while (m--){
int opt=in(),x=in(),y=in();
if (opt==1) printf("%lld\n",query(root,x,y));
else change(root,x,y);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/morestep/article/details/47750457