Processing math: 0%

2021-10-11 杂题选听

2021-10-11 杂题选听

CF1427E Xum
离谱
设原数是 x,把原数不断左移,最低位与最高位对齐,记为 y
由于 k=y\oplus x=x\cdot 2^t-2^t+x,所以 kx 互质
考虑 exgcd 搞出 ak+bx=1,并设 a'\ge |a|,b'\ge |b|,设 a'k+b'x=e
(a'+a)k+(b'+b)x=e+1
那一异或就出 1

CF1340D Nastya and Time Machine
d 为最大度数,答案肯定不小于 d
考虑构造答案为 d 的方案,从任一点开始 dfs,若 u\rightarrow v 时时间是 t,则 v\rightarrow u 也应是 t
当到达一个点时时间到了 d,就要减少时间,减小到 d-deg_u,即可整好在 t 回到父亲

CF1442D Sum
考虑最后一定是有若干个数组取满了,最多有一个数组取了一部分
考虑若有两个数组都只取了一部分,那么由于数组不降,则把其中一个往前一个个删并在另一个后面加会更优
那么如果没取完的是 i,对于剩下取完了的数组就是不考虑物品 i 的背包
这个东西就是分治一下,把左边的物品全加进去再分治到右边,右边全加进去分治到左边
复杂度 O(nk\log n)

#define N 3006
int n,k;
long long f[N],ans[N][N];
int num[N];
long long sum[N];
std::vector<int>a[N];
inline void work(int l,int r){
	if(l==r) return std::memcpy(ans[l],f,sizeof ans[l]),void();
	int mid=(l+r)>>1;
	long long *backup=new long long[N];
	std::memcpy(backup,f,sizeof f);
	for(int i=l;i<=mid;i++){
		for(int j=k;j>=num[i];j--) f[j]=std::max(f[j],f[j-num[i]]+sum[i]);
	}
	work(mid+1,r);
	std::memcpy(f,backup,sizeof f);
	delete backup;
	for(int i=mid+1;i<=r;i++){
		for(int j=k;j>=num[i];j--) f[j]=std::max(f[j],f[j-num[i]]+sum[i]);
	}
	work(l,mid);
}
int main(){
	n=read();k=read();
	for(int i=1;i<=n;i++){
		num[i]=read();
		for(int j=0;j<num[i];j++) a[i].push_back(read()),sum[i]+=a[i][j];
	}
	work(1,n);
	long long Ans=0;
	for(int i=1;i<=n;i++){
		Ans=std::max(Ans,ans[i][k]);
		long long sum=0;
		for(int s=a[i].size(),j=0;j<s&&j<k;j++){
			sum+=a[i][j];
			Ans=std::max(Ans,ans[i][k-j-1]+sum);
		}
	}
	printf("%lld\n",Ans);
	return 0;
}

CF1446C Xor Tree
考虑建出 trie 来在上面 dp 最多能拿多少个
叶子的 f_u=1,若一个点有两个儿子,则如果两边都选了超过一个数,则肯定是自己子树内连没有跨过子树的边
所以有一子树最多选一个,f_u=\max(f_{ls},f_{rs})+1

CF1439B Graph Subset Problem
从度数最小的点开始删,删到最小点度数 k 时,则满足了条件 2
满足条件 1 的情况必然有 k\le \sqrt{m},那么删的时候若删的是一个 k-1 度的点就暴力判一下他和他相邻的所有点是否构成团
O(n\sqrt{m}\log n),用 unordered_map 就没 \log

P4007 小 Y 和恐怖的奴隶主
(i,a,b,c) 表示进行了 i 此攻击,1,2,3 血随从分别由 a,b,c
然后有用状态大概 \tbinom{8+3}{3}=165,矩阵就是 166\times 166 的,那么每次暴力矩乘就是 O(T166^3\log n)
对于多测,可以把矩阵的 2^i 次幂都预处理出来,每次拿向量乘 O(\log n) 个矩阵,就有 O(166^3\log n+T166^2\log n)

hdu6145 Arithmetic of Bomb II
维护数对 (a,b,c) 表示 a+b\times c
那么有如下变化:

  • 加入一个数字 d,有 (a,b,c\times 10+d)
  • 加入一个加号,有 (a+b\times c,1,0)
  • 加入一个减号,有 (a+b\times c,-1,0)
  • 加入一个乘号,有 (a,b\times c,0)

再维护一个 b\times c,这些玩意都可以用矩乘表示出来,于是就对每个重复部分加速一下就行

直接硬分类讨论也行?

P4766 [CERC2014]Outer space invaders
如果想按照时间从前往后 dp,需要记录的信息非常多
那么可以区间 dp,设 f_{i,j} 是将左右端点都在 [i,j] 里的人干掉需要的最小代价
设其中 d 最大的人是 id,那么肯定要开炮距离为 d_{id} 的,于是枚举啥时候开:

f_{i,j}=\min_{l_{id}\le k\le r_{id}}\{f_{i,k-1}+f_{k+1,j}\}+d_{id}

P4350 [CERC2015]Export Estimate
对于权值的限制,离线并从大到小加边
0,2 度点被删掉,2 度点会使得边数减一
但若对于一个无弦的环,上面都是二度点,但是最后会剩下一个点和一条自环没删掉
所以:点数=总点数-0,2 度点数+无弦环数
边数=加了的边数-2 度点数+无弦环数

P4748 [CERC2017]Justified Jungle
枚举 n 的约数是小于 \sqrt{n} 的,所以考虑对于每个暴力枚举并 O(n) 判断
若点满足子树大小是 \dfrac{n}{k+1} 的倍数,就可以切他和他父亲的边,若这样的点有 k+1 个(有个是根)就是可以

P4750 [CERC2017]Lunar Landscape
坐标很小,所以对于正着的正方形直接暴力差分
对于斜着的,每个格子拆成四个小三角形,对这些三角形差分
处理完直接枚举格子暴力数

AGC052B Tree Edges XOR
离谱
考虑规定点权,使得每个边权等于两端点点权异或和,比如可以规定点权是到根路径的异或和
这样一次操作相当于交换点权,那么就比较新旧树的点权是否相等即可,但要枚举根(端点异或相等不一定要求两个端点必须相等),还有个排序所以是 O(n^2\log n)
考虑如何省去枚举根的过程,从 1 为根求出原树的数组若为 a,则以 rt 为根求出来的就是每个 a_i 都异或上 a_{rt}
再记目标树点权数组为 b,那么就是 a 全部异或上其中某一项要和 b 相等,那么把 a,b 中所有项异或起来,就是 na_{rt} 异或起来,n 是奇数所以就是 a_{rt} 的值
那么给 a 全异或上 a_{rt} 再判断就行了

COCI2018-2019 Final T4 TENIS
考虑平面上建出三排点,分别按照三个属性排名排序,同一个人不同行的三个点连边
这样会产生若干个竖着的分割线(不经过连出的边),每两个分割线中间的部分对应着竞赛图的一个强连通分量,只有最左边的那个部分可以获胜
于是线段树维护,把每个人最小排名到最大排名的区间,加上 1,求最左边的 0
O(n\log n)

P5307 [COCI2019] Mobitel
\lceil\dfrac{n}{1}\rceil,\lceil\dfrac{n}{2}\rceil,\cdots,\lceil\dfrac{n}{n}\rceil 一共 O(\sqrt{n}) 种取值
于是记录 f(i,j,k) 表示走到 i,j,再乘 k 就超过 n 的方案数,共 O(rs\sqrt{n})

P7207 [COCI2019-2020#3] Sob
由于对于任意 n,m 都有解,若能将区间 [n-k,n-1][m,m+k-1] 匹配上,就能递归到子问题
k 是能使得 m+k-1n-1 匹配上的最小的 k,则有结论 n-k \sim n-1m+k-1 \sim m 按顺序分别可以匹配
考虑 i 是所有 n-11m0 的位中的最高位,那么 k 增大的过程就是把后 i 位加到和 n-1 相同,再减回去仍然可以

COI 2020 Pastiri
考虑目前深度最大的那个点,守卫放在里他最近但深度最浅的位置
如果守卫放他子树里显然不优,而如果不是放在他到根的链上的某个点上,而是在这些点的子树中,由于子树里也不会有更深的,所以也不会更优
于是每个点到最近的需要被看守的点的最短距离直接多源 bfs 预处理

COI 2020 Semafor
先把前 k 位灯管的转化 dp 出来,再舍弃不是数字的状态,转移 \frac{n}{k}
后面的矩阵大小是 100\times 100,有 O(100^3\log n)
但前面直接搞是 O((2^{10})^3\log k) 的,但发现改哪根灯管都是等价的,所以只拿 \operatorname{popcount} 转移就行,矩阵大小 11\times 11

AGC043B 123 Triangle
先把数都减一,然后只剩 0,1,2,若有 1,则答案为 01,否则为 02
都划归乘只有 0,1 的问题(不存在 1 就除以二,然后放 \mod 2 意义下),然后差分变成异或,第 i 位被异或了 \tbinom{n-1}{i}

AGC044B Joker
先从边界开始做一遍最短路,然后每次把没了的点放回队列里继续跑最短路,类似spfa
最短路 dis 和是 O(n^3) 的,每次只有 dis 降低才会进队,所以复杂度就 O(n^3)

AGC045B 01 Unbalanced
考虑 110-1,答案就是前缀和的极差
然后你枚举最大值,能填 1 的问号尽量填 1,否则搞成 -1,判断是否能的办法就是对于每个后缀,记录每个 ? 都是 -1 的时候这个后缀的前缀最大值,看他有没有超过枚举的这个最大值
这样就是 O(n^2)
考虑设所有问号都填 -1 的最大值为 s,那么把一个负一变成正一,则若最大值加 2,则最小值最多加 2,不会更优
那么只拿 ss+1 跑一边就 O(n)

AGC045C Range Set
A\ge B
逆着操作,每次把 A0B1 替换成任意串,然后如果操作到有 A 个连续的 0 就一定合法了
于是可以把所有大于等于 B1 全换成 0,dp 设 f(i,j,0/1) 表示考虑到第 i 个,替换后 0 的连续个数是 j,目前在填 0/1 的方案数
需要个前缀和优化

CF1458C Latin Square
ab 列是 c,那么记录 A_{a,b}=c,B_{a,c}=b,C_{b,c}=a
如果是移动操作,就是给下标打标记,如果是变成逆排列操作,就是交换一个下标和他的值,也就是再开一个变量记录现在应该用哪个数组

CF1444D Rectangular Polyline
如果 h\neq v 或者无法把水平、竖直分别分成两个长度和相同的组,则无解
否则任意背包出一组,给出构造:
先考虑向右下走,把竖直这从大到小放,水平的从小到大放,这样一定不会穿过最终组成图形的对角线
从右下再走回来按照类似方法,就不会和之前有交了

posted @   suxxsfe  阅读(113)  评论(0编辑  收藏  举报

Copyright © 2025 suxxsfe
Powered by .NET 9.0 on Kubernetes
点击右上角即可分享
微信分享提示