zoukankan      html  css  js  c++  java
  • FZU 2029 买票问题 树状数组+STL

    题目链接:买票问题

    思路:优先队列维护忍耐度最低的人在队首,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
    ", 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
    ", tsum);
                        if (tsum > tendu) {
                            vis[tid] = 0;
                            update(tid, -1);
                        }
                    }
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    ControlExtensionTest(一)
    CCNotificationCenter(二)---NotificationCenterTest
    CCNotificationCenter(一)
    cocos2d-x笔记-CCGLProgram
    cocos2d-x笔记 ccTouchesBegan、ccTouchesMoved、ccTouchesEnded
    CCDictionary(转)
    ios笔记一(面向对象编程)
    cocos2d-x--精灵反转效果--CCOrbitCamera
    Android系统框架介绍
    cocos2d-x 粒子动作 setTexture
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5372584.html
Copyright © 2011-2022 走看看