返回顶部

Lyft Level 5 Challenge 2018 - Elimination Round C. Permutation Game (博弈,dp)

  • 题意:有一个长度为\(n\)的排列,A和B进行博弈,每次操作可以在当前数\(a_i\)的基础移动到另一个位置,但是新的位置上的数\(a_j>a_i\)\(|i-j|\) mod \(a_i\)=0.A先手,问你所有\([1,n]\)的情况中,A从\(i\)开始的结局情况.

  • 题解:因为\(a_i\)每次只能移动到比自己大的数的位置,所以我们可以从\(n\)开始倒着枚举,那么所有比\(a_i\)大的数的情况都是确定的,用pair存值和位置,排个序,每次跑\(\frac{n}{n},\frac{n}{n-1},...,\frac{n}{1}\).根据调和级数,复杂度为\(O(nlogn)\).

  • 代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
     
     
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	int n;
    	cin>>n;
    	vector<PII> p(n+1);
    	vector<int> res(n+1);
     
    	rep(i,1,n){
    		cin>>p[i].fi;
    		p[i].se=i;
    	}
     
    	sort(p.begin()+1,p.end(),greater<PII>());
     
    	rep(i,1,n){
    		if(p[i].se+p[i].fi>n && p[i].se-p[i].fi<1){
    			res[p[i].se]=2;
    			continue;
    		}
    		rep(j,1,n){
    			int cur=p[i].se+j*p[i].fi;
    			if(cur>n) break;
    			if(res[cur]){
    				if(res[cur]==2){
    					res[p[i].se]=1;
    					break;
    				} 
    			}
    		}
    		rep(j,1,n){
    			int cur=p[i].se-j*p[i].fi;
    			if(cur<1) break;
    			if(res[cur]){
    				if(res[cur]==2){
    					res[p[i].se]=1;
    					break;
    				}
    			}
    		}
    		if(res[p[i].se]!=1) res[p[i].se]=2;
    	}
     
    	rep(i,1,n){
    		if(res[i]==1) cout<<'A';
    		else cout<<'B';
    	}
     
        return 0;
    }
    
posted @ 2021-05-01 15:49  Rayotaku  阅读(43)  评论(0编辑  收藏  举报