NOIP模拟66
T1:
比较显然的背包问题,然而暴零了,需要注意使用STL过程中,一般auto仅用作遍历,
一边auto一边插入由于内存原因会出错
背包理论上界为1e9,通过前缀和卡上下界即可
代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define I long long 4 #define C char 5 #define B bool 6 #define V void 7 #define D double 8 #define LL long long 9 #define UI unsigned int 10 #define UL unsigned long long 11 #define P pair<I,I> 12 #define MP make_pair 13 #define a first 14 #define b second 15 #define lowbit(x) (x & -x) 16 #define debug cout << "It's Ok Here !" << endl; 17 #define FP(x) freopen (#x,"r",stdin) 18 #define FC(x) freopen (#x,"w",stdout) 19 const I N = 1e3 + 3; 20 I n,m,w1[N],w2[N],v1[N],v2[N],f1[N*N],f2[N*N],Pre1[N],Pre2[N]; 21 inline I read () { 22 I x(0),y(1); C z(getchar()); 23 while (!isdigit(z)) { if (z == '-') y = -1; z = getchar(); } 24 while ( isdigit(z)) x = x * 10 + (z ^ 48), z = getchar(); 25 return x * y; 26 } 27 inline V Max (LL &a,LL b) { a = a > b ? a : b; } 28 inline V Min (LL &a,LL b) { a = a < b ? a : b; } 29 inline LL max (LL a,LL b) { return a > b ? a : b; } 30 inline LL min (LL a,LL b) { return a < b ? a : b; } 31 inline V swap (I &a,I &b) { a ^= b, b ^= a, a ^= b; } 32 inline I abs (I a) { return a >= 0 ? a : -a; } 33 inline P operator + (const P &a,const P &b) { 34 return MP (a.a + b.a,a.b + b.b); 35 } 36 inline P operator - (const P &a,const P &b) { 37 return MP (a.a - b.a,a.b - b.b); 38 } 39 signed main () { 40 FP (game.in), FC (game.out); 41 n = read(), m = read(); 42 for (I i(1);i <= n; ++ i) { 43 w1[i] = read(), v1[i] = read(); 44 Pre1[i] = Pre1[i - 1] + w1[i]; 45 } 46 for (I i(1);i <= m; ++ i) { 47 w2[i] = read(), v2[i] = read(); 48 Pre2[i] = Pre2[i - 1] + w2[i]; 49 } 50 I MA (max (Pre1[n],Pre2[m])); 51 for (I i(1);i <= MA; ++ i) 52 f1[i] = f2[i] = -(I)1e18; 53 f1[w1[1]] = v1[1], f2[w2[1]] = v2[1]; 54 for (I i(2);i <= n; ++ i) 55 for (I j(Pre1[i]);j >= w1[i]; -- j) 56 Max (f1[j],f1[j - w1[i]] + v1[i]); 57 for (I i(2);i <= m; ++ i) 58 for (I j(Pre2[i]);j >= w2[i]; -- j) 59 Max (f2[j],f2[j - w2[i]] + v2[i]); 60 LL ans (0); 61 for (I i(1);i <= MA; ++ i) 62 Max (ans,f1[i] + f2[i]); 63 printf ("%lld\n",ans); 64 }
T2:
数学题,首先考虑部分分,n <= 20通过Dfs + LCA预处理可以做到,对于m = 2的情况
是比较经典的树形DP,对于链上情况显然答案为中位数,枚举中位数计算贡献即可
正解仍然为考虑每条边的贡献,为sigma(C(s,i) * C(n - s,i) * min (i,m - i))
容易想到拆min,分情况即可,发现两式结构相似,于是设g[i] = sigma (C(i,j) * C(n - i,m - j) * j)
将变量j转化为i得到g[i] = i * sigma(C(i - 1,j - 1) * (n - i,m - j)),考虑如何求g[i],由于C上下两项为定值
于是考虑递推
考虑变量,即钦定第s个位置必选与钦定s + 1个位置必选进行容斥,再将式子平移可以转化为相同
结构,于是发现变量即为-C(i - 1,k - 1) * C(n - i - 1,m - k - 1),O(n)递推即可
代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define I long long 4 #define C char 5 #define B bool 6 #define V void 7 #define D double 8 #define LL long long 9 #define UI unsigned int 10 #define UL unsigned long long 11 #define P pair<I,I> 12 #define MP make_pair 13 #define a first 14 #define b second 15 #define lowbit(x) (x & -x) 16 #define debug cout << "It's Ok Here !" << endl; 17 #define FP(x) freopen (#x,"r",stdin) 18 #define FC(x) freopen (#x,"w",stdout) 19 const I N = 1e6 + 3, mod = 1e9 + 7; 20 I n,m,tmp,ans,size[N]; 21 I tot,to[N << 1],nxt[N << 1],head[N]; 22 I J[N],Y[N],g[N]; 23 inline I read () { 24 I x(0),y(1); C z(getchar()); 25 while (!isdigit(z)) { if (z == '-') y = -1; z = getchar(); } 26 while ( isdigit(z)) x = x * 10 + (z ^ 48), z = getchar(); 27 return x * y; 28 } 29 inline V Max (I &a,I b) { a = a > b ? a : b; } 30 inline V Min (I &a,I b) { a = a < b ? a : b; } 31 inline I max (I a,I b) { return a > b ? a : b; } 32 inline I min (I a,I b) { return a < b ? a : b; } 33 inline V swap (I &a,I &b) { a ^= b, b ^= a, a ^= b; } 34 inline I abs (I a) { return a >= 0 ? a : -a; } 35 inline P operator + (const P &a,const P &b) { 36 return MP (a.a + b.a,a.b + b.b); 37 } 38 inline P operator - (const P &a,const P &b) { 39 return MP (a.a - b.a,a.b - b.b); 40 } 41 inline V found (I x,I y) { 42 to[++tot] = y, nxt[tot] = head[x], head[x] = tot; 43 to[++tot] = x, nxt[tot] = head[y], head[y] = tot; 44 } 45 inline I fp (I a,I b) { 46 I ans(1); 47 for (; b ;b >>= 1, a = a * a % mod) 48 if (b & 1) ans = ans * a % mod; 49 return ans; 50 } 51 inline I _C (I n,I m) { 52 if (m < 0 || m > n) return 0; 53 return J[n] * Y[m] % mod * Y[n - m] % mod; 54 } 55 V Dfs (I x,I father) { 56 size[x] = 1; 57 for (I i(head[x]),y(to[i]); i ;i = nxt[i],y = to[i]) if (y != father) { 58 Dfs (y,x); size[x] += size[y]; 59 (ans += size[y] * g[size[y]] % mod) %= mod, (ans += (n - size[y]) * g[n - size[y]] % mod) %= mod; 60 if (!(m & 1)) (ans += (m >> 1) * _C (size[y],m >> 1) % mod * _C (n - size[y],m >> 1) % mod) %= mod; 61 } 62 } 63 V Dfs3 (I x,I father) { 64 size[x] = 1; 65 for (I i(head[x]),y(to[i]); i ;i = nxt[i],y = to[i]) if (y != father) { 66 Dfs3 (y,x); size[x] += size[y]; (ans += size[y] * (n - size[y]) % mod) %= mod; 67 } 68 } 69 signed main () { 70 FP (meeting.in), FC (meeting.out); 71 n = read (), m = read (); 72 for (I i(2);i <= n; ++ i) 73 found (read(),i); 74 //if (m == 2) { Dfs3 (1,0); printf ("%lld\n",ans); return 0; } 75 J[0] = Y[0] = 1; 76 for (I i(1);i <= n; ++ i) 77 J[i] = J[i - 1] * i % mod; 78 Y[n] = fp (J[n],mod - 2); 79 for (I i(n - 1); i; -- i) 80 Y[i] = Y[i + 1] * (i + 1) % mod; 81 I tmp (m - 1 >> 1); 82 if (tmp) g[1] = _C (n - 1,m - 1); 83 for (I i(1);i < n; ++ i) 84 g[i + 1] = (g[i] - _C (i - 1,tmp - 1) * _C (n - i - 1,m - tmp - 1)) % mod; 85 Dfs (1,0); 86 printf ("%lld\n",(ans + mod) % mod); 87 }
T3:
比较暴力的假做法,考虑枚举时分秒,计算角度,取最值即可,需要注意lower/upper的边界问题
以及角度的正负问题即可
代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define I int 4 #define C char 5 #define B bool 6 #define V void 7 #define D double 8 #define LL long long 9 #define UI unsigned int 10 #define UL unsigned long long 11 #define P pair<I,I> 12 #define MP make_pair 13 #define a first 14 #define b second 15 #define lowbit(x) (x & -x) 16 #define debug cout << "It's Ok Here !" << endl; 17 #define FP(x) freopen (#x,"r",stdin) 18 #define FC(x) freopen (#x,"w",stdout) 19 const I N = 5e4 + 3; 20 I n,h[N],m[N],s[N]; 21 D a[N],b[N],arg1,arg2,ans(1e9); 22 inline I read () { 23 I x(0),y(1); C z(getchar()); 24 while (!isdigit(z)) { if (z == '-') y = -1; z = getchar(); } 25 while ( isdigit(z)) x = x * 10 + (z ^ 48), z = getchar(); 26 return x * y; 27 } 28 inline V Max (D &a,D b) { a = a > b ? a : b; } 29 inline V Min (D &a,D b) { a = a < b ? a : b; } 30 inline D max (D a,D b) { return a > b ? a : b; } 31 inline D min (D a,D b) { return a < b ? a : b; } 32 inline V swap (I &a,I &b) { a ^= b, b ^= a, a ^= b; } 33 inline I abs (I a) { return a >= 0 ? a : -a; } 34 inline P operator + (const P &a,const P &b) { 35 return MP (a.a + b.a,a.b + b.b); 36 } 37 inline P operator - (const P &a,const P &b) { 38 return MP (a.a - b.a,a.b - b.b); 39 } 40 signed main () { 41 FP (unreal.in), FC (unreal.out); 42 n = read (); 43 for (I i(1);i <= n; ++ i) { 44 h[i] = read (), m[i] = read (), s[i] = read (); 45 if (h[i] >= 12) h[i] %= 12; 46 a[i] = 6.0 * m[i] + 0.1 * s[i]; 47 b[i] = 30.0 * h[i] + 0.5 * m[i] + 0.5 / 60.0 * s[i]; 48 } 49 sort (a + 1,a + n + 1), sort (b + 1,b + n + 1); 50 a[0] = a[n], a[n + 1] = a[1], b[0] = b[n], b[n + 1] = b[1]; 51 for (I i(0);i < 12; ++ i) 52 for (I j(0);j < 60; ++ j) 53 for (D k(0);k < 60;k += 0.01) { 54 arg1 = 6.0 * j + 0.1 * k; 55 arg2 = 30.0 * i + 0.5 * j + 0.5 / 60.0 * k; 56 D tmp1 (arg1 + 180), tmp2 (arg2 + 180); 57 if (tmp1 >= 360) tmp1 -= 360; if (tmp2 >= 360) tmp2 -= 360; 58 I it1 = upper_bound (a + 1,a + n + 1,tmp1) - a, 59 it2 = upper_bound (b + 1,b + n + 1,tmp2) - b; 60 D tmp3 (180 - a[it1] + tmp1), tmp4 (180 - tmp1 + a[it1 - 1]), 61 tmp5 (180 - b[it2] + tmp2), tmp6 (180 - tmp2 + b[it2 - 1]); 62 if (tmp3 < 0) tmp3 += 360; if (tmp4 < 0) tmp4 += 360; 63 if (tmp5 < 0) tmp5 += 360; if (tmp6 < 0) tmp6 += 360; 64 if (tmp3 >= 360) tmp3 -= 360; if (tmp4 >= 360) tmp4 -= 360; 65 if (tmp5 >= 360) tmp5 -= 360; if (tmp6 >= 360) tmp6 -= 360; 66 Min (tmp3,360 - tmp3), Min (tmp4,360 - tmp4), 67 Min (tmp5,360 - tmp5), Min (tmp6,360 - tmp6); 68 Min (ans,max (max (tmp3,tmp4),max (tmp5,tmp6))); 69 } 70 printf ("%.5lf",ans); 71 }