ACM-ICPC 2018 沈阳赛区网络预赛 Solution

A. Gudako and Ritsuka

留坑。

B. Call of Accepted

留坑。

C. Convex Hull

留坑。

D. Made In Heaven

题意:找第k短路

思路:A_star

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef long long ll;
  6 
  7 const int MOD = 1e9 + 7;
  8 const int INF = 0x3f3f3f3f;
  9 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
 10 
 11 #define N 1005
 12 #define M 50005
 13 
 14 int n, m, k;
 15 ll T;
 16 bool vis[N];
 17 int d[N];
 18 
 19 struct node {
 20     int v; int cost;
 21     node() {}
 22     node(int v, ll cost) : v(v), cost(cost){}
 23     inline bool operator < (const node &b) const {
 24         return cost + d[v] > b.cost + d[b.v];
 25     }
 26 }edge[M],revedge[M];
 27 
 28 struct Edge{
 29     int v, cost;
 30     inline Edge(){}
 31     inline Edge(int v, int cost):v(v), cost(cost){}
 32 };
 33 
 34 vector<Edge>E[N], revE[N];
 35 
 36 
 37 inline void Dijstra(int st)
 38 {
 39     memset(vis, false, sizeof vis);
 40     for (int i = 1; i <= n; ++i)
 41     {
 42         d[i] = INF;
 43     }
 44     priority_queue<node>q;
 45     d[st] = 0;
 46     q.push(node(st, 0));
 47     while (!q.empty())
 48     {
 49         node tmp = q.top();
 50         q.pop();
 51         int u = tmp.v;
 52         if (vis[u]) continue;
 53         vis[u] = true;
 54         int len = E[u].size();
 55         for (int i = 0; i < len; ++i)
 56         {
 57             int v = E[u][i].v;
 58             int cost = E[u][i].cost;
 59             if (!vis[v] && d[v] > d[u] + cost)
 60             {
 61                 d[v] = d[u] + cost;
 62                 q.push(node(v, d[v]));
 63             }
 64         }
 65     }
 66 }
 67 
 68 inline int A_star(int st, int ed)
 69 {
 70     priority_queue<node>q;
 71     q.push(node(st, 0));
 72     --k;
 73     while (!q.empty())
 74     {
 75         node tmp = q.top();
 76         q.pop();
 77         int u = tmp.v;
 78         if (u == ed)
 79         {
 80             if (k) --k;
 81             else return tmp.cost;
 82         }
 83         int len = revE[u].size(); 
 84         for (int i = 0; i < len; ++i)
 85         {
 86             int v = revE[u][i].v;
 87             int cost = revE[u][i].cost;
 88             q.push(node(v, tmp.cost + cost));
 89         }
 90     }
 91     return -1;
 92 }
 93 
 94 inline void addedge(int u, int v, int w)
 95 {
 96     revE[u].push_back(Edge(v, w));
 97     E[v].push_back(Edge(u, w));
 98 }
 99 
100 int st, ed;
101 
102 inline void RUN()
103 {
104     while (~scanf("%d %d", &n, &m))
105     {
106         for (int i = 0; i <= n; ++i)
107         {
108             E[i].clear();
109             revE[i].clear();
110         }
111         scanf("%d %d %d %lld", &st, &ed, &k, &T);
112         for (int i = 1; i <= m; ++i)
113         {
114             int u, v, w;
115             scanf("%d %d %d", &u, &v, &w);
116             addedge(u, v, w);
117         }
118         Dijstra(ed);
119         if (d[st] == INF)
120         {
121             puts("Whitesnake!");
122             continue;
123         }
124         int ans = A_star(st, ed);
125         if (ans == -1)
126         {
127             puts("Whitesnake!");
128             continue;
129         }
130         puts(ans <= T ? "yareyaredawa" : "Whitesnake!");
131     }
132 }
133 
134 int main()
135 {
136 #ifdef LOCAL_JUDGE
137     freopen("Text.txt", "r", stdin);
138 #endif // LOCAL_JUDGE
139 
140     RUN();
141 
142 #ifdef LOCAL_JUDGE
143     fclose(stdin);
144 #endif // LOCAL_JUDGE
145 
146 }
View Code

E. The cake is a lie

留坑。

F. Fantastic Graph

题意:给出一张二分图,若干条边,选择一些边进去,使得所有点的度数在$[L,R]$ 之间

思路:XDL说爆搜,加上优秀的剪枝(8ms)

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef long long ll;
  6 
  7 const int MOD = 1e9 + 7;
  8 const int INF = 0x3f3f3f3f;
  9 const int maxn = 1e4 + 10;
 10 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
 11 
 12 struct node {
 13     int l, r;
 14     inline node(){}
 15     inline node(int l,int r):l(l),r(r){}
 16 }arr[maxn];
 17 
 18 bool flag = false;
 19 int n, m, k;
 20 int sum;
 21 int res_L;
 22 int res_R;
 23 int L, R;
 24 int du_left[maxn];
 25 int du_right[maxn];
 26 
 27 inline void Init()
 28 {
 29     memset(du_left, 0, sizeof du_left);
 30     memset(du_right, 0, sizeof du_right);
 31 }
 32 
 33 inline void DFS(int idx, int cnt)
 34 {
 35     if (sum == n + m)
 36     {
 37         flag = true;
 38         return;
 39     }
 40     if (idx > k) return;
 41     if (k - idx + 1 + cnt < res_L) return;
 42     if (cnt >= res_R) return;
 43     if (flag) return;
 44     //do
 45     if (du_left[arr[idx].l] < R && du_right[arr[idx].r] < R)
 46     {
 47         du_left[arr[idx].l]++;
 48         du_right[arr[idx].r]++;
 49         if (du_left[arr[idx].l] == L) sum++;
 50         if (du_right[arr[idx].r] == L) sum++;
 51         DFS(idx + 1, cnt + 1);
 52         if (flag) return;
 53         if (du_left[arr[idx].l] == L) sum--;
 54         if (du_right[arr[idx].r] == L) sum--;
 55         du_left[arr[idx].l]--;
 56         du_right[arr[idx].r]--;
 57     }
 58     //not do
 59     DFS(idx + 1, cnt);
 60     if (flag) return;
 61 }
 62 
 63 inline void RUN()
 64 {
 65     int cas = 0;
 66     while (~scanf("%d %d %d", &n, &m, &k))
 67     {
 68         printf("Case %d: ", ++cas);
 69         Init();
 70         scanf("%d %d", &L, &R);
 71         int cnt = 0;
 72         for (int i = 1; i <= k; ++i)
 73         {
 74             scanf("%d %d", &arr[i].l, &arr[i].r);
 75             du_left[arr[i].l]++;
 76             du_right[arr[i].r]++;
 77             if (du_left[arr[i].l] == L) cnt++;
 78             if (du_right[arr[i].r] == L) cnt++;
 79         }
 80         if (L == 0)
 81         {
 82             puts("Yes");
 83             continue;
 84         }
 85         if (cnt != n + m )
 86         {
 87             puts("No");
 88             continue;
 89         }
 90         sum = 0;
 91         res_L = ((n + m) * L + 1) / 2;
 92         res_R = ((n + m) * R) / 2;
 93         Init();
 94         flag = false;
 95         DFS(1, 0);
 96         puts(flag ? "Yes" : "No");
 97     }
 98 }
 99 
100 int main()
101 {
102 #ifdef LOCAL_JUDGE
103     freopen("Text.txt", "r", stdin);
104 #endif // LOCAL_JUDGE
105 
106     RUN();
107 
108 #ifdef LOCAL_JUDGE
109     fclose(stdin);
110 #endif // LOCAL_JUDGE
111 
112 }
View Code

G. Spare Tire

题意:

思路:

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef long long ll;
  6 
  7 const int MOD = 1e9 + 7;
  8 const int INF = 0x3f3f3f3f;
  9 const int maxn = 1e4 + 10;
 10 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
 11 
 12 int tot;
 13 bool isprime[maxn];
 14 int prime[maxn];
 15 ll inv[maxn];
 16 
 17 
 18 inline void Init_prime()
 19 {
 20     inv[1] = 1;
 21     for (int i = 2; i < maxn; ++i)
 22     {
 23         inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
 24     }
 25     memset(isprime, true, sizeof isprime);
 26     tot = 0;
 27     for (int i = 2; i < maxn; ++i)
 28     {
 29         if (isprime[i])
 30         {
 31             prime[tot++] = i;
 32             for (int j = (i << 1); j < maxn; j += i)
 33             {
 34                 isprime[i] = false;
 35             }
 36         }
 37     }
 38 }
 39 
 40 vector<ll>vec;
 41 ll n, m;
 42 ll ans;
 43 
 44 inline void Init(ll x)
 45 {
 46     vec.clear();
 47     for (int i = 0; i < tot && prime[i] < x; ++i)
 48     {
 49         if (x % prime[i] == 0)
 50         {
 51             vec.push_back(prime[i]);
 52             while (x % prime[i] == 0)
 53             {
 54                 x /= prime[i];
 55             }
 56         }
 57     }
 58     if (x != 1) vec.push_back(x);
 59 }
 60 
 61 inline void RUN()
 62 {
 63     Init_prime();
 64     while (~scanf("%lld %lld", &n, &m))
 65     {
 66         ans = n % MOD * (n + 1) % MOD * (n + 2) % MOD * inv[3] % MOD;
 67         if (m == 1)
 68         {
 69             printf("%lld\n", ans);
 70             continue;
 71         }
 72         Init(m);
 73         int len = vec.size();
 74         for (int i = 1; i < (1 << len); ++i)
 75         {
 76             int cnt = 0;
 77             ll t = 1;
 78             for (int j = 0; j < len; ++j)
 79             {
 80                 if (i & (1 << j))
 81                 {
 82                     cnt++;
 83                     t *= vec[j];
 84                 }
 85             }
 86             ll x = n / t; 
 87             ll tmp = x % MOD * (x + 1) % MOD * (2 * x % MOD + 1) % MOD * inv[6] % MOD * t % MOD  * (t + 1) % MOD - x % MOD * (x + 1) % MOD * (x - 1) % MOD * inv[3] % MOD * t % MOD;
 88             tmp = (tmp + MOD) % MOD;
 89             if (cnt & 1)
 90             {
 91                 ans = (ans - tmp + MOD) % MOD;
 92             }
 93             else
 94             {
 95                 ans = (ans + tmp) % MOD;
 96             }
 97         }
 98         printf("%lld\n", ans);
 99     }
100 }
101 
102 int main()
103 {
104 #ifdef LOCAL_JUDGE
105     freopen("Text.txt", "r", stdin);
106 #endif // LOCAL_JUDGE
107 
108     RUN();
109 
110 #ifdef LOCAL_JUDGE
111     fclose(stdin);
112 #endif // LOCAL_JUDGE
113 
114 }
View Code

H. Hamming Weight

留坑。

I. Lattice's basics in digital electronics

按题意模拟即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 
 6 int t, n, m; 
 7 string str, tmp, ttmp, ans, s; 
 8 unordered_map <string, char> mp;
 9 unordered_map <char, string> mmp;
10 
11 inline void Init()
12 {
13     mmp.clear();
14     mmp['0'] = "0000";
15     mmp['1'] = "0001";
16     mmp['2'] = "0010";
17     mmp['3'] = "0011";
18     mmp['4'] = "0100";
19     mmp['5'] = "0101";
20     mmp['6'] = "0110";
21     mmp['7'] = "0111";
22     mmp['8'] = "1000";
23     mmp['9'] = "1001";
24     mmp['A'] = "1010";
25     mmp['B'] = "1011";
26     mmp['C'] = "1100";
27     mmp['D'] = "1101";
28     mmp['E'] = "1110";
29     mmp['F'] = "1111";
30     mmp['a'] = "1010";
31     mmp['b'] = "1011";
32     mmp['c'] = "1100";
33     mmp['d'] = "1101";
34     mmp['e'] = "1110";
35     mmp['f'] = "1111";
36 }
37 
38 inline bool ok(string s)
39 {
40     int cnt = 0;
41     for (int i = 0; i < 8; ++i) cnt += (s[i] == '1');
42     if ((s[8] == '0' && (cnt & 1)) || (s[8] == '1' && (cnt & 1) == 0)) return true;
43     return false;
44 }
45 
46 inline void Run()
47 {
48     cin.tie(0), cout.tie(0); Init();
49     ios::sync_with_stdio(false); 
50     cin >> t;
51     while (t--)
52     {
53         mp.clear(); cin >> m >> n;  
54         for (int i = 1, num; i <= n; ++i)  
55         {
56             cin >> num >> str;
57             mp[str] = num;
58         }
59         cin >> s; tmp = ""; str = "";
60         for (int i = 0, len = s.size(); i < len; ++i)
61             tmp += mmp[s[i]];  
62         for (int i = 0, len = tmp.size(); i < len; )
63         {
64             if (len - i < 9) break; 
65             ttmp = "";
66             for (int cnt = 0; cnt < 9; ++cnt, ++i)   
67                 ttmp += tmp[i];
68             if (ok(ttmp))
69             {
70                 ttmp.erase(ttmp.end() - 1);  
71                 str += ttmp;
72                 //cout << ttmp << endl;
73             }
74         }
75         //for (auto it : mp) cout << it.first << " " << it.second << endl;
76         ans.clear(), tmp.clear();
77         for (int i = 0, len = str.size(); i < len && ans.size() < m; ++i) 
78         {
79             tmp += str[i];
80             if (mp.find(tmp) != mp.end())
81             {
82                 ans += mp[tmp]; 
83                 tmp = ""; 
84             }
85         }
86         cout << ans << endl;
87     }
88 }
89 
90 int main()
91 {
92     #ifdef LOCAL
93         freopen("Test.in", "r", stdin);
94     #endif
95 
96     Run();
97     return 0;
98 }
View Code

J. Ka Chang

题意:两种操作 $1 L X$ 所有深度为L的加上x $2 X$ 查询以x为根的所有子节点的和

思路:以x为根的子节点的和可以用DFS序使得所有子树的标号在一块

然后对于更新操作,考虑两种方法操作

1° 暴力更新每个点

2° 记录这个深度更新了多少,查询的时候找出这个深度中有子节点有几个  直接加上

如果只用第二个操作更新,那么当给的树是一条链的时候,查询的复杂度达到$O(nlogn)$

只用第一个操作更新,那么更新的操作当给的树是菊花形的时候,更新的复杂度达到$O(nlogn)$

那么考虑将两种操作结合,当某个深度中元素个数大于sqrt(100000) 的时候,用第二种操作 否则用第一种

然后查询的时候 要记得 都加上

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define ll long long 
  6 
  7 struct Edge
  8 {
  9     int to, nx;
 10     inline Edge() {}
 11     inline Edge(int to, int nx) : to(to), nx(nx) {}
 12 }edge[N << 1]; 
 13 
 14 int n, q, Maxdeep; 
 15 int head[N], pos;
 16 int ord[N], son[N], deep[N], fa[N], cnt; 
 17 vector <int> dep[N], Lar;
 18 ll sum[N]; 
 19 
 20 inline void Init()
 21 {
 22     memset(head, -1, sizeof head);
 23     pos = 0; cnt = 0; Maxdeep = 0; Lar.clear(); 
 24     for (int i = 0; i <= 1; ++i) dep[i].clear();
 25     fa[1] = 1; deep[1] = 0; 
 26 }
 27 
 28 inline void addedge(int u, int v)
 29 {
 30     edge[++pos] = Edge(v, head[u]); head[u] = pos;
 31 }
 32 
 33 inline void DFS(int u, int pre)
 34 {
 35     ord[u] = ++cnt; 
 36     dep[deep[u]].emplace_back(cnt); 
 37     Maxdeep = max(Maxdeep, deep[u]);
 38     for (int it = head[u]; ~it; it = edge[it].nx)
 39     {
 40         int v = edge[it].to;
 41         if (v == pre) continue;
 42         deep[v] = deep[u] + 1;
 43         DFS(v, u);
 44     }
 45     son[u] = cnt; 
 46 }
 47 
 48 struct node
 49 {
 50     int l, r;
 51     ll sum;
 52     inline node() {}
 53     inline node(int l, int r, ll sum) : l(l), r(r), sum(sum) {}
 54 }tree[N << 2];
 55 
 56 inline void pushup(int id)
 57 {
 58     tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
 59 }
 60 
 61 inline void build(int id, int l, int r)
 62 {
 63     tree[id] = node(l, r, 0);
 64     if (l == r) return;
 65     int mid = (l + r) >> 1;
 66     build(id << 1, l, mid);
 67     build(id << 1 | 1, mid + 1, r);
 68 }
 69 
 70 inline void update(int id, int pos, ll val)
 71 {
 72     if (tree[id].l == tree[id].r)
 73     {
 74         tree[id].sum += val;
 75         return;
 76     }
 77     int mid = (tree[id].l + tree[id].r) >> 1;
 78     if (pos <= mid) update(id << 1, pos, val);
 79     else if (pos > mid) update(id << 1 | 1, pos, val);
 80     pushup(id);
 81 }
 82 
 83 ll anssum;
 84 
 85 inline void query(int id, int l, int r)
 86 {
 87     if (tree[id].l >= l && tree[id].r <= r)
 88     {
 89         anssum += tree[id].sum;
 90         return;
 91     }
 92     int mid = (tree[id].l + tree[id].r) >> 1;
 93     if (l <= mid) query(id << 1, l, r);
 94     if (r > mid) query(id << 1 | 1, l, r);
 95 }
 96 
 97 inline void Run()
 98 {
 99     while (scanf("%d%d", &n, &q) != EOF)
100     {
101         Init(); 
102         for (int i = 1, u, v; i < n; ++i)
103         {
104             scanf("%d%d", &u, &v);
105             addedge(u, v); addedge(v, u);
106         }
107         DFS(1, 1); build(1, 1, n);
108         int limit = (int)sqrt(100000);  
109         for (int i = 1; i <= Maxdeep; ++i)
110         {
111             if (dep[i].size() >= limit)
112             {
113                 Lar.emplace_back(i);
114                 sort(dep[i].begin(), dep[i].end()); 
115             }
116         }
117         for (int i = 1, op, l, x; i <= q; ++i)
118         {
119             scanf("%d", &op);
120             if (op == 1)
121             {
122                 scanf("%d%d", &l, &x); 
123                 if (dep[l].size() < limit)
124                 {
125                     for (auto it : dep[l]) update(1, it, (ll)x); 
126                 }
127                 else
128                     sum[l] += (ll)x;              
129             }
130             else
131             {
132                 scanf("%d", &x);
133                 anssum = 0; query(1, ord[x], son[x]);
134                 ll ans = anssum;
135                 int l = ord[x], r = son[x];
136                 for (auto it : Lar)
137                 {
138                     if (it < deep[x]) continue;
139                     int k = upper_bound(dep[it].begin(), dep[it].end(), r) - lower_bound(dep[it].begin(), dep[it].end(), l);
140                     if (k == 0) break;
141                     ans += sum[it] * k;
142                 }
143                 printf("%lld\n", ans);
144             }
145         }
146     }
147 }
148 
149 int main()
150 {
151     #ifdef LOCAL 
152         freopen("Test.in", "r", stdin);
153     #endif  
154 
155     Run();
156     return 0;
157 }
View Code

K. Supreme Number

只有几个数,爆搜出来,判断一下

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 const int MOD = 1e9 + 7;
 8 const int INF = 0x3f3f3f3f;
 9 const int maxn = 2e6 + 10;
10 
11 string s[] = { "1","2","3","5","7","11","13","17","23","31","37","53","71","73","113","131","137","173","311","317" };
12 
13 inline void RUN()
14 {
15     int t;
16     cin >> t;
17     for (int cas = 1; cas <= t; ++cas)
18     {
19         cout << "Case #" << cas << ": ";
20         string ans;
21         string str;
22         cin >> str;
23         for (int i = 0; i < 20; ++i)
24         {
25             if (str.length() == s[i].length())
26             {
27                 if (str >= s[i]) ans = s[i];
28             }
29             else if (str.length() < s[i].length())
30             {
31                 continue;
32             }
33             else ans = s[i];
34         }
35         cout << ans << endl;
36     }
37 }
38 
39 int main()
40 {
41 #ifdef LOCAL_JUDGE
42     freopen("Text.txt", "r", stdin);
43 #endif // LOCAL_JUDGE
44     ios::sync_with_stdio(false);
45     cin.tie(0);
46     cout.tie(0);
47     RUN();
48 
49 #ifdef LOCAL_JUDGE
50     fclose(stdin);
51 #endif // LOCAL_JUDGE
52 
53 }
View Code

猜你喜欢

转载自www.cnblogs.com/Dup4/p/9609757.html