ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

"蔚来杯"2022牛客暑期多校训练营4

2022-08-04 02:00:17  阅读:135  来源: 互联网

标签:int 蔚来 LL 多校 牛客 ans -- it1 define


链接

\(A:Task Computing\)

微扰法可以证明,若 \(i\) 排在 \(j\) 前面,则 \(w_i(p_j-1) < w_j(p_i-1)\) 。
先将其按该方法排序,我们只需要选出 \(m\) 个按顺序排即可。
\(m\) 很小,考虑 \(dp\) ,\(f_{i,j}\) 表示从前 \(i\) 个中选出 \(j\) 个的最大值。
但从前向后还有 \(p\) 会对后续答案产生影响,不好处理。
发现后面的对前面没有影响,我们可以从后往前 \(dp\) ,豁然开朗。

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define IL inline
#define LL long long
#define LF double
using namespace std;
const int N=1e5+3;
const LF inf=1e18;
struct hh{
	int w,op;LF p;
	bool operator<(const hh &a) const{
		if(op^a.op) return op>a.op;
		return w*(a.p-1)<a.w*(p-1);
	}
}a[N];
int n,m;
LF f[N][22];
IL LL in(){
    char c;int f=1;
    while((c=getchar())<'0'||c>'9')
      if(c=='-') f=-1;
    LL x=c-'0';
    while((c=getchar())>='0'&&c<='9')
      x=x*10+c-'0';
    return x*f;
}
int main()
{
	int x,y;
	n=in(),m=in();
	for(int i=1;i<=n;++i) a[i].w=in();
	for(int i=1;i<=n;++i){
		x=in();
		if(x<10000) a[i].op=0;
		else if(x==10000) a[i].op=1;
		else a[i].op=2;
		a[i].p=1.0*x/10000;
	}
	sort(a+1,a+n+1);
	f[n+1][0]=0;
	for(int i=1;i<=m;++i) f[n+1][i]=-inf;
	for(int i=n;i;--i)
	  for(int j=0;j<=m;++j){
	  	f[i][j]=f[i+1][j];
	  	if(j) f[i][j]=max(f[i][j],a[i].w+a[i].p*f[i+1][j-1]);
	  }
	printf("%.12lf\n",f[1][m]);
  return 0;
}

\(C:Easy Counting Problem\)

考虑 \(EGF\) ,答案为 \(\prod\limits_{i=0}^{w-1}(e^x-\sum\limits_{j=0}^{c_i-1}\frac{1}{j!})\) 的第 \(n\) 项系数乘上 \(n!\) 。
因为 \(n\) 很大,而 \(\sum\limits_{i=0}^{w-1}c_i\) 较小,将式子拆开,是一个容斥的形式,我们可以用背包预处理出选出 \(k\) 个项相乘的系数之和,枚举计算即可。

#include<bits/stdc++.h>
#define IL inline
#define LL long long
using namespace std;
const int N=2e5+3,M=1e7+3,p=998244353,G=3,Gi=332748118;
int r[N],fac[M],inv[M],_a[N],_b[N],_c[N],d[N],pw[M];
int w,f[11][N],c[N],len[11],g[11][N];
IL int in(){
	char c;int f=1;
	while((c=getchar())<'0'||c>'9')
	  if(c=='-') f=-1;
	int x=c-'0';
	while((c=getchar())>='0'&&c<='9')
	  x=x*10+c-'0';
	return x*f;
}
IL int mod(int x){return x>=p?x-p:x;}
IL int ksm(int a,int b){
  int c=1;
  while(b){
  	if(b&1) c=1ll*c*a%p;
  	a=1ll*a*a%p,b>>=1;
  }
  return c;
}
IL void calc(int lim){
	for(int i=0;i<lim;++i)
	  r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
}
IL void init(int n){
	fac[0]=1;for(int i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%p;
	inv[n]=ksm(fac[n],p-2);
	for(int i=n;i;--i) inv[i-1]=1ll*inv[i]*i%p;
}
IL void NTT(int *a,int lim,int op){
	calc(lim);
	for(int i=0;i<lim;++i)
	  if(i<r[i]) swap(a[i],a[r[i]]);
	for(int i=1;i<lim;i<<=1){
		int wn=ksm(~op?G:Gi,(p-1)/(i<<1));
		for(int j=0;j<lim;j+=i<<1){
			int w=1;
			for(int k=0;k<i;++k,w=1ll*w*wn%p){
				int x=a[j+k],y=1ll*w*a[j+i+k]%p;
				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
			}
		}
	}
	if(op==-1){
		int inv=ksm(lim,p-2);
		for(int i=0;i<lim;++i) a[i]=1ll*a[i]*inv%p;
	}
}
IL void mul(int *a,int *b,int *c,int n,int m){
	int lim=1,_a[N],_b[N];
	while(lim<n+m-1) lim<<=1;
	memcpy(_a,a,4*n),memcpy(_b,b,4*m),
	memset(_a+n,0,4*(lim-n)),memset(_b+m,0,4*(lim-m));
	NTT(_a,lim,1),NTT(_b,lim,1);
	for(int i=0;i<lim;++i) c[i]=1ll*_a[i]*_b[i]%p;
	NTT(c,lim,-1);
}
int main()
{
	init(1e7);
	w=in();for(int i=0;i<w;++i) c[i]=in();
	for(int i=0;i<w;++i)
	  for(int j=0;j<c[i];++j)
	  	g[i][j]=inv[j];
	f[0][0]=1,len[0]=1;
	for(int i=0;i<w;++i)
	  for(int j=i+1;j;--j){
	  	mul(f[j-1],g[i],d,len[j-1],c[i]);
	  	len[j]=max(len[j],len[j-1]+c[i]-1);
	  	for(int k=0;k<len[j-1]+c[i]-1;++k) f[j][k]=mod(f[j][k]+d[k]);
	  }
	int q=in();
	while(q--){
		int n=in(),ans=0,op=1;
		for(int i=0;i<w;++i,op*=-1)
		  for(int j=min(n,len[i]-1),mu=ksm(w-i,n-j);~j;--j,mu=1ll*mu*(w-i)%p)
		    ans=(ans+1ll*op*f[i][j]*mu%p*inv[n-j]%p+p)%p;
		if(n<len[w]) ans=(ans+1ll*op*f[w][n]%p+p)%p;
		ans=1ll*ans*fac[n]%p;
		printf("%d\n",ans);
	}
	return 0;
}

\(D:Jobs (Easy Version)\)

三维前缀和即可。

\(E:Jobs (Hard Version)\)

对每个公司的工作,考虑容斥,对三维空间的点处理使得求出前缀和后,满足能到该公司的点为 \(1\),否则为 \(0\) 。
直接枚举子集容斥复杂度肯定会爆,需要想个更聪明的办法。
考虑二维的情况,可以将工作抽象成一个个矩形,如果一个矩形覆盖另一个矩形,则前者没有意义,我们可以无视它。
这样就会得到一个长度单调递增,高度单调递减的一堆矩阵。显然我们要在矩阵右上角顶点处加 \(1\),在恰好覆盖相邻两个矩阵的矩阵右上角处减 \(1\) 以去重,可以用 \(set\) 维护。
对于三维情况,我们将点按第三维排序,从下往上将矩阵插入,即可转化成二维情况。

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<random>
#define IL inline
#define LL long long
using namespace std;
const int N=2e6+3,M=4e2,p=998244353;
struct hh{
	int a,b,c;
	bool operator<(const hh &d) const{
		return a^d.a?a<d.a:b<d.b;
	}
}a[N];
bool cmp1(const hh &a,const hh &b){
	return a.c<b.c;
};
int n,m,q,flag,pre[M+2][M+2][M+2];
multiset<hh>st;
multiset<hh>::iterator it,it1,it2;
IL int in(){
	char c;int f=1;
	while((c=getchar())<'0'||c>'9')
	  if(c=='-') f=-1;
	int x=c-'0';
	while((c=getchar())>='0'&&c<='9')
	  x=x*10+c-'0';
	return x*f;
}
void dele(multiset<hh>::iterator pos,int h){
	--pre[pos->a][pos->b][h];
	if(pos==st.begin()){
		if(pos!=--st.end()){
			it1=pos,++it1;
			++pre[it1->a][pos->b][h];
		}
	}
	else if(pos==--st.end()){
		it1=pos,--it1;
		++pre[pos->a][it1->b][h];
	}
	else{
		it1=it2=pos,--it1,++it2;
		++pre[pos->a][it1->b][h],
		++pre[it2->a][pos->b][h],
		--pre[it2->a][it1->b][h];
	}
	st.erase(pos);
}
void ins(hh x){
	it=st.insert(x);
	++pre[x.a][x.b][x.c];
	if(it==st.begin()){
		if(++it!=st.end()) --pre[it->a][x.b][x.c];
	}
	else if(it==--st.end()){
		if(it!=st.begin()) --it,--pre[x.a][it->b][x.c];
	}
	else{
		it1=it,--it1,it2=it,++it2;
		++pre[it2->a][it1->b][x.c];
		--pre[it2->a][it->b][x.c];
		--pre[it->a][it1->b][x.c];
	}
}
IL int chk(hh x){
	it=st.upper_bound(x);
	if(it!=st.end()){if(it->b>=x.b){dele(it,x.c);return 0;}}
	if(it!=st.begin()){if((--it)->b<=x.b){flag=0;return 1;}}
	return 1;
}
int main()
{
	n=in(),q=in();
	for(int i=1;i<=n;++i){
		int k=in();
		for(int j=1;j<=k;++j)
		  a[j]=(hh){in(),in(),in()};
		st.clear(),sort(a+1,a+k+1,cmp1);
		for(int j=1;j<=k;++j){
			flag=1;while(!chk(a[j]));
			if(flag) ins(a[j]);
		}
	}
	for(int i=1;i<=M;++i)
	  for(int j=0;j<=M;++j)
	    for(int k=0;k<=M;++k)
	      pre[i][j][k]+=pre[i-1][j][k];
	for(int i=0;i<=M;++i)
	  for(int j=1;j<=M;++j)
	    for(int k=0;k<=M;++k)
	      pre[i][j][k]+=pre[i][j-1][k];
	for(int i=0;i<=M;++i)
	  for(int j=0;j<=M;++j)
	    for(int k=1;k<=M;++k)
	      pre[i][j][k]+=pre[i][j][k-1];	
	int ans=0,lastans=0,seed=in();
	std::mt19937 rng(seed);
	std::uniform_int_distribution<> u(1,400);
	while(q--){
	    int IQ=(u(rng)^lastans)%400+1;
	    int EQ=(u(rng)^lastans)%400+1;
	    int AQ=(u(rng)^lastans)%400+1;
	    ans=(1ll*ans*seed%p+(lastans=pre[IQ][EQ][AQ]))%p;
	}
	printf("%d\n",ans);
	return 0;
}

\(G:Wall Builder I\)

细节题,分 \(1,2,3\) 条线构成矩形分别讨论取最大值即可。。。即可个鬼!

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define IL inline
#define LL long long
#define LF double
using namespace std;
const int N=1e5+3;
int k,n,m,a[4][N],b[2][N];
LL ans;
IL LL in(){
    char c;int f=1;
    while((c=getchar())<'0'||c>'9')
      if(c=='-') f=-1;
    LL x=c-'0';
    while((c=getchar())>='0'&&c<='9')
      x=x*10+c-'0';
    return x*f;
}
IL void solve(){
	int x,y;ans=0;
	k=in(),n=in(),m=in();
	a[0][0]=a[1][0]=a[2][0]=a[3][0]=0,b[0][0]=b[1][0]=0;
	for(int i=1;i<=k;++i){
		x=in(),y=in();
		if(!x) a[0][++a[0][0]]=y,b[0][++b[0][0]]=y;
		else if(y==m) a[1][++a[1][0]]=x,b[1][++b[1][0]]=x;
		else if(x==n) a[2][++a[2][0]]=y,b[0][++b[0][0]]=y;
		else a[3][++a[3][0]]=x,b[1][++b[1][0]]=x;
	}
	sort(a[0]+1,a[0]+a[0][0]+1),
	sort(a[1]+1,a[1]+a[1][0]+1),
	sort(a[2]+1,a[2]+a[2][0]+1),
	sort(a[3]+1,a[3]+a[3][0]+1),
	sort(b[0]+1,b[0]+b[0][0]+1),
	sort(b[1]+1,b[1]+b[1][0]+1);
	
	if(b[0][0]&&!a[3][0]) ans=max(ans,1ll*b[0][1]*n);
	if(b[0][0]&&!a[1][0]) ans=max(ans,1ll*(m-b[0][b[0][0]])*n);
	if(b[1][0]&&!a[0][0]) ans=max(ans,1ll*b[1][1]*m);
	if(b[1][0]&&!a[2][0]) ans=max(ans,1ll*(n-b[1][b[1][0]])*m);
	
	for(int i=2;i<=b[0][0];++i) ans=max(ans,1ll*(b[0][i]-b[0][i-1])*n);
	for(int i=2;i<=b[1][0];++i) ans=max(ans,1ll*(b[1][i]-b[1][i-1])*m);
	
	for(int i=1;i<=a[0][0];++i){
		if(i==1&&a[3][0]) ans=max(ans,1ll*a[0][1]*a[3][1]);
		if(i==a[0][0]&&a[1][0]) ans=max(ans,1ll*(m-a[0][i])*a[1][1]);
		if(a[3][0]&&(!a[2][0]||a[2][1]>a[0][i])) ans=max(ans,1ll*a[0][i]*(n-a[3][a[3][0]]));
		if(a[1][0]&&(!a[2][0]||a[2][a[2][0]]<a[0][i])) ans=max(ans,1ll*(m-a[0][i])*(n-a[1][a[1][0]]));
	}
	
	for(int i=1;i<=a[1][0];++i){
		if(i==1&&a[0][0]) ans=max(ans,1ll*a[1][1]*(m-a[0][a[0][0]]));
		if(i==a[1][0]&&a[2][0]) ans=max(ans,1ll*(n-a[1][i])*(m-a[2][a[2][0]]));
		if(a[0][0]&&(!a[3][0]||a[3][1]>a[1][i])) ans=max(ans,1ll*a[1][i]*a[0][1]);
		if(a[2][0]&&(!a[3][0]||a[3][a[3][0]]<a[1][i])) ans=max(ans,1ll*(n-a[1][i])*a[2][1]);
	}
	
	for(int i=1;i<=a[2][0];++i){
		if(i==1&&a[3][0]) ans=max(ans,1ll*a[2][1]*(n-a[3][a[3][0]]));
		if(i==a[2][0]&&a[1][0]) ans=max(ans,1ll*(m-a[2][a[2][0]])*(n-a[1][a[1][0]]));
		if(a[3][0]&&(!a[0][0]||a[0][1]>a[2][i])) ans=max(ans,1ll*a[2][i]*a[3][1]);
		if(a[1][0]&&(!a[0][0]||a[0][a[0][0]]<a[2][i])) ans=max(ans,1ll*(m-a[2][i])*a[1][1]);
	}
	
	for(int i=1;i<=a[3][0];++i){
		if(i==1&&a[0][0]) ans=max(ans,1ll*a[3][1]*a[0][1]);
		if(i==a[3][0]&&a[2][0]) ans=max(ans,1ll*(n-a[3][i])*a[2][1]);
		if(a[0][0]&&(!a[1][0]||a[1][1]>a[3][i])) ans=max(ans,1ll*a[3][i]*(m-a[0][a[0][0]]));
		if(a[2][0]&&(!a[1][0]||a[1][a[1][0]]<a[3][i])) ans=max(ans,1ll*(n-a[3][i])*(m-a[2][a[2][0]]));
	}
	for(int i=2;i<=a[0][0];++i) if(b[1][0]) ans=max(ans,1ll*(a[0][i]-a[0][i-1])*b[1][b[1][0]]);
	for(int i=2;i<=a[1][0];++i) if(b[0][0]) ans=max(ans,1ll*(a[1][i]-a[1][i-1])*(m-b[0][1]));
	for(int i=2;i<=a[2][0];++i) if(b[1][0]) ans=max(ans,1ll*(a[2][i]-a[2][i-1])*(n-b[1][1]));
	for(int i=2;i<=a[3][0];++i) if(b[0][0]) ans=max(ans,1ll*(a[3][i]-a[3][i-1])*b[0][b[0][0]]);
	if(a[1][0]){
		for(int i=1,j=1;i<=a[0][0];++i){
			while(j<=a[2][0]&&a[2][j]<a[0][i]) ++j;
			if(j==a[2][0]+1) break;
			ans=max(ans,1ll*(n-a[1][1])*(a[2][j]-a[0][i]));
		}
	}
	if(a[3][0]){
		for(int i=a[0][0],j=a[2][0];i;--i){
			while(j&&a[2][j]>a[0][i]) --j;
			if(!j) break;
			ans=max(ans,1ll*(n-a[3][1])*(a[0][i]-a[2][j]));
		}
	}
	if(a[2][0]){
		for(int i=1,j=1;i<=a[1][0];++i){
			while(j<=a[3][0]&&a[3][j]<a[1][i]) ++j;
			if(j==a[3][0]+1) break;
			ans=max(ans,1ll*a[2][a[2][0]]*(a[3][j]-a[1][i]));
		}
	}
	if(a[0][0]){
		for(int i=a[1][0],j=a[3][0];i;--i){
			while(j&&a[3][j]>a[1][i]) --j;
			if(!j) break;
			ans=max(ans,1ll*a[0][a[0][0]]*(a[1][i]-a[3][j]));
		}
	}
	if(a[1][0]){
		for(int i=1,j=1;i<=a[2][0];++i){
			while(j<=a[0][0]&&a[0][j]<a[2][i]) ++j;
			if(j==a[0][0]+1) break;
			ans=max(ans,1ll*a[1][a[1][0]]*(a[0][j]-a[2][i]));
		}
	}
	if(a[3][0]){
		for(int i=a[2][0],j=a[0][0];i;--i){
			while(j&&a[0][j]>a[2][i]) --j;
			if(!j) break;
			ans=max(ans,1ll*a[3][a[3][0]]*(a[2][i]-a[0][j]));
		}
	}
	if(a[2][0]){
		for(int i=1,j=1;i<=a[3][0];++i){
			while(j<=a[1][0]&&a[1][j]<a[3][i]) ++j;
			if(j==a[1][0]+1) break;
			ans=max(ans,1ll*(m-a[2][1])*(a[1][j]-a[3][i]));
		}
	}
	if(a[0][0]){
		for(int i=a[3][0],j=a[1][0];i;--i){
			while(j&&a[1][j]>a[3][i]) --j;
			if(!j) break;
			ans=max(ans,1ll*(m-a[0][1])*(a[3][i]-a[1][j]));
		}
	}
	printf("%lld\n",ans);
}
int main()
{
	int T=in();
	while(T--) solve();
  return 0;
}

\(H:Wall Builder II\)

枚举矩形的长宽贪心放尽量长的砖块即可。
(代码打表,过长不放。)

\(J:Counting Fish Again\)

对于 \(x+y=k\) 的线,若向右上延伸则无限制,若向左下延伸,对于三角形直角顶点 \((x,y)\) ,最左下方的点为 \((2x+y-k,2y+x-k)\) ,要满足横纵坐标皆大于等于 \(0\) ,相当于两个半平面交,求其与一个直角三角形交集的整数点数。用 \(set\) 维护各个 \(x+y\) 不相等的线段。

\(K:NIO's Sword\)

若进行 \(k\) 次,\(x -> x \cdot 10^k +(0\) ~ \((10^k-1)) \mod n\) ,枚举判断即可。
注意 \(n=1\) 是答案为 \(0\) 。

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define IL inline
#define LL long long
#define pb push_back
using namespace std;
const int N=1e6+3;
IL int in(){
    char c;int f=1;
    while((c=getchar())<'0'||c>'9')
      if(c=='-') f=-1;
    int x=c-'0';
    while((c=getchar())>='0'&&c<='9')
      x=x*10+c-'0';
    return x*f;
}
IL void solve(){
	int n=in();int val=0,ans=0;
	if(n==1){puts("0");return;}
	for(int i=1;i<=n;++i){
		val=i-1;
		for(int j=1,k=10;;++j,k*=10){
			val=val*10%n;
			if(val<=i%n&&val+k-1>=i%n){ans+=j;break;}
			if(val>i%n&&val+k-1>=i%n+n){ans+=j;break;}
		}
	}
	cout<<ans<<endl;
}
int main()
{
    solve();
    return 0;
}

\(N:Particle Arts\)

最后肯定会变为对于任意 \(i,j\) ,若 \(a_i \leq a_j\) ,则 \(a_i \& a_j =a_i\) 。
我们提取出所有 \(a\) 的每一位,将 \(1\) 都分配到最右端,显然这样是唯一满足其的方案。

#include<bits/stdc++.h>
#define IL inline
#define LL long long
using namespace std;
const int N=1e5+3;
int n,buk[N];
LL a[N],b[N],sum;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
struct kk{
	LL a,b;
	kk operator+(const kk &c) const{
		LL d=gcd(b,c.b);
		LL a0=a*c.b/d+c.a*b/d,b0=b*c.b/d;
		d=gcd(a0,b0);
		return (kk){a0/d,b0/d};
	}
	kk operator-(const kk &c) const{
		LL d=gcd(b,c.b);
		LL a0=a*c.b/d-c.a*b/d,b0=b*c.b/d;
		d=gcd(a0,b0);
		return (kk){a0/d,b0/d};
	}
	void maintain(){
		LL d=gcd(a,b);
		a/=d,b/=d;	
	}
	kk pf(){return (kk){a*a,b*b};}
	kk operator/(const int &k){
		LL d=gcd(a,b*k);
		return (kk){a/d,b*k/d};
	}
}s,mi;
IL LL in(){
    char c;int f=1;
    while((c=getchar())<'0'||c>'9')
      if(c=='-') f=-1;
    LL x=c-'0';
    while((c=getchar())>='0'&&c<='9')
      x=x*10+c-'0';
    return x*f;
}
int main()
{
	n=in();
	for(int i=1;i<=n;++i){
		sum+=(a[i]=in());
		for(int j=0;j<15;++j)
		  if(a[i]>>j&1) ++buk[j];
	}
	for(int i=0;i<15;++i)
	  for(int j=1;j<=buk[i];++j)
	    b[j]|=1<<i;
	mi.a=sum*sum,mi.b=n,mi.maintain();
	for(int i=1;i<=n;++i) s.a+=b[i]*b[i];
	s.b=1,s=s-mi,s=s/n;
	printf("%lld/%lld\n",s.a,s.b);
	return 0;
}

标签:int,蔚来,LL,多校,牛客,ans,--,it1,define
来源: https://www.cnblogs.com/yiqiAtiya/p/16549303.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有