zoukankan      html  css  js  c++  java
  • LOJ#541. 「LibreOJ NOIP Round #1」七曜圣贤

    有一辆车一开始装了编号0-a的奶茶,现有m次操作,每次操作Pi在[-1,b),若Pi为一个未出现过编号的奶茶,就把他买了并装上车;若Pi为一个在车上的奶茶,则把他丢下车;否则,此次操作为捡起最早丢下去的奶茶,若没有符合要求的奶茶则忽略此次操作。对每次操作需要在线询问:操作进行后,不在车上的奶茶的最小编号。m<=1e6,b<=2m,a<=m,数据组数T<=50。

    方法一:nlogn暴力,什么树状数组优先队列尽管上。。

    方法二:不在车上的最小编号,其实就是还没买的最小和丢下车的最小,还没买的最小可以一个队列搞定,那丢下车的呢?由于先丢下车的会先捡起来,也就是先退出答案考虑的范围,如果某个奶茶又是早丢下车的,编号又不如一个后丢下车的小,那在这个奶茶退出答案前的整个过程他都不会再被当做答案。所以对丢下车的,用一个普通队列记顺序,一个单调队列记答案即可。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<math.h>
      5 #include<algorithm>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 namespace IO{
     10     int c;
     11     unsigned int seed;
     12     unsigned int randnum(){
     13         seed^=seed<<13;
     14         seed^=seed>>17;
     15         seed^=seed<<5;
     16         return seed;
     17     }
     18 
     19     inline int read(int &x){scanf("%d",&x);return x;}
     20     inline void init_case(int &m,int &a,int &b,int &d,int p[]){
     21         scanf("%d%u%d%d%d%d",&m,&seed,&a,&b,&c,&d);
     22         for(int i=1;i<=m;i++){
     23             if(randnum()%c==0)p[i]=-1;
     24             else p[i]=randnum()%b;
     25         }
     26     }
     27 
     28     inline void update_ans(unsigned int &ans_sum,unsigned int cur_ans,int no){
     29         const static unsigned int mod=998244353;
     30         ans_sum^=(long long)no*(no+7)%mod*cur_ans%mod;
     31     }
     32 }
     33 using IO::read;
     34 using IO::init_case;
     35 using IO::update_ans;
     36 /*
     37 一开始请调用read(T)读入数据组数T
     38 接下来每组数据开始时请调用init_case(m,a,b,d,p)读入m,a,b,d,p[]
     39 每组数据开始时请用一个初始化为0的32位无符号整形变量ans_sum存储答案,然后对于每个i,
     40 用32位无符号整形变量cur_ans存储第i次答案,并调用update_ans(ans_sum,cur_ans,i)更新。最后输出ans_sum即可。
     41 */
     42 
     43 //示例代码:
     44 int n;
     45 #define maxn 2000011
     46 unsigned int qin[maxn],headin,tailin,qout[maxn],headout,tailout,q[maxn],head,tail;bool buy[maxn],have[maxn];
     47 int main()
     48 {
     49     static int p[2000005];
     50     int T;read(T);
     51     int m,a,b,d;
     52     while(T--)
     53     {
     54         unsigned int ans_sum=0,cur_ans=0;
     55         init_case(m,a,b,d,p);
     56         
     57         memset(buy,0,sizeof(buy));
     58         memset(have,0,sizeof(have));
     59         headin=tailin=headout=tailout=head=tail=0;
     60         for (int i=0;i<=a;i++) buy[i]=have[i]=1;
     61         for (int i=a+1;i<=2*m;i++) qin[tailin++]=i;
     62         
     63         for(int i=1;i<=m;i++)
     64         {
     65             if (d)
     66             {
     67                 if (p[i]==-1) cur_ans=0;
     68                 else if (!buy[p[i]])
     69                 {
     70                     buy[p[i]]=have[p[i]]=1;
     71                     while (buy[qin[headin]]) headin++;
     72                     cur_ans=qin[headin];
     73                     if (headout<tailout) cur_ans=min(cur_ans,qout[headout]);
     74                 }
     75                 else cur_ans=0;
     76             }
     77             //d=1 hai mei pan duan 
     78             else if (p[i]<0)
     79             {
     80                 if (head==tail) cur_ans=0;
     81                 else
     82                 {
     83                     have[q[head]]=1;
     84                     if (qout[headout]==q[head]) headout++;
     85                     head++;
     86                     cur_ans=qin[headin];
     87                     if (headout<tailout) cur_ans=min(cur_ans,qout[headout]);
     88                 }
     89             }
     90             else if (!buy[p[i]])
     91             {
     92                 buy[p[i]]=have[p[i]]=1;
     93                 while (buy[qin[headin]]) headin++;
     94                 cur_ans=qin[headin];
     95                 if (headout<tailout) cur_ans=min(cur_ans,qout[headout]);
     96             }
     97             else if (have[p[i]])
     98             {
     99                 have[p[i]]=0;
    100                 q[tail++]=p[i];
    101                 while (headout<tailout && qout[tailout-1]>p[i]) tailout--;
    102                 qout[tailout++]=p[i];
    103                 cur_ans=min(qin[headin],qout[headout]);
    104             }
    105             else
    106             {
    107                 if (head==tail) cur_ans=0;
    108                 else
    109                 {
    110                     have[q[head]]=1;
    111                     if (qout[headout]==q[head]) headout++;
    112                     head++;
    113                     cur_ans=qin[headin];
    114                     if (headout<tailout) cur_ans=min(cur_ans,qout[headout]);
    115                 }
    116             }
    117             update_ans(ans_sum,cur_ans,i);
    118         }
    119         printf("%u
    ",ans_sum);
    120     }
    121     return 0;
    122 }
    View Code

    这题的读入有点新颖。。

  • 相关阅读:
    BZOJ 3625: [Codeforces Round #250]小朋友和二叉树
    HDU 2069 Coin Change
    HDU 1709 The Balance
    HDU 1398 Square Coins
    HDU 1171 Big Event in HDU
    HDU 1085 Holding Bin-Laden Captive!
    BZOJ 3167: [Heoi2013]Sao
    BZOJ 1408: [Noi2002]Robot
    BZOJ 3163: [Heoi2013]Eden的新背包问题
    【Tsinsen-A1486】树(王康宁) 点分治 + Trie
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7791464.html
Copyright © 2011-2022 走看看