[hdu5392 Infoplane in Tina Town]置换的最小循环长度,最小公倍数取模,输入挂

题意:给一个置换,求最小循环长度对p取模的结果

思路:一个置换可以写成若干循环的乘积,最小循环长度为每个循环长度的最小公倍数。求最小公倍数对p取模的结果可以对每个数因式分解,将最小公倍数表示成质数幂的乘积形式,然后用快速幂取模,而不能一边求LCM一边取模。

由于这题数据量太大,需要用到输入挂,原理是把文件里面的东西用fread一次性读到内存。

输入挂模板:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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;
        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
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jklongint/p/4734253.html