# BZOJ3211 花神游历各国 线段树

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

typedef struct NODE{
NODE *lchild,*rchild;
int L,R;
long long sum;
bool lazy;
NODE(){}
}*TREE;
TREE root;
int n,m;

void Pushup(TREE & node){
node->sum=node->lchild->sum+node->rchild->sum;
node->lazy=node->lchild->lazy&node->rchild->lazy;
}

void Build(TREE & root,int l,int r){
root=new NODE;
root->L=l,root->R=r,root->sum=root->lazy=0;

if(l==r){
scanf("%lld",&root->sum);
if(root->sum==0 || root->sum==1) root->lazy=1;
return;
}

int m=(l+r)>>1;
Build(root->lchild,l,m);
Build(root->rchild,m+1,r);

Pushup(root);
}

long long Query(TREE & root,int l,int r){
if(l<=root->L && r>=root->R) return root->sum;

int m=(root->L+root->R)>>1;
long long tmp=0;
if(l<=m) tmp+=Query(root->lchild,l,r);
if(r>=m+1) tmp+=Query(root->rchild,l,r);

return tmp;
}

void Update(TREE & root,int l,int r){
if(root->lazy) return;

if(root->L==root->R){
root->sum=(long long)sqrt(root->sum);
if(root->sum==1 || root->sum==0) root->lazy=1;
return;
}

int m=(root->L+root->R)>>1;
if(l<=m) Update(root->lchild,l,r);
if(r>m) Update(root->rchild,l,r);

Pushup(root);
}

void Delete(TREE & root){
if(root->L==root->R){
delete root;
return;
}

Delete(root->lchild);
Delete(root->rchild);

delete root;
}

void Visit(TREE & root){
if(root->L==root->R){
cout << root->sum << " ";
return;
}

Visit(root->lchild);
Visit(root->rchild);

cout << root->sum << " ";
}

int main(){
cin >> n;
Build(root,1,n);

cin >> m;
int x,l,r;
while(m--){
cin >> x >> l >> r;
l=min(l,r),r=max(l,r);

if(x==1) cout << Query(root,l,r) << endl;
if(x==2) Update(root,l,r);
}

Delete(root);

return 0;
}
View Code

posted @ 2017-02-28 01:12  WDZRMPCBIT  阅读(120)  评论(0编辑  收藏  举报