zoukankan      html  css  js  c++  java
  • 2018 Multi-University Training Contest 5

    贱贱补不动题了T^T

    Always Online

    发现之前的点双都在乱写,就顺便花了点时间重造板子

    考虑一个仙人掌,割要么是一条树边要么是环上两条边,注意到切环时其中一条一定是环上最小的

    跑一遍Tarjan搞出所有点双,把环上最小边切了权值加到环上其他边上,这样转化为树上问题

    树上做法,类似于Kruskal从大到小合并边,两边的子树大小乘积为这条边的贡献

    由于这里的贡献带了异或,按位考虑即可,注意答案暴了ll

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef unsigned long long ull;
      4 const int maxn = 1e5 + 10;
      5 const int maxm = 2e5 + 10;
      6 int u[maxm], v[maxm], w[maxm];
      7 vector<int> G[maxn], E;
      8 bool cmp(int i, int j) {
      9     return w[i] > w[j];
     10 }
     11 
     12 // BCC
     13 stack<int> S;
     14 vector<int> bcc[maxm];
     15 int bcc_cnt, bccno[maxm];
     16 int dfs_clock, dfn[maxn], low[maxn], iscut[maxn];
     17 void dfs(int x, int fe) { // fe 表示父边 id
     18     low[x] = dfn[x] = ++dfs_clock;
     19     int ch = 0;
     20     for (int i = 0; i < G[x].size(); ++i) {
     21         int e = G[x][i];
     22         if (e == fe) continue;
     23         int y = u[e] == x ? v[e] : u[e];
     24         if (!dfn[y]) {
     25             S.push(e);
     26             ch++, dfs(y, e); // 注意是 e
     27             low[x] = min(low[x], low[y]);
     28             if (low[y] >= dfn[x]) {
     29                 iscut[x] = 1;
     30                 bcc_cnt++;
     31                 while (1) {
     32                     int t = S.top();
     33                     S.pop();
     34                     bccno[t] = bcc_cnt;
     35                     bcc[bcc_cnt].push_back(t);
     36                     if (t == e) break;
     37                 }
     38             }
     39         } else if (dfn[y] < dfn[x]) {
     40             low[x] = min(low[x], dfn[y]);
     41             S.push(e);
     42         }
     43     }
     44     if (!fe && ch == 1) iscut[x] = 0;
     45 }
     46 void find_bcc(int n, int m) {
     47     dfs_clock = bcc_cnt = 0;
     48     for (int i = 0; i <= n; ++i) dfn[i] = iscut[i] = 0;
     49     for (int i = 0; i <= m; ++i) bccno[i] = 0, bcc[i].clear();
     50     for (int i = 1; i <= n; ++i) if (!dfn[i]) dfs(i, 0);
     51 }
     52 
     53 int fa[maxn], r[maxn][31][2];
     54 void init(int n) {
     55     for(int i = 0; i <= n; ++i) {
     56         fa[i] = i;
     57         for(int j = 0; j <= 30; ++j) {
     58             r[i][j][1] = (i & (1 << j)) ? 1 : 0;
     59             r[i][j][0] = 1 - r[i][j][1];
     60         }
     61     }
     62 }
     63 int Find(int x) {
     64     return fa[x] == x ? x : fa[x] = Find(fa[x]);
     65 }
     66 void Union(int x, int y) {
     67     x = Find(x), y = Find(y);
     68     if(x == y) return;
     69     fa[x] = y;
     70     for(int j = 0; j <= 30; ++j)
     71         for(int k = 0; k <= 1; ++k) r[y][j][k] += r[x][j][k];
     72 }
     73 
     74 int main() {
     75     int T;
     76     scanf("%d", &T);
     77     while(T--) {
     78         int n, m;
     79         scanf("%d %d", &n, &m);
     80         for(int i = 1; i <= n; ++i) G[i].clear();
     81         for(int i = 1; i <= m; ++i) {
     82             scanf("%d %d %d", u + i, v + i, w + i);
     83             G[u[i]].push_back(i);
     84             G[v[i]].push_back(i);
     85         }
     86         find_bcc(n, m);
     87         E.clear();
     88         for(int i = 1; i <= bcc_cnt; ++i) {
     89             if(bcc[i].size() == 1) {
     90                 E.push_back(bcc[i][0]);
     91                 continue;
     92             }
     93             int mi = 1000000000, p;
     94             for(int j = 0; j < bcc[i].size(); ++j) {
     95                 int x = bcc[i][j];
     96                 if(w[x] < mi) mi = w[x], p = j;
     97             }
     98             for(int j = 0; j < bcc[i].size(); ++j) {
     99                 if(j == p) continue;
    100                 int x = bcc[i][j];
    101                 E.push_back(x), w[x] += mi;
    102             }
    103         }
    104         init(n);
    105         ull ans = 0;
    106         sort(E.begin(), E.end(), cmp);
    107         for(int i = 0; i < E.size(); ++i) {
    108             int x = E[i], U = Find(u[x]), V = Find(v[x]), W = w[x];
    109             for(int j = 0; j <= 30; ++j) {
    110                 if(W & (1 << j)) ans += ((ull) r[U][j][0] * r[V][j][0] + (ull) r[U][j][1] * r[V][j][1]) * (1 << j);
    111                 else ans += ((ull) r[U][j][0] * r[V][j][1] + (ull) r[U][j][1] * r[V][j][0]) * (1 << j);
    112             }
    113             Union(U, V);
    114         }
    115         printf("%llu
    ", ans);
    116     }
    117     return 0;
    118 }
    Aguin

    Beautiful Now

    暴力全排列竟然过了

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 vector< vector<int> > P[11];
     4 vector<int> num[11];
     5 
     6 int main() {
     7     int fac = 1;
     8     for(int i = 1; i <= 9; ++i) {
     9         fac *= i;
    10         vector<int> v;
    11         for(int j = 1; j <= i; ++j) v.push_back(j);
    12         for(int j = 0; j < fac; ++j) {
    13             int vis[11] = {0}, cnt = 0;
    14             for(int k = 1; k <= i; ++k) {
    15                 if(vis[k]) continue;
    16                 int p = k;
    17                 while(!vis[p]) vis[p] = 1, p = v[p - 1], cnt++;
    18                 cnt--;
    19             }
    20             P[i].push_back(v);
    21             num[i].push_back(cnt);
    22             next_permutation(v.begin(), v.end());
    23         }
    24     }
    25     int T;
    26     scanf("%d", &T);
    27     while(T--) {
    28         int n, k;
    29         scanf("%d %d", &n, &k);
    30         if(n == 1000000000) {
    31             puts("1000000000 1000000000");
    32             continue;
    33         }
    34         int mi = n, ma = n, b = 0, d[11] = {0};
    35         while(n) d[++b] = n % 10, n /= 10;
    36         for(int i = 0; i < P[b].size(); ++i) {
    37             if(num[b][i] > k) continue;
    38             if(b > 1 && d[P[b][i][b - 1]] == 0) continue;
    39             int x = 0;
    40             for(int j = b - 1; j >= 0; --j) x = x * 10 + d[P[b][i][j]];
    41             mi = min(x, mi), ma = max(x, ma);
    42         }
    43         printf("%d %d
    ", mi, ma);
    44     }
    45     return 0;
    46 }
    Aguin

    Call It What You Want

    传说中的Easy题

    分圆多项式有$(1 - x^n) = prod_{d|n}Phi_{d}(x)$,莫比乌斯反演一下$Phi_{n}(x)=prod_{d|n}(1 - x^{frac{n}{d}})^{mu(d)}$

    题面说了$Phi_{n}(x)$是$varphi(n)$次多项式,而一个数最多只有$6$个不同的素因子,考虑莫比乌斯函数不为$0$的项,求单个$Phi_{n}(x)$最多做$2^6$次多项式乘除法

    而每次乘除的都是一个只有两项的多项式,可以直接在模$x^{varphi(n) + 1}$下算,用类似背包的写法,单次就是$varphi(n)$的复杂度

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef pair<int, int> pii;
      4 const int maxn = 1e5 + 10;
      5 
      6 int tot, check[maxn], prime[maxn], phi[maxn], mu[maxn];
      7 void Sieve() {
      8     tot = 0;
      9     phi[1] = mu[1] = 1;
     10     memset(check, 0, sizeof(check));
     11     for(int i = 2; i < maxn; ++i) {
     12         if(!check[i]) prime[++tot] = i, phi[i] = i - 1, mu[i] = -1;
     13         for(int j = 1; j <= tot; ++j) {
     14             if(i * prime[j] >= maxn) break;
     15             check[i * prime[j]] = 1;
     16             if(i % prime[j] == 0) {
     17                 phi[i * prime[j]] = phi[i] * prime[j];
     18                 mu[i * prime[j]] = 0;
     19                 break;
     20             }
     21             else {
     22                 phi[i * prime[j]] = phi[i] * (prime[j] - 1);
     23                 mu[i * prime[j]] = -mu[i];
     24             }
     25         }
     26     }
     27 }
     28 
     29 vector<int> fac[maxn], Mul[maxn], Div[maxn];
     30 vector< vector<pii> > v;
     31 vector<int> id;
     32 bool cmp(int i, int j) {
     33     for(int k = 0; ; ++k) {
     34         if(k == v[i].size()) return v[j][k].second > 0;
     35         if(k == v[j].size()) return v[i][k].second < 0;
     36         if(v[i][k].first > v[j][k].first) return v[i][k].second < 0;
     37         if(v[i][k].first < v[j][k].first) return v[j][k].second > 0;
     38         if(v[i][k].second != v[j][k].second) return v[i][k].second < v[j][k].second;
     39     }
     40 }
     41 void solve(int n) {
     42     vector<int> p(phi[n] + 1, 0);
     43     p[0] = 1;
     44     for(int i = 0; i < Mul[n].size(); ++i) {
     45         int k = Mul[n][i];
     46         for(int j = phi[n]; j - k >= 0; --j) p[j] -= p[j - k];
     47     }
     48     for(int i = 0; i < Div[n].size(); ++i) {
     49         int k = Div[n][i];
     50         for(int j = 0; j + k <= phi[n]; ++j) p[j + k] += p[j];
     51     }
     52     vector<pii> t;
     53     for(int i = phi[n]; i >= 0; --i) {
     54         if(p[i] == 0) continue;
     55         t.push_back(pii(i, p[i]));
     56     }
     57     v.push_back(t);
     58 }
     59 
     60 void p(vector<pii> &t) {
     61     stringstream s;
     62     s << "(";
     63     int flag = 0;
     64     for(int k = 0; k < t.size(); ++k) {
     65         int x = t[k].first, y = t[k].second;
     66         if(y < 0) s << "-";
     67         else if(flag) s << "+";
     68         if(abs(y) != 1) s << abs(y);
     69         if(x > 0) s << "x";
     70         else if(abs(y) == 1) s << "1";
     71         if(x > 1) s << "^" << x;
     72         flag = 1;
     73     }
     74     s << ")";
     75     cout << s.str();
     76 }
     77 
     78 int main() {
     79     Sieve();
     80     for(int i = 1; i <= 100000; ++i) {
     81         for(int j = i; j <= 100000; j += i) fac[j].push_back(i);
     82         if(!mu[i]) continue;
     83         for(int j = i; j <= 100000; j += i) {
     84             if(mu[i] == 1) Mul[j].push_back(j / i);
     85             else Div[j].push_back(j / i);
     86         }
     87     }
     88     int T;
     89     scanf("%d", &T);
     90     while(T--) {
     91         int n;
     92         scanf("%d", &n);
     93         v.clear(), id.clear();
     94         for(int i = 0; i < fac[n].size(); ++i) if(fac[n][i] > 1) solve(fac[n][i]);
     95         for(int i = 0; i < v.size(); ++i) id.push_back(i);
     96         sort(id.begin(), id.end(), cmp);
     97         printf("(x-1)");
     98         for(int i = 0; i < v.size(); ++i) p(v[id[i]]);
     99         puts("");
    100     }
    101     return 0;
    102 }
    Aguin

    Daylight

    答案为到$u$不超过$w$的点加到$v$不超过$w$的点减去到$u$,$v$都不超过的点,即减去的部分是到$u$,$v$中点不超过$w - frac{dis(u, v)}{2}$的点

    注意到中点可能不是一个节点而是某一条边的中点,即问题可归结为两种询问,询问距离点$u$不超过$k$的点数和询问距离边$u-v$不超过$k$的点数

    对于第一个经典问题,首先树分治并维护点分树,每个重心用一个不定长数组记录子树中到重心距离为$k$的点数,同时记录到点分树父亲距离为$k$的点数

    对于每次询问,从询问点往点分树根部爬,每次计算该重心子树中的贡献,并减去会与父亲重复计算的部分

    对于第二个问题,注意到$u$与$v$是相邻点,故在点分树上必然一个点是另一个点的祖先,那么从点分树上深度较大的点出发会经过所有包含$u$或者$v$的子树

    对于询问,只要在每个重心时将询问点取$u$与$v$中距离重心较近的一个即可

    卡常有意思吗加了一堆inline过了

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 // fastIO
      5 namespace fastIO {
      6 #define BUF_SIZE 100000
      7     //fread -> read
      8     bool IOerror = 0;
      9     inline char nc() {
     10         static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
     11         if(p1 == pend) {
     12             p1 = buf;
     13             pend = buf + fread(buf, 1, BUF_SIZE, stdin);
     14             if(pend == p1) {
     15                 IOerror = 1;
     16                 return -1;
     17             }
     18         }
     19         return *p1++;
     20     }
     21     inline bool blank(char ch) {
     22         return ch == ' ' || ch == '
    ' || ch == '
    ' || ch == '	';
     23     }
     24     inline void read(int &x) {
     25         char ch;
     26         while(blank(ch = nc()));
     27         if(IOerror)
     28             return;
     29         for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
     30     }
     31 #undef BUF_SIZE
     32 };
     33 using namespace fastIO;
     34 
     35 
     36 const int maxn = 1e5 + 10;
     37 vector<int> G[maxn];
     38 
     39 // LCA
     40 int dfs_clock;
     41 int dep[maxn], tid[maxn << 1], dfn[maxn];
     42 int fa[maxn][21];
     43 // 进出时间都要记录,数组需要开两倍
     44 void dfs(int x, int f) {
     45     fa[x][0] = f;
     46     dep[x] = dep[f] + 1;
     47     tid[++dfs_clock] = x, dfn[x] = dfs_clock;
     48     for (int i = 0; i < G[x].size(); ++i) {
     49         int to = G[x][i];
     50         if (to == f) continue;
     51         dfs(to, x);
     52         tid[++dfs_clock] = x; // 每个点出栈时加入父亲
     53     }
     54 }
     55 int lg2[maxn << 1], rmq[maxn << 1][21];
     56 void init(int n) {
     57     // LCA-ST
     58     lg2[0] = -1;
     59     for (int i = 1; i <= dfs_clock; ++i) lg2[i] = lg2[i >> 1] + 1;
     60     for (int i = 1; i <= dfs_clock; ++i) rmq[i][0] = tid[i];
     61     for (int j = 1; (1 << j) <= dfs_clock; ++j) {
     62         for (int i = 1; i + (1 << j) - 1 <= dfs_clock; ++i) {
     63             int ls = rmq[i][j - 1], rs = rmq[i + (1 << (j - 1))][j - 1];
     64             rmq[i][j] = dep[ls] < dep[rs] ? ls : rs;
     65         }
     66     }
     67     // 树上倍增
     68     for (int j = 1; (1 << j) <= n; ++j)
     69         for (int i = 1; i <= n; ++i) fa[i][j] = fa[fa[i][j - 1]][j - 1];
     70 }
     71 inline int LCA(int x, int y) {
     72     if (dfn[x] > dfn[y]) swap(x, y);
     73     int k = lg2[dfn[y] - dfn[x] + 1];
     74     int ls = rmq[dfn[x]][k], rs = rmq[dfn[y] - (1 << k) + 1][k];
     75     return dep[ls] < dep[rs] ? ls : rs;
     76 }
     77 inline int dis(int x, int y) {
     78     int lca = LCA(x, y);
     79     return dep[x] + dep[y] - dep[lca] * 2;
     80 }
     81 
     82 struct V {
     83     vector<int> c;
     84     V(int n = 0) {vector<int>(n + 1, 0).swap(c);}
     85     inline void modify(int i, int x) {
     86         if (i >= 0 && i < c.size()) c[i] += x;
     87     }
     88     inline void sum() {
     89         for (int i = 1; i < c.size(); ++i) c[i] += c[i - 1];
     90     }
     91     inline int query(int i) {
     92         if (i >= 0) return c[min((int) c.size() - 1, i)];
     93         return 0;
     94     }
     95 } T[maxn], FT[maxn];
     96 
     97 // D&C
     98 int vis[maxn], sz[maxn];
     99 void SZ(int x, int f) {
    100     sz[x] = 1;
    101     for (int i = 0; i < G[x].size(); ++i) {
    102         int to = G[x][i];
    103         if (vis[to] || to == f) continue;
    104         SZ(to, x), sz[x] += sz[to];
    105     }
    106 }
    107 int tot, mi, rt;
    108 // 重心:最大子树最小
    109 void RT(int x, int f) {
    110     int ma = tot - sz[x];
    111     for (int i = 0; i < G[x].size(); ++i) {
    112         int to = G[x][i];
    113         if (vis[to] || to == f) continue;
    114         RT(to, x), ma = max(ma, sz[to]);
    115     }
    116     if (ma < mi) mi = ma, rt = x;
    117 }
    118 // 处理点分树上父亲至子树中的点最近距离
    119 int F[maxn], D[maxn], mf[maxn];
    120 void MF(int x, int f, int C) {
    121     mf[C] = min(mf[C], dis(F[C], x));
    122     for (int i = 0; i < G[x].size(); ++i) {
    123         int to = G[x][i];
    124         if (vis[to] || to == f) continue;
    125         MF(to, x, C);
    126     }
    127 }
    128 void INS(int x, int f, int C) {
    129     T[C].modify(dis(x, C), 1);
    130     if (F[C]) FT[C].modify(dis(x, F[C]) - mf[C], 1);
    131     for (int i = 0; i < G[x].size(); ++i) {
    132         int to = G[x][i];
    133         if (vis[to] || to == f) continue;
    134         INS(to, x, C);
    135     }
    136 }
    137 void build(int x, int f) {
    138     SZ(x, 0);
    139     tot = mi = sz[x], RT(x, 0), x = rt;
    140     F[x] = f, D[x] = D[f] + 1;
    141     T[x] = V(tot);
    142     // FT[x].query(i) 询问的是子树中距离父亲 i + mf[x] 的点权值和
    143     if (f) FT[x] = V(tot), mf[x] = dis(x, f), MF(x, 0, x);
    144     INS(x, 0, x), T[x].sum(), FT[x].sum();
    145     vis[x] = 1;
    146     for (int i = 0; i < G[x].size(); ++i) {
    147         int to = G[x][i];
    148         if (vis[to]) continue;
    149         build(to, x);
    150     }
    151 }
    152 int q1(int x, int y, int k) {
    153     int ret = T[x].query(k - dis(x, y));
    154     int fd = dis(F[x], y);
    155     // 询问一直处理到根,即便中间有点贡献为零
    156     if (F[x]) ret += q1(F[x], y, k) - FT[x].query(k - fd - mf[x]);
    157     return ret;
    158 }
    159 int q2(int x, int u, int v, int k) {
    160     int ret = T[x].query(k - min(dis(x, u), dis(x, v)));
    161     int fd = min(dis(F[x], u), dis(F[x], v));
    162     if (F[x]) ret += q2(F[x], u, v, k) - FT[x].query(k - fd - mf[x]);
    163     return ret;
    164 }
    165 
    166 int anc(int x, int d) {
    167     for(int i = 20; i >= 0; --i)
    168         if(d >= (1 << i)) d -= (1 << i), x = fa[x][i];
    169     return x;
    170 }
    171 int m1(int u, int v) {
    172     int d = dis(u, v);
    173     int lca = LCA(u, v);
    174     if(dep[u] - dep[lca] > dep[v] - dep[lca]) return anc(u, d / 2);
    175     return anc(v, d / 2);
    176 }
    177 typedef pair<int, int> pii;
    178 pii m2(int u, int v) {
    179     int lca = LCA(u, v);
    180     int d = dis(u, v), dl = d / 2, dr = d - dl;
    181     int ml = dep[u] - dep[lca] >= dl ? anc(u, dl) : anc(v, dr);
    182     int mr = dep[u] - dep[lca] >= dr ? anc(u, dr) : anc(v, dl);
    183     return pii(ml, mr);
    184 }
    185 
    186 int main() {
    187     int T;
    188     read(T);
    189     while(T--) {
    190         int n, m;
    191         read(n), read(m);
    192         for(int i = 1; i <= n; ++i) G[i].clear(), vis[i] = 0;
    193         for(int i = 2; i <= n; ++i) {
    194             int u, v;
    195             read(u), read(v);
    196             G[u].push_back(v);
    197             G[v].push_back(u);
    198         }
    199         dfs_clock = 0, dfs(1, 0), init(n);
    200         build(1, 0);
    201         int ans = 0;
    202         while(m--) {
    203             int u, v, w;
    204             read(u), read(v), read(w);
    205             u = (u + ans) % n + 1;
    206             v = (v + ans) % n + 1;
    207             w = (w + ans) % n;
    208             int d = dis(u, v);
    209             ans = q1(u, u, w) + q1(v, v, w);
    210             if(d <= w + w) {
    211                 if(d & 1) {
    212                     pii t = m2(u, v);
    213                     u = t.first, v = t.second;
    214                     ans -= q2(D[u] > D[v] ? u : v, u, v, w - d / 2 - 1);
    215                 }
    216                 else {
    217                     int mid = m1(u, v);
    218                     ans -= q1(mid, mid, w - d / 2);
    219                 }
    220             }
    221             printf("%d
    ", ans);
    222         }
    223     }
    224     return 0;
    225 }
    Aguin

    Everything Has Changed

    为什么不用判断优弧劣弧呢呢

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const double pi = acos(-1);
     4 int sqr(int x) {return x * x;}
     5 
     6 int main() {
     7     int T;
     8     scanf("%d", &T);
     9     while(T--) {
    10         int m, R;
    11         scanf("%d %d", &m, &R);
    12         double ans = 2 * R * pi;
    13         while(m--) {
    14             int x, y, r;
    15             scanf("%d %d %d", &x, &y, &r);
    16             if(sqr(x) + sqr(y) >= sqr(R + r)) continue;
    17             if(sqr(x) + sqr(y) < sqr(R - r)) continue;
    18             double d = sqrt(sqr(x) + sqr(y));
    19             double theta1 = 2 * acos((sqr(R) + sqr(x) + sqr(y) - sqr(r)) / (2 * R * d));
    20             double theta2 = 2 * acos((sqr(r) + sqr(x) + sqr(y) - sqr(R)) / (2 * r * d));
    21             ans -= theta1 * R - theta2 * r;
    22         }
    23         printf("%.8f
    ", ans);
    24     }
    25     return 0;
    26 }
    Aguin

    Fireflies

    前面一堆著名结论我是不知道的,直接从转变为$sum_{i = 1}^{n}x_{i} = lfloor frac{1}{2}sum_{i = 1}^{n}(p_{i} + 1)  floor$开始做

    首先容斥成$sum_{I subseteq J} (-1) ^{|I|} C_{M - 1 - sum_{i in I} p_{i}}^{n - 1}$,组合数是关于$sum_{i in I} p_{i}$的$n - 1$次多项式

    可以先暴力把组合数拆开,求出多项式的系数,然后分别考虑每一项的贡献,这样就可以折半枚举一边,再用二项式定理合起来

    广义组合数是有负数定义的,但是考虑实际情况组合数不为零需要满足$M - sum_{i in I} p_{i} geq n$

    所以折半的两边要先按大小排序,枚举一半的时候用双指针维护另一半的幂的和

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll mod = 1e9 + 7;
     5 
     6 ll fp(ll a, ll b) {
     7     ll ret = 1;
     8     while (b) {
     9         if (b & 1) ret = ret * a % mod;
    10         a = a * a % mod;
    11         b >>= 1;
    12     }
    13     return ret;
    14 }
    15 ll inv(ll x) {
    16     return fp(x, mod - 2);
    17 }
    18 
    19 ll sum[2][1 << 17];
    20 int id[2][1 << 17], cnt[2][1 << 17];
    21 bool cmp1(int i, int j) {
    22     return sum[0][i] < sum[0][j];
    23 }
    24 bool cmp2(int i, int j) {
    25     return sum[1][i] > sum[1][j];
    26 }
    27 
    28 int main() {
    29     ll c[44][44] = {0};
    30     for(int i = 0; i < 44; ++i) c[i][0] = c[i][i] = 1;
    31     for(int i = 2; i < 44; ++i)
    32         for(int j = 1; j < i; ++j)
    33             c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
    34     int T;
    35     scanf("%d", &T);
    36     while(T--) {
    37         int n;
    38         scanf("%d", &n);
    39         ll M = 0, p[35], a[35] = {1}, t = 1;
    40         for(int i = 1; i <= n; ++i) scanf("%lld", p + i), M += p[i] + 1;
    41         M /= 2;
    42         for(int i = 0; i < n - 1; ++i) {
    43             t = t * (i + 1) % mod;
    44             for(int j = i + 1; j > 0; --j) a[j] = mod - a[j - 1];
    45             a[0] = 0;
    46             for(int j = 0; j <= i; ++j) a[j] = (a[j] + a[j + 1] * (mod + 1 - M % mod + i)) % mod;
    47         }
    48         t = inv(t);
    49         for(int i = 0; i <= n - 1; ++i) a[i] = a[i] * t % mod;
    50         int l = n / 2, r = n - l;
    51         for(int i = 0; i < (1 << l); ++i) {
    52             id[0][i] = i, sum[0][i] = cnt[0][i] = 0;
    53             for(int j = 0; j < l; ++j)
    54                 if(i & (1 << j)) sum[0][i] = sum[0][i] + p[j + 1], cnt[0][i]++;
    55         }
    56         sort(id[0], id[0] + (1 << l), cmp1);
    57         for(int i = 0; i < (1 << r); ++i) {
    58             id[1][i] = i, sum[1][i] = cnt[1][i] = 0;
    59             for(int j = 0; j < r; ++j)
    60                 if(i & (1 << j)) sum[1][i] = sum[1][i] + p[l + j + 1], cnt[1][i]++;
    61         }
    62         sort(id[1], id[1] + (1 << r), cmp2);
    63         int pos = 0;
    64         ll ans = 0, s[2][44] = {0};
    65         for(int i = 0; i < (1 << r); ++i) {
    66             int x = id[1][i];
    67             if(sum[1][x] > M - n) continue;
    68             while(pos < (1 << l) && sum[0][id[0][pos]] + sum[1][x] <= M - n) {
    69                 int y = id[0][pos];
    70                 ll tmp = 1;
    71                 for(int j = 0; j < n; ++j) {
    72                     s[cnt[0][y] % 2][j] = (s[cnt[0][y] % 2][j] + tmp) % mod;
    73                     tmp = tmp * (sum[0][y] % mod) % mod;
    74                 }
    75                 pos++;
    76             }
    77             for(int j = 0; j < n; ++j) {
    78                 ll tmp = 0, mul = 1;
    79                 for(int k = 0; k <= j; ++k) {
    80                     tmp = (tmp + mul * c[j][k] % mod * s[cnt[1][x] % 2][j - k]) % mod;
    81                     tmp = (tmp + mod - mul * c[j][k] % mod * s[(cnt[1][x] % 2) ^ 1][j - k] % mod) % mod;
    82                     mul = mul * (sum[1][x] % mod) % mod;
    83                 }
    84                 ans = (ans + tmp * a[j]) % mod;
    85             }
    86         }
    87         printf("%lld
    ", ans);
    88     }
    89     return 0;
    90 }
    Aguin

    Glad You Came

    反着用ST表

    考虑正常ST表,首先预处理的时候每个长度为$2^k$的区间的$max$是两个重叠的长度为$2^{k-1}$的子区间传递过来的,询问的时候只要找两个长度不大于$log_{2}(r - l + 1)$的区间合并

    反过来就是每次修改对两个长度不大于$log_{2}(r - l + 1)$的区间标记,后处理的时候把每个长度为$2^k$的区间的标记下传到两个重叠的长度为$2^{k-1}$的子区间

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 
     5 ui X, Y, Z;
     6 ui f() {
     7     X = X ^ (X << 11);
     8     X = X ^ (X >> 4);
     9     X = X ^ (X << 5);
    10     X = X ^ (X >> 14);
    11     ui W = X ^ (Y ^ Z);
    12     X = Y;
    13     Y = Z;
    14     Z = W;
    15 }
    16 
    17 const int maxn = 1e5 + 10;
    18 int rmq[maxn][20], lg[maxn];
    19 void init(int n) {
    20     for (int j = 0; j <= lg[n]; j++)
    21         for (int i = 1; i + (1 << j) - 1 <= n; i++)
    22             rmq[i][j] = 0;
    23 }
    24 void modify(int l, int r, int v) {
    25     int k = lg[r - l + 1];
    26     rmq[l][k] = max(rmq[l][k], v);
    27     rmq[r - (1 << k) + 1][k] = max(rmq[r - (1 << k) + 1][k], v);
    28 }
    29 void cal(int n) {
    30     for (int j = lg[n]; j >= 1; j--)
    31         for (int i = 1; i + (1 << j) - 1 <= n; i++)
    32             rmq[i][j - 1] = max(rmq[i][j - 1], rmq[i][j]), rmq[i + (1 << j - 1)][j - 1] = max(
    33                     rmq[i + (1 << j - 1)][j - 1], rmq[i][j]);
    34 }
    35 
    36 int main() {
    37     lg[0] = -1;
    38     for(int i = 1; i < maxn; ++i) lg[i] = lg[i / 2] + 1;
    39     int T;
    40     scanf("%d", &T);
    41     for(int i = 1; i <= T; ++i) {
    42         int n, m;
    43         scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z);
    44         init(n);
    45         for(int i = 1; i <= m; ++i) {
    46             int l = f() % n + 1, r = f() % n + 1, v = f() % (1 << 30);
    47             if(l > r) swap(l, r);
    48             modify(l, r, v);
    49         }
    50         cal(n);
    51         long long ans = 0;
    52         for(int i = 1; i <= n; ++i) ans ^= 1ll * i * rmq[i][0];
    53         printf("%lld
    ", ans);
    54     }
    55     return 0;
    56 }
    Aguin

    Hills And Valleys

    $f[i][j]$表示前缀$[1...i]$最后一个数是$j$的最长不减子序列,$g[i][j][k][l]$表示前缀$[1...i]$第一段(递增)末尾是数字$j$,第二段(递减)开头是数字$k$,末尾是数字$l$的最长子序列

    注意到需要满足$j leq l leq k$所以实际状态没有那么多,第一维滚动数组优化掉,同时从$f$转移到$g$的时候记录一下左端点,第三段(递增)和第一段一样后缀预处理好

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1e5 + 10;
     4 int f[maxn][10], g[10][10][10], h[10][10][10], lg[10][10][10], lh[10][10][10];
     5 int p[maxn][10];
     6 int A[maxn];
     7 char s[maxn];
     8 
     9 int main() {
    10     int T;
    11     scanf("%d", &T);
    12     while(T--) {
    13         int n;
    14         scanf("%d %s", &n, s + 1);
    15         for(int i = 1; i <= n; ++i) A[i] = s[i] - '0';
    16         for(int i = 0; i <= n + 1; ++i)
    17             for(int j = 0; j < 10; ++j) f[i][j] = p[i][j] = 0;
    18         for(int i = n; i >= 1; --i) {
    19             for(int j = 0; j < 10; ++j) p[i][j] = p[i + 1][j];
    20             for(int j = 9; j >= A[i]; --j) p[i][A[i]] = max(p[i][A[i]], p[i + 1][j] + 1);
    21         }
    22         for(int j = 0; j < 10; ++j) for(int k = 9; k >= j; --k) for(int l = j; l <= k; ++l) g[j][k][l] = lg[j][k][l] = 0;
    23         int m = 0, L = 0, R = 0;
    24         for(int i = 1; i <= n; ++i) {
    25             for(int j = 0; j < 10; ++j) f[i][j] = f[i - 1][j];
    26             for(int j = 0; j <= A[i]; ++j) f[i][A[i]] = max(f[i][A[i]], f[i - 1][j] + 1);
    27             for(int j = 0; j < 10; ++j) for(int k = 9; k >= j; --k) for(int l = j; l <= k; ++l)
    28                 h[j][k][l] = g[j][k][l], lh[j][k][l] = lg[j][k][l];
    29             for(int j = 0; j <= A[i]; ++j) if(f[i - 1][j] + 1 > g[j][A[i]][A[i]]) g[j][A[i]][A[i]] = f[i - 1][j] + 1, lg[j][A[i]][A[i]] = i;
    30             for(int j = 0; j <= A[i]; ++j) for(int k = 9; k >= A[i]; --k) for(int l = k; l >= A[i]; --l)
    31                 if(h[j][k][l] + 1 > g[j][k][A[i]]) g[j][k][A[i]] = h[j][k][l] + 1, lg[j][k][A[i]] = lh[j][k][l];
    32             for(int j = 0; j <= A[i]; ++j) for(int k = 9; k >= A[i]; --k) for(int l = 9; l >= k; --l)
    33                 if(g[j][k][A[i]] + p[i + 1][l] > m) m = g[j][k][A[i]] + p[i + 1][l], L = lg[j][k][A[i]], R = i;
    34         }
    35         if(R && !L) L = 1;
    36         if(!L && !R) int x = 1 / 0;
    37         printf("%d %d %d
    ", m, L, R);
    38     }
    39     return 0;
    40 }
    Aguin

    Innocence

    题解有点没说清楚阿……

    考虑没有下界约束的情况,这个做法很多,但是为了后面方便,先考虑一个暴力数位打牌的做法

    先把问题拆分成$log$个,从高位往低位,找到第一个位$b$满足$N$个数中至少有一个此位与上界$R$不相等

    如果不存在这样的$b$,那么这$N$个数都与上界相等,这个情况单独考虑即可

    找到$b$后,要$dp$出所有满足至少一个数此位小于上界的方案数,状态为$f[i][j][k]$表示取了$i$个数,$j = 0/1$表示前$i$个数中是否有此位小于上界,$k$表示前$i$个数此位异或值

    转移的时候枚举新加的一个数,第$b$位是$0/1$,若此位填的数与上界相等,那么后缀填数方案要满足不大于上界,否则后面可以填任意数

    注意到每增加一个数的转移是一样的,可以对第一维做矩阵快速幂转移

    再考虑有下界的情况,可以暴力容斥转化为没有下界的情况,即至少$0$个数小于下界$-$至少$1$个数小于下界$+$至少$2$个数下于下界……

    也就是说新加入一个数的时候,要考虑这个数的约束是仅小于上界,还是同时小于下界两种情况转移,状态也要多加一维$f[i][j][k][l]$其中$l$表示$i$个数中强制要求小于下界的数有$l$个

    这样状态数就炸了,但是很容易发现容斥的时候正负号只和$l$的奇偶有关,所以状态存$l mod 2$就可以了,依然可以矩阵快速幂把$i$优化掉

    询问时对于每个$K$,枚举一下$b$统计方案,并单独处理$b$不存在的情况

    两个容易忽视的坑点是$K$大于最高位要直接输出$0$,$R$为$0$要特判……

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll mod = 1e9 + 7;
     5 // f[i][j][k] 是否卡上界 当前0/1 <L数目%2
     6 
     7 const int maxm = 8;
     8 struct Mat {
     9     ll a[maxm][maxm];
    10     Mat() {memset(a, 0, sizeof(a));}
    11     void E() {
    12         for(int i = 0; i < maxm; ++i)
    13             for(int j = 0; j < maxm; ++j)
    14                 a[i][j] = i == j ? 1 : 0;
    15     }
    16 } f[30];
    17 void Mul(Mat A, Mat B, Mat& C) {
    18     for(int i = 0; i < maxm; ++i)
    19         for(int j = 0; j < maxm; ++j)
    20             C.a[i][j] = 0;
    21     for(int i = 0; i < maxm; ++i) {
    22         for(int j = 0; j < maxm; ++j) {
    23             if(!A.a[i][j]) continue;
    24             for(int k = 0; k < maxm; ++k) {
    25                 if(!B.a[j][k]) continue;
    26                 C.a[i][k] = (C.a[i][k] + A.a[i][j] * B.a[j][k]) % mod;
    27             }
    28         }
    29     }
    30 }
    31 void Pow(Mat& A, ll n) {
    32     Mat ret; ret.E();
    33     while(n) {
    34         if(n & 1) Mul(ret, A, ret);
    35         Mul(A, A, A), n >>= 1;
    36     }
    37     A = ret;
    38 }
    39 
    40 int main() {
    41     int T;
    42     scanf("%d", &T);
    43     while(T--) {
    44         int N, L, R, Q;
    45         scanf("%d %d %d %d", &N, &L, &R, &Q);
    46         int mx = 0;
    47         while((1 << mx) <= R) ++mx;
    48         for(int b = 0; b < mx; ++b) {
    49             f[b] = Mat();
    50             int rb = ((1 << b) & R) ? 1 : 0, lb = L && ((1 << b) & (L - 1)) ? 1 : 0;
    51             for(int i = 0; i <= 1; ++i) for(int j = 0; j <= 1; ++j) for(int k = 0; k <= 1; ++k) {
    52                 int msk = (i << 2) + (j << 1) + k;
    53                 for(int nb = 0; nb <= 1; ++nb) {
    54                     if(rb || !nb) {
    55                         int ni = i && (rb == nb), nj = j ^ nb, nk = k;
    56                         int nmsk = (ni << 2) + (nj << 1) + nk;
    57                         f[b].a[nmsk][msk] += nb < rb ? (i ? 1 : (1 << b)) : ((R & ((1 << b) - 1)) + 1);
    58                     }
    59                     if(L && (lb || !nb)) {
    60                         int ni = i && (lb == nb), nj = j ^ nb, nk = k ^ 1;
    61                         int nmsk = (ni << 2) + (nj << 1) + nk;
    62                         f[b].a[nmsk][msk] += nb < lb ? (i ? 1 : (1 << b)) : (((L - 1) & ((1 << b) - 1)) + 1);
    63                     }
    64                 }
    65             }
    66             Pow(f[b], N);
    67         }
    68         while(Q--) {
    69             int K;
    70             scanf("%d", &K);
    71             if(K >= (1 << mx)) {puts("0"); continue;}
    72             if(R == 0) {puts("1"); continue;}
    73             ll ans = 0;
    74             int o = N & 1, r = o ? R : 0, l = L ? r ^ R ^ (L - 1) : 0;
    75             int okr = 1, okl = 1;
    76             for(int b = mx - 1; b >= 0; --b) {
    77                 int nr = (r & (1 << b)) ? 1 : 0;
    78                 int nl = (l & (1 << b)) ? 1 : 0;
    79                 int nk = (K & (1 << b)) ? 1 : 0;
    80                 if(okr) ans = (ans + f[b].a[nk << 1][4]) % mod;
    81                 if(L && okl) ans = (ans + mod - f[b].a[(nk << 1) + 1][4]) % mod;
    82                 if(nr != nk) okr = 0;
    83                 if(nl != nk) okl = 0;
    84             }
    85             if(r == K) ans = (ans + f[0].a[4 + ((K & 1) << 1)][4]) % mod;
    86             if(L && l == K) ans = (ans + mod - f[0].a[4 + ((K & 1) << 1) + 1][4]) % mod;
    87             printf("%lld
    ", ans);
    88         }
    89     }
    90     return 0;
    91 }
    Aguin

    Just So You Know

    题意有点迷,一次$Conjecture$本质上是询问目标串是否在一个子集中,这个子集是可以任意选取的

    考虑一个简单版本,一个多重集,等概率选择一个数,按同样的规则每次猜测该数是否在某子集中,合理决策使询问期望最少

    一次询问根据回答的$Yes/No$实际上是将一个集合划分为两部分,即询问的子集和它的补集,至上而下划分便形成了一棵二叉决策树

    那么使询问期望最小,等同于让每个点的深度与概率乘积之和最小,本质上是求一个哈夫曼树,也就是经典的合并果子问题

    于是原问题可以看成两部分,第一部分是统计出现$i$次的子串数目,然后就转化为上面的简化问题,需要做一个哈夫曼树

    第一部分可牛逼了,首先需要一个代表国内最牛逼后缀数组水平的$SA-IS$,这个可以去陈敏锐小给给的博客那蒯一个

    然后建一个小根的笛卡尔树,就可以线性统计出现$i$次的子串数目,然后好像笛卡尔树这里深搜爆栈了很难受只好换了个丑丑的$BFS$

    统计完后开始合并果子,由于一共有$frac{n(n + 1)}{2}$个子串,所以出现次数相同的要一起合并

    对于某个频数的子串,如果有偶数个就直接自己合并,否则留一个出来和后面比它大的合并

    对于频数小于$n$的子串,从小到大边扫边合并就行了,发现会合并出大小为$O(n^2)$级别的节点出来

    但是由于总串数的限制,大于$n$的结点数是$O(n)$级别的,所以一旦合并出来大于$n$,就丢到一个队列里,最后做一次普通的合并果子即可

    btw感觉dls这题代码合并的时候是$O(nlogn)$的……

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 
      5 const int N = 1e6 + 10;
      6 namespace SA {
      7     int sa[N], rk[N], ht[N], s[N<<1], t[N<<1], p[N], cnt[N], cur[N];
      8 #define pushS(x) sa[cur[s[x]]--] = x
      9 #define pushL(x) sa[cur[s[x]]++] = x
     10 #define inducedSort(v) fill_n(sa, n, -1); fill_n(cnt, m, 0);                  
     11     for (int i = 0; i < n; i++) cnt[s[i]]++;                                  
     12     for (int i = 1; i < m; i++) cnt[i] += cnt[i-1];                           
     13     for (int i = 0; i < m; i++) cur[i] = cnt[i]-1;                            
     14     for (int i = n1-1; ~i; i--) pushS(v[i]);                                  
     15     for (int i = 1; i < m; i++) cur[i] = cnt[i-1];                            
     16     for (int i = 0; i < n; i++) if (sa[i] > 0 &&  t[sa[i]-1]) pushL(sa[i]-1); 
     17     for (int i = 0; i < m; i++) cur[i] = cnt[i]-1;                            
     18     for (int i = n-1;  ~i; i--) if (sa[i] > 0 && !t[sa[i]-1]) pushS(sa[i]-1)
     19     void sais(int n, int m, int *s, int *t, int *p) {
     20         int n1 = t[n-1] = 0, ch = rk[0] = -1, *s1 = s+n;
     21         for (int i = n-2; ~i; i--) t[i] = s[i] == s[i+1] ? t[i+1] : s[i] > s[i+1];
     22         for (int i = 1; i < n; i++) rk[i] = t[i-1] && !t[i] ? (p[n1] = i, n1++) : -1;
     23         inducedSort(p);
     24         for (int i = 0, x, y; i < n; i++) if (~(x = rk[sa[i]])) {
     25                 if (ch < 1 || p[x+1] - p[x] != p[y+1] - p[y]) ch++;
     26                 else for (int j = p[x], k = p[y]; j <= p[x+1]; j++, k++)
     27                         if ((s[j]<<1|t[j]) != (s[k]<<1|t[k])) {ch++; break;}
     28                 s1[y = x] = ch;
     29             }
     30         if (ch+1 < n1) sais(n1, ch+1, s1, t+n, p+n1);
     31         else for (int i = 0; i < n1; i++) sa[s1[i]] = i;
     32         for (int i = 0; i < n1; i++) s1[i] = p[sa[i]];
     33         inducedSort(s1);
     34     }
     35     template<typename T>
     36     int mapCharToInt(int n, const T *str) {
     37         int m = *max_element(str, str+n);
     38         fill_n(rk, m+1, 0);
     39         for (int i = 0; i < n; i++) rk[str[i]] = 1;
     40         for (int i = 0; i < m; i++) rk[i+1] += rk[i];
     41         for (int i = 0; i < n; i++) s[i] = rk[str[i]] - 1;
     42         return rk[m];
     43     }
     44 // Ensure that str[n] is the unique lexicographically smallest character in str.
     45     template<typename T>
     46     void suffixArray(int n, const T *str) {
     47         int m = mapCharToInt(++n, str);
     48         sais(n, m, s, t, p);
     49         for (int i = 0; i < n; i++) rk[sa[i]] = i;
     50         for (int i = 0, h = ht[0] = 0; i < n-1; i++) {
     51             int j = sa[rk[i]-1];
     52             while (i+h < n && j+h < n && s[i+h] == s[j+h]) h++;
     53             if (ht[rk[i]] = h) h--;
     54         }
     55     }
     56 };
     57 
     58 int a[N], *h;
     59 int fa[N], st[N], l[N], r[N], vis[N];
     60 ll tot, f[N], sz[N];
     61 void dfs(int x, int fa) {
     62     int len = h[x];
     63     if(fa) len -= h[fa];
     64     sz[x] = 2;
     65     if(l[x]) dfs(l[x], x), sz[x] += sz[l[x]] - 1;
     66     if(r[x]) dfs(r[x], x), sz[x] += sz[r[x]] - 1;
     67     f[sz[x]] += len, tot -= sz[x] * len;
     68 }
     69 
     70 vector<int> v;
     71 queue<int> q;
     72 queue<ll> q1, q2;
     73 int main() {
     74     int T;
     75     scanf("%d", &T);
     76     while(T--) {
     77         ll n;
     78         scanf("%lld", &n);
     79         for(int i = 0; i < n; ++i) scanf("%d", a + i), a[i]++;
     80         a[n] = 0;
     81         SA :: suffixArray(n, a);
     82         h = SA :: ht + 1;
     83         int top = 0;
     84         for (int i = 1; i < n; ++i) l[i] = r[i] = vis[i] = 0;
     85         for (int i = 1; i < n; ++i) {
     86             int k = top;
     87             while (k > 0 && h[st[k - 1]] > h[i]) --k;
     88             if (k) r[st[k - 1]] = i;
     89             if (k < top) l[i] = st[k];
     90             st[k++] = i;
     91             top = k;
     92         }
     93         for (int i = 1; i < n; ++i) vis[l[i]] = vis[r[i]] = 1;
     94         int rt = 0;
     95         for (int i = 1; i < n; ++i) if (!vis[i]) rt = i;
     96         for (int i = 1; i <= n; ++i) f[i] = 0;
     97         tot = n * (n + 1) / 2;
     98         while(!q.empty()) q.pop();
     99         q.push(rt);
    100         fa[rt] = 0;
    101         v.clear();
    102         while(!q.empty()) {
    103             int x = q.front(); q.pop();
    104             v.push_back(x);
    105             if(l[x]) q.push(l[x]), fa[l[x]] = x;
    106             if(r[x]) q.push(r[x]), fa[r[x]] = x;
    107         }
    108         for(int i = v.size() - 1; i >= 0; --i) {
    109             int x = v[i], len = h[x];
    110             if(fa[x]) len -= h[fa[x]];
    111             sz[x] = 2;
    112             if(l[x]) sz[x] += sz[l[x]] - 1;
    113             if(r[x]) sz[x] += sz[r[x]] - 1;
    114             f[sz[x]] += len, tot -= sz[x] * len;
    115         }
    116         f[1] = tot;
    117         ll ans = 0, o = 0;
    118         for(int i = 1; i <= n; ++i) {
    119             if(!f[i]) continue;
    120             if(o) {
    121                 f[i]--;
    122                 if(i + o <= n) f[i + o]++;
    123                 else q1.push(i + o);
    124                 ans += i + o, o = 0;
    125             }
    126             if(f[i] & 1) o = i, f[i]--;
    127             if(!f[i]) continue;
    128             if(i + i <= n) f[i + i] += f[i] / 2, ans += f[i] * i;
    129             else for(int j = 1; j <= f[i] / 2; ++j) q1.push(i + i), ans += i + i;
    130         }
    131         while(!q1.empty() || !q2.empty()) {
    132             ll x = 0, y = 0;
    133             if(o) x = o, o = 0;
    134             else {
    135                 if(!q1.empty() && !q2.empty()) {
    136                     if(q1.front() < q2.front()) x = q1.front(), q1.pop();
    137                     else x = q2.front(), q2.pop();
    138                 }
    139                 else if(!q1.empty()) x = q1.front(), q1.pop();
    140                 else x = q2.front(), q2.pop();
    141             }
    142             if(q1.empty() && q2.empty()) break;
    143             if(!q1.empty() && !q2.empty()) {
    144                 if(q1.front() < q2.front()) y = q1.front(), q1.pop();
    145                 else y = q2.front(), q2.pop();
    146             }
    147             else if(!q1.empty()) y = q1.front(), q1.pop();
    148             else y = q2.front(), q2.pop();
    149             ans += x + y;
    150             q2.push(x + y);
    151         }
    152         ll t = n * (n + 1) / 2;
    153         ll g = __gcd(ans, t);
    154         ans /= g, t /= g;
    155         printf("%lld", ans);
    156         if(t > 1) printf("/%lld", t);
    157         puts("");
    158     }
    159     return 0;
    160 }
    Aguin

    Kaleidoscope

    好像不会计数哇T^T

    Lost In The Echo

    论文都没有的题不补><

  • 相关阅读:
    JsCV Core v0.2发布 & Javascript图像处理系列目录
    Javascript图像处理
    SOE开发之IMapServerSourceDescription
    SOE之JSONObject
    SOE开发之adddynamiclayertomapserver
    JavaScript 的 async/await
    ArcGIS Engine开发系列:将地图导出为图片的两种方法(ZZ)
    原型链
    更优美的javaScript(2)
    CSS选择器
  • 原文地址:https://www.cnblogs.com/Aguin/p/9440656.html
Copyright © 2011-2022 走看看