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

    【题意】一开始车上有编号为0~a的红茶,过程中出现的红茶编号仅有[0,b),有三种操作:

    1.买进编号未在车上出现过的红茶。

    2.丢掉车上指定编号的红茶。

    3.将最早丢出去的红茶捡回来。

    每次操作后求编号最小的不在车上的红茶。

    【算法】单调队列

    【题解】本题最重要的性质在于早丢早捡

    因此,当进行丢掉编号为x的红茶这一操作时,如果编号>x的红茶早丢,那么也一定早捡,所以这些红茶没有贡献。

    所以用单调队列维护所有有效的红茶,那么捡回来的时候判断是否队头,每次答案就是min(队头,maxs+1),maxs是当前已买过的红茶编号。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    namespace IO{
        int c;
        unsigned int seed;
        unsigned int randnum(){
            seed^=seed<<13;
            seed^=seed>>17;
            seed^=seed<<5;
            return seed;
        }
    
        inline int read(int &x){scanf("%d",&x);return x;}
        inline void init_case(int &m,int &a,int &b,int &d,int p[]){
            scanf("%d%u%d%d%d%d",&m,&seed,&a,&b,&c,&d);
            for(int i=1;i<=m;i++){
                if(randnum()%c==0)p[i]=-1;
                else p[i]=randnum()%b;
            }
        }
    
        inline void update_ans(unsigned int &ans_sum,unsigned int cur_ans,int no){
            const static unsigned int mod=998244353;
            ans_sum^=(long long)no*(no+7)%mod*cur_ans%mod;
        }
    }
    using IO::read;
    using IO::init_case;
    using IO::update_ans;
    const int maxn=2000010;
    int p[maxn];
    bool A[maxn],B[maxn];
    int q[maxn],head,tail;
    queue<int>Q;
    void ins(int x){
        while(head<tail&&q[tail-1]>x)tail--;
        q[tail++]=x;
    }
    int main(){
        int T;read(T);
        int m,a,b,d;
        while(T--){
            unsigned int ans_sum=0,cur_ans=0;
            init_case(m,a,b,d,p);
            memset(A,0,sizeof(A));
            memset(B,0,sizeof(B));
            head=0;tail=0;
            for(int i=0;i<=a;i++)A[i]=B[i]=1;
            while(!Q.empty())Q.pop();
            int ans=a+1,maxs=a;
            for(int i=1;i<=m;i++){
                bool ok=1;
                if(p[i]==-1){
                    if(Q.empty()||d)ok=0;else{
                        int x=Q.front();
                        A[x]=1;Q.pop();
                        if(head<tail&&q[head]==x)head++;
                        if(head<tail)ans=min(maxs+1,q[head]);else ans=maxs+1;
                    }
                }
                else if(!B[p[i]]){
                    A[p[i]]=B[p[i]]=1;
                    while(B[maxs+1]){
                        if(ans==maxs+1)ans++;
                        maxs++;
                    }
                    if(head<tail&&maxs+1>=q[head])ans=q[head];
                }
                else if(A[p[i]]){
                    if(d)ok=0;else{
                        Q.push(p[i]);A[p[i]]=0;
                        ins(p[i]);
                        ans=min(ans,q[head]);
                    }
                }
                else{
                    if(Q.empty()||d)ok=0;else{
                        int x=Q.front();
                        A[x]=1;Q.pop();
                        if(head<tail&&q[head]==x)head++;
                        if(head<tail)ans=min(maxs+1,q[head]);else ans=maxs+1;
                    }
                }
                if(!ok)cur_ans=0;else cur_ans=ans;
                update_ans(ans_sum,cur_ans,i);
            }
            printf("%u
    ",ans_sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java 从入门到进阶之路(五)
    Java 从入门到进阶之路(四)
    Java 从入门到进阶之路(三)
    Java 从入门到进阶之路(二)
    Java 从入门到进阶之路(一)
    调用百度翻译 API 来翻译网站信息
    jquery.i18n 网站呈现各国语言
    VUE+Element UI实现简单的表格行内编辑效果
    Python 爬虫从入门到进阶之路(十八)
    Python 爬虫从入门到进阶之路(十七)
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7791471.html
Copyright © 2011-2022 走看看