【洛谷P1486】郁闷的出纳员【树状数组】
题目描述
题目链接
分析
听说暴力能过 ,不敢打Treap/线段树。
很巧妙的一道题,第一次听说树状数组查询第k大/小的数。
定义树状数组为工资点上的人数,对于工资的整体增减可以通过设置变量p统一维护,这个是很关键的变量,处理工资的整体浮动。
因为数值变化在正负数之间,而树状数组下标必须从1开始,因此要对所有工资值进行坐标平移,也就是
定义数轴原点dt=200000。
整体加工资,直接加到p值里;新员工入职用update 进行单点插入处理;
比较麻烦的是如何高效的处理减工资产生的离职和查询第k高收入。
先处理第k高收入的工资值查询,对于这个查询其实可以反过来看,如果当前在职总人数为cnt,则第k高
工资等价于第cnt-k+1小的工资,由树状数组的构造方式可以知道统计这个前缀值可以查询比他小的数,这个前cnt-k+1可以看作前缀和,设为s,可以使用倍增法快速逼近。
对于离职人员的处理,我们每次取出最低工资的人判断是否要离职(如果不用后面都不用),离职的人只需要将s这个工资点的人全部删掉(加上-c[s])。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;int n,mn,leave,tot;
int dt=2e5,p;
long long c[400010];int lowbit(int x){return x&(-x);}
void update(int x,int v)
{for(int i=x;i<=4e5;i+=lowbit(i)) c[i]+=v;}
int getsum(int x)//用不着
{int s=0;for(int i=x;i;i-=lowbit(i)) s+=c[i];return s;
}int query(int k)//这里手动求和了,不用求和函数
{int s=0,ans=0;for(int i=20;i>=0;i--)//枚举2^i,倍增 {ans+=(1<<i);if(ans>4e5||s+c[ans]>=k) ans-=(1<<i);else s+=c[ans];//求和,统计前面总共比他小的数的个数 }return ans+1;//这个就是第k小的数
}void del(int k)
{while(tot){int s=query(1);if(s>=k) break;//如果最低的都不会离职 tot-=c[s];leave+=c[s];update(s,-c[s]);}
}int main()
{cin>>n>>mn;for(int i=1;i<=n;i++){char op;int k;cin>>op>>k;if(op=='I'){if(k<mn) continue;tot++;update(k-p+dt,1); }else if(op=='A'){p+=k;}else if(op=='S'){p-=k;del(mn-p+dt);//减工资之后的工资基准点 }else if(op=='F'){if(k>tot) cout<<-1<<endl;else cout<<query(tot-k+1)-dt+p<<endl;}}cout<<leave;return 0;
}
【洛谷P1486】郁闷的出纳员【树状数组】相关推荐
- 洛谷P3688/uoj#291. [ZJOI2017]树状数组
传送门(uoj) 传送门(洛谷) 这里是题解以及我的卡常数历程 话说后面那几组数据莫不是lxl出的这么毒 首先不难发现这个东西把查询前缀和变成了查询后缀和,结果就是查了\([l-1,r-1]\)的区间 ...
- 洛谷P3374 【模板】树状数组 1
题目链接:[模板]树状数组 1 - 洛谷 模板题就不多说了 ac代码: #include <cstdio> #include <iostream> #include <a ...
- 洛谷P3368 【模板】树状数组 2(Python和C++代码)
##就是常规写法 用树状数组维护一个差分数组的前缀和,因为可推得若b[i]=a[i]-a[i-1],则a[i]=b[1]+-+b[i] (b[1]=a[1]-a[0],a[0]=0) . 可发现a[i ...
- [洛谷P1908] 逆序对|归并排序|树状数组
题目描述 Description 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为&qu ...
- 洛谷 P1908 逆序对(树状数组+离散化)
题目描述 猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计. 最近,TOM 老猫查阅到一个人类称之为"逆序对& ...
- 洛谷P2448 无尽的生命 树状数组
给出231−12^{31}-1231−1范围的1−n1-n1−n的数列,然后有不超过k≤1e5k\leq1e5k≤1e5次交换,求问最终的逆序对的个数是多少. 被交换的值不超过2k2k2k个,然后再考 ...
- 洛谷P2357 守墓人(差分+树状数组)
原题链接 什么是差分? 7 8 6 5 8 18 20 35 //原数组 7 1 -2 -1 3 10 2 15 //差分数组 差分数组的前缀sum[i]即原数组的a[i] 我们构建两个树状数组 su ...
- 洛谷 P5149 会议座位(树状数组+Trie)
题目是一道求逆序对的题目,但是我们先要将每一个名字转化为数字再进行计算 求逆序对的个数用树状数组或归并即可 题目有个坑点,名字包含大小写字母,所以字典树需要开大一点 #include <iost ...
- 洛谷P3374 【模板】树状数组 1(Python和C++代码)
import math import sys import string import cmath import bisect import copy import heapq from collec ...
- 洛谷 P3368 【模板】树状数组 2
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...
最新文章
- ubuntu18.04虚拟机突然不能上网问题解决办法
- Codeforces Round #520 (Div. 2)
- UIColor的封装
- Android 5.0 + IDA 6.8 调试经验分享
- PHP Ajax 跨域问题最佳解决方案
- iOS开发——高级篇——二维码的生产和读取
- mysql 命令行可以连接 php不能,mysql连接命令行可以php竟然不可以
- android中json解析及使用 (下)
- linux查看服务命令是什么,linux系统查看所有服务的命令
- 关于单细胞批次矫正那些事(二) KBET 用于单细胞批次矫正结果的评估
- 好久没来51cto了。
- c语言程序创建的基本步骤,c语言程序设计基本步骤
- Shiro 实战教程(上)
- Oracle自增序列字段
- 一看就懂系列:什么是相速度与群速度
- 使用云服务器被攻击了怎么办
- 物流系统管理课程(二)
- 适合Mac版的即时翻译软件
- 咬定青山不放松,立根原在破岩中。千磨万击还坚劲,任尔东南西北风!
- 判断计算机硬件和网络故障,计算机硬件故障的识别与处理