Codeforces #669 Div2 E. Little Artem and Time Machine(离线、优先队列)

题目链接:
Codeforces #669 Div2 E. Little Artem and Time Machine
题意:
定义一个元素重复集合multiset,然后在不同的时间对集合添加和删除元素操作,需要输出在不同的查询时间集合中元素出现的次数。
分析;
离线处理。首先将查询按照查询时间排序,然后检查所有在这个查询的输入之前的操作,
如果操作时间小于查询时间那么就执行,否则就存进一个优先队列中,等到时间够了再执行。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
using namespace std;
const int MAX_N=100010;

int n,total1,total2;

struct Query{
    int id,step,data,ans;
}query[MAX_N];

struct Oper{
    int id,step,data,flag;
    //bool operator < (const Oper& rhs) const{
    //  return step > rhs.step;
    //}
};
Oper oper[MAX_N];

bool cmp1(struct Query a,struct Query b)
{
    return a.stepbool cmp2(struct Query a,struct Query b)
{
    return a.id < b.id;
}

struct cmp { //cmp比较函数,a
    bool operator () (const Oper& a,const Oper& b) const {
        //因为优先队列是“大”的元素先出来,我们需要的是step小的先出来,只能定义a.step>b.step时a
        return a.step > b.step;
    }
};

int main()
{
    freopen("Ein.txt","r",stdin);
    while(~scanf("%d",&n)){
        map<int,int> mp;
        total1=total2=0;
        for(int i=0;iint t,a,b;
            scanf("%d%d%d",&t,&a,&b);
            if(t==1||t==2){
                oper[total1].flag=(t==1?1:0); // 1.添加  0.删除
                oper[total1].step=a;
                oper[total1].data=b;
                oper[total1].id=i;
                total1++;
            } else {
                query[total2].step=a;
                query[total2].data=b;
                query[total2].id=i;
                total2++;
            }
        }

        sort(query,query+total2,cmp1); //按照查询的时间排序
        priority_queue < Oper,vector, cmp>  que; //定义操作时间在前的先出的优先队列

        for(int i=0,j=0;jwhile(i//将所有在这次查询的输入之前的操作执行
                int step=oper[i].step;
                if(step>query[j].step){ //如果这次操作是在这次查询之后执行的
                    que.push(oper[i]);  //先存进优先队列中
                }else {
                    if(oper[i].flag==1) mp[oper[i].data]++;  //添加元素
                    else mp[oper[i].data]--; //删除元素
                }
                i++;
            }
            while(1){ //查找之前操作中的所有操作时间在查询时间之前的操作
                if(que.empty()) break;
                Oper tmp=que.top();
                //printf("tmp.step=%d \n",tmp.step);
                if(tmp.step < query[j].step){
                    que.pop();
                    if(tmp.flag==1) mp[tmp.data]++;
                    else mp[tmp.data]--;
                }else {
                    break;
                }
            }
            query[j].ans=mp[query[j].data];
        }

        sort(query,query+total2,cmp2); //按照查询的输入顺序排序
        for(int i=0;iprintf("%d\n",query[i].ans);
        }
    }

    return 0;
}

你可能感兴趣的:(Codeforces)