CF 1033C Permutation Jeu tri topologique +

Signification des questions: une gamme complète, alice peut commencer à partir d'un certain nombre, allez à j des conditions i sont les suivants:

un [j]> a [i], et de se conformer de i à j | ij |% a [i] = 0, s'il y a un gagnant alice le numéro de police, la sortie B ou A

Des idées, le tri topologique + théorie des jeux (cette question m'a laissé faire trop perdu seulement), associé au nombre et plusieurs autres connexions avec le tableau ci-contre, si au premier degré 0, c.-à-alice sélectionner ce point, l'autre côté ne peut pas autour d'un autre point gagnant Alice, les coordonnées sont stockées dans un tableau, ils sont alors l'analyse de bord connecté, vous pouvez déterminer qui gagne, le code pour voir les détails.

#include <iostream> 
#include <vector> 
#include <cmath> 
#include < set > 
#include <map> 
#include <cstring> 
#include <file> 
#include <stack> 
#include <algorithme>
 en utilisant l'  espace de noms std;
#define ll long long
 #define N 200005
 #define fori for (i = 0; i <n; i ++)
 #define fori1 for (i = 1; i <= n; i ++) 
ll a [N]; 
vecteur <ll> G [N];
carbonisation de [N]; 
degré ll [N]; 
ll q [N];
vides dfs () 
{ 

} 
int main () 
{ 
    
    ll i, j, k; 
    ll n; 

    cin >> n;
    pour (i = 1 ; i <= n; i ++ ) 
        cin >> a [i];
    pour (i = 1 ; i <= n; i ++ ) 
    { 
        pour (j = i + a [i]; j <= n; j + = a [i])
             si (a [j]> a [i]) G [j] .push_back (i), le degré [i] ++; // 邻接表,拓扑重要一环节
        pour (j = i - a [i]; j> = 1 , j - = a [i])
             si(A [J]> A [I]) G [J] .push_back (I), Degré [I] ++ ; 
    }     
    Memset (VIS, - 1. , La sizeof (VIS)); 
    LL L = . 1 , R & lt = 0 ;
     pour (i = 1. , I <= N-; I ++ )
         IF q [R & lt ++] = I, VIS [I] = (degré [I]!) 0 ; // en 0 degré, le réseau en q, le point nécessairement gagnant Alice (sélectionner le point ne peut pas prendre) 
    le tout (l <= R & lt) {
         int U = Q [l ++ ];
         pour (i = 0 ; I <G [U] .size (); I ++) / / ce point a une relation sera adversaire saigné alice mettra ce point
        {
             Int v = G [U] [I];
             SI (VIS [v] == - . 1 ) { // Si vis [u] est alice victoire, l'adversaire gagne le point v, ou entrée concurrent 
                IF (vis [u] == 0 ) VIS [V] = 1. ;
                 l'autre VIS [V] = 0 ; 
            } 
            else 
                IF (VIS [U] == 0 ) VIS [V] = 1. ; 
            degré [V] -; // pénétration Sauvegarder aller, si le degré est 0, le point peut être une victoire de points 
            sI Q [R & lt ++] = (degré [V]!) V; 
        } 
    } 
    pour (I = . 1 , I <= n, I ++)
         Si (vis [i]) Cout << ' A ' ;
        autre Cout << ' B ' ; 

}

 

Je suppose que tu aimes

Origine www.cnblogs.com/ch-hui/p/12642871.html
conseillé
Classement