LibreOJ #541. 「LibreOJ NOIP Round #1」七曜圣贤(单调队列)

  被以前自己瞎YY的东西坑了T T...单调队列的确是可以维护这种操作的....

  显然这题可以转化成维护不在车上的东西的最小值, 支持插入和删去最早出现的值,然后就可以用单调队列了T T

#include
#include
#include
#include
#include
#define ll long long
#define uint unsigned int
using namespace std;
const int maxn=20000010, inf=1e9;
int n, m, a, b, d, T, l, r, L, R, up, fir, firans;
int p[maxn], h[maxn], q[maxn];
uint ans_sum, cur_ans;    
bool fly[maxn], car[maxn];
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;
inline void qpush(int x)
{
    while(L<=R && q[R]>=x) R--;
    q[++R]=x;
}
inline int min(int a, int b){return aa:b;}
int main()
{
    read(T);
    while(T--)
    {
        init_case(m, a, b, d, p);
        up=max(a+1, b);
        memset(fly, 0, (up+1));
        memset(car, 0, (up+1));
        L=1; R=0; l=1; r=0; ans_sum=0; firans=a+1;
        for(int i=0;i<=a;i++) car[i]=1;
        for(int i=1;i<=m;i++)
        {
            cur_ans=0;
            if(p[i]==-1) 
            {
                if(l<=r && !d) 
                {
                    if(L<=R && q[L]==h[l]) L++;
                    fly[h[l++]]=0, cur_ans=(L<=R)?min(firans, q[L]):firans;
                }
            }
            else
            {
                if(!car[p[i]])
                {
                    car[p[i]]=1;
                    while(car[firans]) firans++;
                    cur_ans=(L<=R)?min(firans, q[L]):firans;
                }
                else if(car[p[i]] && !fly[p[i]] && !d) fly[p[i]]=1, h[++r]=p[i], qpush(p[i]), cur_ans=(L<=R)?min(firans, q[L]):firans;
                else if(l<=r && !d)
                {
                    if(L<=R && q[L]==h[l]) L++;
                    fly[h[l++]]=0, cur_ans=(L<=R)?min(firans, q[L]):firans;
                }
            }    
            update_ans(ans_sum, cur_ans, i);
        }
        printf("%u\n", ans_sum);
    }
    return 0;
}
View Code

转载于:https://www.cnblogs.com/Sakits/p/7791475.html

你可能感兴趣的:(LibreOJ #541. 「LibreOJ NOIP Round #1」七曜圣贤(单调队列))