Advertisement
Guest User

NAC 2020 J

a guest
Feb 24th, 2020
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.43 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int MX = 6000, N = 31;
  5.  
  6. int n, m, a, cnt[N];
  7. vector<int> adj[MX][N];
  8. bool chk[2][MX];
  9. vector<int> ve;
  10. vector<vector<int>> par;
  11.  
  12. struct trie {
  13.     int ind;
  14.     trie *ch[N];
  15.  
  16.     trie(int _ind = 0) : ind(_ind) {
  17.         fill(ch, ch + N, nullptr);
  18.     }
  19.  
  20.     trie *access(int u) {
  21.         if (ch[u] == nullptr) {
  22.             ch[u] = new trie();
  23.         }
  24.         return ch[u];
  25.     }
  26. } *rt = new trie();
  27.  
  28. void make_partition(int n, int cur, trie *nod = rt) {
  29.     if (n == 0) {
  30.         nod->ind = par.size();
  31.         par.push_back(ve);
  32.     }
  33.     if (n < cur) {
  34.         return;
  35.     }
  36.     ve.push_back(cur);
  37.     make_partition(n - cur, cur, nod->access(cur));
  38.     ve.pop_back();
  39.     make_partition(n, cur + 1, nod);
  40. }
  41.  
  42. void make_edge(vector<int> &pr, int x, int pos = 0, int cur = 0, int sum = 0) {
  43.     if (sum > n / 2) {
  44.         return;
  45.     }
  46.     if (pos == pr.size()) {
  47.         trie *nod = rt;
  48.         for (int i = 1; i <= n; i++) {
  49.             for (int j = 0; j < cnt[i]; j++) {
  50.                 nod = nod->access(i);
  51.             }
  52.         }
  53.         adj[x][sum].push_back(nod->ind);
  54.         ve.clear();
  55.     } else {
  56.         cnt[cur]++; cnt[pr[pos] - cur]++;
  57.         int nxt = (pos + 1 == pr.size() || pr[pos + 1] == pr[pos] ? cur : 0);
  58.         make_edge(pr, x, pos + 1, nxt, sum + cur);
  59.         cnt[cur]--; cnt[pr[pos] - cur]--;
  60.         if (cur < pr[pos]) {
  61.             make_edge(pr, x, pos, cur + 1, sum);
  62.         }
  63.     }
  64. }
  65.  
  66. int main() {
  67.     ios_base::sync_with_stdio(false);
  68.     cin.tie(nullptr);
  69.     cin >> n >> m;
  70.     make_partition(n, 1);
  71.     for (int i = 0; i < par.size(); i++) {
  72.         make_edge(par[i], i);
  73.     }
  74.     int cur = 1, prv = 0;
  75.     chk[1][par.size() - 1] = true;
  76.     for (int i = 0; i < m; i++) {
  77.         swap(cur, prv);
  78.         fill(chk[cur], chk[cur] + par.size(), false);
  79.         cin >> a;
  80.         a = min(a, n - a);
  81.         for (int j = 0; j < par.size(); j++) {
  82.             if (chk[prv][j]) {
  83.                 for (int &v : adj[j][a]) {
  84.                     chk[cur][v] = true;
  85.                 }
  86.             }
  87.         }
  88.     }
  89.     int mx = 0;
  90.     for (int i = 0; i < par.size(); i++) {
  91.         if (chk[cur][i]) {
  92.             int cnt = 0;
  93.             for (int j = 0; j < par[i].size(); j++) {
  94.                 cnt += (par[i][j] == 1);
  95.             }
  96.             mx = max(mx, cnt);
  97.         }
  98.     }
  99.     cout << mx << '\n';
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement