第一周 2.28-3.5
2.28-2.29
什么都没干。
3.1
CF 633 E Startup Funding
对于每个l找r的时候p是单峰的,但是不能三分因为可能有平台。
但是max递增min递减可以二分两个的交点,两边check一下。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1e6 + 10; 6 int n, v[maxn], c[maxn]; 7 int rmqv[maxn][20], rmqc[maxn][20]; 8 int tmp[maxn]; 9 10 void RMQ_init() 11 { 12 for(int i = 1; i <= n; i++) rmqv[i][0] = v[i]; 13 for(int j = 1; (1 << j) <= n; j++) 14 for(int i = 1; i + ( 1 << j ) - 1 <= n; i++) 15 rmqv[i][j] = max(rmqv[i][j-1] , rmqv[i+(1<<j-1)][j-1]); 16 for(int i = 1; i <= n; i++) rmqc[i][0] = c[i]; 17 for(int j = 1; (1 << j) <= n; j++) 18 for(int i = 1; i + ( 1 << j ) - 1 <= n; i++) 19 rmqc[i][j] = min(rmqc[i][j-1] , rmqc[i+(1<<j-1)][j-1]); 20 } 21 22 int qv(int l, int r) 23 { 24 int k = 0; 25 while( ( 1 << (k + 1) ) <= r - l + 1 ) k++; 26 return max(rmqv[l][k], rmqv[r-(1<<k)+1][k]); 27 } 28 29 int qc(int l, int r) 30 { 31 int k = 0; 32 while( ( 1 << (k + 1) ) <= r - l + 1 ) k++; 33 return min(rmqc[l][k], rmqc[r-(1<<k)+1][k]); 34 } 35 36 int main(void) 37 { 38 int k; 39 scanf("%d %d", &n, &k); 40 for(int i = 1; i <= n; i++) scanf("%d", v + i); 41 for(int i = 1; i <= n; i++) scanf("%d", c + i); 42 RMQ_init(); 43 for(int i = 1; i <= n; i++) 44 { 45 int l = i, r = n, m; 46 while(l < r) 47 { 48 m = r - (r - l) / 2; 49 if(100 * qv(i, m) < qc(i, m)) l = m; 50 else r = m - 1; 51 } 52 tmp[i] = min(100 * qv(i, l), qc(i, l)); 53 if(l < n) tmp[i] = max(tmp[i], min(100 * qv(i, l+1), qc(i, l+1))); 54 } 55 sort(tmp + 1, tmp + 1 + n); 56 double ans = 0.0, b = 1.0 * k / n; 57 for(int i = 1; i <= n - k + 1; i++) 58 { 59 ans += b * tmp[i]; 60 b *= 1.0 * (n - k + 1 - i) / (n - i); 61 } 62 printf("%.9f\n", ans); 63 return 0; 64 }
3.2
TC SRM683 DIV1 250 MoveStones
POJ2940 PLUS。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 typedef long long LL; 6 7 class MoveStones 8 { 9 public: 10 11 long long get(vector <int> a, vector <int> b) 12 { 13 int n = a.size(); 14 LL sa = 0LL, sb = 0LL; 15 for(int i = 0; i < n; i++) 16 { 17 sa += (LL) a[i]; 18 sb += (LL) b[i]; 19 } 20 if(sa != sb) return -1; 21 LL ret = 1e18; 22 for(int i = 0; i < n; i++) 23 { 24 LL sum = 0LL, tmp = 0LL; 25 for(int j = 0; j < n; j++) 26 { 27 tmp = tmp + a[(i+j)%n] - b[(i+j)%n]; 28 sum += tmp > 0 ? tmp : -tmp; 29 } 30 ret = min(ret, sum); 31 } 32 return ret; 33 } 34 35 };
3.3
CF 633 F The Chocolate Spree
树dp。从边考虑。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 const int maxn = 1e5 + 10; 8 int cnt, h[maxn]; 9 LL a[maxn], dp[maxn<<1], dp1[maxn<<1]; 10 11 struct edge 12 { 13 int fm, to, pre; 14 } e[maxn<<1]; 15 16 void add(int from, int to) 17 { 18 cnt++; 19 e[cnt].pre = h[from]; 20 e[cnt].fm = from; 21 e[cnt].to = to; 22 h[from] = cnt; 23 } 24 25 LL dfs(int x) 26 { 27 if(dp1[x] != -1) return dp1[x]; 28 LL ret = a[e[x].to]; 29 for(int i = h[e[x].to]; i; i = e[i].pre) 30 if(e[i].to != e[x].fm) 31 ret = max(ret, dfs(i) + a[e[x].to]); 32 return dp1[x] = ret; 33 } 34 35 LL DP(int x) 36 { 37 if(dp[x] != -1) return dp[x]; 38 LL ret = 0LL, m1 = 0LL, m2 = 0LL; 39 for(int i = h[e[x].to]; i; i = e[i].pre) 40 { 41 if(e[i].to == e[x].fm) continue; 42 ret = max(ret, DP(i)); 43 LL tmp = dfs(i); 44 if(tmp >= m1) m2 = m1, m1 = tmp; 45 else if(tmp > m2) m2 = tmp; 46 } 47 ret = max(ret, m1 + m2 + a[e[x].to]); 48 return dp[x] = ret; 49 } 50 51 int main(void) 52 { 53 int n; 54 scanf("%d", &n); 55 memset(dp, -1, sizeof(dp)); 56 memset(dp1, -1, sizeof(dp1)); 57 for(int i = 1; i <= n; i++) scanf("%I64d", a + i); 58 for(int i = 1; i < n; i++) 59 { 60 int u, v; 61 scanf("%d %d", &u, &v); 62 add(u, v), add(v, u); 63 } 64 LL ans = 0LL; 65 for(int i = 1; i <= cnt; i += 2) ans = max(ans, DP(i) + DP(i+1)); 66 printf("%I64d\n", ans); 67 return 0; 68 }
3.4
什么都没干。
3.5
CF 633 G Yash And Trees
bitset优化。爆int没发现QAQ。
1 #include <iostream> 2 #include <cstdio> 3 #include <bitset> 4 using namespace std; 5 const int maxn = 2e5 + 10; 6 int n, m, a[maxn], t[maxn<<1]; 7 bitset<1111> r; 8 9 //tree 10 int cnt, h[maxn]; 11 struct edge 12 { 13 int to, pre; 14 } e[maxn<<1]; 15 16 void add(int from, int to) 17 { 18 cnt++; 19 e[cnt].pre = h[from]; 20 e[cnt].to = to; 21 h[from] = cnt; 22 } 23 24 //dfs 25 int timer, dfn[maxn][2]; 26 void dfs(int p, int f) 27 { 28 dfn[p][0] = ++timer; 29 t[timer] = a[p]; 30 for(int i = h[p]; i; i = e[i].pre) 31 { 32 int to = e[i].to; 33 if(to == f) continue; 34 dfs(to, p); 35 } 36 dfn[p][1] = ++timer; 37 t[timer] = a[p]; 38 } 39 40 //seg_tree 41 bitset<1111> b[maxn<<2]; 42 int tag[maxn<<2]; 43 void gather(int p) 44 { 45 b[p] = b[p<<1] | b[p<<1|1]; 46 } 47 48 void Rotate(int p, int x) 49 { 50 x %= m; 51 b[p] = ((b[p] << x) | (b[p] >> (m-x))) & r; 52 } 53 54 void push(int p) 55 { 56 if(tag[p]) 57 { 58 tag[p<<1] = (tag[p<<1] + tag[p]) % m; 59 tag[p<<1|1] = (tag[p<<1|1] + tag[p]) % m; 60 Rotate(p<<1, tag[p]); 61 Rotate(p<<1|1, tag[p]); 62 tag[p] = 0; 63 } 64 } 65 66 void build(int p, int l, int r) 67 { 68 tag[p] = 0; 69 if(l < r) 70 { 71 int mid = (l + r) >> 1; 72 build(p<<1, l, mid); 73 build(p<<1|1, mid + 1, r); 74 gather(p); 75 } 76 else b[p][t[l]] = 1; 77 } 78 79 void modify(int p, int tl, int tr, int l, int r, int v) 80 { 81 if(tr < l || r < tl) return; 82 if(l <= tl && tr <= r) 83 { 84 tag[p] = (tag[p] + v) % m; 85 Rotate(p, v); 86 return; 87 } 88 push(p); 89 int mid = (tl + tr) >> 1; 90 modify(p<<1, tl, mid, l, r, v); 91 modify(p<<1|1, mid+1, tr, l, r, v); 92 gather(p); 93 } 94 95 bitset<1111> query(int p, int tl, int tr, int l, int r) 96 { 97 bitset<1111> ret, tmp; 98 if(tr < l || r < tl) return ret; 99 if(l <= tl && tr <= r) return b[p]; 100 push(p); 101 int mid = (tl + tr) >> 1; 102 ret = query(p<<1, tl, mid, l, r); 103 tmp = query(p<<1|1, mid+1, tr, l, r); 104 ret |= tmp; 105 return ret; 106 } 107 108 //prime 109 int pr[1111]; 110 bitset<1111> bb; 111 void GetPrime() 112 { 113 for(int i = 2; i < 1111; i++) 114 { 115 if(!pr[i]) pr[++pr[0]] = i; 116 for(int j = 1; j <= pr[0] && pr[j] * i < 1111; j++) 117 { 118 pr[i*pr[j]] = 1; 119 if(i % pr[j] == 0) break; 120 } 121 } 122 for(int i = 1; pr[i] <= 1000; i++) bb[pr[i]] = 1; 123 for(int i = 0; i < m; i++) r[i] = 1; 124 } 125 126 int main(void) 127 { 128 scanf("%d %d", &n, &m); 129 GetPrime(); 130 for(int i = 1; i <= n; i++) scanf("%d", a + i), a[i] %= m; 131 for(int i = 1; i < n; i++) 132 { 133 int u, v; 134 scanf("%d %d", &u, &v); 135 add(u, v), add(v, u); 136 } 137 dfs(1, 0); 138 build(1, 1, timer); 139 int q; 140 scanf("%d", &q); 141 while(q--) 142 { 143 int op, v, x; 144 scanf("%d", &op); 145 if(op == 1) 146 { 147 scanf("%d %d", &v, &x); 148 modify(1, 1, timer, dfn[v][0], dfn[v][1], x); 149 } 150 else 151 { 152 scanf("%d", &v); 153 bitset<1111> ret = query(1, 1, timer, dfn[v][0], dfn[v][1]); 154 int ans = (bb & ret).count(); 155 printf("%d\n", ans); 156 } 157 } 158 return 0; 159 }
CF 633 H Fibonacci-ish II
不是很懂Fib。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 typedef long long LL; 7 const int maxn = 3e4 + 10; 8 int a[maxn], b[maxn], c[maxn]; 9 int n, m, fib[maxn]; 10 11 //seg_tree 12 int sum[2][maxn<<2], sz[maxn<<2]; 13 void gather(int p) 14 { 15 sz[p] = sz[p<<1] + sz[p<<1|1]; 16 sum[0][p] = (sum[0][p<<1] + fib[sz[p<<1]+1] * sum[0][p<<1|1] + fib[sz[p<<1]] * sum[1][p<<1|1]) % m; 17 if(sz[p<<1]) sum[1][p] = (sum[1][p<<1] + fib[sz[p<<1]] * sum[0][p<<1|1] + fib[sz[p<<1]-1] * sum[1][p<<1|1]) % m; 18 else sum[1][p] = sum[1][p<<1|1]; 19 } 20 21 void modify(int p, int tl, int tr, int x, int v) 22 { 23 if(tr < x || x < tl) return; 24 if(tl == tr) 25 { 26 sz[p] = v; 27 sum[0][p] = v ? b[tl] % m : 0; 28 return; 29 } 30 int mid = (tl + tr) >> 1; 31 modify(p<<1, tl, mid, x, v); 32 modify(p<<1|1, mid+1, tr, x, v); 33 gather(p); 34 } 35 36 //Mo's 37 int ans[maxn]; 38 int block, cnt[maxn]; 39 struct query 40 { 41 int id, l, r; 42 }Q[maxn]; 43 44 bool cmp(query A, query B) 45 { 46 if(A.l / block != B.l / block) return A.l / block < B.l / block; 47 return A.r < B.r; 48 } 49 50 int main(void) 51 { 52 scanf("%d %d", &n, &m); 53 fib[1] = fib[2] = 1 % m; 54 for(int i = 3; i <= n; i++) fib[i] = (fib[i-2] + fib[i-1]) % m; 55 for(int i = 1; i <= n; i++) scanf("%d", a + i), b[i] = a[i]; 56 sort(b + 1, b + 1 + n); 57 int tot = unique(b + 1, b + 1 + n) - b - 1; 58 for(int i = 1; i <= n; i++) 59 c[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b; 60 int q; 61 scanf("%d", &q); 62 for(int i = 0; i < q; i++) 63 scanf("%d %d", &Q[i].l, &Q[i].r), Q[i].id = i; 64 block = sqrt(n), sort(Q, Q + q, cmp); 65 int l = 1, r = 0; 66 for(int i = 0; i < q; i++) 67 { 68 while(r < Q[i].r) 69 { 70 r++, cnt[c[r]]++; 71 if(cnt[c[r]] == 1) modify(1, 1, n, c[r], 1); 72 } 73 while(r > Q[i].r) 74 { 75 cnt[c[r]]--; 76 if(!cnt[c[r]]) modify(1, 1, n, c[r], 0); 77 r--; 78 } 79 while(l < Q[i].l) 80 { 81 cnt[c[l]]--; 82 if(!cnt[c[l]]) modify(1, 1, n, c[l], 0); 83 l++; 84 } 85 while(l > Q[i].l) 86 { 87 l--, cnt[c[l]]++; 88 if(cnt[c[l]] == 1) modify(1, 1, n, c[l], 1); 89 } 90 ans[Q[i].id] = sum[0][1]; 91 } 92 for(int i = 0; i < q; i++) printf("%d\n", ans[i]); 93 return 0; 94 }
补BC。
HDU 5637 Transform
二进制大坑。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 typedef long long LL; 8 const LL mod = 1e9 + 7; 9 const int maxn = 1e5 + 10; 10 int a[22], dist[maxn<<1]; 11 12 int main(void) 13 { 14 int T; 15 scanf("%d", &T); 16 while(T--) 17 { 18 int n, m; 19 scanf("%d %d", &n, &m); 20 for(int i = 1; i <= n; i++) scanf("%d", a + i); 21 memset(dist, -1, sizeof(dist)); 22 queue<int> q; 23 dist[0] = 0; 24 q.push(0); 25 while(!q.empty()) 26 { 27 int v = q.front(); q.pop(); 28 for(int i = 0; i < 18; i++) 29 { 30 int nxt = v ^ (1 << i); 31 if(nxt < (maxn<<1) && dist[nxt] == -1) 32 { 33 dist[nxt] = dist[v] + 1; 34 q.push(nxt); 35 } 36 } 37 for(int i = 1; i <= n; i++) 38 { 39 int nxt = v ^ a[i]; 40 if(nxt < (maxn<<1) && dist[nxt] == -1) 41 { 42 dist[nxt] = dist[v] + 1; 43 q.push(nxt); 44 } 45 } 46 } 47 LL ans = 0LL; 48 for(int i = 1; i <= m; i++) 49 { 50 int s, t; 51 scanf("%d %d", &s, &t); 52 ans = (ans + (LL) dist[s^t] * i) % mod; 53 } 54 printf("%I64d\n", ans); 55 } 56 return 0; 57 }
HDU 5638 Toposort
乱搞。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <vector> 6 #include <algorithm> 7 using namespace std; 8 typedef long long LL; 9 const LL mod = 1e9 + 7; 10 const int maxn = 1e5 + 10; 11 int in[maxn], vis[maxn], ans[maxn]; 12 vector<int> G[maxn]; 13 14 int main(void) 15 { 16 int T; 17 scanf("%d", &T); 18 while(T--) 19 { 20 int n, m, k; 21 scanf("%d %d %d", &n, &m, &k); 22 memset(in, 0, sizeof(in)); 23 memset(vis, 0, sizeof(vis)); 24 for(int i = 1; i <= n; i++) G[i].clear(); 25 for(int i = 0; i < m; i++) 26 { 27 int u, v; 28 scanf("%d %d", &u, &v); 29 G[u].push_back(v); 30 in[v]++; 31 } 32 priority_queue<int> pq; 33 for(int i = 1; i <= n; i++) 34 if(in[i] <= k) pq.push(-i), vis[i] = 1; 35 int pos = 0; 36 while(!pq.empty()) 37 { 38 int v = -pq.top(); pq.pop(); 39 vis[v] = 0; 40 if(in[v] > k) continue; 41 k -= in[v], in[v] = -1; 42 ans[++pos] = v; 43 int sz = G[v].size(); 44 for(int j = 0; j < sz; j++) 45 { 46 int nxt = G[v][j]; 47 if(in[nxt] == -1) continue; 48 in[nxt]--; 49 if(!vis[nxt] && in[nxt] <= k) pq.push(-nxt), vis[nxt] = 1; 50 } 51 } 52 LL ret = 0LL; 53 for(int i = 1; i <= n; i++) ret = (ret + (LL) ans[i] * i) % mod; 54 printf("%I64d\n", ret); 55 } 56 return 0; 57 }
HDU 5636 Shortest Path
瞎写。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 const LL mod = 1e9 + 7; 8 int a[4], b[4]; 9 int dist[7][7]; 10 11 int main(void) 12 { 13 int T; 14 scanf("%d", &T); 15 while(T--) 16 { 17 int n, m; 18 scanf("%d %d", &n, &m); 19 for(int i = 1; i <= 3; i++) scanf("%d %d", a + i, b + i); 20 LL ans = 0LL; 21 for(int i = 1; i <= m; i++) 22 { 23 scanf("%d %d", a, b); 24 for(int j = 1; j <= 3; j++) 25 { 26 for(int k = 1; k <= 3; k++) dist[j][k] = abs(a[j] - a[k]); 27 for(int k = 4; k <= 6; k++) dist[j][k] = abs(a[j] - b[k-3]); 28 } 29 for(int j = 4; j <= 6; j++) 30 { 31 for(int k = 1; k <= 3; k++) dist[j][k] = abs(b[j-3] - a[k]); 32 for(int k = 4; k <= 6; k++) dist[j][k] = abs(b[j-3] - b[k-3]); 33 } 34 for(int j = 1; j <= 3; j++) dist[j][j+3] = dist[j+3][j] = min(1, dist[j][j+3]); 35 for(int j = 1; j <= 6; j++) 36 for(int k = 1; k <= 6; k++) 37 for(int l = 1; l <= 6; l++) 38 dist[k][l] = min(dist[k][l], dist[k][j] + dist[j][l]); 39 int tmp = abs(a[0] - b[0]); 40 for(int j = 1; j <= 3; j++) 41 { 42 for(int k = 1; k <= 3; k++) tmp = min(tmp, abs(a[0] - a[j]) + dist[j][k] + abs(b[0] - a[k])); 43 for(int k = 4; k <= 6; k++) tmp = min(tmp, abs(a[0] - a[j]) + dist[j][k] + abs(b[0] - b[k-3])); 44 } 45 for(int j = 4; j <= 6; j++) 46 { 47 for(int k = 1; k <= 3; k++) tmp = min(tmp, abs(a[0] - b[j-3]) + dist[j][k] + abs(b[0] - a[k])); 48 for(int k = 4; k <= 6; k++) tmp = min(tmp, abs(a[0] - b[j-3]) + dist[j][k] + abs(b[0] - b[k-3])); 49 } 50 ans = (ans + (LL) tmp * i) % mod; 51 } 52 printf("%I64d\n", ans); 53 } 54 return 0; 55 }
HDU 5659 Deletion
二分二分图。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 const int INF = 1e9; 8 const int maxn = 2e5 + 10; 9 int lv[maxn], it[maxn]; 10 int cnt, h[maxn]; 11 int fm[maxn], to[maxn]; 12 13 struct edge 14 { 15 int to, pre, cap; 16 } e[maxn<<1]; 17 18 void init() 19 { 20 memset(h, -1, sizeof(h)); 21 cnt = 0; 22 } 23 24 void add(int from, int to, int cap) 25 { 26 e[cnt].pre = h[from]; 27 e[cnt].to = to; 28 e[cnt].cap = cap; 29 h[from] = cnt; 30 cnt++; 31 } 32 33 void ad(int from, int to, int cap) 34 { 35 add(from, to, cap); 36 add(to, from, 0); 37 } 38 39 void bfs(int s) 40 { 41 memset(lv, -1, sizeof(lv)); 42 queue<int> q; 43 lv[s] = 0; 44 q.push(s); 45 while(!q.empty()) 46 { 47 int v = q.front(); q.pop(); 48 for(int i = h[v]; i >= 0; i = e[i].pre) 49 { 50 int cap = e[i].cap, to = e[i].to; 51 if(cap > 0 && lv[to] < 0) 52 { 53 lv[to] = lv[v] + 1; 54 q.push(to); 55 } 56 } 57 } 58 } 59 60 int dfs(int v, int t, int f) 61 { 62 if(v == t) return f; 63 for(int &i = it[v]; i >= 0; i = e[i].pre) 64 { 65 int &cap = e[i].cap, to = e[i].to; 66 if(cap > 0 && lv[v] < lv[to]) 67 { 68 int d = dfs(to, t, min(f, cap)); 69 if(d > 0) 70 { 71 cap -= d; 72 e[i^1].cap += d; 73 return d; 74 } 75 } 76 } 77 return 0; 78 } 79 80 int Dinic(int s, int t) 81 { 82 int flow = 0; 83 while(1) 84 { 85 bfs(s); 86 if(lv[t] < 0) return flow; 87 memcpy(it, h, sizeof(it)); 88 int f; 89 while((f = dfs(s, t, INF)) > 0) flow += f; 90 } 91 } 92 93 int main(void) 94 { 95 int T; 96 scanf("%d", &T); 97 while(T--) 98 { 99 int n, m; 100 scanf("%d %d", &n, &m); 101 for(int i = 0; i < m; i++) scanf("%d %d", fm + i, to + i); 102 int S = n + m + 1, T = S + 1; 103 int l = 0, r = m, mid; 104 while(l < r) 105 { 106 init(); 107 mid = l + (r - l) / 2; 108 for(int i = 1; i <= n; i++) ad(S, i, mid); 109 for(int i = 0; i < m; i++) 110 { 111 ad(fm[i], n + i + 1, 1); 112 ad(to[i], n + i + 1, 1); 113 ad(n + i + 1, T, 1); 114 } 115 if(Dinic(S, T) == m) r = mid; 116 else l = mid + 1; 117 } 118 printf("%d\n", r); 119 } 120 return 0; 121 }