HDU4288 Coder(线段树)
注意添加到集合中的数是升序的,先将数据读入,再离散化。
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(线段树)的更多相关文章
- HDU4288:Coder(线段树单点更新版 && 暴力版)
Problem Description In mathematics and computer science, an algorithm describes a set of procedures ...
- hdu4428(Coder)线段树
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 4288 Coder(线段树)
题意: 给定三种操作 1. add x 向序列中添加x,添加之后序列还保持有序 2. del x 删除序列中值为x的元素 3. sum 求下边模5等于3的元素和 思路: 直接暴力也可以过,就是看暴 ...
- hdu 4288 Coder (线段树+离线)
题意: 刚开始有一个空集合.有三种操作: 1.往集合中加入一个集合中不存在的数 x 2.从集合中删除一个已经存在的数 x 3.计算集合的digest sum并输出. digest sum求 ...
- HDU 4288 Coder (线段树)
Coder 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4288 题意:有三种类型的操作,(1)."add x",表示往集合里加入�数 ...
- 线段树(多棵) HDOJ 4288 Coder
题目传送门 题意:集合,add x, del x, 求和 分析:首先,暴力可以过这题.用上线段树能大大降低时间的消耗,具体就是类似开了5棵线段树,每个节点都有5个空间,表示该区间的id%5后的和,区间 ...
- HDU 4288 Coder 【线段树+离线处理+离散化】
题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...
- hdu4288 Coder(段树+分离)
主题链接: huangjing 题意: 题目中给了三个操作 1:add x 就是把x插进去 2:delete x 就是把x删除 3:sum 就是求下标%5=3的元素的和. 另一个条件是插入和删除最后 ...
- HDU 4288 Coder ( 离散化 + 离线 + 线段树 )
这题跟ZOJ 3606的解题思路很相似. 题意:有3中操作:1.向集合中增加一个数x(1≤x≤1e9):2.从集合中删去一个数x(保证这个数存在):3.查询集合中所有位置满足i%5==3的数a[i]的 ...
随机推荐
- 1. dex和Jar反编译对比
Java源码 public class Hello { public int foo(int a,int b) { return (a + b) * (a - b); } public static ...
- MySQL 临时表的使用
-- step 1.创建临时表,命名为item_orders create temporary table item_orders ( item_id int, orderList ) ) -- st ...
- Nginx 使用 sever 段规则屏蔽恶意 User Agent
相对于 Apache,Nginx 占用的系统资源更少,更适合 VPS 使用.恶意的 User Agent 无处不在,博客更换到 WordPress 没几天,就被 SPAM(垃圾留言)盯上,又被暴力破解 ...
- C语言宏定义时#(井号)和##(双井号)的用法
C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...
- Myeclipse8.5 反编译插件 jad 安装
准备工作 下载jad.exe文件和下载jadeclipse插件:http://pan.baidu.com/s/1pJKjVwn JadClipse 官网:http://jadclipse.source ...
- JS插件之——ztree
很牛逼的一个树形菜单,树形下拉框插件.一年前用过,很好用.今天又有机会拿过来用,温故一下基本点,nice!! 官方文档说明的非常详细,按照API慢慢看,耐心解读,自然就可以解惑了. 官方文档及其源码下 ...
- Interleaving Positive and Negative Numbers
Given an array with positive and negative integers. Re-range it to interleaving with positive and ne ...
- 如何将ADT项目导入Android studio及常見問題
ADT导出Android studio项目 右键-->ExportAndroid/Generate Gradle build files--> Android studio导入项目 Fil ...
- ClassLoad的加载过程及分析
-Xbootclasspath:bootclasspath 让jvm从指定路径(可以是分号分隔的目录.jar.或者zip)中加载bootclass,用来替换jdk的rt.jar:若非必要,一般不会用到 ...
- eclipse修改项目名称
一. 右键工程:Refactor->Rename,或选中工程按F2,修改名称二.右键工程:Properties->Web Project Settings,修改Context Root 三 ...