Hnoi2017试题泛做

Posted cot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hnoi2017试题泛做相关的知识,希望对你有一定的参考价值。

Day1

4825: [Hnoi2017]单旋

注意到二叉查找树的一个性质:其中序遍历就是所有元素按权值排序的顺序。

所以我们可以离线地把这棵树的中序遍历求出来。然后我们在插入的时候就可以用一个set来维护前驱后继,这样就可以维护出整棵树的形态。

接着我们发现将最大、最小单旋到根后,一定会有一边儿子是空的,并且剩下的子树的深度+1。于是我们就只要支持单点修改、区间加、单点查询的数据结构即可。树状数组就好了。

然后树的形态维护的时候大力判断一下就好啦。

技术分享
  1 #include <cstdio>
  2 #include <cmath>
  3 #include <set>
  4 #include <algorithm>
  5 
  6 #define R register
  7 #define P std::pair<int, int>
  8 #define mkp std::make_pair
  9 #define maxn 100010
 10 #define fir first
 11 #define sec second
 12 int v[maxn], ch[maxn][2], fa[maxn], tot;
 13 std::set<P> s;
 14 int q[maxn];
 15 int dfn[maxn], inv[maxn], timer, pos[maxn], ltag;
 16 int ql, qr;
 17 int hash[maxn];
 18 int bt[maxn];
 19 void add(R int x, R int val) {for (; x <= tot; x += x & -x) bt[x] += val;}
 20 int query(R int x) {R int ret = 0; for (; x; x -= x & -x) ret += bt[x]; return ret;}
 21 void modify(R int l, R int r, R int v)
 22 {
 23 //    printf("l = %d r = %d v = %d\n", l, r, v);
 24     add(l, v); add(r + 1, -v);
 25 }
 26 int main()
 27 {
 28     R int n, root; scanf("%d", &n);
 29     s.insert(mkp(0, 0));
 30     s.insert(mkp(1e9 + 7, 0));
 31     for (R int i = 1; i <= n; ++i)
 32     {
 33         R int opt; scanf("%d", &opt); q[i] = opt;
 34         if (opt == 1) {R int key; scanf("%d", &key); v[++tot] = key; hash[tot] = key;}
 35     }
 36     std::sort(hash + 1, hash + tot + 1);
 37     for (R int i = 1; i <= n; ++i) dfn[i] = std::lower_bound(hash + 1, hash + tot + 1, v[i]) - hash;
 38     for (R int i = 1, nw = 0; i <= n; ++i)
 39     {
 40         R int opt = q[i];
 41         if (opt == 1)
 42         {
 43             R P now = mkp(v[++nw], nw);
 44             R P prev = *(--s.upper_bound(now)), next = *s.upper_bound(now);
 45             s.insert(now);
 46             if (prev.sec && !ch[prev.sec][1])
 47             {
 48                 ch[prev.sec][1] = nw;
 49                 fa[nw] = prev.sec;
 50             }
 51             else if (next.sec && !ch[next.sec][0])
 52             {
 53                 ch[next.sec][0] = nw;
 54                 fa[nw] = next.sec;
 55             }
 56             !fa[nw] ? root = nw : 0;
 57 
 58             R int dep;
 59             printf("%d\n", dep = fa[nw] ? query(dfn[fa[nw]]) + 1 : 1);
 60             modify(dfn[nw], dfn[nw], dep - query(dfn[nw]));
 61         }
 62         else if (opt == 2)
 63         {
 64             R P xmin = *(++s.begin()); R int xc = xmin.sec;
 65             printf("%d\n", query(dfn[xc]));
 66 //            printf("fa %d\n", fa[xc]);
 67             modify(!fa[xc] ? tot + 1 : dfn[fa[xc]], tot, 1);
 68             modify(dfn[xc], dfn[xc], 1 - query(dfn[xc]));
 69 
 70             if (root != xc)
 71             {
 72                 ch[fa[xc]][0] = ch[xc][1];
 73                 fa[ch[xc][1]] = fa[xc];
 74                 fa[root] = xc;
 75                 ch[xc][1] = root;
 76                 root = xc;
 77                 fa[xc] = 0;
 78             }
 79         }
 80         else if (opt == 3)
 81         {
 82             R P xmax = *(++s.rbegin()); R int xc = xmax.sec;
 83             printf("%d\n", query(dfn[xc]));
 84             modify(1, !fa[xc] ? 0 : dfn[fa[xc]], 1);
 85             modify(dfn[xc], dfn[xc], 1 - query(dfn[xc]));
 86 
 87             if (root != xc)
 88             {
 89                 ch[fa[xc]][1] = ch[xc][0];
 90                 fa[ch[xc][0]] = fa[xc];
 91                 fa[root] = xc;
 92                 ch[xc][0] = root;
 93                 root = xc;
 94                 fa[xc] = 0;
 95             }
 96         }
 97         else if (opt == 4)
 98         {
 99             R P xmin = *(++s.begin()); R int xc = xmin.sec;
100             printf("%d\n", query(dfn[xc]));
101             modify(dfn[xc] + 1 , !fa[xc] ? tot : dfn[fa[xc]] - 1, -1);
102             
103             xc == root ? fa[root = ch[xc][1]] = 0 :
104             (ch[fa[xc]][0] = ch[xc][1],
105             fa[ch[xc][1]] = fa[xc]);
106             s.erase(xmin);
107         }
108         else
109         {
110             R P xmax = *(++s.rbegin()); R int xc = xmax.sec;
111 //            printf("max %d %d\n", xc, fa[xc]);
112             printf("%d\n", query(dfn[xc]));
113             modify(!fa[xc] ? 1 : dfn[fa[xc]] + 1, dfn[xc] - 1, -1);
114 
115             xc == root ? fa[root = ch[xc][0]] = 0 :
116             (ch[fa[xc]][1] = ch[xc][0],
117             fa[ch[xc][0]] = fa[xc]);
118             s.erase(xmax);
119         }
120     }
121     return 0;
122 }
123 /*
124 6
125 1 1
126 1 2
127 1 4
128 4
129 2
130 5
131 性质:二叉查找树的子树的权值对应的是一个区间。并且有且仅有所有子树内的点在这个区间内。
132 */
D1T1

4826: [Hnoi2017]影魔

第1种的贡献可以用单调栈算。第2种的贡献没那么好算,所以我们来考虑1+2的贡献。1+2的贡献可以转为二维偏序,用排序+线段树来搞。

技术分享
  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 
  5 #define R register
  6 #define maxn 200010
  7 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
  8 inline int F()
  9 {
 10     R char ch; R int cnt;
 11     while (ch = getchar(), ch < 0 || ch > 9) ;
 12     cnt = ch - 0;
 13     while (ch = getchar(), ch >= 0 && ch <= 9) cnt = cnt * 10 + ch - 0;
 14     return cnt;
 15 }
 16 typedef long long ll;
 17 struct Query {
 18     int l, r;
 19 } q[maxn];
 20 struct Chain {
 21     Chain *next;
 22     int id;
 23 } *last[maxn], mem[maxn], *tot = mem;
 24 struct Opt {
 25     int x, id, type;
 26     inline bool operator < (const Opt &that) const {return x < that.x;}
 27 } op[maxn << 1];
 28 int ans1[maxn]; ll ans2[maxn];
 29 int st[maxn], top, a[maxn];
 30 int ql, qr;
 31 ll tr[maxn << 2], tag[maxn << 2];
 32 inline void pushdown(R int o, R int l, R int r, R int mid)
 33 {
 34     if (tag[o])
 35     {
 36         tag[o << 1] += tag[o];
 37         tag[o << 1 | 1] += tag[o];
 38         tr[o << 1] += 1ll * tag[o] * (mid - l + 1);
 39         tr[o << 1 | 1] += 1ll * tag[o] * (r - mid);
 40         tag[o] = 0;
 41     }
 42 }
 43 inline void update(R int o) {tr[o] = tr[o << 1] + tr[o << 1 | 1];}
 44 void modify(R int o, R int l, R int r)
 45 {
 46     if (ql <= l && r <= qr)
 47     {
 48         ++tag[o]; tr[o] += (r - l + 1);
 49         return ;
 50     }
 51     R int mid = l + r >> 1;
 52     pushdown(o, l, r, mid);
 53     if (ql <= mid) modify(o << 1, l, mid);
 54     if (mid < qr) modify(o << 1 | 1, mid + 1, r);
 55     update(o);
 56 }
 57 ll query(R int o, R int l, R int r)
 58 {
 59     if (ql <= l && r <= qr) return tr[o];
 60     R int mid = l + r >> 1;
 61     R ll ret = 0;
 62     pushdown(o, l, r, mid);
 63     if (ql <= mid) ret += query(o << 1, l, mid);
 64     if (mid < qr) ret += query(o << 1 | 1, mid + 1, r);
 65     return ret;
 66 }
 67 int bt[maxn], n, lef[maxn], rig[maxn], r[maxn], Fa[maxn];
 68 int Find(R int x) {return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);}
 69 inline void add(R int x) {for (; x <= n; x += x & -x) ++bt[x];}
 70 inline int query(R int x) {R int ret = 0; for (; x; x -= x & -x) ret += bt[x]; return ret;}
 71 int main()
 72 {
 73     n = F(); R int m = F(), p1 = F(), p2 = F();
 74     for (R int i = 1; i <= n; ++i) a[i] = F(), r[a[i]] = i, Fa[i] = lef[i] = rig[i] = i;
 75     R int opcnt = 0;
 76     for (R int i = 1; i <= m; ++i)
 77     {
 78         q[i] = (Query) {F(), F()};
 79         *++tot = (Chain) {last[q[i].r], i}; last[q[i].r] = tot;
 80         op[++opcnt] = (Opt) {q[i].l - 1, i, -1};
 81         op[++opcnt] = (Opt) {q[i].r, i, 1};
 82     }
 83 
 84     memset(bt, 0, (n + 1) << 2); top = 0;
 85     for (R int i = 1; i <= n; ++i)
 86     {
 87         R int rr = i - 2;
 88         while (top && a[st[top]] < a[i]) add(st[top--]);
 89         if (top) add(st[top]);
 90         st[++top] = i;
 91         for (R Chain *iter = last[i]; iter; iter = iter -> next)
 92             ans1[iter -> id] += query(q[iter -> id].r) - query(q[iter -> id].l - 1);
 93     }
 94 
 95     std::sort(op + 1, op + opcnt + 1);
 96     for (R int i = 1; i <= n; ++i)
 97     {
 98         R int ps = r[i], f1;
 99         if (ps != 1 && a[ps - 1] < i) lef[ps] = lef[f1 = Find(ps - 1)], Fa[f1] = ps;
100         if (ps != n && a[ps + 1] < i) rig[ps] = rig[f1 = Find(ps + 1)], Fa[f1] = ps;
101     }
102     R int p = 1;
103     while (op[p].x == 0) ++p;
104     for (R int i = 1; i <= n; ++i)
105     {
106 //        printf("%d %d\n", lef[i], rig[i]);
107         ql = lef[i]; qr = rig[i];
108         modify(1, 1, n);
109         while (op[p].x == i)
110         {
111             ql = q[op[p].id].l; qr = q[op[p].id].r;
112             ans2[op[p].id] += op[p].type * query(1, 1, n);
113             ++p;
114         }
115     }
116     for (R int i = 1; i <= m; ++i) printf("%lld\n", 1ll * ans1[i] * p1 + (ans2[i] - (q[i].r - q[i].l + 1) - ans1[i]) * p2);
117     return 0;
118 }
119 /*
120 9 4
121 12 5
122 2 0
123 5 1
124 5 2
125 30
126 39
127 4
128 13
129 16
130 
131 */
D1T2

4827: [Hnoi2017]礼物

把式子拆开完就是一个卷积和二次函数的形式,二次函数用对称轴公式来算,卷积用FFT来算。

技术分享
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 
 5 #define R register
 6 #define maxn 262145
 7 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
 8 typedef double db;
 9 const db pi = acos(-1);
10 struct Complex {
11     db x, y;
12     inline Complex operator - (const Complex &that) const {return (Complex) {x - that.x, y - that.y};}
13     inline Complex operator * (const Complex &that) const {return (Complex) {x * that.x - y * that.y, x * that.y + that.x * y};}
14     inline void operator += (const Complex &that) {x += that.x; y += that.y;}
15 } w[maxn << 1];
16 int N;
17 void init()
18 {
19     R int h = N >> 1;
20     for (R int i = 0; i < N; ++i) w[i + h] = (Complex) {cos(2 * pi / N * i), sin(2 * pi / N * i)};
21     for (R int i = h; i--; ) w[i] = w[i << 1];
22 }
23 void bit_reverse(R Complex *a, R Complex *b)
24 {
25     for (R int i = 0; i < N; ++i) b[i] = a[i];
26     for (R int i = 0, j = 0; i < N; ++i)
27     {
28         i > j ? std::swap(b[i], b[j]), 1 : 0;
29         for (R int l = N >> 1; (j ^= l) < l; l >>= 1) ;
30     }
31 }
32 void dft(R Complex *a)
33 {
34     for (R int l = 2, m = 1; m < N; l <<= 1, m <<= 1)
35         for (R int i = 0; i < N; i += l)
36             for (R int j = 0; j < m; ++j)
37             {
38                 R Complex tmp = a[i + j + m] * w[j + m];
39                 a[i + j + m] = a[i + j] - tmp;
40                 a[i + j] += tmp;
41             }
42 }
43 Complex a[maxn], b[maxn], c[maxn], ta[maxn], tb[maxn], tc[maxn];
44 int main()
45 {
46     R int n, m, ans = 0x7fffffff, ret = 0, sum = 0; scanf("%d%d", &n, &m);
47     for (R int i = 0; i < n; ++i) scanf("%lf", &a[i].x), sum -= a[i].x;
48     for (R int i = 0; i < n; ++i) scanf("%lf", &b[i].x), sum += b[i].x;
49     std::reverse(b, b + n);
50     for (R int i = 0; i < n; ++i) b[i + n] = b[i];
51     for (N = 1; N < (n << 1); N <<= 1);
52     init();
53     R int ccc = round((db) sum / n);
54 
55     for (R int i = 0; i < n; ++i) a[i].x += ccc, ret += a[i].x * a[i].x + b[i].x * b[i].x;
56 //    printf("%d %d\n", ccc, ret);
57     bit_reverse(a, ta);
58     bit_reverse(b, tb);
59     dft(ta); dft(tb);
60     for (R int i = 0; i < N; ++i) c[i] = ta[i] * tb[i];
61     std::reverse(c + 1, c + N);
62     bit_reverse(c, tc); dft(tc);
63 //    for (R int i = 0; i < N; ++i) printf("%lf %lf\n", tc[i].x, tc[i].y);
64     for (R int i = 0; i < n; ++i) cmin(ans, (int) ret - (2 * tc[i + n].x / N));
65 
66     printf("%d\n", ans);
67     return 0;
68 }
D1T3

Day2

4828: [Hnoi2017]大佬

玄学搜索题。搜索出来完用双指针扫一扫。

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <map>
  5 #include <bitset>
  6 
  7 #define R register
  8 #define maxn 110
  9 int a[maxn], w[maxn];
 10 int f[maxn][maxn];
 11 const int oo = 1e8;
 12 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
 13 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
 14 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
 15 const int mod = 8260817;
 16 typedef long long ll;
 17 struct Queue {
 18     int step, level, f;
 19 } q[10000010];
 20 struct Hash {
 21     Hash *next;
 22     ll key;
 23 } *last[mod], mem[mod], *tot = mem;
 24 inline ll hash_key(R int a, R int b)
 25 {
 26     return 1ll * b * 233 + a;
 27 }
 28 inline bool insert(R int a, R int b)
 29 {
 30     R ll key = hash_key(a, b);
 31     R int pos = key % mod;
 32     for (R Hash *iter = last[pos]; iter; iter = iter -> next)
 33         if (iter -> key == key) return 0;
 34     *++tot = (Hash) {last[pos], key}; last[pos] = tot;
 35     return 1;
 36 }
 37 struct Data {
 38     int f, s;
 39     inline bool operator < (const Data &that) const {return f < that.f;}
 40 } st[maxn * maxn * maxn];
 41 int scnt, qu[30];
 42 int main()
 43 {
 44     R int n, m, mc; scanf("%d%d%d", &n, &m, &mc);
 45     for (R int i = 1; i <= n; ++i) scanf("%d", &a[i]);
 46     for (R int i = 1; i <= n; ++i) scanf("%d", &w[i]);
 47     memset(f, -63, sizeof (f));
 48     f[0][mc] = 0;
 49     for (R int i = 1; i <= n; ++i)
 50     {
 51         for (R int j = a[i]; j <= mc; ++j)
 52             cmax(f[i][j - a[i]], f[i - 1][j] + 1),
 53             cmax(f[i][dmin(j - a[i] + w[i], mc)], f[i - 1][j]);
 54     }
 55     R int Day = -1;
 56     for (R int j = 0; j <= n; ++j) for (R int i = 0; i <= mc; ++i) cmax(Day, f[j][i]);
 57     R int oo = 0;
 58     for (R int i = 1; i <= m; ++i) scanf("%d", &qu[i]), cmax(oo, qu[i]);
 59 
 60     R int head = 0, tail = 1;
 61     q[1] = (Queue) {0, 0, 1};
 62     while (head < tail)
 63     {
 64         R Queue now = q[++head];
 65         if (insert(0, now.f)) st[++scnt] = (Data) {now.f, now.step + 1};
 66         if (now.step >= Day - 1) continue;
 67         if (now.level > 0 && oo / now.level < now.f) continue;
 68         if (insert(now.level + 1, now.f)) q[++tail] = (Queue) {now.step + 1, now.level + 1, now.f};
 69 
 70         if (1ll * now.f * now.level <= oo && now.f > 0)
 71         {
 72             if (insert(now.level, now.f * now.level))
 73                 q[++tail] = (Queue) {now.step + 1, now.level, now.f * now.level};
 74         }
 75     }
 76     st[++scnt] = (Data) {0, 0};
 77     std::sort(st + 1, st + scnt + 1);
 78     for (R int _ = 1; _ <= m; ++_)
 79     {
 80         R int c = qu[_], flag = 0;
 81         if (Day <= 0) {puts("0"); continue;}
 82         if (c <= Day) {puts("1"); continue;}
 83         R int j = 0, mx = -oo * 2;
 84         for (R int i = scnt; i; --i)
 85         {
 86             for (; j < scnt && st[j + 1].f + st[i].f <= c; ++j, cmax(mx, st[j].f - st[j].s));
 87             if (mx + st[i].f - st[i].s >= c - Day)
 88             {
 89                 flag = 1;
 90                 break;
 91             }
 92         }
 93         printf("%d\n", flag);
 94     }
 95     return 0;
 96 }
 97 /*
 98 10 20 100
 99 22 18 15 16 20 19 33 15 38 49
100 92 14 94 92 66 94 1 16 90 51
101 4
102 5
103 9
104 338
105 5222
106 549
107 7491
108 9
109 12
110 3288
111 3
112 1
113 2191
114 833
115 3
116 6991
117 2754
118 3231
119 360
120 6
121 
122 1
123 1
124 1
125 0
126 0
127 0
128 0
129 1
130 1
131 0
132 1
133 1
134 0
135 0
136 1
137 0
138 0
139 0
140 0
141 1
142 */
D2T1

4829: [Hnoi2017]队长快跑

看起来很nan,没去看。听说是一道不可做题。

4830: [Hnoi2017]抛硬币

广义Lucas定理。普通的Lucas一般指用于质数,广义的可以做质数的k次方的,然后用CRT(中国剩余定理)合并。

技术分享
  1 #include <cstdio>
  2 
  3 #define R register
  4 typedef long long ll;
  5 int pw0[10], pw2[10], pw5[10];
  6 int counter;
  7 inline int qpow(R int base, R ll power, R int mod)
  8 {
  9     R int ret = 1;
 10     for (; power; power >>= 1, base = 1ll * base * base % mod)
 11         power & 1 ? ret = 1ll * ret * base % mod : 0;
 12     return ret;
 13 }
 14 int mod, k;
 15 void exgcd(R int a, R int b, R int &x, R int &y)
 16 {
 17     if (!b) {x = 1, y = 0; return ;}
 18     exgcd(b, a % b, y, x);
 19     y -= a / b * x;
 20 }
 21 inline int inv(R int a, R int p)
 22 {
 23     R int x, y;
 24     exgcd(a, p, x, y);
 25     return (x % p + p) % p;
 26 }
 27 int f2[10][1024], f5[10][1953125];
 28 inline int fac(R ll n, R int fact, R int p, R int pk, R int *fk)
 29 {
 30     if (!n) return 1;
 31     R ll y = n / pk;
 32     R int ret = 1ll * qpow(fact, y, pk) * fk[n % pk] % pk;
 33     return 1ll * fac(n / p, fact, p, pk, fk) * ret % pk;
 34 }
 35 int ft2[10], ft5[10];
 36 inline int Lucas(R ll n, R ll m, R int p, R int pk, R bool div)
 37 {
 38     R ll num = 0;
 39     for (R ll tmp = p; tmp <= n; tmp *= p) num += n / tmp;
 40     for (R ll tmp = p; tmp <= m; tmp *= p) num -= m / tmp;
 41     for (R ll tmp = p; tmp <= n - m; tmp *= p) num -= (n - m) / tmp;
 42     
 43     R int fact = p == 2 ? ft2[k] : ft5[k],
 44           *fk  = p == 2 ? f2[k]  : f5[k],
 45           fa = 1, fb, fc;
 46     if (div)
 47     {
 48         if (p == 2) --num;
 49         else fa = inv(2, pk);
 50     }
 51     if (num >= k) return 0;
 52 
 53     fa = 1ll * fa * fac(n, fact, p, pk, fk) % pk;
 54     fb = fac(m, fact, p, pk, fk);
 55     fc = fac(n - m, fact, p, pk, fk);
 56     fb = inv(fb, pk); fc = inv(fc, pk);
 57     
 58 
 59     return 1ll * fa * fb % pk * fc % pk * qpow(p, num, pk) % pk;
 60 }
 61 inline int C(R ll n, R ll m, R bool div = 0)
 62 {
 63     if (m > n) return 0;
 64 //    printf("C(%lld, %lld) %d\n", n, m, div);
 65     R int C2 = Lucas(n, m, 2, pw2[k], div);
 66     R int C5 = Lucas(n, m, 5, pw5[k], div);
 67 //    printf("%d %d\n", C2, C5);
 68     R int t2 = inv(pw5[k], pw2[k]);
 69     R int t5 = inv(pw2[k], pw5[k]);
 70     R int ans = (1ll * C2 * pw5[k] % mod * t2 + 1ll * C5 * pw2[k] % mod * t5) % mod;
 71 //    printf("%d\n", ans);
 72     return ans;
 73 }
 74 int main()
 75 {
 76     R ll a, b;
 77     pw0[0] = pw2[0] = pw5[0] = 1;
 78     for (R int i = 1; i < 10; ++i)
 79         pw0[i] = pw0[i - 1] * 10,
 80         pw2[i] = pw2[i - 1] * 2,
 81         pw5[i] = pw5[i - 1] * 5;
 82 
 83     for (R int i = 1; i < 10; ++i)
 84     {
 85         f2[i][0] = 1;
 86         for (R int j = 1; j < pw2[i]; ++j)
 87             f2[i][j] = 1ll * f2[i][j - 1] * (j % 2 ? j : 1) % pw2[i];
 88         ft2[i] = f2[i][pw2[i] - 1];
 89     }
 90     for (R int i = 1; i < 10; ++i)
 91     {
 92         f5[i][0] = 1;
 93         for (R int j = 1; j < pw5[i]; ++j)
 94             f5[i][j] = 1ll * f5[i][j - 1] * (j % 5 ? j : 1) % pw5[i];
 95         ft5[i] = f5[i][pw5[i] - 1];
 96     }
 97 
 98     while (scanf("%lld%lld%d", &a, &b, &k) != EOF)
 99     {
100         char str[10];
101         R int ans = 0;
102         mod = pw0[k];
103         ans = qpow(2, a + b - 1, mod);
104         if (a == b) (ans += mod - C(a + a, a, 1)) %= mod;
105         else
106         {
107             if (((a + b) & 1) == 0) (ans += C(a + b, (a + b) / 2, 1)) %= mod;
108             for (R ll j = (a + b) / 2 + 1; j < a; ++j)
109                 (ans += C(a + b, j)) %= mod;
110         }
111         sprintf(str, "%%0%dd\n", k);
112         printf(str, ans);
113     }
114     return 0;
115 }
116 /*
117 488754688
118 1000000000000000 999999999990000 9
119 1000000000000000 999999999990000 8
120 1000000000000000 999999999990000 7
121 1000000000000000 999999999990000 6
122 1000000000000000 999999999990000 5
123 1000000000000000 999999999990000 4
124 1000000000000000 999999999990000 3
125 1000000000000000 999999999990000 2
126 1000000000000000 999999999990000 1
127 */
D2T3

 

以上是关于Hnoi2017试题泛做的主要内容,如果未能解决你的问题,请参考以下文章

Shoi2017试题泛做

「美团 CodeM 资格赛」试题泛做

SNOI2017(BZOJ5015~5018)泛做

「泛做题解」曾经的 AtCoder 题解汇总

片段(Java) | 机试题+算法思路+考点+代码解析 2023

[BZOJ1486][HNOI2009]最小圈