洛谷——P4145 上帝造题的七分钟2 / 花神游历各国

P4145 上帝造题的七分钟2 / 花神游历各国

 

分块

分块太慢了,贡献一篇指针线段树的写法。

注意细节,对每个点都要新开一个空间。。。(emmm,好像没什么了

 

思路与分块差不多,都是暴力嘛

 

#include<bits/stdc++.h>

#define LL long long
#define N 1000000
using namespace std;

LL n,m,cnt;
struct node{
    LL l,r;
    LL s,Max;
    node *ch[2];
}tr[N],*root;

void push_up(node *t){
    t->s=t->ch[0]->s+t->ch[1]->s;
    t->Max=max(t->ch[0]->Max,t->ch[1]->Max);
}

void build(node *t,LL l,LL r){
    t->l=l,t->r=r;
    if(l==r) {scanf("%lld",&t->s);t->Max=t->s;return;}
    LL mid=(l+r)>>1;
    node *lson=&tr[++cnt],*rson=&tr[++cnt];
    t->ch[0]=lson,t->ch[1]=rson;
    build(t->ch[0],l,mid);
    build(t->ch[1],mid+1,r);
    push_up(t);
}

void update(node *t,LL ql,LL qr){
    if(t->l==t->r){
        t->s=sqrt(t->s);
        t->Max=sqrt(t->Max);
        return;
    }
    LL mid=(t->l+t->r)>>1;
    if(ql<=mid&&t->ch[0]->Max>1) update(t->ch[0],ql,qr);
    if(qr>mid&&t->ch[1]->Max>1) update(t->ch[1],ql,qr);
    push_up(t);
}

LL query(node *t,LL ql,LL qr){
    if(t->l==ql&&t->r==qr) return t->s;
    LL mid=(t->l+t->r)>>1;
    if(ql>mid) return query(t->ch[1],ql,qr);
    else if(qr<=mid) return query(t->ch[0],ql,qr);
    else return query(t->ch[0],ql,mid)+query(t->ch[1],mid+1,qr);
}

int main() {
    scanf("%lld",&n);
    root=&tr[0];
    build(root,1,n);
    scanf("%lld",&m);
    for(LL opt,l,r,i=1; i<=m; i++) {
        scanf("%lld%lld%lld",&opt,&l,&r);
        if(l>r) swap(l,r);
        if(!opt) update(root,l,r);
        else printf("%lld\n",query(root,l,r));
    }

    return 0;
}

 

posted @ 2018-10-14 16:40  清风我已逝  阅读(172)  评论(0编辑  收藏  举报