首页 > 其他分享 >2022牛客暑假第七场C、F、J、K

2022牛客暑假第七场C、F、J、K

时间:2022-08-15 20:25:29浏览次数:100  
标签:cnt 先手 int res sum 第七场 牛客 num 2022

C-Constructive Problems Never Die_"蔚来杯"2022牛客暑期多校训练营7 (nowcoder.com)

容易知道,只要A中的数不是全部相同,就一定有解。

我们思考如何构造:

  1. 如果A中的数是一个排列,即其中的数两两不相同,最好的方法是把整个排列往右边错开一位。
  2. 因此可以找到A中每个数出现的第一个位置,只考虑这些位置,把它们向右错开一位排列下去。剩下的待填的数直接乱填就可以了,一定不会出现矛盾。
#define x first
#define y second
const int N=1e5+5;
typedef pair<int,int>PII;
int T;
vector<int>pos[N];
vector<PII>num;
int n;
int a[N],b[N],has[N];

int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++)pos[i].clear();
		num.clear(); memset(has,0,sizeof(has));
		int flag=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			if(i>1 && a[i-1]!=a[i])flag=1;
			pos[a[i]].push_back(i); has[a[i]]=1;
		}
		
		if(!flag){ cout<<"NO"<<endl; continue;}
		
		for(int i=1;i<=n;i++)
			if(pos[i].size())num.push_back({i,pos[i][0]});
		int len=num.size()-1;
		
		b[num[0].y]=num[len].x;
		for(int i=0;i<len;i++){
			b[num[i+1].y]=num[i].x;
		}

		int k=1;
		for(int i=1;i<=n;i++){
			for(int j=1;j<pos[i].size();j++){
				while(has[k])k++;
				b[pos[i][j]]=k++;
			}
		}
		
		printf("YES\n");
		for(int i=1;i<=n;i++)printf("%d ",b[i]);
		printf("\n");
	}
	return 0;
}

F-Candies_"蔚来杯"2022牛客暑期多校训练营7 (nowcoder.com)

可以发现两种删数的情况是一样的,所以我们遇到一对删掉一对就可以。

这样的操作很像括号匹配,考虑开一个栈来做。

由于是一个环,最后还需要对栈中的数首尾匹配

const int N=1e5+5;
int n,x;
int a[N];
int stk[N],top;

int main(){
	scanf("%d%d",&n,&x);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	
	int res=0;
	for(int i=1;i<=n;i++){
		if(!top)stk[++top]=a[i];
		else{
			while(top && i<=n && (stk[top]==a[i] || stk[top]+a[i]==x)){
				res++;
				top--;
				i++;
			}
			if(i<=n)stk[++top]=a[i];
		}
	}
	
	int i=1,j=top;
	while((stk[i]==stk[j] || stk[i]+stk[j]==x) && i<j){
		res++;
		i++; j--;
	}
	
	cout<<res<<endl;
	return 0;
}

J-Melborp Elcissalc_"蔚来杯"2022牛客暑期多校训练营7 (nowcoder.com)

对于一个子序列\([l,r]\),当满足\((sum[r]-sum[l-1])\%k=0\),即\(sum[r]\%k=sum[l-1]\%k\)时,我们说这个子序列是好的。

由于数组中的数都在\([0,k-1]\)范围内,因此通过前缀和数组可以唯一得出原数组,所以我们只需要考虑前缀和数组就可以了。

如何计算出good区间的数量(goodness)?假设有\(sum[i]\%k=x\),cnt[x]表示x出现的次数,则可以得出good区间的数量即为\(\sum_{x=0}^{k-1} C_{cnt[x]}^2\)。

所以问题转化成:构造出一个\(sum[]\)数组,\(cnt[x]\)表示每个\(sum[i]\%k\)的出现次数,满足\(\sum_{x=0}^{k-1} C_{cnt[x]}^2=t\)。但是直接考虑构造sum数组会很难维护cnt和上述和式,所以我们考虑构造cnt。

构造出的cnt只需要满足\(\sum cnt[i]=n\)即可。

设数组f[i][j][p]表示考虑到了第i种数,当前选择数的总个数为j个,当前的goodness值是p的所有方案,属性是构造出的数组种类数。

可以得出转移方程f[i][j][p]+=f[i-1][x][y]*C[n-x][j-x], p=y+C[j-x][2]

C[n-x][j-x]表示剩下还有n-x个位置需要选数,我们把其中的j-x个选成i的方案数。C[j-x][2]表示当前选择j-xi能够贡献的goodness。

可以写成正推的形式:

ll &v=f[i][j+num][u+C[num+(i==1)][2]];
v=(v+f[i-1][j][u]*C[n-j][num]%p)%p;

其中,当i==1时,表示正在考虑数“0”,由于前缀和s[0]==0,所以我们实际上要多考虑一个0,可以写成num+(i==1)

const int N=72,p=998244353;
typedef long long ll;
int n,k,t;
ll f[N][N][N*N];
int C[N][N];

int main(){
	C[0][0]=1;
	for(int i=1;i<=N-3;i++){
		for(int j=0;j<=i;j++){
			if(i==j || j==0)C[i][j]=1;
			else C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
		}
	}
	
	scanf("%d%d%d",&n,&k,&t);
	
	f[0][0][0]=1;
	for(int i=1;i<=k;i++){
		for(int j=0;j<=n;j++){
			for(int u=0;u<=t;u++){//实际上u和num循环顺序可以对调,为了可以做下面的剪枝,我们把u循环放在前面
				if(f[i-1][j][u]==0)continue;//剪
				for(int num=0;num+j<=n;num++){
					if(u+C[num+(i==1)][2]>t)break;
					ll &v=f[i][j+num][u+C[num+(i==1)][2]];
					v=(v+f[i-1][j][u]*C[n-j][num]%p)%p;
				}
			}
		}
	}
	cout<<f[k][n][t]<<endl;
	return 0;
}

K-Great Party_"蔚来杯"2022牛客暑期多校训练营7 (nowcoder.com)

如果只有1堆石头,肯定是先手必胜。

如果有2堆石头:

  1. 两堆石头都是1个,那么先手必败。
  2. 一堆是1个,另一堆是x个,先手可以拿x-1个后把必败局留给后手,先手必胜。
  3. 两堆都是两个。如果先手拿一个石头且不合并,后手也拿一个留下1,1的必败局给先手;如果先手拿一个石头且合并,后手直接拿完;如果先手拿一堆,后手直接拿完。所以这种情况先手必败。
  4. 如果两堆都是x个。无论先手拿多少个,后手可以做对称操作,最后一定会变成上述[1],[2]的局面,先手必输。
  5. 如果两堆数量不同。先手可以拿到两堆数量相同,所以后手就面临了[4]的必败局面,此时先手必胜。

如果有三堆石头:

  1. 如果是1,1,1:先手必胜。

  2. 如果是2,2,2:先手拿走一堆,后手面临2,2必败

  3. 如果2,2,3:同理,先手必胜

  4. 如果4,5,6:先手拿5个,剩下一个合进4,后手面临5,5必败

    总的来说,先手赢麻了。

如果有四堆石头:没有人会做合并操作,否则就会把必胜的局面留给对方,所以最后石子一定是1,1,1,1....的情况。

在奇数堆的情况下,推广结论可知:先手必胜。(不知道怎么推的......)

在偶数堆的情况下:没有人会做合并操作把奇数的情况让给对方,因此偶数一定不合并。那么最后拿来拿去一定会变成每堆石子只有1个的情况,因为有偶数堆,因此谁当前面对这个情况谁就死。考虑如何计算最后谁面对这个情况。考虑每堆石子的数量为\(a[i]-1\),把它们拿完后最后拿不了的人面临的就是全1的情况,这可以套经典nim,即看区间异或和是否为0。

考虑莫队离线处理每个询问,以右端点r增加1为例,增加的区间数目只需要考虑以r+1结尾的子区间的不满足条件的数目的偶数区间即可,即看\([l-1,r]\)中有多少个\(S[i]\ xor\ S[r+1]=0\),这是可以\(O(1)\)维护的,最后的结果就是区间所有子区间减去这些不满足条件的偶区间的数目。

const int N=1e5+5,S=1e6+5;
typedef long long ll;
int n,m;
int a[N],s[N];
int f[2*S],g[2*S];//f记录奇数位置、g记录偶数位置
int len,idx[N];
ll ans[N];
struct que{
	int id,l,r;
}q[N];

void add(int p,int &res){
	if(p&1){
		res+=f[s[p]];//因为我们记录的左端点都是l-1,所以奇偶要换一下
		f[s[p]]++;
	}
	else{
		res+=g[s[p]];
		g[s[p]]++;
	}
}

void del(int p,int &res){
	if(p&1){
		f[s[p]]--;
		res-=f[s[p]];
	}
	else{
		g[s[p]]--;
		res-=g[s[p]];
	}
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		a[i]--;
		s[i]=s[i-1]^a[i];
	}
	
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		q[i]={i,x-1,y};//区间应该是[l-1,r]
	}
	len=sqrt(n);
	for(int i=0;i<=n;i++)idx[i]=i/len;
	
	sort(q+1,q+m+1,[](struct que a,struct que b){
		if(idx[a.l]!=idx[b.l])return idx[a.l]<idx[b.l];
		return a.r<b.r;
	});
	
	int res=0;
	for(int k=1,i=1,j=0;k<=m;k++){
		int id=q[k].id, l=q[k].l, r=q[k].r;
		int tl=r-l;
		while(j<r)add(++j,res);
		while(j>r)del(j--,res);
		while(i<l)del(i++,res);
		while(i>l)add(--i,res);
		ans[id]=(ll)(tl+1)*tl/2-res;
	}
	
	for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
	return 0;
}


标签:cnt,先手,int,res,sum,第七场,牛客,num,2022
From: https://www.cnblogs.com/tshaaa/p/16589515.html

相关文章

  • 2022-08-15 第四小组 王星苹 学习笔记
    学习心得       开始MySQL数据库的学习,创建库,再创建表,在表中保存多条数据,一列就是一个字段,也可以增删改查心情 又新学个新东西,新起点,出发加油掌握情况:背......
  • 2022/8/15 总结
    题单贴贴A.Begin这是道结论题。但令人惊奇的是我完全没往这方面想用奇怪的策略做居然得到了\(\mathtt{80pts}\);Solution观察样例,再结合一点数学知识,我们可以知道......
  • 2022-08-15第七组薛雯匀
    Mysql数据库数据库数据库【按照数据结构来组织、存储和管理数据的仓库】。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据对于公司......
  • 2022 8-15 第四组 曹雨 MySQL数据库01
    MySQLMySQl是一个“关系型数据库管理系统”。MySQL使用了一种语言“SQL语言”MySQL分为社区版和商业版,体积小,速度快,成本低,开源以表的形式存取数据基本操作MySQL操......
  • UPC2022暑期个人训练赛第36场
    多谢两位大佬的帮助,才能勉强完成几个题,这几个题还是挺有意思的问题A:WJ的逃离DFS超时,所以考虑BFS,记得上次炸僵尸也是这个教训,这次忘记了感谢sgjen大佬提供的帮......
  • 20220815 随笔
    昨天是个好日子,我们大部分时间都在宿舍里度过。前一天晚上我们睡得太晚了,所以昨天我们也起得很晚。早上没吃饭,中午和晚上点了外卖。我觉得外卖烤肉饭很好吃,只是酱汁有点......
  • 20220815 第一组 于芮 mysql数据库第一天(第三十一天)
     小白成长记——第三十一天   今天我们告别了java基础,开始了新的旅程——mysql数据库,之前有接触过一点mysql数据库,所以有一点点的基础,对于今天新学的内容,没有那么......
  • "蔚来杯"2022牛客暑期多校训练营7 题解
    C.ConstructiveProblemsNeverDie对于出现次数大于1的数字,用出现次数为0的数字填充。剩下的数字一定两两互不相同,对这些数循环移位,最后进行判断即可。#include<bits/......
  • 2022-项目变大以后的文件组织
    大概是今年4月份吧,我发现股海纹龙的项目文件太大了,上传到gitee的时候,传不上去了。一开始我没有在意,还以为是网不好。后来才知道,一个仓库不能大于500M。最开始的应对一开......
  • 2022-8-15 数据库 mysql 第一天
    Mysql数据库数据库数据库【按照数据结构来组织、存储和管理数据的仓库】。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据对于公司......