1. 程式人生 > >HDU 4027(線段樹)

HDU 4027(線段樹)

提前 線段樹 都是 ace href 操作 代碼 處理 限制

HDU4027

題意:操作指令為0時,對區間[x,y]之間的數字進行開平方;指令為1的時候,對區間[x,y]之間的數字求和並輸出;

思路:線段樹處理就OK了,但是64位內的數最多開8次平方就為1了(開始不信,試了試之後orz.......),所以在開平方的時候加一下限制條件使開平方操作提前結束沒必要的操作就可以了,不然會超時。

代碼中的這句:en - st + 1 == evil[rt]表示區間st到en中所有的數都是1,所以可以提前結束了。

代碼:

技術分享圖片
/*
    Time:2018/8/20
    Author:sykai1
    Funtion:solve HDU 4027
*/
#include 
<iostream> #include <cstdio> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <algorithm> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; typedef pair<double, int> P; const int maxn = 2e5 + 10; ll evil[maxn
* 4]; int n; void Build(int rt, int st, int en) { if (st == en) { scanf("%I64d", &evil[rt]); return; } int mid = (st + en) / 2; Build(rt << 1, st, mid); Build(rt << 1 | 1, mid + 1, en); evil[rt] = evil[rt << 1] + evil[rt << 1 | 1
]; } void Add(int rt, int x, int y, int st, int en) { if (st == en) { evil[rt] = (ll)sqrt(evil[rt]); return; } if (en - st + 1 == evil[rt]) { printf("GG %d\n",evil[rt]); return; } int mid = (st + en) / 2; if (y <= mid) Add(rt << 1, x, y, st, mid); else if (x > mid) Add(rt << 1 | 1, x, y, mid + 1, en); else { Add(rt << 1, x, mid, st, mid); Add(rt << 1 | 1, mid + 1, y, mid + 1, en); } evil[rt] = evil[rt << 1] + evil[rt << 1 | 1]; } ll query(int rt, int x, int y, int st, int en) { ll res = 0; if (x == st && y == en) return evil[rt]; int mid = (st + en) / 2; if (y <= mid) res = query(rt << 1, x, y, st, mid); else if (x > mid) res = query(rt << 1 | 1, x, y, mid + 1, en); else { res = query(rt << 1, x, mid, st, mid); res += query(rt << 1 | 1, mid + 1, y, mid + 1, en); } return res; } int main() { int cnt = 0; while (scanf("%d", &n) != EOF) { printf("Case #%d:\n", ++cnt); Build(1, 1, n); int q, op, x, y; scanf("%d", &q); for (int i = 0; i < q; i++) { scanf("%d%d%d", &op, &x, &y); if (x > y) swap(x, y); if (op == 0) Add(1, x, y, 1, n); else { printf("%lld\n", query(1, x, y, 1, n)); } } printf("\n"); } return 0; }
View Code

HDU 4027(線段樹)