Examples

2022-7-26 #18 CF1458E & CF1172C2 & AGC057E & ABC249H

昨天也很摆😫😫😫。

最近每天都在因自己的菜自闭。

048 CF1458E Nim Shortcuts

首先转化到二维平面上,每次可以沿着坐标轴逆方向向原点移动。

可以发现每行每列除了至多有一个必败态,否则这两个可以转移,一定有一个必胜。

接下来做法很多:

先考察 \(n=1\) 的情况,令 shortcut 为 \((a,b)\)

显然其只会影响 \(x\geqslant a,y\geqslant b\)\((x,y)\)

\(a<b\):可知 \((b,b)\) 必胜,\((b,b+1)\) 必败,同样可知任意 \((x,x+1)\) 必败(镜像策略),那么 \((x,y)\) 必败等价于删掉第 \(b\) 行之后 \((x,y)\) 必败。

\(a=b\) 没有影响,\(a>b\) 等价于翻转坐标系后的 \(a<b\)\((x,y)\) 必败等价于删掉第 \(a\) 列之后 \((x,y)\) 必败。

一般情况可以考虑增量法,一个个加入 shortcut,那么结论仍然成立。(即 \((x,y)\) 必败当且仅当删掉 \(u\)\(v\) 列后 \((x,y)\) 必败)

树状数组维护二维偏序即可,复杂度 \(O(n\log n)\)

可以发现,所有非 shortcut 的必败态构成一个不超过 \(2n\) 段的分段一次函数,我们只需找到这些转折点。

可以发现加入一个 shortcut 会向上向右延伸出两条必胜态,而其与原本非 shortcut 必败态的折线的交点会变成必胜态,这个点之后的折线会向上/右平移一格。

维护这东西可以用数据结构暴力维护,把所有点的 x,y 坐标抽出来归并排序。(感觉有点麻烦啊)

#include<stdio.h>
#include<algorithm>
#include<map>
#define lowbit(x) (x&-x)
using namespace std;
const int maxn=200005;
int n,q,s,tot;
int t[maxn],ans[maxn],num[maxn];
map<int,int>mp,visx,visy;
map<pair<int,int>,int>rec;
struct point{
	int x,y,id;
}p[maxn];
inline int cmp(point a,point b){
	return a.x<b.x||(a.x==b.x&&a.y<b.y)||(a.x==b.x&&a.y<b.y&&a.id<b.id);
}
void update(int x,int v){
	for(int i=x;i<=tot;i+=lowbit(i))
		t[i]+=v;
}
int query(int x){
	int res=0;
	for(int i=x;i;i-=lowbit(i))
		res+=t[i];
	return res;
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&p[i].x,&p[i].y),num[i]=p[i].y,rec[make_pair(p[i].x,p[i].y)]=1;
	for(int i=1;i<=q;i++){
		scanf("%d%d",&p[n+i].x,&p[n+i].y);
		p[n+i].id=i,num[n+i]=p[n+i].y-1;
		if(rec.count(make_pair(p[n+i].x,p[n+i].y)))
			ans[i]=1;
	}
	sort(num+1,num+1+n+q),sort(p+1,p+1+n+q,cmp);
	for(int i=1;i<=n+q;i++)
		if(i==1||num[i]!=num[i-1])
			mp[num[i]]=++tot;
	for(int i=1;i<=n+q;i++){
		int nx=p[i].x-s,ny=p[i].y-query(mp[p[i].y-(p[i].id==0? 0:1)]);
		if(p[i].id==0){
			if(nx<ny&&visy[p[i].y]==0)
				visy[p[i].y]=1,update(mp[p[i].y],1);
			if(nx>ny&&visx[p[i].x]==0)
				visx[p[i].x]=1,s++;
		}
		if(p[i].id&&ans[p[i].id]==0&&visx.count(p[i].x)==0&&visy.count(p[i].y)==0)
			ans[p[i].id]=(nx==ny);
	}
	for(int i=1;i<=q;i++)
		puts(ans[i]==0? "WIN":"LOSE");
	return 0;
}

049 CF1172C2 Nauuo and Pictures (hard version)

很神秘的一道题。

可以发现,对于一张图片,我们只需考虑它的权值、喜欢的图片的总权值,不喜欢的图片的总权值。

立即得到一个 dp:\((f/g)_{i,j,k}\) 表示目前照片是喜欢/不喜欢,喜欢的总权值为 \(i\),不喜欢的总权值为 \(j\),目前权值为 \(k\) 的期望权值。(操作次数是可以表示出来的)

转移:

\[f_{i,j,k}=\frac{k}{i+j}f_{i+1,j,k+1}+\frac{i-k}{i+j}f_{i+1,j,k}+\frac{j}{i+j}f_{i,j-1,k} \]

有一个很神秘的性质,\(f_{i,j,k}=kf_{i,j,1}\)

证明可以考虑归纳,然后将转移方程展开。也可以考虑将一个权值为 \(k\) 的物品拆成 \(k\) 个权值为 \(1\) 的物品,显然与原问题等价。

重新定义 \(f_{i,j}\) 表示目前喜欢总权值为 \(i\),不喜欢总权值为 \(j\),目前权值为 \(1\) 的期望权值,容易发现前两维都是 \(O(m)\) 的。

复杂度 \(O(n+m^2)\)。(懒可以带一个 \(\log\)

#include<stdio.h>
const int maxn=200005,maxm=3005,mod=998244353;
int n,m,ansf,ansg,sum0,sum1;
int t[maxn],w[maxn],f[maxm][maxm],g[maxm][maxm];
inline int max(int a,int b){
	return a>b? a:b;
}
int ksm(int a,int b){
	int res=1;
	while(b){
		if(b&1)
			res=1ll*res*a%mod;
		a=1ll*a*a%mod,b>>=1;
	}
	return res;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&t[i]),t[i]^=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&w[i]);
		if(t[i]==0)
			sum0=(sum0+w[i])%mod;
		else sum1=(sum1+w[i])%mod;
	}
	for(int s=m;s>=0;s--)
		for(int i=max(0,s-sum1);i<=s;i++){
			int j=s-i;
			if(s<m){
				int iv=ksm(sum0+i+sum1-j,mod-2);
				f[i][j]=(2ll*iv*f[i+1][j]+1ll*(sum0+i-1)*iv%mod*f[i+1][j]+1ll*(sum1-j)*iv%mod*f[i][j+1])%mod;
				g[i][j]=(1ll*(sum0+i)*iv%mod*g[i+1][j]+1ll*(sum1-j-1)*iv%mod*g[i][j+1])%mod;
			}
			else f[i][j]=g[i][j]=1;
		}
	ansf=f[0][0],ansg=g[0][0];
	for(int i=1;i<=n;i++)
		printf("%d\n",1ll*w[i]*(t[i]==0? ansf:ansg)%mod);
	return 0;
}

050 AGC057E RowCol/ColRow Sort

不知不觉就到 50 了!

根据排序网络那一套理论,能得到矩阵 B,当且仅当将 \(\leqslant k\) 的数设为 \(1\) 后排序能得到 \(B\) 对应的 01 矩阵。

我们观察每一行,每一列的 \(1\) 个数 \(r_i,c_i\) 在操作后的影响。

Row-sort:\(r\) 不变,\(c\) 排序;Column-sort:\(c\) 不变,\(r\) 排序。

搞不懂。

051 ABC249H Dye Color

题意好难懂啊。。。

考虑停时定理,令 \(f(i)\)\(i\) 个颜色一样的球对应的势能,

列出递推:

\[f(n)+1=\sum_{i=0}^n\sum_{j=0}^{N-n}\frac{{n\choose i}{N-n\choose j}}{2^{i+j}}(\frac{i+j}{N}f(n-i+1)+(1-\frac{i+j}{N})f(n-i)) \]

就是枚举当前颜色选了多少个,非当前颜色选了多少个,如果选了 \(k\) 个球,每个颜色选择概率都是 \(\frac{k}{N}\)

对于每个 \(n\),枚举 \(i\),后面的系数拆一拆预处理一下就好了,复杂度 \(O(n^2)\)

不知道为什么这么菜,推了好久。。。

式子不知道为啥不对,到时候再看吧。。。

\[f(n)+1=\sum_{i=0}^n\sum_{j=0}^{N-n}\frac{{n\choose i}{N-n\choose j}}{2^{i+j}}(\frac{i+j}{N}f(n-i+1)+(1-\frac{i+j}{N})f(n-i))\\ f(n)+1=\sum_{i=0}^n\frac{{n\choose i}}{2^i}f(n-i+1)(\frac{i}{N}\sum_{j=0}^{N-n}\frac{{N-n\choose j}}{2^j}+\frac{1}{N}\sum_{j=0}^{N-n}\frac{{N-n\choose j}j}{2^j})\\ +\frac{{n\choose i}}{2^i}f(n-i)(\frac{N-i}{N}\sum_{j=0}^{N-n}\frac{{N-n\choose j}}{2^j}-\frac{1}{N}\sum_{j=0}^{N-n}\frac{{N-n\choose j}j}{2^j})\\ f(n)+1=\sum_{i=0}^n\frac{{n\choose i}}{2^i}f(n-i+1)(\frac{i}{N}(\frac{3}{2})^{N-n}+\frac{1}{N}\frac{N-n}{2}(\frac32)^{N-n-1})\\ +\frac{{n\choose i}}{2^i}f(n-i)(\frac{N-i}{N}(\frac{3}{2})^{N-n}-\frac{1}{N}\frac{N-n}{2}(\frac32)^{N-n-1}) \]

posted @ 2022-07-26 08:13  xiaoziyao  阅读(69)  评论(0)    收藏  举报