题目链接:买票问题

思路:优先队列维护忍耐度最低的人在队首,leave操作ok.
vis数组记录从1到n的编号的人们是不是在队列中,top维护队首的人的编号。pop操作搞定。
然后,check操作就是在vis数组中查找当前编号之前有多少个为1的数,树状数组大法好。
啊...数据虽然很大,但是t<=100000,所以可以用map把所有的编号标记为1-100000之间的...

dbug全程:开始树状数组求和错误,检查模板没错,后猛然想起,树状数组每次更新i处的值,所有小于maxn的i + lowbit(i)都要更新,所以,sum()函数里,while(i<=maxn) 而不是当前最大位置num。然后发现RE,用mp数组映射的时候,mp[int] = num++; 显然mp数组越界了。果断该成map。大概这就是map的好处吧...然后TLE,我拒绝相信!然后发现队列没有清空,直接开在main函数了,AC之。尝试把队列开成全局变量,然后main函数里清空,依然TLE。

大概,STL用的太多了吧..........

附代码:

/*
不想敲题,不想敲题,这道题真丑~躺在地上打滚中...
思路:优先队列维护忍耐度最低的人在队首,leave操作ok.
vis数组记录从1到n的编号的人们是不是在队列中,top维护队首的人的编号。pop操作搞定。
然后,check操作就是在vis数组中查找当前编号之前有多少个为1的数,树状数组大法好。
啊...数据虽然很大,但是t<=100000,所以可以用map把所有的编号标记为1-100000之间的...
讲真,为什么dangshixiangbuchulaine...
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
#define maxn 100005
#include <map>
#include <queue>
using namespace std; char op[10];
int vis[maxn];
map<int, int>mp;
int a[maxn];
int num; struct Node {
int id, endu;
friend bool operator < (Node a, Node b) {
return a.endu > b.endu; // 从小到大
}
Node(int id, int endu) {
this->id = id, this->endu = endu;
}
}; int lowbit(int x) {
return x & (-x);
} int sum(int id) {
int ans = 0;
while(id > 0) {
ans += a[id];
id -= lowbit(id);
}
return ans;
} void update(int id, int x) {
while(id <= maxn) {
a[id] += x;
id += lowbit(id);
}
} int main() {
int n;
while(~scanf("%d", &n)) {
mp.clear();
num = 1; // 编号
memset(vis, 0, sizeof(vis));
memset(a, 0, sizeof(a));
priority_queue<Node> que;
int top = 0; for (int i=0; i<n; ++i) {
scanf("%s", op);
if (op[0] == 'a') {
int id, endu;
scanf("%d%d", &id, &endu);
mp[id] = num++;
id = mp[id];
vis[id] = 1;
update(id, 1);
Node temp(id, endu);
que.push(temp);
}
else if (op[0] == 'l') {
while(!que.empty() && !vis[que.top().id])
que.pop();
if (!que.empty() && vis[que.top().id]) {
int lid = que.top().id;
que.pop();
vis[lid] = 0;
update(lid, -1);
}
}
else if (op[0] == 'p') {
while(!vis[top] && top<num) top++;
if (top < num && vis[top]) {
vis[top] = 0;
update(top, -1);
}
}
else {
int tid, tendu;
scanf("%d%d", &tid, &tendu);
tid = mp[tid];
if (vis[tid]) {
int tsum = sum(tid);
tsum -= 1;
printf("%d\n", tsum);
if (tsum > tendu) {
vis[tid] = 0;
update(tid, -1);
}
}
}
}
}
return 0;
}

不然,把struct改成pair好了...

附代码:

/*
不想敲题,不想敲题,这道题真丑~躺在地上打滚中...
思路:优先队列维护忍耐度最低的人在队首,leave操作ok.
vis数组记录从1到n的编号的人们是不是在队列中,top维护队首的人的编号。pop操作搞定。
然后,check操作就是在vis数组中查找当前编号之前有多少个为1的数,树状数组大法好。
啊...数据虽然很大,但是t<=100000,所以可以用map把所有的编号标记为1-100000之间的...
讲真,为什么dangshixiangbuchulaine...
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
#define maxn 100005
#include <map>
#include <queue>
using namespace std; char op[10];
int vis[maxn];
map<int, int>mp;
int a[maxn];
int num; typedef pair<int, int>Per; int lowbit(int x) {
return x & (-x);
} int sum(int id) {
int ans = 0;
while(id > 0) {
ans += a[id];
id -= lowbit(id);
}
return ans;
} void update(int id, int x) {
while(id <= maxn) {
a[id] += x;
id += lowbit(id);
}
} int main() {
int n;
while(~scanf("%d", &n)) {
mp.clear();
num = 1; // 编号
memset(vis, 0, sizeof(vis));
memset(a, 0, sizeof(a));
priority_queue<Per, vector<Per>, greater<Per> > que; // 从小到大
int top = 0;
Per per; for (int i=0; i<n; ++i) {
scanf("%s", op);
if (op[0] == 'a') {
int id, endu;
scanf("%d%d", &id, &endu);
mp[id] = num++;
id = mp[id];
vis[id] = 1;
update(id, 1);
per = make_pair(endu, id);
que.push(per);
}
else if (op[0] == 'l') {
while(!que.empty() && !vis[que.top().second])
que.pop();
if (!que.empty() && vis[que.top().second]) {
int lid = que.top().second;
que.pop();
vis[lid] = 0;
update(lid, -1);
}
}
else if (op[0] == 'p') {
while(!vis[top] && top<num) top++;
if (top < num && vis[top]) {
vis[top] = 0;
update(top, -1);
}
}
else {
int tid, tendu;
scanf("%d%d", &tid, &tendu);
tid = mp[tid];
if (vis[tid]) {
int tsum = sum(tid);
tsum -= 1;
printf("%d\n", tsum);
if (tsum > tendu) {
vis[tid] = 0;
update(tid, -1);
}
}
}
}
}
return 0;
}

  

FZU 2029 买票问题 树状数组+STL的更多相关文章

  1. AcWing 260. 买票 (树状数组+二分)打卡

    题目:https://www.acwing.com/problem/content/description/262/ 题意:给定一个队伍,每个人过来的时候可以插队,每个人会输入一个插入到哪个位置,但是 ...

  2. 树状数组+STL FZU 2029 买票问题

    题目传送门 题意:中文题面 分析:隔了一个考试周再做,开始没有什么思路,感觉能用线段树/树状数组维护,树状数组维护最小值不会去写线段树,结果超时.后来发现只要维护前缀几个人以及用优先队列/set维护最 ...

  3. POJ 2029 (二维树状数组)题解

    思路: 大力出奇迹,先用二维树状数组存,然后暴力枚举 算某个矩形区域的值的示意图如下,代码在下面慢慢找... 代码: #include<cstdio> #include<map> ...

  4. FZU 2277 Change(dfs序+树状数组)

    Problem Description There is a rooted tree with n nodes, number from 1-n. Root’s number is 1.Each no ...

  5. FZU Problem 2029 买票问题(树状数组)

    当我看到题目是5秒的时候,压根没有想树状数组,一直奔着模拟队列去想了,最后也没搞定,赛后看到大神的题解才恍然大悟,原来如此,题目中有明显的暗示,求前n项和,骤然感叹,自己太low... 果然还是要多做 ...

  6. POJ 2029 Get Many Persimmon Trees (二维树状数组)

    Get Many Persimmon Trees Time Limit:1000MS    Memory Limit:30000KB    64bit IO Format:%I64d & %I ...

  7. poj 2029 二维树状数组

    思路:简单树状数组 #include<map> #include<set> #include<cmath> #include<queue> #inclu ...

  8. POJ 2029 Get Many Persimmon Trees(DP||二维树状数组)

    题目链接 题意 : 给你每个柿子树的位置,给你已知长宽的矩形,让这个矩形包含最多的柿子树.输出数目 思路 :数据不是很大,暴力一下就行,也可以用二维树状数组来做. #include <stdio ...

  9. FZU 2176 easy problem (DFS序+树状数组)

    对于一颗树,dfs遍历为每个节点标号,在进入一个树是标号和在遍历完这个树的子树后标号,那么子树所有的标号都在这两个数之间,是一个连续的区间.(好神奇~~~) 这样每次操作一个结点的子树时,在每个点的开 ...

随机推荐

  1. Oracle PLSQL语句实例

    /** * plsql:某个项目对效率要求比较高的时候用,一般不用,大多数项目写的是夸数据库平台的,用不上. * pssql大多数能做的东西,java都能替代它.在某些特殊的地方要求用plsql的时候 ...

  2. Win7_提高性能

    1. 设置成经典主题:桌面->右键->个性化->经典主题 2. 计算机->右键->属性->高级系统设置 ==> 系统属性->高级->性能-> ...

  3. Tomcat的使用

    Tomcat的安装较为简单,尤其是Tomcat的安装文件apache-tomcat-7.0.19-windows-x86.zip,直接解压至目标目录下即可. Tomcat的安装目录下包括bin.con ...

  4. mysql 逻辑架构

    1.mysql是基于网络的客户端/服务器架构,服务器上层是连接线程,解析器,查询缓存,下层是存储引擎. 2.每个客户端连接,服务器都有一个对应的线程,这个线程只为这个连接查询服务,高版本的mysql支 ...

  5. Java中List、Collections实现梭哈游戏

    package ch8; import java.util.*; /** * Created by Jiqing on 2016/11/27. */ public class ShowHand { / ...

  6. TortoiseGIT

    TortoiseGIT 是Git版本控制系统的一个免费开源客户端,它是git版本控制的 Windows 扩展.可以使你避免使用枯燥而且不方便的命令行.它完全嵌入 Windows Explorer,使用 ...

  7. 【Todo】Java要学的一些比较好的框架和系统

    commons-pool apache的通用线程池 可以看看这篇文章:<使用common-pool实现的一个简单的线程池> Jmeter 性能测试 Squid Link

  8. [html] 前端角度出发做好SEO需要考虑什么

    Meta标签优化 主要包括主题(Title),网站描述(Description),和关键词(Keywords).还有一些其它的隐藏文字比如Author(作者),Category(目录),Languag ...

  9. Linux mysql常用操作命令

    原文:http://blog.csdn.net/lifuxiangcaohui/article/details/46375931 1.linux下启动MySQL的命令:mysqladmin start ...

  10. C# Socket编程(4)初识Socket和数据流

    经过前面基础知识作为背景,现在对Socket编程进行进一步的学习.在System.Net.Socket命名空间提供了Socket类,利用该类我们可以直接编写Socket的客户端和服务的的程序.但是直接 ...