Luogu 9月月赛B

  显然1的位置确定了整个矩阵,每一段连续的数即是对该位置的限制。化一下式子可以发现是一段区间或一段区间的补集,最后要求的是他们的交。看起来不太好求,于是转为求补集的并,那么排个序就完了。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
ll read()
{
    ll x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
ll n,m,ans,mx,mn,pos;
int s,q,cnt=0;
struct data
{
    ll x,y;
    bool operator <(const data&a) const
    {
        return x<a.x;
    }
}p[1000010];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    n=read(),m=read(),s=read(),q=read();
    while (s--)
    {
        ll a=(m+read()-2)%m,b=(m+read()-2)%m;
        if (a<b) cnt++,p[cnt].x=m-b,p[cnt].y=m-a-1;
        else if (a>b)
        {
            cnt++,p[cnt].x=0,p[cnt].y=m-a-1;
            cnt++,p[cnt].x=m-b,p[cnt].y=m-1;
        }
    }
    cnt++,p[cnt].x=m,p[cnt].y=m;
    sort(p+1,p+cnt+1);
    ll x=-1;pos=-1;
    for (int i=1;i<=cnt;i++)
    if (p[i].x<=x+1) x=max(x,p[i].y);
    else if (p[i].x-x==2&&(pos==-1)) pos=x+1,x=p[i].y;
    else {cout<<"Uncertain!";return 0;}
    if (pos==-1) {cout<<"Impossible!";return 0;}
    if (pos==0) pos=m;
    while (q--)
    {
        ll x=read();
        if ((x+pos-2)/m+1<=n)
        ans^=(x+pos-2)/m+1^(x+pos-2)%m+1;
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Gloid/p/9656915.html