首页 > 其他分享 >2023牛客多校7.24补题

2023牛客多校7.24补题

时间:2023-07-26 20:11:40浏览次数:35  
标签:ch 大数 int 7.24 牛客 补题 && 2n getchar

J-Fine Logic

题意:给定n个点和m对偏序关系(x,y),构造最少的排列数目k,使得在这k个排列中至少有一个排列满足x出现在y的前面。

分析:很考验思维的一道题,首先如果m对偏序关系不构成环,也就是一张有向无环图,于是用拓扑排序构造出一个合理排列即可。要是有环,就直接构造两个排列,一个是1<2<...<n,另一个是n<n-1<...<1。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=1e6+5;
const int M=4e5+5;
const int mod=998244353;
const int inf=1e9;
vector<int>q[N];
queue<int>p;
int n,m,deg[N],id[N];
void topsort(){
	int now=0;
	for(int i=1;i<=n;++i){
		if(!deg[i]){
			p.push(i);
		}
	}
	while(p.size()){
		int u=p.front();p.pop();
		id[++now]=u;
		for(int i=0;i<q[u].size();++i){
			int v=q[u][i];
			--deg[v];
			if(deg[v]==0)p.push(v);
		}
	}
	if(now<n){
		cout<<"2"<<endl;
		for(int i=1;i<=n;++i)cout<<i<<" ";cout<<endl;
		for(int i=1;i<=n;++i)cout<<n+1-i<<" ";cout<<endl;
	}
	else{
		cout<<"1"<<endl;
		for(int i=1;i<=n;++i)cout<<id[i]<<" ";
		cout<<endl;
	}
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=m;++i){
		int x=read(),y=read();
		q[x].push_back(y);
		++deg[y];
	}
	topsort();
	return 0;
}

B-Auspiciousness

题意:2n 张牌面数字分别为 1, 2, . . . , 2n 的牌叠放成牌堆,完成以下流程:

$\ \ \ $1.从牌堆顶取走一张牌

$\ \ \ $2.若牌堆为空则结束流程,否则猜测牌堆顶数字是否大于上一张取走的牌,并从牌堆顶取走一张牌

$\ \ \ $3.若猜测正确则回到上一步继续,否则结束流程

依照上一张牌不超过 n 则猜测牌堆顶大于上一张牌,否则猜测小于的策略猜测问对于所有可能的 (2n)! 种牌堆叠放顺序,总共能取走的牌的数量之和模 m 的结果

分析:1 ∼ n 为小数,n + 1 ∼ 2n 为大数。最终摸到牌的序列一定是小数上升序列和大数下降序列的交替,再加上最后一个不合法的数(也可能没有这个不合法的数,即摸完 2n 张牌)。设 f(i, j, k) 表示已经填了 i 个小数,j 个大数,最后一段是小/大数(k=0/1)的方案数,则\(f[i+k][j][0]=f[i+k][j][0]+f[i][j][1]*C(n-i,k)\),\(f[i][j+k][1]=f[i][j+k][1]+f[i][j][0]*C(n-j,k)\).

上述两种转移下,对答案的贡献分别为\((i+j+k)*f[i][j][1]*C(n-i,k)*(k-1)*(2*n-i-j-k)!\),\((i+j+k)*f[i][j][0]*C(n-j,k)*(k-1)*(2*n-i-j-k)!\),其中\(k-1\)表示最后一段k个数有\(k-1\)种排列方式来保证这次恰好取到\(i+j+k\)个数,即在小数升序或者大数降序的基础上(仅一种情况),把前\(k-1\)个数中的任意一个移到最后而其它数保持不动。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=305;
const int M=4e5+5;
const int mod=998244353;
const int inf=1e9;
int g[N][N],f[N][N][2],jc[N<<1];
int main(){
	int T=read();
	while(T--){
		int n=read(),m=read();
		g[0][0]=1;
		for(int i=1;i<=n;++i){
			g[i][0]=1;
			for(int j=1;j<=i;++j){
				g[i][j]=(g[i-1][j]+g[i-1][j-1])%m;
			}
		}
		jc[0]=1;
		for(int i=1;i<=2*n;++i)jc[i]=(1ll*jc[i-1]*i)%m;
		int ans=0;
		for(int i=0;i<=n;++i){
			for(int j=0;j<=n;++j)f[i][j][0]=f[i][j][1]=0;
		}
		f[0][0][0]=f[0][0][1]=1;
		for(int i=0;i<=n;++i){
			for(int j=0;j<=n;++j){
				for(int k=1;k<=n-i;++k){
					f[i+k][j][0]=(f[i+k][j][0]+1ll*f[i][j][1]*g[n-i][k]%m)%m;
					ans=(ans+1ll*f[i][j][1]*g[n-i][k]%m*(i+j+k)%m*(k-1)%m*jc[2*n-i-j-k]%m)%m;
				}
				for(int k=1;k<=n-j;++k){
					f[i][j+k][1]=(f[i][j+k][1]+1ll*f[i][j][0]*g[n-j][k]%m)%m;
					ans=(ans+1ll*f[i][j][0]*g[n-j][k]%m*(i+j+k)%m*(k-1)%m*jc[2*n-i-j-k]%m)%m;
				}
				if(i==n&&j==n)ans=(ans+2ll*n%m*(f[i][j][0]+f[i][j][1])%m)%m;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

标签:ch,大数,int,7.24,牛客,补题,&&,2n,getchar
From: https://www.cnblogs.com/PPXppx/p/17583449.html

相关文章

  • 暑假集训D3 2023.7.26 补题
    G.P6183[USACO10MAR]TheRockGameS题意:给定长度n,构造\(2^n\)个由X和O组成的字符串,使得第一个字符串和最后一个字符串只由O组成,并且相邻的字符串只有一处不同,不得有重复的字符串.BFS貌似做不了.看题解有佬用格雷码的知识.代码如下#include<stdio.h>#include<st......
  • 7.24 树上问题2笔记
    题单T1题目•有一棵点数为\(n\)的树。•有\(q\)次询问,每次询问有多少个点到\(a,b\)距离相等。•\(1≤n\),\(q≤500000\)。Solution•设询问\(a,b\)两点直接的路长度为\(d\)。•如果\(d\)为奇数,那么无解,\(d\)为偶数有解。•考虑以下几种情况:\(......
  • 暑假集训D2 2023.7.25 补题
    D.P1796汤姆斯的天堂梦这道题目非常ex,赛时死活调不出来,思路是对的,容易发现是一个DAG,所以直接DP就好,虽然后面看题解AC了,发现是重边的问题。但还是来记录一下这道ex的题目,警醒一下自己切记注意重边!!如下两份代码,一份爆0,一份AC#include<stdio.h>#include<stdlib.h>#include<s......
  • 补题报告之S班暑训第二场
    成绩比赛经过糟糕记不清了?\(\text{A}\)题,结论很显然,不出意外应该是很快就搞出来了,但是没有考虑所给的子图可能不连通!挂成\(\text{50}\)了?\(\text{B}\)题,一眼\(\text{DP}\)事实证明我是对的。但是我对一个子问题\(\text{DP}\)。考虑的是\(0\)时刻的方案选取数,本来想......
  • 暑假牛客多校第三场 2023-7-24
    未补完A.WorldFragmentsI算法:构造做法:从x中某一个数位选一个数,这个数有可能是0或者是1。求x变到y的最小数,这个数有可能是负数,要取绝对值。注意如果x是0,那么从x中取的数就只有0了,除非y也等于0,否则输出-1。code#include<iostream>#include<cstring>#include<algori......
  • 牛客暑假多校 2023 第三场
    写在前面比赛地址:https://ac.nowcoder.com/acm/contest/57357。发生了这种事……气槽她气得吐槽了啊!以下按个人向难度排序。A签到。除非\(x=0\)否则可以调整为任意数,步数即两数之差。///*By:Luckyblock*/#include<cmath>#include<cstdio>#include<cctype>#incl......
  • 牛客多校2023 第三场
    A签到,注意$0$的特判#include<bits/stdc++.h>usingnamespacestd;longlongx,y;intmain(){strings1,s2;cin>>s1;cin>>s2;intLen1=s1.length();intLen2=s2.length();for(inti=0;i<Len1;i++)......
  • 2023.7.24
    今天有事,所以也没看多少。看了ret2VDSO,ctfwiki上讲的很简略,原理甚至只有“待补充”几个字。我去看了最下面贴的两个链接,第一个链接全是英文,有点不太想看,第二个链接和ctfwiki上的一模一样。感觉好像这块和之前的ret2reg差不多,都不是特别重要的部分。明天去看SROP......
  • 牛客多校 Day3
    H哥德巴赫J诈骗A签到D要么全\(0\),要么全\(1\)B不得不说我真的纯纯SB真的。考场做法是先转成概率,然后就是计算长度大于等于\(i\)概率之和。\(f(i,j,0/1)\)前\(i+j\)个位置填\(i\)个小于等于\(n\)的数,\(j\)个大于\(n\)的数,最后一段是上升/下降的......
  • 7.24打卡
    L1-096谁管谁叫爹#include<bits/stdc++.h>usingnamespacestd;intdigit_sum(intnum){intsum=0;while(num){sum+=(num%10);num/=10;}returnsum;}intmain(){intN;inti,j;intA,B;cin>>N;for(i=0;i<N;......