多校省选模拟 1


T1 序列

首先发现一个性质,就是一些元素是什么不重要,而是否相同才是重要的

然后可以在给定的a序列上左右添加元素,满足不是彩色序列同时计算方案数

f[i][j]表示生成了长度为 i ,互不相同的最长后缀长度为 j 的非彩色序列数

转移就考虑i+1从这 j 个中挑还是从k-j个中挑

计算答案时若a两两不同,枚举左边加了 i 个,右边加了n-m-i个,然后方案数乘起来

否则将问题转化,求所有长度为n的非彩序列中,连续m个互不相同元素的出现个数

转移与 f 类似,最后除掉\(A_{k}^{m}\)

T2 有向图

这个20%挺奇怪的,然后作用是能大概率找出有趣点,O(n)判断有趣点,满足dfs树只有树边和返祖边

这个东西我一直以为凡是dfs树就只有树边和返祖边,模了几个发现还有前向边,码完调了会儿发现还有横叉边,,,因为是有向图,就挺淦

回到题解,然后以找到的有趣点dfs,x是有趣点条件是x子树内只有一条边伸到x的祖先v,且v是有趣点

然后拿个multiset维护子树内的返祖边就行了

T3 图形

条件是\(\sum x_ic_i=0,\sum y_ic_i=0\)

还有\(\sum_{x_i>0} x_ic_i<=m,\sum_{y_i>0}y_ic_i<=m\)

然后不好维护,但是n和给的坐标都很小,所以可以二进制拆分\(\sum x_ic_i\),然后维护进位

\(dp_{d,px,py,nx,ny,p,q}\)表示第 d 位,x>0进到这一位大小为px,y>0进到这一维是py,对应的负数是nx,ny,然后\(\sum_{x_i>0} x_ic_i\)前i位是否不大于m,q同理是y

然后转移的时候状压枚举选的向量,满足选的正数和负数与各自的进位之和在第i位相等

然后凸包不能S=0,所以最后-1

代码

T1

#include
using namespace std;
#define il inline
#define ll long long
const int N=1e3+5;
const int mod=1e9+7;
il int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')ch=getchar();
	while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
	return s;
}
struct cz1{
	int n,m,k;
	int a[N],nxt[N];
	int tran[N][5];
	int f[N][N][5][5][5],g[N][N][5][5][5];
	il int min_(int x,int y){return x>y?y:x;}
	il void md(int &x){if(x>=mod)x-=mod;return;}
	void kmp()
	{
		int i=0,j=-1;
		nxt[0]=-1;
		while(i<=m&&j<=m)
		{
			if(j==-1||a[j+1]==a[i+1]) nxt[++i]=++j;
			else j=nxt[j];
		}
		return;
	}
	void solve()
	{
		if(k==1){cout<1);x<=k;++x)
						for(int y=(i>0);y<=k;++y)
						{
							if(!g[i][j][x][y][0]) continue;
							for(int h=1;h<=k;++h)
							{
								if(x&&y&&h&&x!=y&&y!=h&&x!=h) continue;
								if(tran[j][h]==m) md(f[i+1][m][y][h][0]+=g[i][j][x][y][0]+f[i][j][x][y][0]);
								else md(f[i+1][tran[j][h]][y][h][0]+=f[i][j][x][y][0]);
								md(g[i+1][tran[j][h]][y][h][0]+=g[i][j][x][y][0]);
							}
						}
			int ans=0;
			for(int i=0;i<=m;++i)
				for(int x=1;x<=k;++x) for(int y=1;y<=k;++y)
					md(ans+=f[n][i][x][y][0]);
			cout<<(mi-ans+mod)%mod<2);x<=k;++x)
						for(int y=(i>1);y<=k;++y)
							for(int z=(i>0);z<=k;++z)
							{
								if(!g[i][j][x][y][z]) continue;
								for(int h=1;h<=k;++h)
								{
									if(x&&y&&z&&h)if(x!=y&&x!=z&&x!=h&&y!=z&&y!=h&&z!=h)continue;
									if(tran[j][h]==m) md(f[i+1][m][y][z][h]+=(g[i][j][x][y][z]+f[i][j][x][y][z])%mod);
									else md(f[i+1][tran[j][h]][y][z][h]+=f[i][j][x][y][z]);
									md(g[i+1][tran[j][h]][y][z][h]+=g[i][j][x][y][z]);
								}
							}
			int ans=0;
			for(int i=0;i<=m;++i)
				for(int x=1;x<=k;++x) for(int y=1;y<=k;++y) for(int z=1;z<=k;++z)
					md(ans+=f[n][i][x][y][z]);
			cout<<(mi-ans+mod)%mod<y?y:x;}
	il void md(int &x){x=(x>=mod)?x-mod:x;return;}
	bool jud[402];
	int n,k,m,num;
	int a[25011],g[25011],h[25011];
	int f[25011][402],sum[25011][402],gg[25011][402];
	int fm(int x,int y){int ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1)ans=ans*x%mod;return ans;}
	void solve2(int ans)
	{
		f[1][1]=k;
		for(int i=1;i=m) md(gg[i][j]+=f[i][j]);
				md(sum[i][j]=sum[i][j-1]+gg[i][j]);
			}
		int s=0;
		for(int i=1;i

T2

#include
using namespace std;
#define il inline
const int N=2e5+11;
bool jd;
bool vis[N];
int n,m;
int f[N],dep[N];
struct st_{int u,v;friend bool operator<(st_ a,st_ b){return dep[a.v] vct[N];
multiset st[N];
multiset::iterator it;
il int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
	return s;
}
void dfs(int x)
{
	vis[x]=1;
	for(int v : vct[x])
	{
		if(!dep[v]) dep[v]=dep[x]+1,dfs(v);
		else if(!vis[v]) jd=1;
		if(jd) return;
	}
	vis[x]=0;
	return;
}
bool jud(int x)
{
	for(int i=1;i<=n;++i) dep[i]=0;
	dep[x]=1,jd=0,dfs(x);
	return !jd;
}
void get_f(int x)
{
	int sn=x;
	for(int v : vct[x])
		if(dep[v]>dep[x])
		{get_f(v);if(st[v].size()>st[sn].size()) sn=v;}
	st[x].swap(st[sn]);
	for(int v : vct[x])
		if(dep[v]>dep[x]&&v!=sn)
			while(st[v].size()) st[x].insert(*st[v].begin()),st[v].erase(st[v].begin());
	for(int v : vct[x]) if(dep[v]v]v;
		++it;if(it!=st[x].end())if(dep[it->v]dep[x])
		{
			if(!vis[v]) vis[v]=vis[f[v]];
			get_ans(v);
		}
	return;
}
int main()
{
	FILE *p=freopen("graph.in","r",stdin);
	p=freopen("graph.out","w",stdout);
//	srand(time(0));
	int t=read();
	while(t--)
	{
		for(int i=1;i<=n;++i) f[i]=0,vct[i].clear(),vis[i]=0,st[i].clear();
		n=read(),m=read();
		for(int x,i=1;i<=m;++i)x=read(),vct[x].push_back(read());
//		for(int i=1;i<=n;++i)if(jud(i)) printf("%d ",i);
		for(int x,i=1;i<=100;++i){x=rand()%n+1;if(jud(x)){solve(x);get_ans(x);break;}}
		for(int i=1;i<=n;++i) if(vis[i]) printf("%d ",i);
		printf("\n");
	}
	return 0;
}

T3

#include
using namespace std;
#define il inline
#define int long long
const int N=10;
const int mod=998244353;
int n,m;
int x[N],y[N];
int f[32][21][21][21][21][2][2];
il void md(int &x){if(x>=mod)x-=mod;return;}
bool check(bool jd,int x){return ((x&1)==(m&1))?jd:((x&1)<(m&1));}
signed main()
{
	FILE* p=freopen("shape.in","r",stdin);
	p=freopen("shape.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>x[i]>>y[i];
	f[0][0][0][0][0][1][1]=1;
	for(int vx1,vx2,vy1,vy2,i=0;i<31;++i,m>>=1)for(int px=0;px<=20;++px)for(int py=0;py<=20;++py)
		for(int nx=0;nx<=20;++nx)for(int ny=0;ny<=20;++ny)
			for(int p=0;p<=1;++p)for(int q=0;q<=1;++q)
			{
				if(!f[i][px][py][nx][ny][p][q]) continue;
				for(int sta=0;sta<(1<0)vx1+=x[j];else vx2-=x[j];}
					if(((vx1+px)&1)!=((vx2+nx)&1))continue;
					vy1=vy2=0;
					for(int j=1;j<=n;++j) if((1<0)vy1+=y[j];else vy2-=y[j];}
					if(((vy1+py)&1)!=((vy2+ny)&1))continue;
					md(f[i+1][(px+vx1)>>1][(py+vy1)>>1][(nx+vx2)>>1][(ny+vy2)>>1][check(p,vx1+px)][check(q,vy1+py)]+=f[i][px][py][nx][ny][p][q]);
				}
			}
	cout<<(f[31][0][0][0][0][1][1]-1+mod)%mod<