2023.2.24模拟赛

T1
题意:
对于给定的数组\(a\),存在多少个四元组\((b_{1},b_{2},b_{3},b_{4})(1\le b_{1}<b_{2}<b_{3}<b_{4}\le n)\),使得\(a_{b_{1}}\) \(xor\) \(a_{b_{2}}\) \(xor\) \(a_{b_{3}}\) \(xor\) \(a_{b_{4}}=0\)
思路:
开桶维护\(a_{b_{1}}\) \(xor\) \(a_{b_{2}}\),然后将\(a_{b_{3}}\) \(xor\) \(a_{b_{4}}\)的个数加进答案。
代码:

#include<iostream>
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;
int a[5010];
long long qian[2000010],hou[2000010];
int main(){
	n=kd();
	for(int i=1;i<=n;i++){
		a[i]=kd();
	}
	long long ans=0;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			ans=(ans+qian[a[i]^a[j]]);
		}
		for(int j=i-1;j>=1;j--){
			qian[a[i]^a[j]]++;
		}
	}
	cout<<ans;
	return 0;
}

T2
题意:
给定一张\(k\)进制乘法表,问每个数字代表什么。
思路:
\(0\times (k-1)=(0)(0)\)
\(1\times (k-1)=(0)(k-1)\)
\(2\times (k-1)=(1)(k-2)\)
……
\((k-1)\times (k-1)=(k-2)(1)\)
通过这个规律,就可以解决这个问题。
代码:

#include<iostream>
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;
int tong[2010];
int m[2010][2010];
int ans[2010];
int f[2010];
int biao[2010];
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		ans[i]=-1;
		for(int j=0;j<n;j++){
			int a,b;
			a=kd();b=kd();
			m[i][j]=a;
			tong[a]++;
		}
	}
	for(int j=0;j<n;j++){
		int p=0;
		for(int i=0;i<n;i++){
			if(m[i][j]!=j){
				p=1;
				break;
			}
		}
		if(p==0){
			ans[j]=0;
			f[0]=j;
		}
	}
	for(int i=0;i<n;i++){
		if(tong[i]==0){
			ans[i]=n-1;
			f[n-1]=i;
		}
	}
	for(int i=0;i<n;i++){
		if(i!=f[0]){
			biao[m[i][f[n-1]]]=i;
		}
	}
	for(int i=1;i<n;i++){
		f[i]=biao[f[i-1]];
		ans[biao[f[i-1]]]=i;
	}
	for(int i=0;i<n;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}

T3
题意:
给定\(n(n\le40)\)个数,问所有子集中的和十进制下数位上4的个数的总数。
思路:
考虑折半搜索,对其中一个数组基数排序,枚举另一个数组,二分查找使每一位为4的个数。
代码:

#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;
int a[50];
long long ans;
long long tonga[1100000];
long long tongb[1100000];
long long ta[1100000];
long long tb[1100000];
void dfs1(int i,long long tot){
	if(i>n/2){
		ta[++ta[0]]=tot;
		return ;
	}
	dfs1(i+1,tot+a[i]);
	dfs1(i+1,tot);
}
void dfs2(int i,long long tot){
	if(i>n){
		tb[++tb[0]]=tot;
		return ;
	}
	dfs2(i+1,tot+a[i]);
	dfs2(i+1,tot);
}
bool cmp(long long x,long long y){
	return x<y;
}
bool cnp(long long x,long long y){
	return x>y;
}
int main(){
	n=kd();
	for(int i=1;i<=n;i++){
		a[i]=kd();
	}
	dfs1(1,0);
	dfs2(n/2+1,0);
	long long t=1;
	for(int k=1;k<=3;k++){
		t*=10;
		for(int i=1;i<=ta[0];i++){
			tonga[ta[i]%t]++;
		}
		for(int i=1;i<=tb[0];i++){
			tongb[tb[i]%t]++;
		}
		for(int i=0;i<=t-1;i++){
			for(int j=0;j<=t-1;j++){
				if((i+j)%t/(t/10)==4){
					ans+=tonga[i]*tongb[j];
				}
			}
		}
		for(int i=0;i<=t-1;i++){
			tonga[i]=0;
			tongb[i]=0;
		}
	}
	for(int k=4;k<=9;k++){
		t*=10;
		tonga[0]=0;
		tongb[0]=0;
		for(int i=1;i<=ta[0];i++){
			tonga[++tonga[0]]=ta[i]%t;
		}
		for(int i=1;i<=tb[0];i++){
			tongb[++tongb[0]]=tb[i]%t;
		}
		sort(tonga+1,tonga+tonga[0]+1,cmp);
		sort(tongb+1,tongb+tongb[0]+1,cnp);
		int j=1;
		for(int i=1;i<=tonga[0];i++){
			while(tongb[j]+tonga[i]>=t/10*15&&j<=tongb[0]){
				ans+=i-1;
				j++;
			}
		}
		for(;j<=tongb[0];j++){
			ans+=tonga[0];
		}
		j=1;
		for(int i=1;i<=tonga[0];i++){
			while(tongb[j]+tonga[i]>=t/10*14&&j<=tongb[0]){
				ans-=i-1;
				j++;
			}
		}
		for(;j<=tongb[0];j++){
			ans-=tonga[0];
		}
		j=1;
		for(int i=1;i<=tonga[0];i++){
			while(tongb[j]+tonga[i]>=t/10*5&&j<=tongb[0]){
				ans+=i-1;
				j++;
			}
		}
		for(;j<=tongb[0];j++){
			ans+=tonga[0];
		}
		j=1;
		for(int i=1;i<=tonga[0];i++){
			while(tongb[j]+tonga[i]>=t/10*4&&j<=tongb[0]){
				ans-=i-1;
				j++;
			}
		}
		for(;j<=tongb[0];j++){
			ans-=tonga[0];
		}
	}
	cout<<ans;
	return 0;
}

T4
题意:
将数组\(a\)重排,求前\(k\)大的\(\sum_{i=1}^{n-1} |a_{i}-a_{i+1}|\)的值和方案数,方案数对\(1e9+7\)取模。
思路:
\(a_{i}\)从小到大排序,插入序列,将序列分为几个块,新加进来的\(a_{i}\)可以1.组成一个新块,最终权值减\(2\times a_{i}\);2.加进一个块的一端,最终权值不变;3.合并两个块,最终权值加\(2\times a_{i}\);4.放在最边缘,最终权值减\(a_{i}\);5.链接边缘和一个块,最终权值加\(a_{i}\)
\(fin_{i,j,0/1/2,k}\)表示放了\(i\)个数,有\(j\)个块,有\(0/1/2\)个边缘被放了,的第\(k\)大的值。
\(sch_{i,j,0/1/2,k}\)表示其对应的方案数。
代码:

#include<iostream>
#include<algorithm>
#define mod 1000000007
#define int long long
using namespace std;
int n,k;
int a[610];
struct node{
	int fin;
	int sch;
}f[2][610][3][110];
bool cmp(int x,int y){
	return x<y;
}
bool cnp(node x,node y){
	return x.fin>y.fin;
}
int t;
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1,cmp);
	f[0][0][0][1].sch=1;
	for(int i=1;i<=n;i++){
		t^=1;
		for(int j=1;j<=i;j++){
			for(int l=0;l<=2;l++){
				int cnt=0;
				for(int h=1;h<=k;h++){
					if(j>min(i-1,1ll)&&f[t^1][j-1][l][h].sch!=-1){
						cnt++;
						f[t][j][l][cnt].fin=f[t^1][j-1][l][h].fin-a[i]*2;
						f[t][j][l][cnt].sch=f[t^1][j-1][l][h].sch*(j-l)%mod;
					}
					if(f[t^1][j][l][h].sch!=-1){
						cnt++;
						f[t][j][l][cnt].fin=f[t^1][j][l][h].fin;
						f[t][j][l][cnt].sch=f[t^1][j][l][h].sch*(2*j-l)%mod;
					}
					if(f[t^1][j+1][l][h].sch!=-1){
						cnt++;
						f[t][j][l][cnt].fin=f[t^1][j+1][l][h].fin+a[i]*2;
						f[t][j][l][cnt].sch=f[t^1][j+1][l][h].sch*(j)%mod;
					}
					if(l>0){
						if(f[t^1][j][l-1][h].sch!=-1){
							cnt++;
							f[t][j][l][cnt].fin=f[t^1][j][l-1][h].fin+a[i];
							f[t][j][l][cnt].sch=f[t^1][j][l-1][h].sch*(3-l)%mod;
						}
						if(f[t^1][j-1][l-1][h].sch!=-1&&j>min(i-1,1ll)){
							cnt++;
							f[t][j][l][cnt].fin=f[t^1][j-1][l-1][h].fin-a[i];
							f[t][j][l][cnt].sch=f[t^1][j-1][l-1][h].sch*(3-l)%mod;
						}
					}
				}
				sort(f[t][j][l]+1,f[t][j][l]+cnt+1,cnp);
				int w=1;
				for(int h=1;h<=k;h++){
					while(w<=cnt&&f[t][j][l][w].sch<=0){
						w++;
					}
					if(w>cnt){
						f[t][j][l][h].fin=-1;
						f[t][j][l][h].sch=-1;
						continue;
					}
					f[t][j][l][h].fin=f[t][j][l][w].fin;
					f[t][j][l][h].sch=f[t][j][l][w].sch;
					w++;
					while(w<=cnt&&f[t][j][l][h].fin==f[t][j][l][w].fin){
						f[t][j][l][h].sch=(f[t][j][l][h].sch+f[t][j][l][w].sch)%mod;
						w++;
					}
				}
			}
		}
	}
	for(int h=1;h<=k;h++){
		cout<<f[t][1][2][h].fin<<" "<<f[t][1][2][h].sch<<endl;
	}
	return 0;
}
posted @ 2023-02-28 22:24  zzzzzz2  阅读(26)  评论(0编辑  收藏  举报