您的位置:首页 > 其它

HDU 4288 Coder(线段树)

2015-11-09 19:25 375 查看
题意:

给定三种操作

  1. add x 向序列中添加x,添加之后序列还保持有序

  2. del x 删除序列中值为x的元素

  3. sum 求下边模5等于3的元素和

思路:

直接暴力也可以过,就是看暴力写的好不好了。用数组直接暴力可过。

暴力代码:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 100010;
typedef long long ll;
int a[maxn];

int main()
{
int n;
while (~scanf("%d", &n))
{
char cmd[10];
int d;
int len = 0;
while (n--)
{
scanf("%s", cmd);
if (cmd[0] == 'a')
{
scanf("%d", &d);
int i;
for (i = len++; i >= 1; i--)
{
if (a[i] <= d) break;
a[i + 1] = a[i];
}
a[i + 1] = d;
}
else if (cmd[0] == 'd')
{
scanf("%d", &d);
int i;
for (i = 1; i <= len; i++)
if (a[i] == d) break;
for (; i < len; i++)
a[i] = a[i + 1];
len--;
}
else
{
ll ans = 0;
for (int i = 3; i <= len; i += 5)
ans += (ll)a[i];
printf("%lld\n", ans);
}
}
}
return 0;
}


也可以用线段树来维护。先把所有的数据都读进来,然后离散化一下建树。树的每个节点维护一个sum[5],就是模上5之后的余数,还有一个当前区间的有多少个数字的个数。注意:每个节点的sum当中的下边都是对应线段树中该节点的下边来说的。所以叶子节点一定对应1,就是sum[0], 关键就是pushup,因为往上更新的时候,考虑一个父区间,它的左孩子区间对应的sum[i],就是父区间的sum[i],但是右区间的sum[i]对应的不是父区间的sum[i],而是sum[(i + lson.cnt)%5]。所以这样就可以做拉。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 100010;
typedef long long ll;
struct Tree {
int cnt;
ll sum[5];
}tree[maxn << 2];
int dat[maxn], tmp[maxn];
char cmd[maxn][10];
void pushup(int rt)
{
for (int i = 0; i < 5; i++)
tree[rt].sum[i] = tree[rt<<1].sum[i] + tree[rt<<1|1].sum[((i - tree[rt<<1].cnt) % 5 + 5) % 5];
tree[rt].cnt = tree[rt<<1].cnt + tree[rt<<1|1].cnt;
//当然也可以这么写。
//int j = (i + tree[rt<<1].cnt) % 5;
//tree[rt].sum[j] = tree[rt<<1].sum[j] + tree[rt<<1|1].sum[i];
}
void build(int rt, int l, int r)
{
for (int i = 0; i < 5; i++) tree[rt].sum[i] = 0;
tree[rt].cnt = 0;
if (l == r) return;
int mid = (l + r) / 2;
build(rt<<1, l, mid);
build(rt<<1|1, mid + 1, r);
}
void update(int rt, int l, int r, int p, int val, int flag)
{
if (l == r)
{
tree[rt].cnt += flag;
tree[rt].sum[0] = val;
return;
}
int mid = (l + r) / 2;
if (p <= mid) update(rt<<1, l, mid, p, val, flag);
else update(rt<<1|1, mid + 1, r, p, val, flag);
pushup(rt);
}
int main()
{
int n;
while (~scanf("%d", &n))
{
int num = 0;
for (int i = 0; i < n; i++) {
scanf("%s", cmd[i]);
if (cmd[i][0] != 's')
{
scanf("%d", &dat[i]);
tmp[num++] = dat[i];
}
}
sort(tmp, tmp + num);
num = unique(tmp, tmp + num) - tmp;

build(1, 1, n);
for (int i = 0; i < n; i++)
{
int p = lower_bound(tmp, tmp + num, dat[i]) - tmp;
if (cmd[i][0] == 's')
printf("%lld\n", tree[1].sum[2]);
else if (cmd[i][0] == 'a')
update(1, 1, n, p, dat[i], 1);
else update(1, 1, n, p, 0, -1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: