标签:
题意:点击打开链接
把m,k表示成d进制,对于这个递归函数,每一次递归都是一次每一位数字的置换,求出每一位的循环节,最终f(m)=k就是要每一位都相等,即解同余方程组。
代码:
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include<climits> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <numeric> #include <iomanip> #include <bitset> #include <list> #include <stdexcept> #include <functional> #include <utility> #include <ctime> using namespace std; #define PB push_back #define MP make_pair #define REP(i,x,n) for(int i=x;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define FORD(i,h,l) for(int i=(h);i>=(l);--i) #define SZ(X) ((int)(X).size()) #define ALL(X) (X).begin(), (X).end() #define RI(X) scanf("%d", &(X)) #define RII(X, Y) scanf("%d%d", &(X), &(Y)) #define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z)) #define DRI(X) int (X); scanf("%d", &X) #define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y) #define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z) #define OI(X) printf("%d",X); #define RS(X) scanf("%s", (X)) #define MS0(X) memset((X), 0, sizeof((X))) #define MS1(X) memset((X), -1, sizeof((X))) #define LEN(X) strlen(X) #define F first #define S second #define Swap(a, b) (a ^= b, b ^= a, a ^= b) #define Dpoint strcut node{int x,y} #define cmpd int cmp(const int &a,const int &b){return a>b;} /*#ifdef HOME freopen("in.txt","r",stdin); #endif*/ const int MOD = 1e9+7; typedef vector<int> VI; typedef vector<string> VS; typedef vector<double> VD; typedef long long LL; typedef pair<int,int> PII; //#define HOME int Scan() { int res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } /*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> using namespace std; const int MAXN = 410; struct bign { int len, s[MAXN]; bign () { memset(s, 0, sizeof(s)); len = 1; } bign (int num) { *this = num; } bign (const char *num) { *this = num; } bign operator = (const int num) { char s[MAXN]; sprintf(s, "%d", num); *this = s; return *this; } bign operator = (const char *num) { for(int i = 0; num[i] == '0'; num++) ; //去前导0 len = strlen(num); for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0'; return *this; } bign operator + (const bign &b) const //+ { bign c; c.len = 0; for(int i = 0, g = 0; g || i < max(len, b.len); i++) { int x = g; if(i < len) x += s[i]; if(i < b.len) x += b.s[i]; c.s[c.len++] = x % 10; g = x / 10; } return c; } bign operator += (const bign &b) { *this = *this + b; return *this; } void clean() { while(len > 1 && !s[len-1]) len--; } bign operator * (const bign &b) //* { bign c; c.len = len + b.len; for(int i = 0; i < len; i++) { for(int j = 0; j < b.len; j++) { c.s[i+j] += s[i] * b.s[j]; } } for(int i = 0; i < c.len; i++) { c.s[i+1] += c.s[i]/10; c.s[i] %= 10; } c.clean(); return c; } bign operator *= (const bign &b) { *this = *this * b; return *this; } bign operator - (const bign &b) { bign c; c.len = 0; for(int i = 0, g = 0; i < len; i++) { int x = s[i] - g; if(i < b.len) x -= b.s[i]; if(x >= 0) g = 0; else { g = 1; x += 10; } c.s[c.len++] = x; } c.clean(); return c; } bign operator -= (const bign &b) { *this = *this - b; return *this; } bign operator / (const bign &b) { bign c, f = 0; for(int i = len-1; i >= 0; i--) { f = f*10; f.s[0] = s[i]; while(f >= b) { f -= b; c.s[i]++; } } c.len = len; c.clean(); return c; } bign operator /= (const bign &b) { *this = *this / b; return *this; } bign operator % (const bign &b) { bign r = *this / b; r = *this - r*b; return r; } bign operator %= (const bign &b) { *this = *this % b; return *this; } bool operator < (const bign &b) { if(len != b.len) return len < b.len; for(int i = len-1; i >= 0; i--) { if(s[i] != b.s[i]) return s[i] < b.s[i]; } return false; } bool operator > (const bign &b) { if(len != b.len) return len > b.len; for(int i = len-1; i >= 0; i--) { if(s[i] != b.s[i]) return s[i] > b.s[i]; } return false; } bool operator == (const bign &b) { return !(*this > b) && !(*this < b); } bool operator != (const bign &b) { return !(*this == b); } bool operator <= (const bign &b) { return *this < b || *this == b; } bool operator >= (const bign &b) { return *this > b || *this == b; } string str() const { string res = ""; for(int i = 0; i < len; i++) res = char(s[i]+'0') + res; return res; } }; istream& operator >> (istream &in, bign &x) { string s; in >> s; x = s.c_str(); return in; } ostream& operator << (ostream &out, const bign &x) { out << x.str(); return out; } int a[105],b[105]; int ansm[1000],ansk[1000]; int vis[105]; int vis2[105]; void ex_gcd(LL a, LL b, LL &d, LL &x, LL &y) { if (!b) {d = a, x = 1, y = 0;} else { ex_gcd(b, a % b, d, y, x); y -= x * (a / b); } } LL ex_crt(LL *m, LL *r, int n,int lena,int cato) { LL M = lena, R = cato, x, y, d; for (int i = 1; i < n; ++i) { ex_gcd(M, m[i], d, x, y); if ((r[i] - R) % d) return -1; x = (r[i] - R) / d * x % (m[i] / d); R += x * M; M = M / d * m[i]; R %= M; } return R > 0 ? R : R + M; } int main() {int d; while(RI(d)!=EOF) { if(d==-1) break; MS0(a); MS0(b); MS0(ansm); MS0(ansk); REP(i,1,d) RI(a[i]); REP(i,0,d) RI(b[i]); bign m,k; cin>>m; cin>>k; bign tmp(0); tmp.len=1; bign r; int p=0; MS0(ansm); MS0(ansk); //cout<<m<<k<<endl; while(m!=tmp) {//cout<<m<<endl; r=m%bign(d); m=m/bign(d); for(int i=r.len-1;i>=0;i--) ansm[p]=ansm[p]*10+r.s[i]; p++; } for(int i=0;i<p/2;i++) swap(ansm[i],ansm[p-1-i]); int q=0; while(k!=tmp) { r=k%bign(d); k=k/bign(d); for(int i=r.len-1;i>=0;i--) ansk[q]=ansk[q]*10+r.s[i]; q++; } for(int i=0;i<q/2;i++) swap(ansk[i],ansk[q-1-i]); if(p!=q) { printf("NO\n"); continue; } MS0(vis); int lena=0; int now=ansm[0]; int ok=0; int cato=0; if(now==ansk[0]) ok=1; vis[now]=1; lena++; while(!vis[a[now]]) { lena++; now=a[now]; vis[now]=1; if(!ok) cato++; if(now==ansk[0]) ok=1; } long long int lenb[105]; long long int cto[105]; MS0(vis2); int okb[105]; for(int i=1;i<p;i++) { MS0(vis2); lenb[i]=0; now=ansm[i]; okb[i]=0; cto[i]=0; if(now==ansk[i]) okb[i]=1; vis2[now]=1; lenb[i]++; while(!vis2[b[now]]) {lenb[i]++; now=b[now]; vis2[now]=1; if(!okb[i]) cto[i]++; if(now==ansk[i]) okb[i]=1; } } if(!ok) { printf("NO\n"); continue; } int tok=1; REP(i,1,p) if(!okb[i]) { tok=0; printf("NO\n"); break; } if(!tok) continue; long long int res=ex_crt(lenb,cto,p,lena,cato); if(res==-1) { printf("NO\n"); continue; } printf("%I64d\n",res); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013840081/article/details/47158767