統計字母簽到題網絡
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; int t, n; char str[MAXN]; int cnt[10]; int main() { map<char, int>mp; //hello world mp['h'] = 1; // 1 mp['e'] = 2; // 1 mp['l'] = 3; // 3 mp['o'] = 4; // 2 mp['w'] = 5; // 1 mp['r'] = 6; // 1 mp['d'] = 7; // 1 scanf("%d", &t); while(t--) { scanf("%s", str); n = strlen(str); memset(cnt, 0, sizeof(cnt)); for(int i = 0; i < n; i++ ) { if(mp.count(str[i])) { cnt[ mp[str[i]] ]++; } } cnt[ mp['l'] ] /= 3; cnt[ mp['o'] ] /= 2; int ans = 0x3f3f3f3f; for(int i = 1; i <= 7; i++ ) { ans = min(ans, cnt[i]); } printf("%d\n", ans); } return 0; } /** 3 helloworld helloworldooooooooooo helloworldhelloworldasjdkl */
相似題: HDU 5950,我隨手改了遞推式spa
這麼裸的矩陣快速冪 F[n] = 2 * f[n - 1] + 3 * f[n - 2] + 3 * n^5
, 除了那個n^5。code
第一項,第二項直接輸出答案it
當 n >= 3 時, 咱們假設ast
\[ A_n=\left[ \begin{matrix} F[n] & F[n-1] & n^5 & n^4 & n^3 & n^2 & n^1 & n^0\\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ \end{matrix} \right] \]class
\[ A_{n+1}=\left[ \begin{matrix} F[n+1] & F[n] & (n+1)^5 & (n+1)^4 & (n+1)^3 & (n+1)^2 & n+1 & 1\\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ \end{matrix} \right] \]jdk
假設一個矩陣B, 咱們須要算一個B使得map
\[ A_{n+1} = A_n * B \]二進制
按照矩陣乘法規則易得
\[ B=\left[ \begin{matrix} 2 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 3 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 3 & 0 & 1 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 5 & 1 & 0 & 0 &0 &0 \\ 0 & 0 & 10 & 4 & 1 & 0 &0 &0 \\ 0 & 0 & 10 & 6 & 3 & 1 &0 &0 \\ 0 & 0 & 5 & 4 & 3 & 2 &1 &0 \\ 0 & 0 & 1 & 1 & 1 & 1 &1 &1 \\ \end{matrix} \right] \]
因此咱們假設
\[ A = \left[ \begin{matrix} b & a & 3^5 & 3^4 & 3^3 & 3^2 & 3^1 & 3^0\\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ \end{matrix} \right] \]
\[ B = \left[ \begin{matrix} 2 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 3 & 0 & 0 & 0 & 0 & 0 &0 &0 \\ 3 & 0 & 1 & 0 & 0 & 0 &0 &0 \\ 0 & 0 & 5 & 1 & 0 & 0 &0 &0 \\ 0 & 0 & 10 & 4 & 1 & 0 &0 &0 \\ 0 & 0 & 10 & 6 & 3 & 1 &0 &0 \\ 0 & 0 & 5 & 4 & 3 & 2 &1 &0 \\ 0 & 0 & 1 & 1 & 1 & 1 &1 &1 \\ \end{matrix} \right] \]
令矩陣 C = A * B ^ (n - 2), 答案爲C[0][0]
標稱
#include <bits/stdc++.h> using namespace std; const int MAXN = 110; typedef long long LL; const LL MOD = 2147493647; #define mod(x) ((x)%MOD) int n = 8; struct Mat { LL m[MAXN][MAXN]; void init() { memset(m, 0, sizeof(m)); } void set() { init(); for(int i = 0; i < MAXN; i++ ) { m[i][i] = 1; } } void disp() { for(int i = 0; i < n; i++ ) { for(int j = 0; j < n; j++ ) { printf("%-10d", m[i][j]); } puts(""); } } } unit; Mat operator * (const Mat &a, const Mat &b) { Mat ret; ret.init(); LL x = 0; for(int i = 0; i < n; i++ ) { for(int j = 0; j < n; j++ ) { x = 0; for(int k = 0; k < n; k++ ) { x += mod((a.m[i][k] % MOD) * (b.m[k][j] % MOD)); x = mod(x); } ret.m[i][j] = mod(x); } } return ret; } Mat pow_mod(Mat a, LL n) { Mat ret = unit; while(n) { if(n & 1) { ret = ret * a; } a = a * a; n >>= 1; } return ret; } LL pow_mod(LL a, LL b) { LL res = 1; while(b) { if(b & 1) { res = (res * a) % MOD; } b >>= 1; a = (a * a) % MOD; } return res; } int T; LL N, a, b; int map_b[8][8] = { 2, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0,10, 4, 1, 0, 0, 0, 0, 0,10, 6, 3, 1, 0, 0, 0, 0, 5, 4, 3, 2, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; LL solve_check() { if(N == 1) { //printf("%lld\n", a); return a; } if(N == 2) { //printf("%lld\n", b); return b; } LL c = 0; vector<LL>v; v.push_back(0); v.push_back(a); v.push_back(b); for(int i = 3; i <= N; i++ ) { LL va = v[i - 1] * 2; va %= MOD; va += v[i - 2] * 3; va %= MOD; va += 3 * pow_mod(i, 5); va %= MOD; v.push_back(va); } return v[N]; } LL solve_std() { if(N == 1) { //printf("%lld\n", a); return a; } if(N == 2) { //printf("%lld\n", b); return b; } Mat A, B; A.init(); B.init(); A.m[0][0] = b; A.m[0][1] = a; A.m[0][2] = 3 * 3 * 3 * 3 * 3; A.m[0][3] = 3 * 3 * 3 * 3; A.m[0][4] = 3 * 3 * 3; A.m[0][5] = 3 * 3; A.m[0][6] = 3; A.m[0][7] = 1; for(int i = 0; i < 8; i++ ) { for(int j = 0; j < 8; j++ ) { B.m[i][j] = map_b[i][j]; } } Mat res = A * pow_mod(B, N - 2); return res.m[0][0] % MOD; } void judge_std() { freopen("data.in", "w", stdout); srand(static_cast<unsigned int>(time(0))); LL MAX = (1LL << 31); int cas = 1000; printf("%d\n", cas); for(int i = 1; i <= cas; i++ ) { N = rand() % MAX + 1; a = rand() % MAX + 1; b = rand() % MAX + 1; printf("%lld %lld %lld\n", N, a, b); continue; LL ans1 = solve_std(); LL ans2 = solve_check(); if(ans1 != ans2) { puts(ans1 == ans2 ? "Yes" : "No"); printf("cas = %d %lld %lld %lld\n", i, N, a, b); printf("%lld %lld\n", ans1, ans2); puts("error"); return ; } } //puts("Accept"); } int main() { // freopen("data.in", "r", stdin); // freopen("data.out", "w", stdout); unit.set(); //judge_std(); scanf("%d", &T); while(T--) { scanf("%lld %lld %lld", &N, &a, &b); printf("%lld\n", solve_std()); } return 0; }
相似題: BZOJ 2400 SPOJ839
前置技能網絡流最小割
異或運算中二進制位之間沒有影響。咱們能夠把每一位單獨處理。
那麼對於某一個二進制位。變成了取0和取1,不一樣就會對答案有貢獻,對於邊權的貢獻最少?
下面咱們只針對二進制某一位。
那麼咱們能夠當作兩種決策,一種把點歸成0, 另外一種歸爲1,那麼點的兩種決策就會形成貢獻,咱們要讓它最小。就變成二選一的最小割模型了。
咱們對原圖的邊,創建雙向邊,權爲1。對於某一位已知01的點,分別劃分兩個集合,一個連源點,一個匯點,權無窮大。那麼咱們求該圖的最小割。就會在割掉某些邊,使得點屬於某一個集合,0集合或者1集合。咱們要的邊權最小也符合最小割的定義。最後咱們跑最大流便可。而後在吧每一位的答案整合。
#include <bits/stdc++.h> using namespace std; const int MAX_N = 555; const int MAX_M = 3050 * 2; int n, m, k; struct Edge { int u, v; } edge[MAX_M]; int p[MAX_N], v[MAX_N]; int vis[MAX_N]; struct Dinic { static const int MAXN = 500 + 7; static const int MAXM = MAXN * MAXN; static const int INF = 0x3f3f3f3f; int n, m, s, t; int first[MAXN], cur[MAXN], dist[MAXN], sign; struct Node { int to, flow, next; } edge[MAXM * 4]; inline void init(int start, int vertex, int ss, int tt) { n = vertex, s = ss, t = tt; for(int i = start; i <= n; i++ ) { first[i] = -1; } sign = 0; } inline void addEdge(int u, int v, int flow) { edge[sign].to = v, edge[sign].flow = flow, edge[sign].next = first[u]; first[u] = sign++; } inline void add_edge(int u, int v, int flow) { addEdge(u, v, flow); addEdge(v, u, 0); } inline int dinic() { int max_flow = 0; while(bfs(s, t)) { for(int i = 0; i <= n; i++ ) { cur[i] = first[i]; } max_flow += dfs(s, INF); } return max_flow; } bool bfs(int s, int t) { memset(dist, -1, sizeof(dist)); queue<int>que; que.push(s), dist[s] = 0; while(!que.empty()) { int now = que.front(); que.pop(); if(now == t) { return 1; } for(int i = first[now]; ~i; i = edge[i].next) { int to = edge[i].to, flow = edge[i].flow; if(dist[to] == -1 && flow > 0) { dist[to] = dist[now] + 1; que.push(to); } } } return 0; } int dfs(int now, int max_flow) { if(now == t) { return max_flow; } int ans = 0, next_flow = 0; for(int &i = cur[now]; ~i; i = edge[i].next) { int to = edge[i].to, flow = edge[i].flow; if(dist[to] == dist[now] + 1 && flow > 0) { next_flow = dfs(to, min(max_flow - ans, flow)); ans += next_flow; edge[i].flow -= next_flow; edge[i ^ 1].flow += next_flow; if(ans == max_flow) { return max_flow; } } } if(ans == 0) { return dist[now] = 0; } return ans; } void find_set_s(int x) { vis[x] = 1; for(int i = first[x]; ~i; i = edge[i].next) { int to = edge[i].to, flow = edge[i].flow; if(!vis[to] && flow) { find_set_s(to); } } } } cwl; int ans[MAX_N]; int main() { int t; scanf("%d", &t); while(t--) { scanf("%d %d", &n, &m); for(int i = 1; i <= m; i++ ) { scanf("%d %d", &edge[i].u, &edge[i].v); } scanf("%d", &k); for(int i = 1; i <= k; i++ ) { scanf("%d %d", &p[i], &v[i]); } memset(ans, 0, sizeof(ans)); for(int bit = 0; bit < 31; bit++ ) { cwl.init(0, n + 1, 0, n + 1); for(int i = 1; i <= m; i++ ) { int u = edge[i].u, v = edge[i].v; cwl.add_edge(u, v, 1); cwl.add_edge(v, u, 1); } for(int i = 1; i <= k; i++ ) { if((v[i] >> bit) & 1) { cwl.add_edge(0, p[i], cwl.INF); } else { cwl.add_edge(p[i], n + 1, cwl.INF); } } cwl.dinic(); memset(vis, 0, sizeof(vis)); cwl.find_set_s(0); for(int i = 1; i <= n; i++ ) { if(vis[i]) { ans[i] += (1 << bit); } } } //for(int i = 1; i <= n; i++ ) { // printf("data = %d\n", ans[i]); //} long long res = 0; for(int i = 1; i <= m; i++ ) { res += ans[ edge[i].u ] ^ ans[ edge[i].v ]; } printf("%lld\n", res); } return 0; }