ARC 201
A
这里是一个完全不优的解法。
我们要最大化 \(\min(d_1,d_2)\)。对于一个 \(a,b,c\),如果 \(a+c\le b\),那么可以 \(d_1\gets d_1+a,d_2\gets d_2+a\)。否则我们要选择 \(a+c-b\) 个删掉。
考虑 \(\sum a\) 和 \(\sum c\) 大的那一个。尽量要让他“减的更多”。可以算出他减的范围,分类讨论即可。
B
因为是 \(2^x\) 的重量,发现 \(2^{x-1}+2^{x-1}=2^x\),即两个可以合成一个。从小到大考虑,把没有用上的合并,贪心即可。
C
trie 树上 dp。考虑插入一个数的时候只会修改路径上的,那么时间是 \(\mathcal{O}(\sum |s_i|)\)。
设 \(dp_u\) 为“表示完”\(u\) 子树的方案数。那么:
-
如果 \(ls_u,rs_u\) 都存在,\(dp_u\gets dp_{ls_u}\times dp_{rs_u}\)。
-
如果 \(u\) 是一个字符串的终止节点,\(dp_{u}\gets dp_{u}+2^{sz_u-1}\)。\(sz_u\) 为子树内的终止个数。
D
把 \(a\) 降序,\(b\) 升序并且扩大成两倍(\(b_{i+n}=b_i+m\)),发现一定是 \(a\) 在“滑动”匹配。
进一步发现二分后,对于 \(a_i\) 可以匹配的是一个区间,那么就有了“滑动距离”的长度限制区间。取交看是不是非空即可。
bool chk(int mid){
int x=0,y=0,cl=0,cr=n;
for (int i=1; i<=n; i++){
int lb=m-a[i],rb=m+mid-a[i];
while (y+1<=n*2 && b[y+1]<=rb) y++;
while (x+1<=n*2 && b[x]<lb) x++;
int mvl=x-i,mvr=y-i;
mvl=max(mvl,0);
cl=max(cl,mvl);
cr=min(cr,mvr);
}
return cl<=cr;
}
E
考虑 \(\max,\min\) 组合相乘算贡献不好算,原因是要维护 \(\max,\min\) 的值。
考虑另一种拆贡献:对于一个 \((x,y)—(x+1,y+1)\) 的格子算出贡献。那么 \(\le x,\le y\ge x+1,\ge y+1\) 都要存在。容斥,等于 \(2^n-C(\le x)-C(\le y)-C(\ge x+1)-C(\ge y+1)+C(\le x,\le y)+C(\le x,\ge y)+C(\ge x+1,\le y)+C(\ge x+1,\ge y+1)\)。\(C(\cdots)\) 为满足 \(\cdots\) 的方案数。
前四个是好算的,因为又有对称性,不妨只算 \(C(\le x,\le y)\)。
这个可以按照 \(X\) 坐标加入点的时候维护,每一次相当于给一个后缀 \(\times 2\),求和,用线段树即可。
浙公网安备 33010602011771号