标签:
题意:给一个置换,求最小循环长度对p取模的结果
思路:一个置换可以写成若干循环的乘积,最小循环长度为每个循环长度的最小公倍数。求最小公倍数对p取模的结果可以对每个数因式分解,将最小公倍数表示成质数幂的乘积形式,然后用快速幂取模,而不能一边求LCM一边取模。
由于这题数据量太大,需要用到输入挂,原理是把文件里面的东西用fread一次性读到内存。
输入挂模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
namespace IO { const static int maxn = 200 << 20; static char buf[maxn], *pbuf = buf, *End; void init() { int c = fread(buf, 1, maxn, stdin); End = buf + c; } int &readint() { static int ans; static char ch; ans = 0; while (pbuf != End && !isdigit(*pbuf)) pbuf ++; while (pbuf != End && isdigit(*pbuf)) { ans = ans * 10 + *pbuf - ‘0‘; pbuf ++; } return ans; } } |
源程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
#pragma comment(linker, "/STACK:10240000") #include <map> #include <set> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define X first #define Y second #define pb push_back #define mp make_pair #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) #define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll; typedef pair<int, int> pii; typedef unsigned long long ull; //#ifndef ONLINE_JUDGE void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);} void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R> void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1; while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T> void print(const T t){cout<<t<<endl;}template<typename F,typename...R> void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T> void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;} //#endif template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);} template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} const double PI = acos(-1.0); const int INF = 1e9 + 7; const double EPS = 1e-8; /* -------------------------------------------------------------------------------- */ const int maxn = 3e6 + 7; const unsigned int md = 3221225473; vector<int> prime; vector<vector<pii> > R; bool vis[maxn], flag[maxn]; int power[maxn], a[maxn]; void init() { for (ll i = 2; i < maxn; i ++) { if (flag[i]) continue; prime.pb(i); for (ll j = i * i; j < maxn; j += i) { flag[j] = true; } } } void add(int x) { vector<pii> buf; for (int i = 0; x > 1 && i < prime.size(); i ++) { int c = 0; while (x % prime[i] == 0) { c ++; x /= prime[i]; } if (c) buf.pb(mp(i, c)); } R.pb(buf); } unsigned int powermod(int a, int b, unsigned int md) { if (b == 0) return 1; ull buf = powermod(a, b >> 1, md); buf = buf * buf % md; if (b & 1) buf = buf * a % md; return buf; } namespace IO { const static int maxn = 200 << 20; static char buf[maxn], *pbuf = buf, *End; void init() { int c = fread(buf, 1, maxn, stdin); End = buf + c; } int &readint() { static int ans; static char ch; ans = 0; while (pbuf != End && !isdigit(*pbuf)) pbuf ++; while (pbuf != End && isdigit(*pbuf)) { ans = ans * 10 + *pbuf - ‘0‘; pbuf ++; } return ans; } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE int T, n; IO::init(); T = IO::readint(); init(); while (T --) { n = IO::readint(); for (int i = 1; i <= n; i ++) { a[i] = IO::readint(); } fillchar(vis, 0); R.clear(); for (int i = 1; i <= n; i ++) { if (vis[i] || a[i] == i) continue; int cnt = 0; for (int j = i; !vis[j]; j = a[j]) { vis[j] = true; cnt ++; } add(cnt); } fillchar(power, 0); int maxpower = 0; for (int i = 0; i < R.size(); i ++) { for (int j = 0; j < R[i].size(); j ++) { umax(power[R[i][j].X], R[i][j].Y); umax(maxpower, R[i][j].X); } } unsigned int ans = 1; for (int i = 0; i <= maxpower; i ++) { ans = ((ull)ans * powermod(prime[i], power[i], md)) % md; } printf("%u\n", ans); } return 0; } |
[hdu5392 Infoplane in Tina Town]置换的最小循环长度,最小公倍数取模,输入挂
标签:
原文地址:http://www.cnblogs.com/jklongint/p/4734253.html