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 ...
随机推荐
- Android优化——UI优化(五) Listview 重用convertView
1.重用convertView 我们对convertView添加判断,如果存在我们就直接使用,否则初始化一个convertView的实例.(如下图) 2.使用viewHolder 使用viewHold ...
- 导航 tab
- 自定义WPF ListBox的选中项样式
首先介绍一种简单地方法:就是通过自定义SystemColors类的参数来自定义WPF ListBox选择颜色的,SystemColors的HighlightBrushKey和HighlightText ...
- 磁盘操作- inode/Block深入实战
一 思路: 1,磁盘物理结构及大小计算 2,分区 MBR GPT知识 3,fdisk分区 挂载 自动挂载 4,格式化文件系统 5,inode block 软硬链接 查看磁盘: [root@moban ...
- C语言 文件操作8--fputs()和fgets()
//fputs()和fgets() #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> # ...
- HighCharts 详细使用及API文档说明
一.HighCharts开发说明: HighCharts开发实际上配置HighCharts每个部分,比如配置标题(title),副标题(subtitle)等,其中每个部分又有更细的参数配置,比如标题下 ...
- Jdeveloper 太慢 slowly
https://blogs.oracle.com/shay/entry/is_your_jdeveloper_slow_it_sho http://bexhuff.com/2012/09/jdevel ...
- Python快速教程 尾声(转)
原文地址: http://www.cnblogs.com/vamei/p/3603046.html 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留 ...
- 2015老男孩Python培训第八期视频教程
2015老男孩Python培训第八期视频教程,希望您通过本教程的学习,能学会常用方法和技巧.教程从基础知识开始讲解一直到后期的案例实战,完全零基础学习,从初学者的角度探讨分析问题,循序渐进由易到难,确 ...
- [vim配置]windows下在vim中使用gcc/g++编译调试c/cpp文件
在Linux里面混了一个多月,vim编程用得甚爽.无奈前天将Linux里面的编程文件夹误删,而技术不精无法找回,悲痛欲绝.再者,无限怀念windows里面的游戏,并觉得现在在Linux里面也学不到什么 ...