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

来源:互联网 发布:blued刷关注软件 编辑:程序博客网 时间:2024/04/28 05:53

3211: 花神游历各国

Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1508  Solved: 573

Description

这里写图片描述

Input

这里写图片描述

Output

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

Sample Input

41 100 5 551 1 22 1 21 1 22 2 31 1 4

Sample Output

1011111

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,rstruct 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;}
1 0
原创粉丝点击