2018 计蒜之道 初赛 第一场
Posted Algorithms Crush Me
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 计蒜之道 初赛 第一场相关的知识,希望对你有一定的参考价值。
二分
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 2e4 + 10; LL a[maxn]; int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%lld", a + i); LL p, s; scanf("%lld %lld", &p, &s); int l = 1, r = 20000; while(l < r){ int mid = (l + r) >> 1; LL t = 0; for(int i = 1; i <= n; ++i) t += max(0LL, a[i] - mid); if(t * p <= s) r = mid; else l = mid + 1; } printf("%d\n", r); return 0; }
主席树建图
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 1e5 + 10; 5 int a[maxn]; 6 7 LL f[maxn * 35]; 8 9 // Persistent SegmentTree 10 vector<int> G[maxn * 35]; 11 12 struct node { 13 int tag, ls, rs; 14 } nod[maxn * 35]; 15 16 int cnt; 17 int id[maxn]; 18 void build(int p, int tl, int tr){ 19 cnt++; 20 if(tl == tr){ 21 id[tl] = p; 22 nod[p].tag = a[tl]; 23 return; 24 } 25 int mid = (tl + tr) >> 1; 26 nod[p].ls = cnt + 1, G[p].push_back(cnt + 1), build(cnt + 1, tl, mid); 27 nod[p].rs = cnt + 1, G[p].push_back(cnt + 1), build(cnt + 1, mid + 1, tr); 28 } 29 void update(int l, int r, int &x, int y, int pos, int v) { 30 nod[++cnt] = nod[y]; 31 x = cnt; 32 if (l == r) { 33 id[l] = x; 34 nod[x].tag = v; 35 return; 36 } 37 int mid = (l + r) >> 1; 38 if (pos <= mid) update(l, mid, nod[x].ls, nod[y].ls, pos, v); 39 else update(mid + 1, r, nod[x].rs, nod[y].rs, pos, v); 40 G[x].push_back(nod[x].ls); 41 G[x].push_back(nod[x].rs); 42 } 43 void query(int p, int tl, int tr, int l, int r, int x) 44 { 45 if(tr < l || r < tl) return; 46 if(l <= tl && tr <= r){ 47 G[x].push_back(p); 48 return; 49 } 50 int mid = (tl + tr) >> 1; 51 query(nod[p].ls, tl, mid, l, r, x); 52 query(nod[p].rs, mid + 1, tr, l, r, x); 53 return; 54 } 55 56 // Tarjan 57 stack<int> S; 58 int dfs_clock, dfn[maxn * 35], low[maxn * 35]; 59 int bcc_cnt, bccno[maxn * 35]; 60 void dfs(int u) 61 { 62 dfn[u] = low[u] = ++dfs_clock; 63 S.push(u); 64 for(int i = 0; i < G[u].size(); i++) 65 { 66 int v = G[u][i]; 67 if(!dfn[v]) 68 { 69 dfs(v); 70 low[u] = min(low[u], low[v]); 71 } 72 else if(!bccno[v]) low[u] = min(low[u], dfn[v]); 73 } 74 75 if(low[u] == dfn[u]) 76 { 77 bcc_cnt++; 78 while(1) 79 { 80 int x = S.top(); S.pop(); 81 bccno[x] = bcc_cnt; 82 if(x == u) break; 83 } 84 } 85 } 86 87 void find_bcc(int n) 88 { 89 memset(dfn, 0, sizeof(dfn)); 90 memset(bccno, 0, sizeof(bccno)); 91 dfs_clock = bcc_cnt = 0; 92 for(int i = 1; i <= n; i++) if(!dfn[i]) dfs(i); 93 } 94 95 int main(){ 96 int N, M, rt = 1; 97 scanf("%d", &N); 98 for(int i = 1; i <= N; ++i) scanf("%d", a + i); 99 build(1, 1, N); 100 scanf("%d", &M); 101 while(M--){ 102 int op, x, y, l, r; 103 scanf("%d %d", &op, &x); 104 if(op == 0){ 105 scanf("%d", &y); 106 update(1, N, rt, rt, x, y); 107 } 108 else{ 109 scanf("%d %d", &l, &r); 110 query(rt, 1, N, l, r, id[x]); 111 } 112 } 113 assert(cnt < maxn * 35); 114 find_bcc(cnt); 115 for(int i = 1; i <= cnt; ++i){ 116 f[bccno[i]] += nod[i].tag; 117 for(int j = 0; j < G[i].size(); ++j){ 118 int to = G[i][j]; 119 if(bccno[to] != bccno[i]) f[bccno[i]] = 1e18; 120 } 121 } 122 LL ans = 1e18; 123 for(int i = 1; i <= bcc_cnt; ++i){ 124 ans = min(ans, f[i]); 125 } 126 printf("%lld\n", ans); 127 return 0; 128 }
以上是关于2018 计蒜之道 初赛 第一场的主要内容,如果未能解决你的问题,请参考以下文章