Simulation 88 test summary

Avalanche meteorite

Pass the exam

Nothing. T1 almost fell asleep after thinking for a long time, and then he was violent
Finally, T1dp is false. The T3 modulus is 993244853, which cannot be evaluated at all
At the bottom, I was autistic for a day and didn't do anything. The people next to me cut off \ (10 ^ 9 + 7 \) questions. I can't do anything

T1. Bitwise OR

Violence has little to do with the positive solution, but I think an extremely complex \ (n^3 \) is false
The positive solution lies in tolerance and exclusion,%%% tolerance and exclusion leader WYZG
Regardless of the limit of multiples of 3, you can directly consider the bit of the answer and easily get the result with a \ (log \)
However, it is not fun to have restrictions. It is found that the 3 remainder of several power modules of 2 can only be 1 or 2, so we can use this property
Let \ (p_i \) represent the number of schemes in which 1 is not selected with at least \ (I \) bits, then it is a classic form of odd addition and even subtraction, and the answer is exactly that \ (0 \) bit is not selected
Note that we can't simply combine numbers here, because we also need to ensure that all numbers are multiples of 3
It is found that the 1 remainder of odd bits in binary is 1 and the remainder of even bits is 2. You can enumerate the number of 1 in odd and even bits in this \ (i \) bit
Here is another \ (log \), after enumeration, the rest can be selected or not directly. Let's make a simple dp to determine the final number of schemes
\(f_{i,j} \) indicates that the \ (i \) bit has been determined, and the remainder is the scheme number of \ (0 / 1 / 2 \). Enumerate this bit, and select 1 or not
Since \ (n \) are equivalent, it is also easy to understand that they are multiplied by two combinatorial numbers because they need to be selected from odd and even bits
So \ (log^3 \) is finished. It's not difficult to find. It's just a brain watt

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int N=65;
int n,t,c[N][N];
inline int ksm(int x,int y)
{
	int s=1;x%=mod;
	for(;y;y>>=1)
	{
		if(y&1)s=s*x%mod;
		x=x*x%mod;	
	}
	return s;
}
int f[N][3];
signed main()
{
	freopen("or.in","r",stdin);
	freopen("or.out","w",stdout);
	cin>>n>>t;
	int s1=0,s2=0,s=0;
	while(t)
	{
		s++;
		if(t&1)
		{
			if(s&1)s1++;
			else s2++;
		}
		t>>=1;
	}
	c[0][0]=1;
	for(int i=1;i<=64;i++)
	{
		c[i][0]=1;
		for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
	}
	int ans=0;
	for(int i=0;i<=s1+s2;i++)
	{
		int sum=0;
		for(int j=max(i-s2,(int)0);j<=s1;j++)
		{
			int p1=s1-j,p2=s2-(i-j);
			assert(p1>=0);assert(p2>=0);
			memset(f,0,sizeof(f));
			f[0][0]=1;
			for(int i=0;i<p1;i++)for(int j=0;j<=2;j++) 
			{
				f[i+1][j]=(f[i+1][j]+f[i][j])%mod;
				f[i+1][(j+1)%3]=(f[i+1][(j+1)%3]+f[i][j])%mod;
			}
			for(int i=p1;i<p1+p2;i++)for(int j=0;j<=2;j++)
			{
				f[i+1][j]=(f[i+1][j]+f[i][j])%mod;
				f[i+1][(j+2)%3]=(f[i+1][(j+2)%3]+f[i][j])%mod;
			}
			sum=(sum+ksm(f[p1+p2][0],n)*c[s1][j]%mod*c[s2][i-j]%mod)%mod;
		}
		if(i&1)ans=(ans-sum+mod)%mod;
		else ans=(ans+sum)%mod;
	}
	cout<<ans<<endl;
	return 0;
}

T2. Shortest path

There is no good thinking in the examination room. In fact, it is not very difficult
Considering the optimal strategy of selecting \ (k \) points, it is found that if a simple point is any starting point, go to one point at a time and return to the starting point
I find that I don't have to go back every time. In fact, I should choose one main road to the end, and go back with other forks. Let's have a perceptual understanding
Obviously, if this main road is only taken once and the others are taken twice, then the diameter should be selected
Therefore, we don't understand the virtual tree, which is twice the sum of the distances between any two points minus the diameter and length
However, the problem is not expected, so direct enumeration is certainly not enough. Consider taking apart the contribution of each path
For the former, enumerate each path, and its contribution probability is the probability of points on both sides. You can subtract the probability of illegal (points on one side) from the total number of schemes
The latter directly enumerates the diameter endpoints and considers whether other points can be legal, so as to make it a diameter
The legal condition is that there is no distance less than him, or the distance is equal but the label is small
Then just enumerate directly. Multiply by the probability of \ (cnt-2 \) choosing \ (k-2 \), \ (CNT \) is the legal number of points, and the complexity is \ (m^3 \)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2050;
const int mod=998244353;
struct node{
	int from,to,next;
}a[2*N];
int head[N],mm=1;
inline void add(int x,int y)
{
	a[mm].from=x;a[mm].to=y;
	a[mm].next=head[x];head[x]=mm++;
}
inline int ksm(int x,int y)
{
	int s=1;x%=mod;
	for(;y;y>>=1)
	{
		if(y&1)s=s*x%mod;
		x=x*x%mod;
	}
	return s;
}
inline int ny(int x){return ksm(x,mod-2);}
int jc[N],inv[N],jcny[N],n,m,k;
inline void pre()
{
	jc[0]=jc[1]=inv[1]=jcny[0]=jcny[1]=1;
	for(int i=2;i<=n;i++)
	{
		jc[i]=jc[i-1]*i%mod;
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;
		jcny[i]=jcny[i-1]*inv[i]%mod;
	}	
}
inline int C(int x,int y)
{
	if(x<y)return 0;
	if(!y)return 1;
	return jc[x]*jcny[y]%mod*jcny[x-y]%mod;
}
int d[N],fa[N],size[N],son[N],ss[N];
int top[N],ans,pp[N];bool v[N];
void dfs1(int x)
{
	v[x]=1;
	for(int i=head[x];i;i=a[i].next)
	{
		int y=a[i].to;
		if(v[y])continue;
		d[y]=d[x]+1;fa[y]=x;
		dfs1(y);size[x]+=size[y];ss[x]+=ss[y];
		ans=(ans+(1ll-((C(ss[y],k)+C(m-ss[y],k))%mod*ny(C(m,k))%mod)+mod)%mod*2%mod)%mod;
		if(size[y]>size[son[x]])son[x]=y;
	}
	size[x]++;
	ss[x]+=pp[x];
}
void dfs2(int x,int h)
{
	if(!x)return;
	v[x]=1;top[x]=h;
	dfs2(son[x],h);
	for(int i=head[x];i;i=a[i].next)
	{
		int y=a[i].to;
		if(v[y]||y==son[x])continue;
		dfs2(y,y);
	}
}
inline int getlca(int x,int y)
{
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(d[fx]<d[fy])swap(x,y),swap(fx,fy);
		x=fa[fx],fx=top[x];
	}
	if(d[x]<d[y])swap(x,y);
	return y;
}
inline int getd(int x,int y)
{
	int lca=getlca(x,y);
	return d[x]+d[y]-2*d[lca];
}
int p[N];
signed main()
{
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++)scanf("%lld",&p[i]),pp[p[i]]=1;
	sort(p+1,p+1+m);
	for(int i=1;i<n;i++)
	{
		int x,y;scanf("%lld%lld",&x,&y);
		add(x,y);add(y,x);
	}
	pre();d[1]=1;dfs1(1);
	memset(v,0,sizeof(v));dfs2(1,1);
	for(int i=1;i<=m;i++)for(int j=i+1;j<=m;j++)
	{
		int x=p[i],y=p[j];if(x>y)swap(x,y);
		int dis=getd(x,y),sum=0;
		for(int k=1;k<=m;k++)
		{	
			int z=p[k];if(z==x||z==y)continue;
			int d1=getd(z,x),d2=getd(z,y);
			if(d1>dis||(d1==dis&&z<y))continue;
			if(d2>dis||(d2==dis&&z<x))continue;
			sum++;
		}
		ans=(ans-C(sum,k-2)*ny(C(m,k))%mod*dis%mod+mod)%mod;
	}
	cout<<ans<<endl;
	return 0;
}

T3. Cactus

RT, don't do it, goo

T4. Playing chess

Original title P2490
It is found that A will only go to the right and B will only go to the left. Then take the two pieces as A pile of stones with the number of \ (b_i-a_i-1 \), and you can see that this is A k-nim model through the solution of the problem
The conclusion is that if and only if all \ (a_i \) become binary, the number of 1 on each bit is modulo \ (m+1 \) remaining 0. The proof is shown below

Therefore, dp, let \ (f_{i,j} \) mean that considering the \ (I \) bit, the sum is the number of \ (j \) schemes, and the enumeration is how many times \ (m+1 \)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=100050;
const int mod=1e9+7;
int jc[N],inv[N],jcny[N],n,k,m;
int f[20][N];
inline void pre()
{
	jc[0]=jc[1]=inv[1]=jcny[0]=jcny[1]=1;
	for(int i=2;i<=n;i++)
	{
		jc[i]=jc[i-1]*i%mod;
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;
		jcny[i]=jcny[i-1]*inv[i]%mod;
	}	
}
inline int C(int x,int y)
{
	if(x<y)return 0;
	if(!y)return 1;
	return jc[x]*jcny[y]%mod*jcny[x-y]%mod;
}
signed main()
{
	freopen("chess.in","r",stdin);freopen("chess.out","w",stdout);
	cin>>n>>k>>m;pre();
	f[0][0]=1;int ans=0;
	for(int i=0;i<=12;i++)for(int j=0;j<=n-k;j++)
	{	
		for(int kk=0;j+kk*(1<<i)*(m+1)<=n-k&&kk*(m+1)<=k/2;kk++)
			f[i+1][j+kk*(1<<i)*(m+1)]=(f[i+1][j+kk*(1<<i)*(m+1)]+f[i][j]*C(k/2,kk*(m+1))%mod)%mod;
	}
	for(int i=0;i<=n-k;i++)ans=(ans+f[13][i]*C(n-i-k/2,k/2)%mod)%mod;
	cout<<(C(n,k)-ans+mod)%mod<<endl;
	return 0;
}

Examination summary

There were many reasons why the game failed again. The rhythm was chaotic at the beginning and didn't come back
I hope I can come out as soon as possible. After all, the league has only a few days. We must grasp the mentality in the examination room

Tags: dp

Posted on Wed, 03 Nov 2021 02:26:16 -0400 by az_wraith