洛谷——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; }
博主蒟蒻,若有出错的地方,敬请指出。
如有侵犯您版权的地方,请快速联系我,我会撤回本博文。