1. 程式人生 > >BZOJ 3211: 花神遊歷各國

BZOJ 3211: 花神遊歷各國

com chan mat bzoj 思考 while 維護 type bsp

二次聯通門 : BZOJ 3211: 花神遊歷各國

/*
    BZOJ 3211: 花神遊歷各國
    
    線段樹維護區間和
    
    對於開方操作
    思考一下, 若其為1或0
    則無論其怎樣開方值, 都不會再改變 
    
    那麽打個標記即可, 
    若當前節點的左兒子和右兒子都小於等於1, 那麽就沒有再進行下去的必要了
    
    標記依次上傳即可 

        和上帝那個題一模一樣。。。
*/
#include <cstdio>
#include <cmath>

void read (long long
&now) { now = 0; register char word = getchar (); while (word < 0 || word > 9) word = getchar (); while (word >= 0 && word <= 9) { now = now * 10 + word - 0; word = getchar (); } } inline long long min (long long a, long long
b) { return a < b ? a : b; } inline long long max (long long a, long long b) { return a > b ? a : b; } struct Segment_Tree_Date { Segment_Tree_Date *Left, *Right; long long l, r; long long Mid; long long key; bool Flandre; Segment_Tree_Date () { Left
= NULL; Right = NULL; key = 0; Flandre = false; } }; Segment_Tree_Date *Root; class Segment_Tree_Type { public : void Build (Segment_Tree_Date *&now, long long l, long long r) { now = new Segment_Tree_Date ; now->l = l; now->r = r; if (l == r) { read (now->key); if (now->key <= 1) now->Flandre = true; return ; } now->Mid = l + r >> 1; Build (now->Left, l, now->Mid); Build (now->Right, now->Mid + 1, r); now->key = now->Left->key + now->Right->key; now->Flandre = now->Left->Flandre & now->Right->Flandre; } void Change_Section (Segment_Tree_Date *&now, long long l, long long r) { if (now->l == now->r) { now->key = (long long)sqrt (now->key); if (now->key <= 1) now->Flandre = true; return ; } if (now->Flandre) return ; if (l <= now->Mid) Change_Section (now->Left, l, min (now->Mid, r)); if (r > now->Mid) Change_Section (now->Right, max (now->Mid + 1, l), r); now->key = now->Left->key + now->Right->key; now->Flandre = now->Left->Flandre & now->Right->Flandre; } long long Query_Section (Segment_Tree_Date *&now, long long l, long long r) { if (l <= now->l && now->r <= r) return now->key; long long res = 0; if (l <= now->Mid) res += Query_Section (now->Left, l, min (now->Mid, r)); if (r > now->Mid) res += Query_Section (now->Right, max (now->Mid + 1, l), r); return res; } }; Segment_Tree_Type Tree; long long N; int main (int argc, char *argv[]) { read (N); Tree.Build (Root, 1, N); long long x, y, type; for (read (N); N--; ) { read (type); read (x); read (y); if (type == 1) printf ("%lld\n", Tree.Query_Section (Root, min (x, y), max (x, y))); else Tree.Change_Section (Root, min (x, y), max (x, y)); } return 0; }

BZOJ 3211: 花神遊歷各國