标签:namespace sts max miss title stream 概率 log math
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 131 Accepted Submission(s):
50
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> #include<string> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> using namespace std; typedef long long ll; const int N_MAX = 1000000000 + 2,INF= 1000000007; int N; string s; vector<pair<int,int> >loop;//圈的大小<->圈的个数 ll gcd(ll a,ll b) { if (b == 0)return a; return gcd(b, a%b); } ll lcm(ll a,ll b) { return a / gcd(a, b)*b; } void cal_loop() { loop.clear(); int change[26],vis[26]; memset(vis,0,sizeof(vis)); for (int i = 0; i < s.size();i++) { change[i] = s[i] - ‘a‘; } map<int, int>m; for (int i = 0; i < 26;i++) { if (vis[i])continue; vis[i] = true; int num = 1; int k = change[i];//k代表不断变化的字母 while (i != k) { vis[k] = true; num++;//该圈的元素个数加1 k = change[k];//!!!!!顺序 } m[num]++; } for (map<int, int>::iterator it = m.begin(); it != m.end();it++) { loop.push_back(*it); } } ll mod_pow(ll x,ll n) {//快速幂运算 ll res = 1; while (n>0) { if (n & 1)res = res*x%INF; x = x*x%INF; n >>= 1; } return res; } ll R_C(vector<int>&loop,int N) {//容斥原理,求由这些圈中的元素组成的长度为N的字符串的数量 ll permute = 1 << (loop.size()); ll ans = 0; for (int i = 0; i < permute;i++) { int num = 0; int sum = 0; int sign=-1; for (int j = 0; j < loop.size(); j++) { if (i&(1 << j)) { num++;//num记录利用到的圈的个数 sum += loop[j];//利用到的字符的总个数 } } if (num % 2 == loop.size() % 2)//!!!!!!!! sign = 1; ans =(ans+((sign*mod_pow(sum, N))%INF+INF)%INF)%INF; } return ans; } ll solve(int N) { cal_loop(); vector<int>vec; ll ans = 0; for (int i = 0; i < (1<<loop.size());i++) { ll change_time=1; vec.clear(); for (int j = 0; j < loop.size();j++) { if (i&(1 << j)) { vec.push_back(loop[j].first*loop[j].second); change_time = lcm(change_time, loop[j].first); } } if (vec.size() > N)continue;//挑选出来的圈的个数不能超过字符串长度 ll number = R_C(vec, N); ans = (ans + change_time*number) % INF; } return ans; } int main() { int T; scanf("%d",&T); while (T--) { scanf("%d",&N); cin >> s; printf("%lld\n",solve(N)); } return 0; }
标签:namespace sts max miss title stream 概率 log math
原文地址:http://www.cnblogs.com/ZefengYao/p/6855874.html