一场咕咕咕了三天的AGC
可能我的智商不太适合做AGC?
可是立的flag总得完成!
n = 3 n=3 n=3不好构造,但是给了样例,直接输出即可。
为使全局 gcd = 1 \gcd=1 gcd=1,构造任意个2的倍数,奇数个3的倍数即可。
总存在方案使得 6 ∣ s u m 6|sum 6∣sum:
打表找出 ≤ 12 \leq 12 ≤12的长度为 8 8 8的构造,每次整体 + 12 +12 +12即可(注意分 n n n的奇偶讨论)
由于第 k k k位操作的贡献是 2 k 2^k 2k,所以贪心从高到低诸位确定。
优化也不需要,暴力判即可。
求解最小化火车往返次数。
对于 ≥ 2 L \geq 2L ≥2L的 t i t_i ti,直接 t i m o d 2 L t_i \ mod \ 2L ti mod 2L。
此时所有 t i < 2 L t_i<2L ti<2L,设 l i = [ t i ≤ 2 x i ] , r i = [ t i ≤ 2 ( L − x i ) ] l_i=[t_i\leq 2x_i],r_i=[t_i\leq 2(L-x_i)] li=[ti≤2xi],ri=[ti≤2(L−xi)]分别表示点 i i i能否直接右进右出/左进左出。
安排所有点按标号依次选择,逐步优化:
对于 i < j , l i = r j = 1 i<j,l_i=r_j=1 i<j,li=rj=1,可以先走 j j j再从 j → i j\to i j→i,贪心匹配最多即可。
注意讨论的细节:
code from wxh010910
#include
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 300005;
int n, m, x, y, a[N];
bool l[N], r[N];
LL ans;
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n), Read(m);
for (int i = 1; i <= n; ++i) {
Read(a[i]);
}
for (int i = 1, t; i <= n; ++i) {
Read(t);
if (t % (m << 1) == 0) {
ans += t;
} else {
ans += 1LL * (t / (m << 1) + 1) * (m << 1), t %= m << 1;
if (t <= a[i] << 1) {
l[i] = true;
}
if (t <= m - a[i] << 1) {
r[i] = true;
}
}
}
for (int i = 1; i < n; ++i) {
if (x && r[i]) {
if (l[i]) {
++y;
}
--x, ans -= m << 1;
} else if (!l[i] && r[i]) {
if (y) {
--y, ++x;
}
} else if (l[i]) {
++x;
}
}
if (!r[n]) {
ans += m << 1;
}
printf("%lld\n", ans);
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
设相邻第 i i i个1和第 i + 1 i+1 i+1个1之间的 0 0 0的个数为 a i a_i ai(包括首尾端点),分析如下:
若存在 a p = a q = 0 , p < q a_p=a_q=0,p<q ap=aq=0,p<q且 p p p为奇数, q q q为偶数,则可达目标状态: 0 , 0 0,0 0,0。
DP处理。
另:自动机解法
要被“显然”坑死了(智商捉急)
证明很不完善/严谨,欢迎指正(轻喷
一些明显的条件:
将答案看做 X X X进制数,每一位上答案互不相关。问题转化为找合法的(由合法转移得到) X X X进制数的个数。
且系数均为 + 2 p / − 2 p +2^p/-2^p +2p/−2p的形式,设第 i i i位系数为 p i p_i pi,则 ∑ i = 1 n p i = 1 \sum \limits_{i=1}^n p_i=1 i=1∑npi=1。且 p p p序列中 1 1 1和 − 1 -1 −1的总共出现次数为 1 1 1,且若 ± 2 i ( i > 0 ) \pm 2^i(i>0) ±2i(i>0)出现, ± 2 i − 1 \pm 2^{i-1} ±2i−1必然出现(即系数在2的次幂上是连续的)。
最关键的条件(和命题充分必要):
对于任意 i i i,可以通过调整绝对值为 2 i 2^i 2i的 p p p的符号使得绝对值 ≤ 2 i \leq 2^i ≤2i的数和为 1 1 1。
考虑构造过程,必要性“显然”。
???这里就看不懂了。
经过我长久的思考(1天,我TCL),发现可以归纳法证明(???):
A A A满足, B B B满足, 2 A − B 2A-B 2A−B的所有绝对值 ≤ 2 i \leq 2^i ≤2i项相当于 A A A中所有绝对值 ≤ 2 i − 1 \leq 2^{i-1} ≤2i−1的项(可以调整 2 i − 1 2^{i-1} 2i−1的系数得到 1 1 1,然后 × 2 \times 2 ×2得到 2 2 2)和 B B B中所有绝对值 ≤ 2 i \leq 2^i ≤2i的项,可以调整 2 i 2^{i} 2i的系数得到1,所以最终得到1。
充分性也可以归纳法证明(对于一个满足性质集合 S S S,如果能分成 2 A , − B 2A,-B 2A,−B, A , B A,B A,B也满足这个条件,即得证):
不妨设 − 1 ∈ S -1\in S −1∈S( 1 ∈ S 1\in S 1∈S的情况类似),设 k k k为最小的 2 k ∈ S 2^k\in S 2k∈S:
考虑 D P DP DP,设 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i个数,总和为 1 + j V 1+jV 1+jV的方案数, V V V表示当前枚举到的 V = 2 k V=2^k V=2k项, V V V具体是多少不需要知道,预处理组合数 n 4 n^4 n4转移即可。