正睿20NOIp前冲刺day1
估分:100+10+40+30=180
实际:60+0+40+20=120
T1:
签到题,有手就行,但我用了cin,超时了
垃圾cin,再也不用了
1 #include<cstdio> 2 #include<cstring> 3 #include<map> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 typedef unsigned long long ULL; 9 10 const int N = 10000010; 11 12 char str1[N], str2[N]; 13 map<char, int> st; 14 15 int main() 16 { 17 scanf("%s%s", str1, str2); 18 int n = strlen(str1), m = strlen(str2); 19 ULL ans = (ULL)(n + 1) * (m + 1); 20 for (int i = 0; i < n; i++) st[str1[i]]++; 21 for (int i = 0; i < m; i++) ans -= st[str2[i]]; 22 printf("%llu", ans); 23 }
T2:
暴力没写好,10分没了
当a全部相等的时候,用倍增DP,f(i,j)表示前2i种糖果,占了j个位置的方案数。转移方程如下
初始化,g(0,0...ai)=1。
如果a不相等,把≥m的a全部变成m,对于所有种类的a分别做一遍上面的DP,然后合并起来。
因为n很大,所以用多项式快速幂来做
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 typedef long long LL; 9 10 const int N = 105, M = 10000005; 11 const int mod = 998244353; 12 13 int vis[M], m; 14 LL n; 15 LL cnt[N], f[N], g[N], fac[N], inv[N]; 16 17 LL qmul(LL a, int k) 18 { 19 LL res = 1; 20 while(k) 21 { 22 if (k & 1) res = res * a % mod; 23 a = a * a % mod; 24 k >>= 1; 25 } 26 return res; 27 } 28 29 void init() 30 { 31 fac[0] = 1; 32 for (int i = 1; i <= 100; i++) fac[i] = fac[i - 1] * i % mod; 33 inv[100] = qmul(fac[100], mod - 2); 34 for (int i = 100; i; i--) inv[i - 1] = inv[i] * i % mod; 35 } 36 37 void mul(LL* a, const LL* b) 38 { 39 LL c[N]; 40 memset(c, 0, sizeof(c)); 41 for (int i = 0; i <= m; i++) 42 { 43 for (int j = 0; i + j <= m; j++) 44 { 45 c[i + j] = (c[i + j] + a[i] * b[j]) % mod; 46 } 47 } 48 for (int i = 0; i <= m; i++) a[i] = c[i]; 49 } 50 51 void calc(int p, LL k) 52 { 53 LL t[N]; 54 memset(t, 0, sizeof(t)); 55 memset(g, 0, sizeof(g)); 56 57 g[0] = t[0] = 1; 58 for (int i = 0; i <= p; i++) t[i] = inv[i]; 59 while (k) 60 { 61 if (k & 1) mul(g, t); 62 mul(t, t); 63 k >>= 1; 64 } 65 } 66 67 int main() 68 { 69 init(); 70 scanf("%lld%d", &n, &m); 71 72 int s, p; 73 int a1, A, B, P; 74 scanf("%d%d%d%d", &a1, &A, &B, &P); 75 76 vis[a1] = 1; 77 for (int i = 2; ; i++) 78 { 79 a1 = ((LL)a1 * A + B) % P + 1; 80 if (vis[a1]) 81 { 82 s = vis[a1] - 1; 83 p = i - vis[a1]; 84 break; 85 } 86 vis[a1] = i; 87 } 88 89 if (!p) s = n; 90 LL t = (n - s) / p, q = (n - s) % p; 91 for (int i = 1; i <= P; i++) 92 { 93 if (vis[i]) 94 { 95 if (vis[i] <= s) ++cnt[min(m, i)]; 96 else cnt[min(m, i)] += t + (vis[i] - s <= q); 97 } 98 } 99 100 f[0] = 1; 101 for (int i = 1; i <= m; i++) 102 { 103 calc(i, cnt[i]); 104 mul(f, g); 105 } 106 printf("%lld\n", f[m] * fac[m] % mod); 107 }
T3:
|T|≤2的没写完
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N = 100010; 9 10 int n, m; 11 int nex[N][26], f[26][52]; 12 char str1[N], str2[N]; 13 14 int main() 15 { 16 scanf("%s %s", str1 + 1, str2 + 1); 17 n = strlen(str1 + 1), m = strlen(str2 + 1); 18 19 for (int i = 0; i < 26; i++) nex[n + 1][i] = n + 1; 20 for (int i = n; ~i; i--) 21 { 22 for (int j = 0; j < 26; j++) 23 { 24 nex[i][j] = nex[i + 1][j]; 25 if (i < n && str1[i + 1] == j + 'a') nex[i][j] = i + 1; 26 } 27 } 28 29 int q; 30 scanf("%d", &q); 31 while(q--) 32 { 33 int l, r; 34 scanf("%d %d", &l, &r); 35 memset(f, 0x3f, sizeof(f)); 36 37 f[0][m] = l - 1; 38 for (int j = 1; j <= m; j++) 39 { 40 for (int k = 0; k <= 2 * m; k++) 41 { 42 if (f[j - 1][k] <= n) 43 { 44 if (k) f[j][k - 1] = min(f[j][k - 1], f[j - 1][k]); 45 f[j][k] = min(f[j][k], f[j - 1][k] + 1); 46 f[j][k + 1] = min(f[j][k + 1], nex[f[j - 1][k]][str2[j] - 'a']); 47 } 48 } 49 } 50 51 for (int j = 2 * m; ~j; j--) 52 { 53 if (f[m][j] <= r) 54 { 55 printf("%d\n", r - l + 1 - (j - m)); 56 break; 57 } 58 } 59 } 60 }
T4:
有10分的暴力写炸了
不会
总结:
· 动态规划还是弱项,要多锻炼锻炼。以后再也不用cin了,慢的要死。