Coder
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4288
题意:有三种类型的操作,(1)."add x",表示往集合里加入?数x。(2).“del x”表示将集合中数x删除。(3).“sum”求出从小到大排列的集合中下标模5为3的数的和。集合中的数都是唯一的。
思路:这题巧妙的地方在于先离线输入,然后离散化。输入的数字依照从小到大排序,然后作为线段树的叶子结点。每一个结点包括两个部分,一是该结点包括的数字个数,二是依照区间内模5的余数分组求和。当须要向上pushup时,左子树的区间不变,而右子树的区间内,每一个数字的位置发生改变,一開始为i,之后变为i+cnt(cnt表示左子树区间内数字个数)
代码:
#include<map> #include<set> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<fstream> #include<cstring> #include<ctype.h> #include<iostream> #include<algorithm> #define INF (1<<30) #define PI acos(-1.0) #define mem(a, b) memset(a, b, sizeof(a)) #define rep(i, n) for (int i = 0; i < n; i++) #define debug puts("===============") typedef long long ll; using namespace std; const int maxn = 100200; ll sum[maxn << 2][5]; int cnt[maxn << 2]; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 int n, tot, op[maxn], a[maxn]; char str[maxn][10]; void pushup(int rt) { cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1]; int p = cnt[rt << 1]; for (int i = 0; i < 5; i++) { sum[rt][i] = sum[rt << 1][i] + sum[rt << 1 | 1][((i - p) % 5 + 5) % 5]; } //cout<<rt<<" "<<cnt[rt]<<endl; } void update(int pos, int x, int l, int r, int rt) { if (l == r) { if (x == 1) { sum[rt][1] = a[pos - 1]; cnt[rt] = 1; } else { sum[rt][1] = 0; cnt[rt] = 0; } return ; } int m = (l + r) >> 1; if (pos <= m) update(pos, x, lson); else update(pos, x, rson); pushup(rt); } void build(int l, int r, int rt) { for (int i = 0; i < 5; i++) sum[rt][i] = 0; cnt[rt] = 0; if (l == r) return ; int m = (l + r) >> 1; build(lson); build(rson); } int main () { while(~scanf("%d", &n)) { tot = 0; for (int i = 0; i < n; i++) { scanf("%s", str[i]); if (str[i][0] != 's') { scanf("%d", op + i); a[tot++] = op[i]; } } sort(a, a + tot); tot = unique(a, a + tot) - a; build(1, tot, 1); for (int i = 0; i < n; i++) { if (str[i][0] == 's') printf("%I64d\n", sum[1][3]); else { int pos = lower_bound(a, a + tot, op[i]) - a + 1; if (str[i][0] == 'a') update(pos, 1, 1, tot, 1); else update(pos, -1, 1, tot, 1); } } } return 0; }<strong> </strong>
时间: 2024-10-16 09:59:39