NOIP模拟71
T1:
结论题,口胡证明,考虑首先每两个点之间最多存在一条边(重边视作一条边)
而对于c > 1,显然对于同一对点,出边数大于入边,考虑构造一种情况使得某点负贡献大于1
也就是说,连向该点的边必须为某种颜色,否则入点的平衡会被打破,那么考虑是否存在一种调整方式
使得连向该点的边再颜色改变的情况下保持平衡,那么考虑从某点开始,沿连边将颜色一次递推(调色)
由于出边数大于入边数,那么最终在端点处一定可以通过颜色调换来完成整个递推过程。
代码如下:
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 = 1e6 + 3; 20 I n,m,k,c,ans,In[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 (I &a,I b) { a = a > b ? a : b; } 28 inline V Min (I &a,I b) { a = a < b ? a : b; } 29 inline I max (I a,I b) { return a > b ? a : b; } 30 inline I min (I a,I 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 (qiandao.in), FC (qiandao.out); 41 n = read (), m = read (), k = read (), c = read (); 42 for (I i(1);i <= k; ++ i) { 43 I x (read ()), y (read ()); 44 In[x] ++ , In[y + n] ++ ; 45 } 46 for (I i(1);i <= n + m; ++ i) 47 ans += In[i] % c != 0; 48 printf ("%d\n",ans); 49 }
T2:
树剖板子题,但是容易被菊花图卡,正解为通过倍增寻找子节点,注意卡常
代码如下:
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 = 3e5 + 3; 20 I n,m; 21 I tot,head[N],to[N << 1],nxt[N << 1]; 22 I cnt,dfn[N],size[N],f[N],t[N],s[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 y,I x) { 42 to[++tot] = y, nxt[tot] = head[x], head[x] = tot; 43 to[++tot] = x, nxt[tot] = head[y], head[y] = tot; 44 } 45 V Dfs1 (I x,I father) { 46 f[x] = father, size[x] = 1; 47 for (I i(head[x]),y(to[i]); i ;i = nxt[i],y = to[i]) if (y != father) { 48 Dfs1 (y,x), size[x] += size[y]; 49 if (size[y] > size[s[x]]) s[x] = y; 50 } 51 } 52 V Dfs2 (I x,I top) { 53 dfn[x] = ++cnt, t[x] = top; 54 if (!s[x]) return ; Dfs2 (s[x],top); 55 for (I i(head[x]),y(to[i]); i ;i = nxt[i],y = to[i]) if (y != f[x] && y != s[x]) 56 Dfs2 (y,y); 57 } 58 I LCA (I x,I y) { 59 while (t[x] != t[y]) dfn[x] < dfn[y] ? y = f[t[y]] : x = f[t[x]]; 60 return dfn[x] < dfn[y] ? x : y; 61 } 62 struct SGT { 63 #define lid id << 1 64 #define rid id << 1 | 1 65 #define mid (l + r >> 1) 66 #define update(id) (MA[id] = max (MA[lid],MA[rid])) 67 I MA[N << 2],lazy[N << 2]; 68 inline V pushdown (I id) { 69 MA[lid] += lazy[id], lazy[lid] += lazy[id]; 70 MA[rid] += lazy[id], lazy[rid] += lazy[id]; 71 lazy[id] = 0; 72 } 73 V secmod (I id,I l,I r,I ql,I qr,B typ) { 74 if (ql <= l && r <= qr) 75 return (V) (typ ? (MA[id] ++ , lazy[id] ++ ) : (MA[id] -- , lazy[id] -- )); 76 if (lazy[id] && l != r) pushdown (id); 77 if (ql <= mid) secmod (lid,l,mid,ql,qr,typ); 78 if (qr > mid) secmod (rid,mid + 1,r,ql,qr,typ); 79 update (id); 80 } 81 }SGT; 82 signed main () { 83 FP (magic.in), FC (magic.out); 84 n = read (), m = read (); 85 for (I i(1);i < n; ++ i) 86 found (read (), read ()); 87 Dfs1 (1,0), Dfs2 (1,1); 88 while (m -- ) { 89 I x (read ()), y (read ()); 90 if (dfn[x] > dfn[y]) swap (x,y); 91 if (x == y) SGT.secmod (1,1,n,1,n,1); 92 else { 93 I lca (LCA (x,y)); 94 if (lca == x) { 95 SGT.secmod (1,1,n,1,n,1); 96 for (I i(head[x]),z(to[i]); i ;i = nxt[i],z = to[i]) 97 if (z != f[x] && dfn[y] >= dfn[z] && dfn[y] <= dfn[z] + size[z] - 1) 98 SGT.secmod (1,1,n,dfn[z],dfn[z] + size[z] - 1,0); 99 SGT.secmod (1,1,n,dfn[y],dfn[y] + size[y] - 1,1); 100 } 101 else { 102 SGT.secmod (1,1,n,dfn[x],dfn[x] + size[x] - 1,1); 103 SGT.secmod (1,1,n,dfn[y],dfn[y] + size[y] - 1,1); 104 } 105 } 106 printf ("%d\n",SGT.MA[1]); 107 } 108 }
T3:
考虑转化题意,由于不走回头路且只走最短路,那么老鼠的路径实际上是一棵树
于是通过最短路建立前驱,求最短路生成树即可,剩下的问题即为树形背包
代码如下:
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 = 305, M = 3e4 + 3; 20 I n,m,t,pre[N],d[N]; 21 I tot,head[N],to[M << 1],nxt[M << 1],wgt[M << 1]; 22 vector <I> go[N]; 23 D p[N][N],f[N][N]; 24 inline I read () { 25 I x(0),y(1); C z(getchar()); 26 while (!isdigit(z)) { if (z == '-') y = -1; z = getchar(); } 27 while ( isdigit(z)) x = x * 10 + (z ^ 48), z = getchar(); 28 return x * y; 29 } 30 inline V Max (D &a,D b) { a = a > b ? a : b; } 31 inline V Min (D &a,D b) { a = a < b ? a : b; } 32 inline I max (I a,I b) { return a > b ? a : b; } 33 inline I min (I a,I b) { return a < b ? a : b; } 34 inline V swap (I &a,I &b) { a ^= b, b ^= a, a ^= b; } 35 inline I abs (I a) { return a >= 0 ? a : -a; } 36 inline P operator + (const P &a,const P &b) { 37 return MP (a.a + b.a,a.b + b.b); 38 } 39 inline P operator - (const P &a,const P &b) { 40 return MP (a.a - b.a,a.b - b.b); 41 } 42 inline V found (I z,I y,I x) { 43 to[++tot] = y, wgt[tot] = z, nxt[tot] = head[x], head[x] = tot; 44 to[++tot] = x, wgt[tot] = z, nxt[tot] = head[y], head[y] = tot; 45 } 46 inline V Dijkstra () { 47 priority_queue <P> q; 48 memset (d,0x3f,sizeof d); 49 B vis[N]; memset (vis,0,sizeof vis); 50 q.push (MP (0,1)); d[1] = 0; 51 while (!q.empty ()) { 52 I x (q.top ().b); q.pop (); 53 if (vis[x]) continue; vis[x] = 1; 54 for (I i(head[x]),y(to[i]),z(wgt[i]); i ;i = nxt[i],y = to[i],z = wgt[i]) 55 if (d[x] + z < d[y]) d[y] = d[x] + z, pre[y] = x, q.push (MP (-d[y],y)); 56 } 57 for (I i(2);i <= n; ++ i) go[pre[i]].push_back (i); 58 } 59 V Dfs (I x,I father) { 60 I num (0); 61 for (auto y : go[x]) if (y != father) { 62 Dfs (y,x), num ++ ; 63 for (I j(t); ~j ; -- j) { 64 f[x][j] = f[x][j] * (num - 1) / num; 65 for (I k(j); ~k ; -- k) 66 Max (f[x][j],f[x][k] * (num - 1) / num + f[y][j - k] / num); 67 } 68 } 69 for (I j(t); ~j ; -- j) 70 for (I k(j); ~k ; -- k) 71 Max (f[x][j],p[x][k] + (1 - p[x][k]) * f[x][j - k]); 72 } 73 signed main () { 74 FP (arrest.in), FC (arrest.out); 75 n = read (), m = read (), t = read (); 76 for (I i(1);i <= m; ++ i) 77 found (read (), read (), read ()); 78 for (I i(1);i <= n; ++ i) 79 for (I j(1);j <= t; ++ j) 80 scanf ("%lf",&p[i][j]); 81 Dijkstra (); Dfs (1,0); 82 printf ("%.6lf\n",f[1][t]); 83 }
T4:
注意问题的分析方式,由于m,k很小,分类讨论,问题仅限于整除关系,取代表元判断性质即可