[Offer收割]编程练习赛58

最大的K-偏差排列

分类讨论

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int p[111];
 4 
 5 int main() {
 6     int N, K;
 7     scanf("%d %d", &N, &K);
 8     for (int i = 1; i <= N; ++i) p[i] = i;
 9     for (int i = 1; i + K + K - 1 <= N; i += K + K) {
10         for (int j = i; j < i + K; ++j) swap(p[j], p[j + K]);
11     }
12     int t = N / (K + K) * (K + K);
13     if (N - t > K) {
14         for(int i = t + 1; i + K <= N; ++i) swap(p[i], p[i+K]);
15         for(int i = N - K + 1, j = t + K; i < j; ++i, --j) swap(p[i], p[j]);
16     } else {
17         for (int i = t + 1, j = N; i < j; ++i, --j) swap(p[i], p[j]);
18     }
19     for (int i = 1; i <= N; ++i) printf("%d%c", p[i], i == N ? '
' : ' ');
20     return 0;
21 }
Aguin

孤独的字符

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 typedef long long LL;
 5 vector<int> p[26];
 6 char T[maxn];
 7 
 8 int main() {
 9     scanf("%s", T + 1);
10     int lt = strlen(T + 1);
11     for (int i = 0; i < 26; ++i) p[i].push_back(0);
12     for (int i = 1; i <= lt; ++i) p[T[i] - 'a'].push_back(i);
13     for (int i = 0; i < 26; ++i) p[i].push_back(lt + 1);
14     LL ans = 0;
15     for (int i = 0; i < 26; ++i) {
16         for (int j = 1; j < p[i].size() - 1; ++j) ans += (LL) (p[i][j] - p[i][j - 1]) * (p[i][j + 1] - p[i][j]);
17     }
18     printf("%lld
", ans);
19     return 0;
20 }
Aguin

秋天来了

好像只有我线段树建图缩点了…好像离线就可以直接线段树了…

UPD:出题人说直接扫一遍就好了QAQ

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef pair<int, int> pii;
  4 const int maxn = 1e5 + 10;
  5 int id[maxn], MP;
  6 
  7 int deg[maxn<<2], ans[maxn<<2];
  8 vector<pii> G[maxn<<2], GG[maxn<<2];
  9 void build(int p, int tl, int tr) {
 10     MP = max(MP, p);
 11     if (tl < tr) {
 12         int mid = (tl + tr) >> 1;
 13         build(p << 1, tl, mid);
 14         G[p].push_back(pii(p << 1, 0));
 15         build(p << 1 | 1, mid + 1, tr);
 16         G[p].push_back(pii(p << 1 | 1, 0));
 17     } else id[tl] = p;
 18 }
 19 void add(int p, int tl, int tr, int l, int r, int x) {
 20     if (l > tr || r < tl) return;
 21     if (l <= tl && tr <= r) {
 22         G[x].push_back(pii(p, 1));
 23         return;
 24     }
 25     int mid = (tl + tr) >> 1;
 26     add(p << 1, tl, mid, l, r, x);
 27     add(p << 1 | 1, mid + 1, tr, l, r, x);
 28 }
 29 
 30 // BCC
 31 stack<int> S;
 32 int dfs_clock, dfn[maxn<<2], low[maxn<<2];
 33 int bcc_cnt, bccno[maxn<<2];
 34 void dfs(int u)
 35 {
 36     dfn[u] = low[u] = ++dfs_clock;
 37     S.push(u);
 38     for(int i = 0; i < G[u].size(); i++)
 39     {
 40         int v = G[u][i].first;
 41         if(!dfn[v])
 42         {
 43             dfs(v);
 44             low[u] = min(low[u], low[v]);
 45         }
 46         else if(!bccno[v]) low[u] = min(low[u], dfn[v]);
 47     }
 48 
 49     if(low[u] == dfn[u])
 50     {
 51         bcc_cnt++;
 52         while(1)
 53         {
 54             int x = S.top(); S.pop();
 55             bccno[x] = bcc_cnt;
 56             if(x == u) break;
 57         }
 58     }
 59 }
 60 
 61 void find_bcc(int n)
 62 {
 63     memset(dfn, 0, sizeof(dfn));
 64     memset(bccno, 0, sizeof(bccno));
 65     dfs_clock = bcc_cnt = 0;
 66     for(int i = 1; i <= n; i++) if(!dfn[i]) dfs(i);
 67 }
 68 
 69 queue<int> q;
 70 int main() {
 71     int N, I, H, R;
 72     scanf("%d %d %d %d", &N, &I, &H, &R);
 73     build(1, 1, N);
 74     for(int i = 1; i <= R; ++i){
 75         int A, B;
 76         scanf("%d %d", &A, &B);
 77         G[id[B]].push_back(pii(id[A], 0));
 78         if(min(A, B) < max(A, B) - 1) add(1, 1, N, min(A, B) + 1, max(A, B) - 1, id[A]);
 79     }
 80     find_bcc(MP);
 81     for(int i = 1; i <= MP; ++i){
 82         for(int j = 0; j < G[i].size(); ++j){
 83             int to = G[i][j].first, d = G[i][j].second;
 84             if(bccno[i] != bccno[to]){
 85                 deg[bccno[to]]++;
 86                 GG[bccno[i]].push_back(pii(bccno[to], d));
 87             }
 88         }
 89     }
 90     for(int i = 1; i <= bcc_cnt; ++i) {
 91         ans[i] = H;
 92         if(deg[i] == 0) q.push(i);
 93     }
 94     while (!q.empty()){
 95         int x = q.front();
 96         q.pop();
 97         for(int i = 0; i < GG[x].size(); ++i){
 98             int to = GG[x][i].first, d = GG[x][i].second;
 99             deg[to]--;
100             ans[to] = min(ans[to], ans[x] - d);
101             if(deg[to] == 0) q.push(to);
102         }
103     }
104     for(int i = 1; i <= N; ++i) printf("%d
", ans[bccno[id[i]]]);
105     return 0;
106 }
Aguin

Nim森林

又爆LL也是服气…int128真叼

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 typedef long long LL;
 5 LL a[maxn], W[maxn], b[66];
 6 int id[maxn];
 7 
 8 bool cmp(int i, int j) {
 9     return W[i] > W[j];
10 }
11 
12 void print(__int128 x){
13     string s = "";
14     while(x) s += x % 10 + '0', x /= 10;
15     reverse(s.begin(), s.end());
16     if(s == "") s = "0";
17     cout << s << endl;
18     return;
19 }
20 
21 int main(){
22     int N, one = 0;
23     scanf("%d", &N);
24     N--;
25     __int128 tot = 0, sum = 0;
26     for(int i = 1; i <= N; ++i){
27         LL u, v;
28         scanf("%lld %lld %lld %lld", &u, &v, a + i, W + i);
29         W[i] ^= u ^ v;
30         tot += W[i];
31         id[i] = i;
32         if(a[i] == 1) one++;
33     }
34     if(one == N) {
35         puts("No");
36         return 0;
37     }
38     sort(id + 1, id + 1 + N, cmp);
39     for(int i = 1; i <= N; ++i){
40         int x = id[i];
41         if(a[x] == 1) continue;
42         for(int j = 0; j <= 60; ++j){
43             if(a[x] & (1LL << j)){
44                 if(b[j]) a[x] ^= b[j];
45                 else {
46                     b[j] = a[x];
47                     sum += W[x];
48                     break;
49                 }
50             }
51         }
52     }
53     print(tot - sum);
54     return 0;
55 }
Aguin
原文地址:https://www.cnblogs.com/Aguin/p/8998441.html