Codeforces 85D Sum of Medians
3 seconds
256 megabytes
standard input
standard output
In one well-known algorithm of finding the k-th order statistics we should divide all elements into groups of five consecutive elements and find the median of each five. A median is called the middle element of a sorted array (it's the third largest element for a group of five). To increase the algorithm's performance speed on a modern video card, you should be able to find a sum of medians in each five of the array.
A sum of medians of a sorted k-element set S = {a1, a2, ..., ak}, where a1 < a2 < a3 < ... < ak, will be understood by as

The
operator stands for taking the remainder, that is
stands for the remainder of dividing x by y.
To organize exercise testing quickly calculating the sum of medians for a changing set was needed.
The first line contains number n (1 ≤ n ≤ 105), the number of operations performed.
Then each of n lines contains the description of one of the three operations:
- add x — add the element x to the set;
- del x — delete the element x from the set;
- sum — find the sum of medians of the set.
For any add x operation it is true that the element x is not included in the set directly before the operation.
For any del x operation it is true that the element x is included in the set directly before the operation.
All the numbers in the input are positive integers, not exceeding 109.
For each operation sum print on the single line the sum of medians of the current set. If the set is empty, print 0.
Please, do not use the %lld specificator to read or write 64-bit integers in C++. It is preferred to use the cin, cout streams (also you may use the %I64d specificator).
6
add 4
add 5
add 1
add 2
add 3
sum
3
14
add 1
add 7
add 2
add 5
sum
add 6
add 8
add 9
add 3
add 4
add 10
sum
del 1
sum
5
11
13
-----------------------------------------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N=1e5+;
#define X first
#define Y second
//BIT
int bit[MAX_N], rb;
int sum(int i){
int s=;
while(i){
s+=bit[i];
i-=i&-i;
}
return s;
}
void add(int i, int x){
while(i<=rb){
bit[i]+=x;
i+=i&-i;
}
} typedef pair<int, int> P;
P q[MAX_N];
int val[MAX_N];
char type[MAX_N][];
int lisan(int N){
int v;
for(int i=; i<N; i++){
scanf("%s", type[i]);
switch(*type[i]){
case 'a':
case 'd':
scanf("%d", &v);
q[i]=P(v, i);
break;
case 's':
q[i]=P(, i); //TLE在这里
break;
}
}
sort(q, q+N);
int ord=;
for(int i=; i<N; ord++){
val[ord]=q[i].X;
do{
q[i].X=ord;
i++;
}while(i<N&&q[i].X==val[ord]);
}
return ord;
}
bool cmp(const P &a, const P &b){
return a.Y<b.Y;
}
//ST
struct node{
int l, r, tag;
ll sum[];
int mid(){return (l+r)>>;}
}T[MAX_N<<];
void shift(int id, int cnt){
cnt%=;
if(!cnt) return;
ll tmp[];
memcpy(tmp, T[id].sum, sizeof(tmp));
for(int i=; i<; i++){
int nt=(i+cnt+)%;
T[id].sum[nt]=tmp[i];
}
}
void pushdown(int id){
node &now=T[id], &lch=T[id<<], &rch=T[id<<|];
lch.tag+=now.tag, rch.tag+=now.tag;
shift(id<<, now.tag);
shift(id<<|, now.tag);
now.tag=; //error prone
}
void unite(int id){
node &now=T[id], &lch=T[id<<], &rch=T[id<<|];
for(int i=; i<; i++)
now.sum[i]=lch.sum[i]+rch.sum[i];
}
void build(int id, int l, int r){
node &now=T[id];
T[id].l=l, T[id].r=r, T[id].tag=;
memset(T[id].sum, , sizeof(T[id].sum));
if(l==r) return;
int mid=(l+r)>>;
build(id<<, l, mid);
build(id<<|, mid+, r);
}
void insert(int id, int pos, int ord, int v){
node &now=T[id];
if(now.l==now.r){
now.sum[ord%]+=v;
}
else{
pushdown(id);
if(pos<=now.mid())
insert(id<<, pos, ord, v);
else
insert(id<<|, pos, ord, v);
unite(id);
}
}
void shift(int id, int lb, int cnt){
if(lb>rb) return;
node &now=T[id];
if(now.l>=lb){
shift(id, cnt);
now.tag+=cnt;
}
else{
pushdown(id);
if(lb<=now.mid())
shift(id<<, lb, cnt);
shift(id<<|, lb, cnt);
unite(id);
}
} int main(){
//freopen("in", "r", stdin);
int N;
scanf("%d", &N);
rb=lisan(N);
build(, , rb);
sort(q, q+N, cmp);
for(int i=; i<N; i++){
if(*type[i]=='a'){
int ord=sum(q[i].X)+;
add(q[i].X, );
shift(, q[i].X+, );
insert(, q[i].X, ord, val[q[i].X]);
}
else if(*type[i]=='d'){
int ord=sum(q[i].X);
add(q[i].X, -);
shift(, q[i].X+, -);
insert(, q[i].X, ord, -val[q[i].X]);
}
else{
printf("%I64d\n", T[].sum[]);
}
}
return ;
}
其实我已经考虑到这种无sum询问的输入,但没注意到它会导致我的代码TLE
AC version
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N=1e5+;
#define X first
#define Y second
//BIT
int bit[MAX_N], rb;
int sum(int i){
int s=;
while(i){
s+=bit[i];
i-=i&-i;
}
return s;
}
void add(int i, int x){
while(i<=rb){
bit[i]+=x;
i+=i&-i;
}
} typedef pair<int, int> P;
P q[MAX_N];
int val[MAX_N];
char type[MAX_N][];
int lisan(int N){
int v;
for(int i=; i<N; i++){
scanf("%s", type[i]);
switch(*type[i]){
case 'a':
case 'd':
scanf("%d", &v);
q[i]=P(v, i);
break;
case 's':
q[i]=P(INT_MAX, i); //注意这里的改动
break;
}
}
sort(q, q+N);
int ord=;
for(int i=; i<N;){
++ord;
val[ord]=q[i].X;
do{
q[i].X=ord;
i++;
}while(i<N&&q[i].X==val[ord]);
}
return ord;
}
bool cmp(const P &a, const P &b){
return a.Y<b.Y;
}
//ST
struct node{
int l, r, tag;
ll sum[];
int mid(){return (l+r)>>;}
}T[MAX_N<<];
void shift(int id, int cnt){
cnt%=;
if(!cnt) return;
ll tmp[];
memcpy(tmp, T[id].sum, sizeof(tmp));
for(int i=; i<; i++){
int nt=(i+cnt+)%;
T[id].sum[nt]=tmp[i];
}
}
void pushdown(int id){
node &now=T[id], &lch=T[id<<], &rch=T[id<<|];
lch.tag+=now.tag, rch.tag+=now.tag;
shift(id<<, now.tag);
shift(id<<|, now.tag);
now.tag=; //error prone
}
void unite(int id){
node &now=T[id], &lch=T[id<<], &rch=T[id<<|];
for(int i=; i<; i++)
now.sum[i]=lch.sum[i]+rch.sum[i];
}
void build(int id, int l, int r){
node &now=T[id];
T[id].l=l, T[id].r=r, T[id].tag=;
memset(T[id].sum, , sizeof(T[id].sum));
if(l==r) return;
int mid=(l+r)>>;
build(id<<, l, mid);
build(id<<|, mid+, r);
}
void insert(int id, int pos, int ord, int v){
node &now=T[id];
if(now.l==now.r){
now.sum[ord%]+=v;
}
else{
pushdown(id);
if(pos<=now.mid())
insert(id<<, pos, ord, v);
else
insert(id<<|, pos, ord, v);
unite(id);
}
}
void shift(int id, int lb, int cnt){
if(lb>rb) return;
node &now=T[id];
if(now.l>=lb){
shift(id, cnt);
now.tag+=cnt;
}
else{
pushdown(id);
if(lb<=now.mid())
shift(id<<, lb, cnt);
shift(id<<|, lb, cnt);
unite(id);
}
} int main(){
//freopen("in", "r", stdin);
int N;
scanf("%d", &N);
rb=lisan(N);
build(, , rb);
sort(q, q+N, cmp);
for(int i=; i<N; i++){
if(*type[i]=='a'){
int ord=sum(q[i].X)+;
add(q[i].X, );
shift(, q[i].X+, );
insert(, q[i].X, ord, val[q[i].X]);
}
else if(*type[i]=='d'){
int ord=sum(q[i].X);
add(q[i].X, -);
shift(, q[i].X+, -);
insert(, q[i].X, ord, -val[q[i].X]);
}
else{
printf("%I64d\n", T[].sum[]);
}
}
return ;
}
Codeforces 85D Sum of Medians的更多相关文章
- Codeforces 85D Sum of Medians(线段树)
题目链接:Codeforces 85D - Sum of Medians 题目大意:N个操作,add x:向集合中加入x:del x:删除集合中的x:sum:将集合排序后,将集合中全部下标i % 5 ...
- 数据结构(线段树):CodeForces 85D Sum of Medians
D. Sum of Medians time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...
- CodeForces 85D Sum of Medians Splay | 线段树
Sum of Medians 题解: 对于这个题目,先想到是建立5棵Splay,然后每次更新把后面一段区间的树切下来,然后再转圈圈把切下来的树和别的树合并. 但是感觉写起来太麻烦就放弃了. 建立5棵线 ...
- 85D Sum of Medians
传送门 题目 In one well-known algorithm of finding the k-th order statistics we should divide all element ...
- CF 85D Sum of Medians (五颗线段树)
http://codeforces.com/problemset/problem/85/D 题意: 给你N(0<N<1e5)次操作,每次操作有3种方式, 1.向集合里加一个数a(0< ...
- codeforces 85D D. Sum of Medians Vector的妙用
D. Sum of Medians Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/prob ...
- codeforces 85D D. Sum of Medians 线段树
D. Sum of Medians time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...
- Yandex.Algorithm 2011 Round 1 D. Sum of Medians 线段树
题目链接: Sum of Medians Time Limit:3000MSMemory Limit:262144KB 问题描述 In one well-known algorithm of find ...
- Coderforces 85 D. Sum of Medians(线段树单点修改)
D. Sum of Medians time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...
随机推荐
- Ember模板中的操作指向
模板中的链接操作指向有三个地方,该模板对应的控制器和路由以及视图,默认是先跳转到控制器,如果控制器里没有定义模板中动作的方法,就去该模板对应的路由里找,如果还没找到,就去父级路由找,直到顶级路由,如果 ...
- CSS3弹性伸缩布局(二)——flex布局
上一篇博客<CSS3弹性伸缩布局(一)——box布局>介绍了旧版本的box布局,而这篇博客将主要介绍最新版本的flex布局的基础知识. 新版本简介 新版本的Flexbox模型是2012年9 ...
- swift为UIView添加extension扩展frame
添加swift file:UIView+Extension import UIKit extension UIView { // x var x : CGFloat { get { return fr ...
- struts2验证框架1
<!--该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理.如果用户需要指定多个请求后缀,则多个后缀之间以英文逗 ...
- Linux共享库 日志方法
mylog.h #ifdef __cplusplus extern "C" { #endif //写日志函数 //path:日志文件名 //msg:日志信息 int writelo ...
- IPAdr.exe破解[练手]
[文章标题]: IPAdr.exe破解[软件名称]: IPAdr.exe[加壳方式]: 无[编写语言]: delphi[使用工具]: OD[作者声明]: 失误之处敬请诸位大侠赐教!---------- ...
- Android开发探秘之一:创建可以点击的Button
感觉到自己有必要学习下手机开发方面的知识,不论是为了以后的工作需求还是目前的公司项目. 当然,任何新东西的开始,必然伴随着第一个HelloWorld,Android学习也不例外.既然才开始,我就不做过 ...
- Android EventBus源码解析 带你深入理解EventBus
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40920453,本文出自:[张鸿洋的博客] 上一篇带大家初步了解了EventBus ...
- [CareerCup] 11.5 Search Array with Empty Strings 搜索含有空字符串的数组
11.5 Given a sorted array of strings which is interspersed with empty strings, write a method to fin ...
- DLL函数中内存分配及释放的问题
DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...