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\),求和,用线段树即可。

posted @ 2025-06-24 21:17  SFlyer  阅读(47)  评论(0)    收藏  举报