题目大意:给一个数组a,他的顺序是严格的单调增,然后有如下三个操作

①加入一个val到a数组里面去,加入的位置就是a[i-1]<val<a[i+1]

②删除一个a[i]=val的值

③查询所有下标i%5=3的值

思路:线段树+离线

首先因为线段树中不支持添加、删除操作的,所以只能离线把所有的val离散化以后放到区间里面去。然后关键就是线段树是怎么建立的。

我们知道,每个%5都会有0,1,2,3,4这5个值,然后我们可以通过线段树来维护这5个值。我们首先用sum[5]表示能被5整除的5种求余后不同类型的数的val,然后再用cnt记录当前这个区间里面还存在的数值。接下来我们定义父亲区间,左子区间和右子区间,然后我们发现左子区间的区间范围和父亲区间的是一样的,然后右子区间的范围要发生改变,他的位置改变到如下位置:(i+cnt)%5,其中i表示右子区间的第几个区间,然后cnt表示左子区间的有效的个数。然后我们就这样去维护就好啦。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
const int maxn = 1e5 + ;
struct point{
LL sum[];
int cnt;
void init(){
this -> cnt = ;
memset(sum, , sizeof(sum));
}
}tree[maxn << ];
LL a[maxn];
int q;
pair<char, LL> ch[maxn]; void buildtree(int o, int l, int r){
if (l == r){
tree[o].init();
return ;
}
int mid = (l + r) / ;
if (l <= mid) buildtree(o << , l, mid);
if (r > mid) buildtree(o << | , mid + , r);
tree[o].init();
} inline void push_up(int o){
tree[o].cnt = tree[o << ].cnt + tree[o << | ].cnt;
} void display(int o, int l, int r){
printf("o = %d l = %d r = %d\n", o, l, r);
for (int i = ; i < ; i++) printf("%d ", tree[o].sum[i]);
printf("\n");
} void update(int o, int l, int r, int pos, bool flag){
if (l == r && l == pos){
if (flag) {tree[o].sum[] += a[pos]; tree[o].cnt = ;}
else {tree[o].sum[] -= a[pos]; tree[o].cnt = ;}
return ;
}
int mid = (l + r) / ;
if (pos <= mid) update(o << , l, mid, pos, flag);
if (pos > mid) update(o << | , mid + , r, pos, flag);
memset(tree[o].sum, , sizeof(tree[o].sum));
for (int i = ; i < ; i++){
int j = (i + tree[o << ].cnt) % ;
tree[o].sum[i] += tree[o << ].sum[i];
tree[o].sum[j] += tree[o << | ].sum[i];
}
///display(o, l, r);
push_up(o);
return ;
} int main(){
while (scanf("%d", &q) == && q){
int n = ;
for (int i = ; i <= q; i++){
char s[]; LL tmp = -;
scanf("%s", s);
if (s[] == 'd' || s[] == 'a') scanf("%I64d", &tmp);
ch[i] = mk(s[], tmp);
if (s[] == 'a') a[++n] = tmp;
}
sort(a + , a + + n);///有待商榷
buildtree(, , n);
for (int i = ; i <= q; i++){
pair<char, LL> p = ch[i];
if (p.first == 's'){
printf("%I64d\n", tree[].sum[]);
continue;
}
else {
int pos = lower_bound(a + , a + + n, p.second) - a;
update(, , n, pos, p.first == 'a');
}
}
}
return ;
}

求余区间的求和类问题 离线+线段树 HDU4228的更多相关文章

  1. hdu 4288 离线线段树+间隔求和

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

  2. HDU 5700 区间交 离线线段树

    区间交 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5700 Description 小A有一个含有n个非负整数的数列与m个区间.每个区间可以表示为 ...

  3. bzoj2333 离线 + 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2333 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来 ...

  4. 区间第k大问题 权值线段树 hdu 5249

    先说下权值线段树的概念吧 权值平均树 就是指区间维护值为这个区间内点出现次数和的线段树 用这个加权线段树 解决第k大问题就很方便了 int query(int l,int r,int rt,int k ...

  5. BZOJ 3626 [LNOI2014]LCA 树剖+(离线+线段树 // 在线+主席树)

    BZOJ 4012 [HNOI2015]开店 的弱化版,离线了,而且没有边权(长度). 两种做法 1 树剖+离线+线段树 这道题求的是一个点zzz与[l,r][l,r][l,r]内所有点的lcalca ...

  6. BZOJ 2333 棘手的操作(离线+线段树+带权并查集)

    这题搞了我一天啊...拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊.我的线段树要开8倍才能过啊... 首先可以发现除了那个加边操作,其他的操作有点像线段树啊.如果我们把每次询问的联通块都放在一 ...

  7. POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)

    题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...

  8. 【树状数组区间修改区间求和】codevs 1082 线段树练习 3

    http://codevs.cn/problem/1082/ [AC] #include<bits/stdc++.h> using namespace std; typedef long ...

  9. UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

    题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A< ...

随机推荐

  1. Copy Constructor的构造操作

    Copy Constructor的构造操作 有三种情况,会以一个object的内容作为另一个class object的初值: 1.  对一个object做显式的初始化操作 class X{…}; X ...

  2. FZU 1502 Letter Deletion

    最长公共子序列. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #i ...

  3. Linux关机命令详解

    在linux下一些常用的关机/重启命令有shutdown.halt.reboot.及init,它们都可以达到重启系统的目的,但每个命令的内部工作过程是不同的. Linux centos重启命令: 1. ...

  4. Loadrunner中参数和变量的使用

    //字符串复制strcpy(str,"Hello ") ; //字符串连接strcat(str,"World !");lr_message("str: ...

  5. YII2 运行概述(Overview)

    运行机制概述 每一次 Yii 应用开始处理 HTTP 请求时,它都会进行一个近似的流程. 用户提交指向 入口脚本 web/index.php 的请求. 入口脚本会加载 配置数组 并创建一个 应用 实例 ...

  6. marzullo's algorithm

    given several intervals, how to find a interval which is a intersect of the most number of the given ...

  7. js打印保存用户输入的内容

    在用js打印局部页面时,遇到用户新输入的内容没能打印出来,经过观察,发现我采用的js打印方法是读取页面源代码,而用户输入的内容如果不将其写入到页面源代码中去,是打印不出来的,下面是我的解决方法: // ...

  8. Inno Setup入门(七)——提供安装语言选项

    Inno Setup安装目录下有一个Languages的文件夹,该文件夹提供了可供使用的语言,通过在脚本中加入[languages]段,可以实现该项功能,实现代码如下: [setup] ;全局设置,本 ...

  9. Tomcat配置远程调试端口

    Tomcat配置远程调试端口 1.Linxu系统: apach/bin/startup.sh开始处中增加如下内容: declare -x CATALINA_OPTS="-server -Xd ...

  10. git 提高下载速度

    1.  直接下载分支,就不用下载不需要的源码了. git clone --depth 1 git://github.com/TI-OpenLink/wl18xx.git  --branch ol_r8 ...