您的位置:首页 > 其它

【线段树】【bzoj 3211】花神游历各国

2015-08-18 14:18 483 查看

3211: 花神游历各国

[code]Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1508  Solved: 573


Description



Input



Output

每次x=1时,每行一个整数,表示这次旅行的开心度

Sample Input

[code]4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4


Sample Output

[code]101
11
11


HINT

对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9

Source

SPOJ2713 gss4 数据已加强

题解:

区间开根号显然不能打标记,但是对于一个数,多次开根后一定会变成1,所以我们可以标记一下区间是否都是1,修改时暴力下放即可,因为如果一个区间上一次变成了1,那么下一次就不会访问它了,所以复杂度并没有问题。

Code:

[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: