无聊题目大纪实(HDU 4288 Coder)
这神题,暴力数组可过,vector可过,线段树可过。。。时限拉的太长了,所以就成水题了。。。不过比赛的时候真的没敢用数组暴力写。。。
说说线段树的思路吧。
对树的每个节点 L, R, cnt, sum[5],分别表示左区间,右区间,这段区间上的点数,这段区间上sum[x%5]的和。
先把所有的数据都读入,然后离散化,去掉重复的数据建树。
再处理一边就可以了。
ps:叶节点只有sum[0]需要更新,sum[1...4]更新不到。。这个注意理解。。
View Code
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("data.in", "r", stdin) #define Write() freopen("data.out", "w", stdout); const double eps = 1e-8; typedef long long LL; const int inf = ~0u>>2; using namespace std; const int N = 100010; struct node { int l; int r; int cnt; LL sum[5]; }tree[N<<2]; char op[N][5]; int num[N]; int t[N]; int tt[N]; int cnt, ts, p; void build(int t, int l, int r) { tree[t].l = l; tree[t].r = r; tree[t].cnt = 0; CL(tree[t].sum, 0); if(l == r) return ; int mid = MID(l, r); build(L(t), l, mid); build(R(t), mid + 1, r); } void Push_Up(int t) { for(int i = 0; i < 5; ++i) { tree[t].sum[i] = tree[L(t)].sum[i] + tree[R(t)].sum[((i - tree[L(t)].cnt)%5 + 5)%5]; } } void updata(int t, int pos, int val, bool flag) { if(flag) tree[t].cnt += 1; else tree[t].cnt -= 1; if(tree[t].l == tree[t].r) { tree[t].sum[0] = flag ? val : 0; return ; } int mid = MID(tree[t].l, tree[t].r); if(pos <= mid) updata(L(t), pos, val, flag); else updata(R(t), pos, val, flag); Push_Up(t); } int find(int x) { int l = 0, r = ts - 1, mid; while(l <= r) { mid = MID(l, r); if(tt[mid] == x) return mid; else if(tt[mid] > x) r = mid - 1; else l = mid + 1; } return -1; } int main() { // Read(); int n, i; while(~scanf("%d", &n)) { cnt = 0; for(i = 0; i < n; ++i) { scanf("%s", op[i]); if(op[i][0] != 's') { scanf("%d", &num[i]); t[cnt++] = num[i]; } } sort(t, t + cnt); ts = 0; tt[ts++] = t[0]; for(i = 1; i < cnt; ++i) { if(t[i] != t[i-1]) tt[ts++] = t[i]; } build(1, 0, ts - 1); for(i = 0; i < n; ++i) { if(op[i][0] == 's') { cout << tree[1].sum[2] << endl; } else if(op[i][0] == 'a') { p = find(num[i]); updata(1, p, num[i], 1); } else { p = find(num[i]); updata(1, p, num[i], 0); } } } return 0; }