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 ...
随机推荐
- 纯CSS3制作卡通场景汽车动画效果
前言 今天分享一下我昨晚做的CSS3动画效果——卡通场景汽车动画.在接触CSS3动画之前,我之前实现一些简单的动画效果都是使用flash完成的.但是自从CSS3横空出世,在移动端对CSS3动画的运用越 ...
- Android应用开发中如何使用隐藏API(转)
一开始需要说明的是,Google之所以要将一些API隐藏(指加上@hide标记的public类.方法或常量)是有原因的.其中很大的原因就是Android系统本身还在不断的进化发展中.从1.0.1.1到 ...
- 检测到 LoaderLock:DLL"XXXX"正试图在OS加载程序锁内执行
解决方法: ctrl+D+E或alt+ctl+e或使用菜单调试——>异常——>异常窗口——>Managed Debugging Assistants——>去掉LoaderLoc ...
- 图像相似度算法的C#实现及测评
近日逛博客的时候偶然发现了一个有关图片相似度的Python算法实现.想着很有意思便搬到C#上来了,给大家看看. 闲言碎语 才疏学浅,只把计算图像相似度的一个基本算法的基本实现方式给罗列了出来,以至于在 ...
- Android Touch事件传递机制解析 (推荐)
最近新闻列表里的下拉 down up move 等等让我十分头疼 ,无意间看到了一篇非常不错的帖子,转载如下: 开篇语:最近程序在做一个小效果,要用到touch,结果整得云里面雾里的,干脆就好好把a ...
- 通过jdbc获取数据库中的表结构
通过jdbc获取数据库中的表结构 主键 各个表字段类型及应用生成实体类 1.JDBC中通过MetaData来获取具体的表的相关信息.可以查询数据库中的有哪些表,表有哪些字段,字段的属性等等.Met ...
- Ubuntu 16.04 LTS安装好需要设置的15件事(喜欢新版本)
看到这篇文章说明你已经从老版本升级到 Ubuntu 16.04 或进行了全新安装,在安装好 Ubuntu 16.04 LTS 之后建议大家先做如下 15 件事.无论你是刚加入 Ubuntu 行列的新用 ...
- LeetCode:Jump Game I II
Jump Game Given an array of non-negative integers, you are initially positioned at the first index o ...
- wpf键盘记录器
很简单的一个wpf键盘记录器 这个程序我一样用了全局勾子,之前用的都是winform上运行了,前一段时间 在国外的论坛上逛看到了一个wpf能用的就做了一个小程序记录一下,为了方便大家直关的看我在页面上 ...
- 如何在WPF中引用Windows.System.Forms.Integration
转自 http://www.cnblogs.com/sinozhang1988/archive/2012/11/28/2792804.html “未找到程序集 WindowsFormsIntegrat ...