A radical operation can take up to 5 times to turn any number that appears into 1.
So use the line tree to modify the violence, in the future, only need to see if the current interval is 0 or 1, if so the direct return.
1 /**************************************************************2 problem:32113 user:idy0024 language:c++5 result:accepted6 time:1976 Ms7 memory:7068 KB8 ****************************************************************/9 Ten#include <cstdio> One#include <cmath> A #defineN 100010 - -typedefLong Longdnt; the structNode { - dnt s; - BOOLT; -Node *ls, *rs; +}pool[n*3], *tail=pool, *Root; - + intN, M; A intAa[n]; at -Node *build (intLfintRG) { -Node *nd = + +tail; - if(lf==RG) { -Nd->s =AA[LF]; -Nd->t = aa[lf]<=1; in returnnd; - } to intMid= (LF+RG) >>1; +Nd->ls =build (LF, mid); -Nd->rs = Build (mid+1, RG); theNd->s = Nd->ls->s + nd->rs->s; *nd->t = nd->ls->t && nd->rs->T; $ returnnd;Panax Notoginseng } - voidModify (Node *nd,intLfintRgintLintR) { the if(lf==RG) { +Nd->s = (dnt) sqrt (nd->s); ANd->t = nd->s<=1; the return; + } - if(nd->t)return; $ intMid= (LF+RG) >>1; $ if(l<=mid) Modify (nd->LS, LF, Mid, L, R); - if(r>mid) Modify (Nd->rs, mid+1, RG, L, R); -Nd->s = Nd->ls->s + nd->rs->s; thend->t = nd->ls->t && nd->rs->T; - }Wuyidnt query (Node *nd,intLfintRgintLintR) { the if(L<=lf && rg<=r)returnNd->s; - intMid= (LF+RG) >>1; Wudnt RT =0; - if(L<=mid) Rt+=query (nd->LS, LF, Mid, L, R); About if(R>mid) Rt+=query (Nd->rs, mid+1, RG, L, R); $ returnRT; - } - - intMain () { Ascanf"%d", &n); + for(intI=1; i<=n; i++ ) thescanf"%d", aa+i); -Root = Build (1, n); $scanf"%d", &m); the for(intI=1, Opt,l,r; i<=m; i++ ) { thescanf"%d%d%d", &opt, &l, &R); the if(opt==1 ) theprintf"%lld\n", Query (Root,1, N,l,r)); - Else inModify (Root,1, n,l,r); the } the}
View Code
Bzoj 3211 Segment Tree