2023.2.22模拟赛

T1
题意:
构造一个以1开头,由n个1和m个0组成的01串,使得其表示的二进制数可以被三整除,求其最大值和最小值。
思路:
分讨:
1.n为偶,m为偶,最大值11n00m,最小值100m11n1
2.n为偶,m为奇,最大值11n00m,最小值100m11011n2
3.n为奇,m为偶,最大值11n2010100m2,最小值100m11011n2
4.n为奇,m为奇,最大值11n2010100m2,最小值100m2101011n3
代码:

#include<iostream>
#include<cstdio>
using namespace std;
int kd(){
	int x=0,f=1;
	char a=getchar();
	while(a<'0'||a>'9'){
		if(a=='-'){
			f=-1;
		}
		a=getchar();
	}
	while(a>='0'&&a<='9'){
		x=x*10+a-'0';
		a=getchar(); 
	}
	return x*f;
}
int t;
int n,m;
int main(){
	t=kd();
	while(t--){
		n=kd();m=kd();
		if(n<=1){
			printf("-1");
		}
		else{
			if(n%2==0){
				for(int i=1;i<=n;i++){
					printf("1");
				}
				for(int i=1;i<=m;i++){
					printf("0");
				}
			}
			else{
				if(m<=1){
					printf("-1");
				}
				else{
					for(int i=1;i<=n-2;i++){
						printf("1");
					}
					printf("0101");
					for(int i=1;i<=m-2;i++){
						printf("0");
					}
				}
			}
		}
		printf("\n");
		if(n<=1){
			printf("-1");
		}
		else{
			if(n%2==0){
				printf("1");
				if((n+m)%2==0){
					for(int i=1;i<=m;i++){
						printf("0");
					}
					for(int i=1;i<=n-1;i++){
						printf("1");
					}
				}
				else{
					for(int i=1;i<=m-1;i++){
						printf("0");
					}
					printf("10");
					for(int i=1;i<=n-2;i++){
						printf("1");
					}
				}
			}
			else{
				if((n+m)%2==1){
					if(m==0){
						printf("-1");
					}
					else{
						printf("1");
						for(int i=1;i<=m-1;i++){
							printf("0");
						}
						printf("10");
						for(int i=1;i<=n-2;i++){
							printf("1");
						}
					}
				}
				else{
					if(m==1){
						printf("-1");
					}
					else{
						printf("1");
						for(int i=1;i<=m-2;i++){
							printf("0");
						}
						printf("1010");
						for(int i=1;i<=n-3;i++){
							printf("1");
						}
					}
				}
			}
		}
		printf("\n");
	}
	return 0;
}

T2
题意:
给定一个数n,计数n的排列满足pi的因子个数等于i的因子个数。t组询问,答案对500009取模。n<=1e9
思路:
首先考虑线性筛因子个数Ci=(ak+1)
1.i为质数。因子个数为2。
2.i=j×s (s为质数),且 js的倍数。因子个数为Cj×2
3.i=j×s (s为质数),且 sjCi=Cj×(as+1+1)as+1=2×CjCj×asas+1=2×CjCjs,所以因子个数为2×CjCjs
这样就可以统计出Ci=k的个数 Bk,答案为Bk>0(Bk!),当i2229283时,因为模数,答案为0。
代码:

#include<iostream>
#define mod 500009
#define int long long
using namespace std;
int kd(){
	int x=0,f=1;
	char a=getchar();
	while(a<'0'||a>'9'){
		if(a=='-'){
			f=-1;
		}
		a=getchar();
	}
	while(a>='0'&&a<='9'){
		x=x*10+a-'0';
		a=getchar();
	}
	return x*f;
}
int t;
int n;
int tong[5000010];
bool prime[5000010];
int ss[5000010];
int yz[5000010];
int f[5000010];
int g[5000010];
void shai(){
	yz[1]=1;
	g[1]=1;
	for(int i=2;i<=5000000;i++){
		if(prime[i]==0){
			ss[++ss[0]]=i;
			yz[i]=2;
		}
		tong[yz[i]]++;
		f[i]=tong[yz[i]];
		g[i]=g[i-1]*f[i]%mod;
		for(int j=1;j<=ss[0]&&i*ss[j]<=5000000;j++){
			prime[i*ss[j]]=1;
			if(i%ss[j]!=0){
				yz[i*ss[j]]=yz[i]*2%mod;
			}
			else{
				yz[i*ss[j]]=((yz[i]*2-yz[i/ss[j]])%mod+mod)%mod;
				break;
			}
		}
	}
}
signed main(){
	t=kd();
	shai();
	while(t--){
		n=kd();
		if(n>5000000){
			printf("0\n");
		}
		else{
			printf("%lld\n",g[n]);
		}
	}
	return 0;
}

T3
题意:
n个点(X,Y)q个直角边与x轴和y轴平行的等腰直角三角形(x,y,d),求每个等腰直角三角形覆盖的点有多少个。
思路:
容斥。

7Xx,Yy,X+Yx+y+d=(1+2+3+4+5+6+7)n(1+2+3)X<x(3+4+5)Y<y(5+6+1)X+Y>x+y+d+1X<x,X+Y>x+y+d+3X<x,Y<y+5Y<y,X+Y>x+y+d
1,3,5用二维数点求。
代码:

#include<iostream>
#include<algorithm>
using namespace std;
int kd(){
	int x=0,f=1;
	char a=getchar();
	while(a<'0'||a>'9'){
		if(a=='-'){
			f=-1;
		}
		a=getchar();
	}
	while(a>='0'&&a<='9'){
		x=x*10+a-'0';
		a=getchar();
	}
	return x*f;
}
int n,q;
struct node{
	int x,y;
	int d;
	int id;
}b[1000010],a[1000010];
int ans[1000010];
bool cmp(node x,node y){
	return x.x<y.x;
}
bool cnp(node x,node y){
	return x.y<y.y;
}
bool cup(node x,node y){
	return x.d>y.d;
}
int c[3000010];
int lowbit(int x){
	return x&(-x);
}
void add(int x,int k){
	for(;x<=3000000;x+=lowbit(x)){
		c[x]+=k;
	}
}
int getsum(int x){
	int sum=0;
	for(;x;x-=lowbit(x)){
		sum+=c[x];
	}
	return sum;
}
int main(){
	n=kd();q=kd();
	for(int i=1;i<=n;i++){
		a[i].x=kd();a[i].y=kd();
		a[i].d=a[i].x+a[i].y;
	}
	for(int i=1;i<=q;i++){
		b[i].x=kd();b[i].y=kd();b[i].d=b[i].x+b[i].y+kd();
		b[i].id=i;
		ans[i]=n;
	}
	sort(a+1,a+n+1,cmp);
	sort(b+1,b+q+1,cmp);
	int i=1;
	for(int j=1;j<=q;j++){
		while(i<=n&&a[i].x<b[j].x){
			i++;
		}
		ans[b[j].id]-=i-1;
	}
	i=1;
	for(int j=1;j<=q;j++){
		while(i<=n&&a[i].x<b[j].x){
			add(a[i].y,1);
			i++;
		}
		ans[b[j].id]+=getsum(b[j].y-1);
	}
	for(i=i-1;i>=1;i--){
		add(a[i].y,-1);
	}
	i=1;
	for(int j=1;j<=q;j++){
		while(i<=n&&a[i].x<b[j].x){
			add(a[i].d,1);
			i++;
		}
		ans[b[j].id]+=i-1-getsum(b[j].d);
	}
	for(i=i-1;i>=1;i--){
		add(a[i].d,-1);
	}
	sort(a+1,a+n+1,cnp);
	sort(b+1,b+q+1,cnp);
	i=1;
	for(int j=1;j<=q;j++){
		while(i<=n&&a[i].y<b[j].y){
			i++;
		}
		ans[b[j].id]-=i-1;
	}
	i=1;
	for(int j=1;j<=q;j++){
		while(i<=n&&a[i].y<b[j].y){
			add(a[i].d,1);
			i++;
		}
		ans[b[j].id]+=i-1-getsum(b[j].d);
	}
	for(i=i-1;i>=1;i--){
		add(a[i].d,-1);
	}
	sort(a+1,a+n+1,cup);
	sort(b+1,b+q+1,cup);
	i=1;
	for(int j=1;j<=q;j++){
		while(i<=n&&a[i].d>b[j].d){
			i++;
		}
		ans[b[j].id]-=i-1;
	}
	for(int j=1;j<=q;j++){
		cout<<ans[j]<<endl;
	}
	return 0;
}

T4
题意:
计数,长度为n的字符序列ai[xi,yi]m组限制,(k=ljrjak)mod2=sj
思路:
qiani=(k=1iak)mod2
lj1rj建边,当qianlj1确定时,qianrj也一定确定,可以对搜索进行剪枝。
当某个i与其它位置没有连边时,这不会影响到其他位置的qian,这样就可以对这个位置进行DP。
dpu,0/1,0/1表示第u个位置qianu=0/1aumod2=0/1
ansu,0/1,0/1,i维护最小字典序序列。
代码:

#include<iostream>
#define mod 1000000007
#define int long long
using namespace std;
int kd(){
	int x=0,f=1;
	char a=getchar();
	while(a<'0'||a>'9'){
		if(a=='-'){
			f=-1;
		}
		a=getchar();
	} 
	while(a>='0'&&a<='9'){
		x=x*10+a-'0';
		a=getchar();
	}
	return x*f;
}
int n,m;
struct node{
	int x,y;
	int w[2];
}a[50];
struct nod{
	int to;
	int nxt;
	int val;
}edge[210];
int head[50],tot;
void addedge(int u,int v,int w){
	edge[++tot].to=v;
	edge[tot].nxt=head[u];
	edge[tot].val=w;
	head[u]=tot;
}
int dui[50];
int cnt[50];
int qian[50];
int dp[50][2][2];
int ans[50][2][2][50];
int pd(int u,int i,int j,int k,int h){
	for(int w=u+1;w<=n;w++){
		if(ans[u+1][i][j][w]<ans[u][k][h][w]){
			return 1;
		}
		if(ans[u+1][i][j][w]>ans[u][k][h][w]){
			return 0;
		}
	}
	return 1;
}
void dfs(int u){
	if(u>n){
		return ;
	}
	for(int j=1;j<=n;j++){
		ans[u][0][0][j]=a[j].y;
		ans[u][0][1][j]=a[j].y;
		ans[u][1][0][j]=a[j].y;
		ans[u][1][1][j]=a[j].y;
	}
	dp[u][0][0]=0;
	dp[u][0][1]=0;
	dp[u][1][0]=0;
	dp[u][1][1]=0;
	if(cnt[u]==0){
		dfs(u+1);
		if(qian[u+1]!=1){
			dp[u][0][0]=(dp[u][0][0]+dp[u+1][0][0]*a[u].w[0]%mod)%mod;
			if(dp[u+1][0][0]>0&&pd(u,0,0,0,0)){
				for(int j=u+1;j<=n;j++){
					ans[u][0][0][j]=ans[u+1][0][0][j];
				}
				ans[u][0][0][u]=(a[u].x+1)/2*2;
			}
			dp[u][0][1]=(dp[u][0][1]+dp[u+1][0][0]*a[u].w[1]%mod)%mod;
			if(dp[u+1][0][0]>0&&pd(u,0,0,0,1)){
				for(int j=u+1;j<=n;j++){
					ans[u][0][1][j]=ans[u+1][0][0][j];
				}
				ans[u][0][1][u]=a[u].x/2*2+1;
			}
			dp[u][1][0]=(dp[u][1][0]+dp[u+1][0][1]*a[u].w[0]%mod)%mod;
			if(dp[u+1][0][1]>0&&pd(u,0,1,1,0)){
				for(int j=u+1;j<=n;j++){
					ans[u][1][0][j]=ans[u+1][0][1][j];
				}
				ans[u][1][0][u]=(a[u].x+1)/2*2;
			}
			dp[u][1][1]=(dp[u][1][1]+dp[u+1][0][1]*a[u].w[1]%mod)%mod;
			if(dp[u+1][0][1]>0&&pd(u,0,1,1,1)){
				for(int j=u+1;j<=n;j++){
					ans[u][1][1][j]=ans[u+1][0][1][j];
				}
				ans[u][1][1][u]=a[u].x/2*2+1;
			}
		}
		if(qian[u+1]!=0){
			dp[u][0][0]=(dp[u][0][0]+dp[u+1][1][1]*a[u].w[0]%mod)%mod;
			if(dp[u+1][1][1]>0&&pd(u,1,1,0,0)){
				for(int j=u+1;j<=n;j++){
					ans[u][0][0][j]=ans[u+1][1][1][j];
				}
				ans[u][0][0][u]=(a[u].x+1)/2*2;
			}
			dp[u][0][1]=(dp[u][0][1]+dp[u+1][1][1]*a[u].w[1]%mod)%mod;
			if(dp[u+1][1][1]>0&&pd(u,1,1,0,1)){
				for(int j=u+1;j<=n;j++){
					ans[u][0][1][j]=ans[u+1][1][1][j];
				}
				ans[u][0][1][u]=a[u].x/2*2+1;
			}
			dp[u][1][0]=(dp[u][1][0]+dp[u+1][1][0]*a[u].w[0]%mod)%mod;
			if(dp[u+1][1][0]>0&&pd(u,1,0,1,0)){
				for(int j=u+1;j<=n;j++){
					ans[u][1][0][j]=ans[u+1][1][0][j];
				}
				ans[u][1][0][u]=(a[u].x+1)/2*2;
			}
			dp[u][1][1]=(dp[u][1][1]+dp[u+1][1][0]*a[u].w[1]%mod)%mod;
			if(dp[u+1][1][0]>0&&pd(u,1,0,1,1)){
				for(int j=u+1;j<=n;j++){
					ans[u][1][1][j]=ans[u+1][1][0][j];
				}
				ans[u][1][1][u]=a[u].x/2*2+1;
			}
		}
		return ;
	}
	int zhan[50],top;
	int p;
	if(qian[u]!=1){
		p=0;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(qian[v]!=-1&&qian[v]!=0^edge[i].val){
				p=1;
			}
		}
		if(p==0){
			top=0;
			int t=qian[u];
			qian[u]=0;
			for(int i=head[u];i;i=edge[i].nxt){
				int v=edge[i].to;
				if(qian[v]==-1){
					qian[v]=qian[u]^edge[i].val;
					zhan[++top]=v;
				}
			}
			dfs(u+1);
			if(qian[u+1]!=1){
				dp[u][0][0]=(dp[u][0][0]+dp[u+1][0][0]*a[u].w[0]%mod)%mod;
				if(dp[u+1][0][0]>0&&pd(u,0,0,0,0)){
					for(int j=u+1;j<=n;j++){
						ans[u][0][0][j]=ans[u+1][0][0][j];
					}
					ans[u][0][0][u]=(a[u].x+1)/2*2;
				}
				dp[u][0][1]=(dp[u][0][1]+dp[u+1][0][0]*a[u].w[1]%mod)%mod;
				if(dp[u+1][0][0]>0&&pd(u,0,0,0,1)){
					for(int j=u+1;j<=n;j++){
						ans[u][0][1][j]=ans[u+1][0][0][j];
					}
					ans[u][0][1][u]=a[u].x/2*2+1;
				}
			}
			if(qian[u+1]!=0){
				dp[u][0][0]=(dp[u][0][0]+dp[u+1][1][1]*a[u].w[0]%mod)%mod;
				if(dp[u+1][1][1]>0&&pd(u,1,1,0,0)){
					for(int j=u+1;j<=n;j++){
						ans[u][0][0][j]=ans[u+1][1][1][j];
					}
					ans[u][0][0][u]=(a[u].x+1)/2*2;
				}
				dp[u][0][1]=(dp[u][0][1]+dp[u+1][1][1]*a[u].w[1]%mod)%mod;
				if(dp[u+1][1][1]>0&&pd(u,1,1,0,1)){
					for(int j=u+1;j<=n;j++){
						ans[u][0][1][j]=ans[u+1][1][1][j];
					}
					ans[u][0][1][u]=a[u].x/2*2+1;
				}
			}
			qian[u]=t;
			for(int i=1;i<=top;i++){
				qian[zhan[i]]=-1;
			}
		}
	}
	if(qian[u]!=0){
		p=0;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(qian[v]!=-1&&qian[v]!=1^edge[i].val){
				p=1;
			}
		}
		if(p==0){
			top=0;
			int t=qian[u];
			qian[u]=1;
			for(int i=head[u];i;i=edge[i].nxt){
				int v=edge[i].to;
				if(qian[v]==-1){
					qian[v]=qian[u]^edge[i].val;
					zhan[++top]=v;
				}
			}
			dfs(u+1);
			if(qian[u+1]!=1){
				dp[u][1][0]=(dp[u][1][0]+dp[u+1][0][1]*a[u].w[0]%mod)%mod;
				if(dp[u+1][0][1]>0&&pd(u,0,1,1,0)){
					for(int j=u+1;j<=n;j++){
						ans[u][1][0][j]=ans[u+1][0][1][j];
					}
					ans[u][1][0][u]=(a[u].x+1)/2*2;
				}
				dp[u][1][1]=(dp[u][1][1]+dp[u+1][0][1]*a[u].w[1]%mod)%mod;
				if(dp[u+1][0][1]>0&&pd(u,0,1,1,1)){
					for(int j=u+1;j<=n;j++){
						ans[u][1][1][j]=ans[u+1][0][1][j];
					}
					ans[u][1][1][u]=a[u].x/2*2+1;
				}
			}
			if(qian[u+1]!=0){
				dp[u][1][0]=(dp[u][1][0]+dp[u+1][1][0]*a[u].w[0]%mod)%mod;
				if(dp[u+1][1][0]>0&&pd(u,1,0,1,0)){
					for(int j=u+1;j<=n;j++){
						ans[u][1][0][j]=ans[u+1][1][0][j];
					}
					ans[u][1][0][u]=(a[u].x+1)/2*2;
				}
				dp[u][1][1]=(dp[u][1][1]+dp[u+1][1][0]*a[u].w[1]%mod)%mod;
				if(dp[u+1][1][0]>0&&pd(u,1,0,1,1)){
					for(int j=u+1;j<=n;j++){
						ans[u][1][1][j]=ans[u+1][1][0][j];
					}
					ans[u][1][1][u]=a[u].x/2*2+1;
				}
			}
			qian[u]=t;
			for(int i=1;i<=top;i++){
				qian[zhan[i]]=-1;
			}
		}
	}
}
signed main(){
	n=kd();m=kd();
	for(int i=1;i<=n;i++){
		a[i].x=kd();a[i].y=kd();
		qian[i]=-1;
		cnt[i]=0;
		a[i].w[1]=(a[i].y-a[i].x+1)/2;
		a[i].w[0]=(a[i].y-a[i].x+1)/2;
		if(a[i].x%2==a[i].y%2){
			if(a[i].x%2==1){
				a[i].w[1]++;
			}
			else{
				a[i].w[0]++;
			}
		}
	}
	cnt[0]=0;
	a[0].w[0]=1;
	a[0].w[1]=1;
	qian[n+1]=-1;
	for(int i=1;i<=m;i++){
		int u,v,w;
		u=kd();v=kd();w=kd();
		u--; 
		cnt[u]++;
		cnt[v]++;
		addedge(u,v,w);
	} 
	for(int i=head[0];i;i=edge[i].nxt){
		int v=edge[i].to;
		qian[v]=edge[i].val;
	}
	dp[n+1][0][0]=1;
	dp[n+1][1][0]=1;
	dfs(0); 
	cout<<dp[0][0][0]<<endl;
	if(dp[0][0][0]==0){
		cout<<-1;
	}
	else{
		for(int i=1;i<=n;i++){
			cout<<ans[0][0][0][i]<<" ";
		}
	}
	return 0;
}
posted @   zzzzzz2  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示