FZU Problem 2029 买票问题

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

果然还是要多做多研究啊,下面是代码,还有一处脑残错误在代码里...当时真的是找了好久才发现...

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <cstring>
using namespace std;
#define maxn 100005
int c[maxn],mark[maxn],n;
int lowbit(int k)
{
    return k&(-k);
}
void update(int x,int v)///把树状数组的上界写了变量num,wa了无数次
{
    while(x <= n)
    {
        c[x] += v;
        x += lowbit(x);
    }
}
int cal(int x)
{
    int ans = 0;
    while(x > 0)
    {
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
struct Node
{
    int n,y;
    friend bool operator < (Node a,Node b)
    {
        return a.y > b.y;
    }
};
int main()
{
    int t,top,num,x,y;
    Node tmp;
    char op[20];
    while(~scanf("%d",&t))
    {
        n = t;
        top = 1,num = 1;
        memset(c,0,sizeof(c));
        memset(mark,0,sizeof(mark));
        map<int,int> pos;
        priority_queue<Node>que;
        while(!que.empty()) que.pop();
        while(t--)
        {
            scanf("%s",op);
            if(op[0] == ‘a‘)
            {
                scanf("%d%d",&x,&y);
                tmp.n = num,tmp.y = y;
                que.push(tmp);
                pos[x] = num;
                mark[num] = 1;
                num++;
            }
            else if(op[0] == ‘p‘)
            {
                while(mark[top] == 0 && top <= num) top++;
                if(top > num)continue;
                mark[top] = 0;
                update(top,-1);
            }
            else if(op[0] == ‘l‘)
            {
                while(!que.empty() && mark[que.top().n] == 0)
                {
                    que.pop();
                }
                if(!que.empty())
                {
                    Node now;
                    now = que.top();
                    que.pop();
                    mark[now.n] = 0;
                    update(now.n,-1);
                }
            }
            else if(op[0] == ‘c‘)
            {
                scanf("%d%d",&x,&y);
                int m = pos[x];
                if(pos[x] == 0) continue;
                if(mark[m] == 0) continue;
                int tot = m - 1 + cal(pos[x]-1);
                printf("%d\n",tot);
                if(tot > y)
                {
                    mark[m] = 0;
                    update(m,-1);
                }
            }
        }
    }
    return 0;
}
时间: 2024-10-12 08:59:25

FZU Problem 2029 买票问题的相关文章

poj 2828 Buy Tickets 【买票插队找位置 输出最后的位置序列+线段树】

题目地址:http://poj.org/problem?id=2828 Sample Input 4 0 77 1 51 1 33 2 69 4 0 20523 1 19243 1 3890 0 31492 Sample Output 77 33 69 51 31492 20523 3890 19243 Hint The figure below shows how the Little Cat found out the final order of people in the queue d

编程之美之买票找零

题目:假设有2N个人在排队买票,其中有N个人手持50元的钞票,另外有N个人手持100元的钞票,假设开始售票时,售票处没有零钱,问这2N个人有多少种排队方式,不至使售票处出现找不开钱的局面? 分析:队伍的序号标为0,1,...,2n-1,并把50元看作左括号,100元看作右括号,合法序列即括号能完成配对的序列.对于一个合法的序列,第0个一定是左括号,它必然与某个右括号配对,记其位置为k.那么从1到k-1.k+1到2n-1也分别是两个合法序列.那么,k必然是奇数(1到k-1一共有偶数个),设k=2i

FZU Problem 2171 防守阵地 II (线段树,区间更新)

 Problem 2171 防守阵地 II Accept: 143    Submit: 565Time Limit: 3000 mSec    Memory Limit : 32768 KB  Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守

FZU Problem 2034 Password table (简单模拟题)

这种简单题做了好长时间,我是不是有点逗? 地址:http://acm.fzu.edu.cn/problem.php?pid=2034 不解释了,自己看吧,练手的好题 上个代码吧 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <stdio.h> #include <string.h> #include <stdlib.h>

[BOP][Beauty of Programming][MSRA] 从“买票问题”谈起

问题(买票问题): 在一场激烈的足球赛开始前,售票工作正在紧张地进行中. 已知: 1.每张球票为50元. 2.现在有2n个人排队购票, 其中有n个人手持50元钞票,另外n个人手持100元钞票, 假设开始售票时,售票处没有零钱. 问:这2n个人有多少种排队方式,不至使售票处出现找不开钱的局面? 摘要: 通过对买票找零问题的分析,迁移到括号匹配问题,得到递推式.并通过数学分析中级数幂级数知识,推导出递推式的通项,以此解决部分衍生问题. 这里符号怎么玩…… 见外链吧 http://yunpan.cn/

FZU Problem 2238 Daxia &amp; Wzc&#39;s problem

Daxia在2016年5月期间去瑞士度蜜月,顺便拜访了Wzc,Wzc给他出了一个问题: Wzc给Daxia等差数列A(0),告诉Daxia首项a和公差d; 首先让Daxia求出数列A(0)前n项和,得到新数列A(1); 然后让Daxia求出数列A(1)前n项和,得到新数列A(2); 接着让Daxia求出数列A(2)前n项和,得到新数列A(3); 规律题,首先写出 a.a+d.a+2d.a+3d...这个容易写出 下面一行也容易写出:a.2a+d.3a+3d.... 再下一行,确实难写,但是通过上

电影院买票问题-&gt;排队找钱

问题:有2n个人排队进电影院,票价是50美分.在这2n个人当中,其中n个人只有50美分,另外n个人有1美元(纸票子).愚蠢的电影院开始卖票时1分钱也没有.问:有多少种排队方法使得每当一个拥有1美元买票时,电影院都有50美分找钱 注:1美元=100美分拥有1美元的人,拥有的是纸币,没法破成2个50美分 解析:符合卡特兰数( Catalan数),因此直接可以得出答案:(2n)/(n!*(n+1)!). Catalan数相关:令h(0)=1,h(1)=1: 1.catalan数满足递推式: h(n)=

FZU Problem 2168 防守阵地 I

http://acm.fzu.edu.cn/problem.php?pid=2168 题目大意: 给定n个数和m,要求从n个数中选择连续的m个,使得a[i]*1+a[i+1]*2+--a[i+m]*m最大 思路: 常规思路是以每个数开始,枚举m个,但是这样会TLE. 可以有O(n)的算法. 例如样例的 n=5 m=3 五个数分别为 2 1 3 1 4 有三种连续的三个数 2 * 1 + 1 * 2 + 3* 3 = 13 1 * 1 + 3 * 2 + 1 * 3= 10 3 * 1 + 1 *

FZU Problem 2169 shadow

http://acm.fzu.edu.cn/problem.php?pid=2169 题目大意: S王国有N个城市,有N-1条道路.王都为编号1的城市.叛军驻扎在许多城市.除了王都外有K个城市有军队,这K支军队要向王都进军,并且消灭沿途经过的城市中的叛军.每支军队只能沿着道路走,并且是其所在城市与王都之间的最短路线走.问能够消灭多少叛军? 思路: 有两种方法. 注意到题目只有N-1条边.是一颗树. 我想到的是对编号为1的结点(也就是王都,作为跟结点)进行DFS,一直遍历到树叶为止.沿途若发现有军