BZOJ 2976: [Poi2002]出圈游戏 Excrt+set

人数很少,可以直接用 $set$ 来模拟人的情况. 

然后就能得到若干个方程,用 $excrt$ 进行合并即可. 

#include <set>    
#include <cmath> 
#include <cstdio>  
#include <algorithm>   
#define N 23  
#define ll long long  
#define setIO(s) freopen(s".in","r",stdin)   
using namespace std;   
set<int>S; 
set<int>::iterator it;   
int edges,size,n;    
int ou[N],A[N]; 
ll arr[N],brr[N];      
bool cmp(int i,int j) 
{
    return ou[i]<ou[j]; 
}   
ll exgcd(ll a,ll b,ll &x,ll &y) 
{
    if(!b) 
    {
        x=1,y=0; 
        return a; 
    } 
    ll gcd=exgcd(b,a%b,x,y),tmp=x;      
    x=y,y=tmp-a/b*y;          
    return gcd;     
}   
ll Excrt() 
{
    int i,j; 
    ll ans=arr[1],M=brr[1];                
    for(i=2;i<=n;++i) 
    {    
        ll a=M,b=brr[i],c=arr[i]-ans,x,y; 
        ll gcd=exgcd(a,b,x,y);   
        if(c%gcd) 
        {      
            return -1;  
        }  
        b=abs(b/gcd);    
        x=x*(c/gcd),x=(x%b+b)%b;                
        ans=ans+M*x;       
        M*=brr[i]/__gcd(brr[i],M);       
        ans=(ans%M+M)%M;        
    } 
    return ans;    
}
int main() 
{
    int i,j; 
    // setIO("input");             
    scanf("%d",&n); 
    for(i=1;i<=n;++i) 
    {
        scanf("%d",&ou[i]),A[i]=i;
    } 
    for(i=1;i<=n;++i) S.insert(i);    
    sort(A+1,A+1+n,cmp);         
    arr[1]=A[1]-1; 
    brr[1]=n;                           
    for(i=2;i<=n;++i)  
    {  
        int cnt=0,flag=0;     
        for(it=S.begin();;it++) 
        {  
            if((*it)==A[i-1]) break;         
        }
        cnt=-1;    
        for(it++;it!=S.end();it++) 
        {
            ++cnt;        
            if((*it)==A[i]) 
            {
                flag=1;  
                break; 
            }
        } 
        if(!flag) 
        {
            for(it=S.begin();it!=S.end();it++) 
            {
                ++cnt;      
                if((*it)==A[i]) 
                {
                    break; 
                }
            }
        } 
        S.erase(A[i-1]);   
        brr[i]=brr[i-1]-1, arr[i]=cnt;  
    }                         
    ll p=Excrt();      
    if(p!=-1) printf("%lld
",p+1); 
    else printf("NIE
"); 
    return 0; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11509990.html