CF # 369 D2 DE
Posted chenjunjie1994
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF # 369 D2 DE相关的知识,希望对你有一定的参考价值。
D,只要抓住每个点只有一个出度,那么图就能分成几个部分,而且可以发现,一个部分最多一个环。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define LL long long const int MAXN = 200005; const int MOD = 1e9 + 7; int nt[MAXN]; int two[MAXN]; int part[MAXN]; int visit[MAXN]; int acyc[MAXN], acyn[MAXN]; int n, cyc, cyn; void dfs2(int u){ visit[u] = 3; acyc[cyc] ++; if(visit[nt[u]] == 3) return ; dfs2(nt[u]); } void dfs(int u){ visit[u] = 2; if(visit[nt[u]] == 0){ dfs(nt[u]); } else if(visit[nt[u]] == 1){ cyn = part[nt[u]]; // visit[nt[u]] = 1; } else{ cyc ++; cyn = cyc; dfs2(nt[u]); } visit[u] = 1; part[u] = cyn; acyn[cyn]++; } int main(){ two[0] = 1; for(int i =1 ; i < MAXN; i++) two[i] = (two[i - 1] * 2) % MOD; scanf("%d", &n); memset(visit, 0, sizeof(visit)); memset(part, -1, sizeof(part)); for(int i = 1; i <= n; i++) scanf("%d", &nt[i]); cyc = cyn = 0; for(int i = 1; i <= n; i++){ if(visit[i] == 0){ cyn = 0; dfs(i); } } int ans = 1; /* for(int i = 1; i <= n; i++) printf("%d ", part[i]); puts(""); for(int i = 0; i <= cyc; i++){ printf("%d %d \n", acyc[i], acyn[i]); }*/ for(int i = 0; i <= cyc; i++){ if(i == 0 && acyn[i] > 0){ ans = ((LL)ans * two[acyn[i] - 1])%MOD; } if(i > 0){ ans = (LL)ans * (two[acyn[i]] - (LL)2 * two[acyn[i] - acyc[i]]) % MOD; } } if(ans < 0) ans = ((LL)ans + MOD) % MOD; printf("%d\n", ans); return 0; }
E,题解在注释
/***************** 设 2^n = m ,分母为 m ^k ,算的分子为 m * (m - 1) *.... * (m - k + 1) 只要两个互质,最后用1减就是了,至于化简的过程,就是对分子提取因子2. 边界 太多,搞了一晚……不划算 ***********/ #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define LL long long const int MOD =1000003; int mod[MOD + 5]; bool vis[MOD + 5]; LL tail[100]; int quick(int m, LL k){ int ret = 1; int pow = m; while(k){ if(k&1) ret = (LL)ret * pow % MOD; k >>= 1; pow = (LL)pow * pow % MOD; } return ret; } int cal(LL n, int index){ int m = quick(2, n); int ret = 1; int counts = 0; memset(vis, false, sizeof(vis)); for(LL i = 1; i <= tail[index]; i += 2){ if(vis[(((LL)m - i)%MOD + MOD)%MOD]){ break; } mod[counts++] = (((LL)m - i)%MOD + MOD) %MOD; vis[mod[counts - 1]] = true; } // cout << counts << endl; LL mc = tail[index] / 2 + 1; LL cc = mc / counts; mc = mc % counts; for(int i = 0; i < counts; i++) ret = ((LL)ret * mod[i]) % MOD; ret = quick(ret, cc); for(int i = 0; i < mc; i++){ ret = ((LL)ret * mod[i]) %MOD; } // cout <<"endl" << endl; return ret; } int main(){ LL n, k, tmp; int counts = 0; cin >> n >> k; double tt = log(k) / log(2) - n; if(n < 64){ if( tt > 1e-8){ cout << 1 << " " << 1 << endl; return 0; } else if(tt < 1e-8){ LL ans = 1; for(LL i = 1; i <= n; i++) ans = ans * 2; if(ans > 0 && ans < k){ cout << 1<< " "<< 1 << endl; return 0; } } } tmp = k - 1; LL upc = 0; while(tmp){ if(tmp % 2 == 0){ upc += tmp / 2; tail[counts++] = tmp - 1; tmp = tmp / 2; } else { upc += tmp / 2; tail[counts++] = tmp; tmp = (tmp - 1) / 2; } } // cout << upc << endl << endl; LL k_1 = k - 1 - upc; int down = quick(2, n - 1); down = quick(down, k - 1); down = (LL)down * quick(2, k_1) % MOD; int up = 1; // cout << down <<endl; // cout << "YES" << counts <<endl; for(int i = 0; i < counts; i++){ up = ((LL)up * cal(n - i, i))%MOD; } up = ((down - up) % MOD + MOD) %MOD; cout << up <<" "<< down << endl; }
以上是关于CF # 369 D2 DE的主要内容,如果未能解决你的问题,请参考以下文章
CF w1d2 A. Superhero Transformation
CF w1d2 B. Average Superhero Gang Power
CF 1196D2 RGB Substring (hard version) --- 前缀和 + 思维