码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-08-18 16:31:18      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

3211: 花神游历各国

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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

标签:

原文地址:http://blog.csdn.net/morestep/article/details/47750457

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!