注意添加到集合中的数是升序的,先将数据读入,再离散化。

sum[rt][i]表示此节点的区域位置对5取模为i的数的和,删除一个数则右边的数循环左移一位,添加一个数则右边数循环右移一位,相当于循环左移4位,线段树与树状数组结合,树状数组确定位置。

 le[rt]表示左移的位数,区间更新懒惰标记

#include <iostream>
#include <cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100008;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long LL; int C[N];//注意初始化n
inline int lowbit(int x){
return x&-x;
}
void add(int x, int val, int n){//将第x个数增加val,从1计数
for(int i=x;i<=n;i+=lowbit(i)){
C[i] += val;
}
}
int getsum(int x){//求1到x的和
int ret = 0;
for(int i=x;i>0;i-=lowbit(i)){
ret+=C[i];
}
return ret;
} LL sum[N<<2][5];
int le[N<<2];
LL a[N], b[N]; void PushDown(int l, int r, int rt){
le[rt] %= 5;
if(le[rt]){
if(l < r){
le[rt<<1] = (le[rt] + le[rt<<1]) % 5;
le[rt<<1|1] = (le[rt] + le[rt<<1 | 1]) % 5;
} int t = le[rt];
while(t--){
LL tp = sum[rt][0];
for(int i = 0; i <= 3; i++){
sum[rt][i] = sum[rt][i + 1];
}
sum[rt][4] = tp;
} le[rt] = 0;
}
} void PushUp(int l, int r, int rt){
if(l < r){
int m = (l + r)>>1;
if(le[rt<<1]){//注意
PushDown(lson);
}
if(le[rt << 1 |1]){
PushDown(rson);
}
for(int i = 0; i < 5; i++){
sum[rt][i] = sum[rt <<1 ][i] + sum[rt<<1|1][i];
}
}
}
void build(int l,int r,int rt){
if(l == r){
for(int i = 0 ; i < 5; i++){
sum[rt][i] = 0;
}
le[rt] = 0;
return ;
}
int m = (l + r)>>1;
build(lson);
build(rson);
PushUp(l, r, rt);
} void update(int x, int rdx, int val, int l, int r, int rt){\
PushDown(l, r, rt);
if(l == r){
if(rdx == -1){
for(int i = 0; i < 5; i++){
sum[rt][i] = 0;
}
}else{
sum[rt][rdx] = val;
}
le[rt] = 0; }else{ int m = (l + r)>>1;
if(x <= m){
update(x, rdx, val, lson);
}else{
update(x, rdx, val, rson);
} }
PushUp(l, r, rt);
} void shift(int p, int a, int b, int l , int r, int rt){
PushDown(l ,r , rt);
if(a <= l && b >= r){
le[rt] += p;
PushDown(l, r, rt);
}else{ int m = (l + r)>>1;
if(a <= m){
shift(p, a, b, lson);
}
if(b > m){
shift(p, a, b, rson);
} }
PushUp(l, r, rt);
} int main(){
int n;
while(~scanf("%d", &n)){
memset(C, 0, sizeof(int) * (n + 2));
char str[10]; int cnt = 0;
for(int i = 1; i <= n; i++){
scanf("%s", str);
LL x;
if(str[0] == 'a'){
scanf("%I64d", &x);
a[i] = x << 1|1;
b[cnt++] = x;
}else if(str[0] == 'd'){
scanf("%I64d", &x);
a[i] = x << 1;
}else{
a[i] = -1;
}
}
sort(b, b + cnt);
cnt = unique(b, b + cnt) - b;
build(1, cnt, 1);
for(int i = 1; i <= n; i++){
if(a[i] == -1){
PushDown(1, cnt, 1);
printf("%I64d\n", sum[1][3]);
}else if(a[i] & 1){
a[i] >>= 1;
int pos= lower_bound(b, b + cnt, a[i]) - b + 1;
int rdx = getsum(pos) + 1;
add(pos, 1, cnt); update(pos, rdx % 5, a[i], 1, cnt, 1);
if(pos + 1 <= cnt){
shift(4, pos + 1, cnt, 1, cnt, 1);
}
}else{
a[i] >>= 1;
int pos= lower_bound(b, b + cnt, a[i]) - b + 1;
add(pos, -1, cnt);
update(pos, -1, 0, 1, cnt, 1);
shift(1, pos +1, cnt, 1, cnt, 1);
}
}
}
return 0;
}

为什么我线段树总是写不好,总是要好长时间的debug……

HDU4288 Coder(线段树)的更多相关文章

  1. HDU4288:Coder(线段树单点更新版 && 暴力版)

    Problem Description In mathematics and computer science, an algorithm describes a set of procedures ...

  2. hdu4428(Coder)线段树

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  3. HDU 4288 Coder(线段树)

    题意: 给定三种操作 1. add x 向序列中添加x,添加之后序列还保持有序 2. del x  删除序列中值为x的元素 3. sum  求下边模5等于3的元素和 思路: 直接暴力也可以过,就是看暴 ...

  4. hdu 4288 Coder (线段树+离线)

    题意: 刚开始有一个空集合.有三种操作: 1.往集合中加入一个集合中不存在的数 x 2.从集合中删除一个已经存在的数 x 3.计算集合的digest sum并输出.       digest sum求 ...

  5. HDU 4288 Coder (线段树)

    Coder 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4288 题意:有三种类型的操作,(1)."add x",表示往集合里加入�数 ...

  6. 线段树(多棵) HDOJ 4288 Coder

    题目传送门 题意:集合,add x, del x, 求和 分析:首先,暴力可以过这题.用上线段树能大大降低时间的消耗,具体就是类似开了5棵线段树,每个节点都有5个空间,表示该区间的id%5后的和,区间 ...

  7. HDU 4288 Coder 【线段树+离线处理+离散化】

    题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...

  8. hdu4288 Coder(段树+分离)

    主题链接: huangjing 题意: 题目中给了三个操作 1:add x 就是把x插进去  2:delete x 就是把x删除 3:sum 就是求下标%5=3的元素的和. 另一个条件是插入和删除最后 ...

  9. HDU 4288 Coder ( 离散化 + 离线 + 线段树 )

    这题跟ZOJ 3606的解题思路很相似. 题意:有3中操作:1.向集合中增加一个数x(1≤x≤1e9):2.从集合中删去一个数x(保证这个数存在):3.查询集合中所有位置满足i%5==3的数a[i]的 ...

随机推荐

  1. The Adapter of ListView: Just adapt data to view, don’t do anything else

    The design of SimpleAdapter is not good in my opinion. An adapter should just adapter the data to vi ...

  2. Oauth 2.0第三方账号登录原理图

    百度.QQ等服务商

  3. 关于Jquery学习的几点反思

    1.应用的API插件时,先看说明文档,仔细看,多花点时间也没关系. 2.写出你要完成工作的几个步骤,细化你的工作.保证每一步结果都是正确(特别是在用你不会的东西的时候),这样看起来是在浪费时间,但是最 ...

  4. 不知道数据库中表的列类型的前提下,使用JDBC正确的取出数据

    概要: 使用jdbc 如果在不知道表结构的情况下,如何读出表信息? 使用ResultSetMetaData; 然后使用getColumnType 获取column 类型 使用getColumnName ...

  5. 向数据库中全部表中增加一个字段的SQL

    SELECT 'ALTER TABLE ' + NAME + ' ADD 字段名 int not null default 0' FROM sysobjects AS sWHERE s.[type] ...

  6. gtk+2.24.0-glib-2.28.1-staticLib-mingw32-x86-2016-08-10.7z

    GTK_PATH=D:/MSYS/opt/gtk+2.24.0-staticLib b1-static.sh --------------------------------------------- ...

  7. 日历插件My97DatePicker的使用

    在开发过程中,我们会经常遇到让用户输入日期的表单,这类表单处理起来也不是太繁琐,就是简单的字符串和日期之间的转换.但是,如果用户不按照已设定的日期格式进行输入,必定会造成不必要的麻烦.为了更好的处理这 ...

  8. Python缩小图像

    LyncLynn用途: 缩小图像 # -*- coding: UTF-8 -*- #Version: V1.0 #Author:lynclynn #CreateDate:20151201 #Updat ...

  9. a byte of python(摘04)

    a byte of python 第十章 输入/输出 如何使程序和用户进行交互?(用 raw_input 和 print语句来完成) 对于输出,你也可以使用多种多样的 str(字符串)类.使用 rju ...

  10. 【linux】linux下动态库so文件的一些认识

    来源:http://mypyg.iteye.com/blog/845915 so其实就是shared object的意思.今天看了上面的博客,感觉好吃力.赶紧做个笔记记录一下.下面的内容大多都是连接中 ...