2019 Multi-University Training Contest 1 (补题)

1001.Blank

题意:给一列数组填四种数,使得每个给定第$i$个的区间数的种类刚好有$x_{i}$种

我的思路:dp,状态排完序后是四种数最后的位置,转移时判断合法性即可(卡常有点厉害)

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N = 1e2 + 5;
 5 const int MOD = 998244353;
 6
 7 int dp[2][N][N][N];
 8 int a[N][10];
 9
10 bool check(int i, int j, int k, int l)
11 {
12
13   return (a[l][1] == -1 || a[l][1] > k) &&
14          (a[l][3] == -1 || (a[l][3] > j && a[l][4] <= k)) &&
15          (a[l][5] == -1 || (a[l][5] > i && a[l][6] <= j)) &&
16          (a[l][7] == -1 || a[l][8] <= i);
17 }
18
19 void fadd(int& a, int b)
20 {
21   a += b;
22   if (a >= MOD) a -= MOD;
23 }
24
25 int main()
26 {
27   int T;
28   scanf("%d", &T);
29   while (T --) {
30     int n, m;
31     memset(a, -1, sizeof(a));
32     scanf("%d%d", &n, &m);
33     for (int i = 0; i <= n; ++ i) {
34       for (int j = 0; j <= n; ++ j) {
35         for (int k = 0; k <= n; ++ k) {
36           dp[0][i][j][k] = dp[1][i][j][k] = 0;
37         }
38       }
39     }
40     for (int i = 0; i < m; ++ i) {
41       int l, r, k;
42       scanf("%d%d%d", &l, &r, &k);
43       a[r][k * 2] = max(a[r][k * 2], l);
44       if (a[r][k*2-1] == -1 || l<a[r][k*2-1]) {
45         a[r][k*2-1] = l;
46       }
47     }
48     dp[0][0][0][0] = 1;
49     int pre = 0;
50     for (int l = 0; l < n; ++ l) {
51       pre ^= 1;
52       for (int i = 0; i <= l + 2; ++ i) {
53         for (int j = i; j <= l + 2; ++ j) {
54           for (int k = j; k <= l + 2; ++ k) {
55             dp[pre][i][j][k] = 0;
56           }
57         }
58       }
59       for (int i = 0; i <= l; ++ i) {
60         for (int j = i; j <= l; ++ j) {
61           for (int k = j; k <= l; ++ k) {
62             fadd(dp[pre][i][j][k], dp[pre^1][i][j][k]);
63             fadd(dp[pre][i][j][l], dp[pre^1][i][j][k]);
64             fadd(dp[pre][i][k][l], dp[pre^1][i][j][k]);
65             fadd(dp[pre][j][k][l], dp[pre^1][i][j][k]);
66           }
67         }
68       }
69       for (int i = 0; i <= l; ++ i) {
70         for (int j = i; j <= l; ++ j) {
71           for (int k = j; k <= l; ++ k) {
72             if (!check(i, j, k, l + 1)) dp[pre][i][j][k] = 0;
73           }
74         }
75       }
76     }
77     int ans = 0;
78     for (int i = 0; i < n; ++ i) {
79       for (int j = i; j < n; ++ j) {
80         for (int k = j; k < n; ++ k) {
81           fadd(ans, dp[pre][i][j][k]);
82         }
83       }
84     }
85     printf("%d\n", ans);
86   }
87   return 0;
88 }

1002.Operation

题意:给定一个数列,执行两种操作,第一种是询问区间选数异或能取到的最大值,第二种是在数组尾巴上添加一个数

思路:贪心+线性基,从左往右维护n个线性基,更新线性基时贪心地维护高位最近更新坐标,询问时从高位往低位贪,对于询问$l$,$r$,如果$r$位线性基高位最近更新坐标不小于$l$,我们便可尝试异或该位上的数。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N = 1e6 + 5;
 5
 6 int ind[N][31], f[N][31];
 7
 8 void Insert(int x, int p)
 9 {
10   int np = p;
11   for (int i = 30; i >= 0; -- i) {
12     f[p][i] = f[p - 1][i];
13     ind[p][i] = ind[p - 1][i];
14   }
15   for (int i = 30; i >= 0; -- i) {
16     if ((x >> i) & 1) {
17       if (!ind[p][i]) {
18         ind[p][i] = np; f[p][i] = x;
19         break;
20       }
21       if (ind[p][i] < np) {
22         swap(ind[p][i], np);
23         swap(f[p][i], x);
24       }
25       x ^= f[p][i];
26     }
27   }
28 }
29
30 int main()
31 {
32   int T;
33   scanf("%d", &T);
34   while (T --) {
35     int n, m;
36     scanf("%d%d", &n, &m);
37     for (int i = 1; i <= n; ++ i) {
38       int x;
39       scanf("%d", &x);
40       Insert(x, i);
41     }
42     int ans = 0;
43     for (int i = 0; i < m; ++ i) {
44       int cmd;
45       scanf("%d", &cmd);
46       if (cmd == 0) {
47         int l, r;
48         scanf("%d%d", &l, &r);
49         l ^= ans; l = l % n + 1;
50         r ^= ans; r = r % n + 1;
51         if (l > r) swap(l, r);
52         ans = 0;
53         for (int j = 30; j >= 0; -- j) {
54           if (ind[r][j] >= l && (ans ^ f[r][j]) > ans) {
55             ans ^= f[r][j];
56           }
57         }
58         printf("%d\n", ans);
59       } else {
60         int x;
61         scanf("%d", &x);
62         x ^= ans;
63         Insert(x, n + 1);
64         n ++;
65       }
66     }
67   }
68   return 0;
69 }

1004.Vacation

题意:给出一堆车地长度,坐标和速度,问tom的车到达斑马线的时间是多少。

我的思路:算出每辆车到达不会于阻挡tom车(到达斑马线)的位置,取最大值。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N = 1e5 + 5;
 5
 6 double l[N], s[N], v[N];
 7
 8 int main()
 9 {
10   int n;
11   while (scanf("%d", &n) != EOF) {
12     for (int i = 0; i <= n; ++ i) {
13       scanf("%lf", l + i);
14       if (i > 1) l[i] += l[i - 1];
15     }
16     for (int i = 0; i <= n; ++ i) {
17       scanf("%lf", s + i);
18       if (i > 0) s[i] += l[i];
19     }
20     double t = 0;
21     for (int i = 0; i <= n; ++ i) {
22       scanf("%lf", v + i);
23       t = max(t, s[i] / v[i]);
24     }
25     printf("%.10f\n", t);
26   }
27   return 0;
28 }

1009.String

题意:给定一个串,取一个固定长子序列使得每个字母恰好出现$(L_{i}, R_{i})$次

我的思路:枚举子序列第i位,贪心放字母并判断该操作是否合法。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N = 1e5 + 5;
 5
 6 char s[N], ans[N];
 7 int lft[N][26];
 8 int num[26];
 9 int L[26], R[26];
10 int k;
11
12 int main()
13 {
14   while (scanf("%s%d", s, &k) != EOF) {
15     int l = strlen(s);
16     memset(lft[l], 0, sizeof(lft[l]));
17     memset(num, 0, sizeof(num));
18     for (int i = l - 1; i >= 0; -- i) {
19       for (int j = 0; j < 26; ++ j) {
20         lft[i][j] = lft[i + 1][j];
21       }
22       lft[i][s[i] - ‘a‘] ++;
23     }
24     int sr = 0, sl = 0;
25     for (int i = 0; i < 26; ++ i) {
26       scanf("%d%d", L + i, R + i);
27       sr += R[i];
28       sl += L[i];
29     }
30     if (sr < k || sl > k) {
31       puts("-1");
32       continue;
33     }
34     vector<int> a[26];
35     int pos[26] = {0};
36     for (int i = 0; i < l; ++ i) {
37       a[s[i] - ‘a‘].emplace_back(i);
38     }
39     int ptr = -1, sum = 0;
40     for (int i = 0; i < k; ++ i) {
41       for (int j = 0; j < 26; ++ j) {
42         while (pos[j] < (int)a[j].size() && a[j][pos[j]] <= ptr) {
43           pos[j] ++;
44         }
45         if (pos[j] == (int)a[j].size()) continue;
46         int ps = a[j][pos[j]];
47         if (num[j] + 1 > R[j]) continue;
48         if (sl + sum + (num[j] >= L[j]) > k) continue;
49         num[j] ++;
50         int ok = 1, st = 0;
51         for (int t = 0; t < 26; ++ t) {
52           if (num[t] + lft[ps + 1][t] < L[t]) {
53             ok = 0; break;
54           }
55           st += num[t] + min(R[t] - num[t], lft[ps + 1][t]);
56         }
57         if (!ok || st < k) {
58           num[j] --; continue;
59         }
60         ptr = a[j][pos[j]];
61         sum ++; sl -= (num[j] <= L[j]);
62         ans[i] = j + ‘a‘;
63         break;
64       }
65     }
66     ans[k] = ‘\0‘;
67     printf("%s\n", ans);
68   }
69   return 0;
70 }

1011.Function

题意:给定n,求

$$\sum_{i=1}^n\gcd(\lfloor{\sqrt[3]{i}}\rfloor,i)\mod 998244353$$

我的思路:反过来枚举开立方后的数,利用狄利克雷卷积相关的公式化简表达式(由于时间原因推导暂时不写上来了,以后再补上,Tex写起来很麻烦滴),卡常卡到欲仙欲死。

代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 typedef __int128 ll;
  5
  6 const int MOD = 998244353;
  7 const int N = 1e7 + 5;
  8
  9 int cnt = 0;
 10 int prime[N / 10];
 11 int phi[N];
 12 bool vis[N];
 13
 14 namespace fastIO {
 15   //fread -> read
 16   const int BUF_SIZE = 1000000;
 17   bool IOerror = 0;
 18   inline char nc() {
 19     //FILE* fp=fopen("123.txt","r");
 20     static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
 21     if(p1 == pend) {
 22       p1 = buf;
 23       pend = buf + fread(buf, 1, BUF_SIZE, stdin);
 24       if(pend == p1) {
 25         IOerror = 1;
 26         return -1;
 27       }
 28     }
 29     return *p1++;
 30   }
 31
 32   //输入挂,EOF返回0,有输入返回1.
 33   template <class T>
 34   inline bool read(T &ret) {
 35     char c;
 36     if (c = nc(), c == EOF)return 0; //EOF
 37     while(c != ‘-‘ && (c < ‘0‘ || c > ‘9‘)) c = nc();
 38     int sgn = (c == ‘-‘) ? -1 : 1;
 39     ret = (c == ‘-‘) ? 0 : (c - ‘0‘);
 40     while(c = nc(), c >= ‘0‘ && c <= ‘9‘) ret = ret*10 + (c-‘0‘);
 41     ret *= sgn;
 42     return 1;
 43   }
 44   template <class T>
 45   inline void print(T x) {
 46     if(x>9) print(x/10);
 47     putchar(x%10+‘0‘);
 48   }
 49 }; using fastIO::read; using fastIO::print;
 50
 51 void init()
 52 {
 53   phi[1] = 1;
 54   for (int i = 2; i < N; ++ i) {
 55     if (!vis[i]) {
 56       prime[cnt ++] = i;
 57       phi[i] = i - 1;
 58     }
 59     for (int j = 0; j < cnt && prime[j] * i < N; ++ j) {
 60       vis[prime[j] * i] = 1;
 61       if (i % prime[j] == 0) {
 62         phi[prime[j] * i] = phi[i] * prime[j];
 63         break;
 64       } else {
 65         phi[prime[j] * i] = phi[i] * (prime[j] - 1);
 66       }
 67     }
 68   }
 69 }
 70
 71 void fadd(int& a, ll b)
 72 {
 73   a += b;
 74   if (a >= MOD) a -= MOD;
 75 }
 76
 77 void fsub(int& a, ll b)
 78 {
 79   a -= b;
 80   if (a < 0) a += MOD;
 81 }
 82
 83 ll solve(ll r, ll n)
 84 {
 85   if (r * r * r > n) return 0;
 86   ll l = r * r * r - 1;
 87   int rtn = 0;
 88   int tmp = r;
 89   int sqt = sqrt(tmp);
 90   for (int i = 1; i <= sqt; ++ i) {
 91     if (r % i == 0) {
 92       fadd(rtn, ((n / i) - (l / i)) * phi[i] % MOD);
 93       if (i * i != r) {
 94         fadd(rtn, ((n / (r / i)) - (l / (r / i))) * phi[r / i] % MOD);
 95       }
 96     }
 97   }
 98   return rtn;
 99 }
100
101 int main()
102 {
103   init();
104   int T;
105   read(T);
106   while (T --) {
107     ll n;
108     read(n);
109     if (n <= 10) {
110       int ans = 0;
111       for (int i = 1; i <= n; ++ i) {
112         ans += __gcd((int)sqrt(i), i);
113       }
114       printf("%d\n", ans);
115       continue;
116     }
117     int R;
118     for (int i = 1; ; ++ i) {
119       ll k = i; k = k * k * k;
120       if (k - 1 > n) break;
121       R = i - 1;
122     }
123     int ans = 0;
124     for (int i = 1; i <= R; ++ i) {
125       int d = R / i;
126       int tmp = d + 3ll * d * (d + 1) / 2 % MOD;
127       tmp %= MOD;
128       fadd(tmp, 1ll * d * (d + 1) / 2 % MOD * (d * 2 + 1) % MOD * i % MOD);
129       tmp = 1ll * tmp * phi[i] % MOD;
130       ans += tmp;
131       if (ans >= MOD) ans -= MOD;
132     }
133     fadd(ans, solve(R + 1, n));
134     printf("%d\n", ans);
135   }
136   return 0;
137 }

1012.Sequence

题意:给n长数列和m个操作(最多三种操作),每个操作给定一个k,执行$b_i = \sum_{j = i - k \cdot x}  a_j (0 \leq x, 1\leq j \leq i)$并替换$a_i$,求m次操作后数列的值。

我的思路:根据没种操作的操作数我们可以算出其相应母函数$i$次系数,再用$ntt$进行至多三次卷积加速即可。

代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 namespace fastIO {
  5   //fread -> read
  6   const int BUF_SIZE = 1000000;
  7   bool IOerror = 0;
  8   inline char nc() {
  9     //FILE* fp=fopen("123.txt","r");
 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
 22   //输入挂,EOF返回0,有输入返回1.
 23   template <class T>
 24   inline bool read(T &ret) {
 25     char c;
 26     if (c=nc(),c==EOF)return 0; //EOF
 27     while(c!=‘-‘&&(c<‘0‘||c>‘9‘))c=nc();
 28     int sgn =(c==‘-‘)?-1:1;
 29     ret=(c==‘-‘)?0:(c - ‘0‘);
 30     while(c=nc(),c>=‘0‘&&c<=‘9‘) ret=ret*10+(c-‘0‘);
 31     ret *= sgn;
 32     return 1;
 33   }
 34   template <class T>
 35   inline void print(T x) {
 36     if(x>9) print(x/10);
 37     putchar(x%10+‘0‘);
 38   }
 39 }; using fastIO::read;
 40
 41 const int N = 1e5 + 5;
 42 const int M = 2e6 + 5;
 43 const int MOD = 998244353;
 44
 45 typedef long long ll;
 46
 47 int A[N];
 48 int fac[M], inv[M];
 49
 50 void init()
 51 {
 52   fac[0] = inv[0] = fac[1] = inv[1] = 1;
 53   for (int i = 2; i < M; ++ i) {
 54     fac[i] = 1ll * fac[i - 1] * i % MOD;
 55     inv[i] = 1ll * (MOD - MOD/i) * inv[MOD%i] % MOD;
 56   }
 57   for (int i = 2; i < M; ++ i) {
 58     inv[i] = 1ll * inv[i - 1] * inv[i] % MOD;
 59   }
 60 }
 61
 62 int fpow(int a, int b)
 63 {
 64   int rtn = 1;
 65   while (b) {
 66     if (b & 1) rtn = 1ll * rtn * a % MOD;
 67     a = 1ll * a * a % MOD;
 68     b >>= 1;
 69   }
 70   return rtn;
 71 }
 72
 73 inline int fadd(int a, int b)
 74 {
 75   a += b;
 76   if (a >= MOD) a -= MOD;
 77   return a;
 78 }
 79
 80 inline int fsub(int a, int b)
 81 {
 82   a -= b;
 83   if (a < 0) a += MOD;
 84   return a;
 85 }
 86
 87 int a[4 * N], b[4 * N];
 88 struct NTT
 89 {
 90   int siz;
 91   void init(int n) {
 92     siz = 1;
 93     for (; siz < (n << 1); siz <<= 1);
 94     for (int i = 0; i < siz; ++ i) {
 95       a[i] = b[i] = 0;
 96     }
 97   }
 98   void ntt(int *p, int f) {
 99     for (int i = 0, j = 0; i < siz; ++ i) {
100       if (i < j) swap(p[i], p[j]);
101       for (int k = siz>>1; (j ^= k) < k; k >>= 1);
102     }
103     for(int i = 2; i <= siz; i <<= 1) {
104       int nw = fpow(3, (MOD - 1) / i);
105       if (f == -1) {
106         nw = fpow(nw, MOD - 2);
107       }
108       for (int j = 0, m = i >> 1; j < siz; j += i) {
109         for (int k = 0, w = 1; k < m; ++ k) {
110           int t = 1ll * p[j + k + m] * w % MOD;
111           p[j + k + m] = fsub(p[j + k], t);
112           p[j + k] = fadd(p[j + k], t);
113           w = 1ll * w * nw % MOD;
114         }
115       }
116     }
117     if (f == -1) {
118       int inv = fpow(siz, MOD - 2);
119       for (int i = 0; i < siz; ++ i) {
120         p[i] = 1ll * p[i] * inv % MOD;
121       }
122     }
123   }
124   void fmul() {
125     ntt(a, 1); ntt(b, 1);
126     for (int i = 0; i < siz; ++ i) {
127       a[i] = 1ll * a[i] * b[i] % MOD;
128     }
129     ntt(a, -1);
130   }
131 };
132
133 int C(int a, int b)
134 {
135   return 1ll * fac[a] * inv[b] % MOD * inv[a - b] % MOD;
136 }
137
138 int main()
139 {
140   init();
141   int T;
142   read(T);
143   while (T --) {
144     int n, m;
145     read(n); read(m);
146     for (int i = 0; i < n; ++ i) {
147       read(A[i]);
148     }
149     int num[4] = {0};
150     for (int i = 0; i < m; ++ i) {
151       int x; read(x);
152       num[x] ++;
153     }
154     NTT Nt;
155     Nt.init(n);
156     for (int i = 0; i < n; ++ i) {
157       a[i] = A[i];
158     }
159     for (int i = 1; i <= 3; ++ i) {
160       if (num[i] == 0) continue;
161       for (int j = n; j < Nt.siz; ++ j) {
162         a[j] = b[j] = 0;
163       }
164       for (int j = 0; j < n; ++ j) {
165         b[j] = (j % i == 0 ? C(j / i + num[i] - 1, num[i] - 1) : 0);
166       }
167       Nt.fmul();
168     }
169     ll ans = 0;
170     for (int i = 0; i < n; ++ i) {
171       ans ^= 1ll * (i + 1) * a[i];
172     }
173     printf("%lld\n", ans);
174   }
175   return 0;
176 }

原文地址:https://www.cnblogs.com/UtopioSPH001/p/11260801.html

时间: 2024-11-14 12:52:39

2019 Multi-University Training Contest 1 (补题)的相关文章

2019 HDOJ Multi-University Training Contest Stage 4(杭电多校)

很抱歉过了这么多天才补这场,最近真的挺忙的…… 出题人是朝鲜的(目测是金策工业?),挺难. 题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=851 A: 签到题. 对于当前的点,若其编号为偶数,则可与1相连使得边权贡献为0.否则从低位向高位找当前点编号的二进制表示的第一个0,使这个0变为1,其他位置变为0并检查新的数字是否小于等于n.若小于等于n则贡献为0,反之贡献为1. 1 /* basic header */ 2 #inclu

2019 HDOJ Multi-University Training Contest Stage 8(杭电多校)

中规中矩的一场. 题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=855 C: 定义函数f(d,k)为数字d在数字k中出现的次数.给定d和x,找到尽量大的k使得k<=x且f(d,k)==k. 很诡异的一题,最好的做法仍然是打表找规律.题解给了一个很神奇的结论:满足条件的k<1011且k的分布非常稀疏. 1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* defin

2019 HDOJ Multi-University Training Contest Stage 10(杭电多校)

最后一场多校打得一般般. 题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=857 C: E: I: BFS水题. 1 /* Codeforces Contest 2019_mutc_10 2 * Problem I 3 * Au: SJoshua 4 */ 5 #include <queue> 6 #include <cstdio> 7 #include <vector> 8 #include <s

Comet OJ - Contest #13 补题题解

A.险恶的迷宫 题意:在二维平面坐标内,给出一个圆心坐标 (a,b),以及圆的半径 r , 再给出 n 个点的坐标 (x_i,y_i),  求有多少点在圆内. 数据范围:0  <  n  <= 1e5,      0< r , x , y  <=1e9 思路:对于判断距离根据勾股定理: sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) <= r ,即在圆的范围内.由于此题数据较大,sqrt可能导致精度损失,所以直接开long long 进行平方比较

2019 HDOJ Multi-University Training Contest Stage 2(杭电多校)

服务器时不时爆炸,有点难受. 题目链接:http://acm.hdu.edu.cn/userloginex.php?cid=849 A: 神仙题.不可做题. B: dp. C: 推式子题. D: 边分治. E: 可以数学推理的题.但是显然打表更快找出规律.对打出来的结果做两次差分即可. 1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou doubl

2020.3.28 UCF Local Programming Contest 2016补题与解题报告

A.Majestic 10 大致题意就是指看有几个大于等于10,直接按照题意输出就行,签到题 代码: #include<stdio.h> int main(){ int n,a,b,c; scanf("%d",&n); while(n--){ scanf("%d %d %d",&a,&b,&c); int sum=0; printf("%d %d %d\n",a,b,c); if(a>=10) s

2019 Nowcoder Multi-University Training Contest 1 H-XOR

由于每个元素贡献是线性的,那么等价于求每个元素出现在多少个异或和为$0$的子集内.因为是任意元素可以去异或,那么自然想到线性基.先对整个集合A求一遍线性基,设为$R$,假设$R$中元素个数为$r$,那么任取一个不在$R$内的元素,$R$中肯定存在一种取法能和这个元素异或和为$0$.同理,取定一个不在$R$内的元素,再随便取另外任意个不在$R$内的元素,$R$内仍然存在一种取法使得这个异或和为$0$.那么每个不在$R$内的元素包含在$2^{n - r - 1}$个集合内(其他不在$R$内的元素可以

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

HDU校赛 | 2019 Multi-University Training Contest 3

2019 Multi-University Training Contest 3 http://acm.hdu.edu.cn/contests/contest_show.php?cid=850 1004. Distribution of books 考虑二分答案,设当前二分出来的是\(x\). 设\(f_i\)表示前\(i\)个能分成最多的段数,使得每一段和都\(\leqslant x\). 转移显然,枚举一个\(j\),若\(s_i-s_j\leqslant x\)则转移,\(s_i\)表示前