• 玲珑杯 Round #5 Problem E Tetration (枚举 + 欧拉公式)


    题目链接  Tetration

    题意  给定一个排列  现在可以任意调整这个排列的顺序

       求$a_{1}^{a_{2}^{a_{3}^{...^{a_{n}}}}}$对$p$取模的最小值

     

    直接枚举$a$的每一个排列,然后计算取最小值即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    const int N = 10;
    
    int n;
    int T;
    int f[N];
    LL a[N], c[N];
    LL m;
    LL ans;
    map <LL, LL> mp;
    
    LL phi(LL n){
    	if (mp.count(n)) return mp[n];
    	LL ans = n, z = n;
    	for (LL i = 2; i * i <= n; ++i){
    		if (n % i == 0){
    			ans -= ans / i;
    			while (n % i == 0) n /= i;
    		}
    	}
    
    	if (n > 1) ans -= ans / n;
    	return mp[z] = ans;
    }
    
    LL Pow(LL a, LL b, LL mod){
    	LL ret = 1;
    	LL fl  = a >= mod;
    	for (; b; b >>= 1){
    		if (b & 1){
    			ret *= a;
    			if (ret >= mod) fl = 1, ret %= mod;
    		}
    
    		a *= a;
    		if (a >= mod) a %= mod, fl = 1;
    	}
    
    	return ret + fl * mod;
    }
    
    LL solve(int l, int r, LL mod){
    	if (l == r) return c[l];
    	if (mod == 1) return 1;
    	return Pow(c[l], solve(l + 1, r, phi(mod)), mod);
    }
    
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%lld", &n, &m);
    		ans = 1e18;
    		rep(i, 1, n) scanf("%lld", a + i);
    		rep(i, 1, n) f[i] = i;
    		do{
    			rep(i, 1, n) c[i] = a[f[i]];
    			ans = min(ans, solve(1, n, m) % m);
    		}
    		while (next_permutation(f + 1, f + n + 1));
    		printf("%lld
    ", ans);
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    linux内核启动汇编部分详解
    linux内核zImage详解
    Linux内核zImage怎么来的?
    Linux内核编译make做了什么?
    关于makefile的几点经验
    note
    tmp0000
    tmp
    SSL学习与总结
    C++学习笔记
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8387662.html
Copyright © 2020-2023  润新知