牛客多校Day5

不会B,我是弱智实锤。/kk

大致按难度排序。

H

// 1 1 0 0 ...
// 0 0 1 1 ...
// ...
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
int main()
{
	int n=read(),m=read();
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(i&1){if(j%4==1||j%4==2)putchar('1');else putchar('0');}
			else {if(j%4==1||j%4==2)putchar('0');else putchar('1');}
		}
		putchar('\n'); 
	}
}

K

双指针即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
const int N=1e5+10;
int st1[N][30],st2[N][30],a[N],Log[N];
int query1(int l,int r)//max
{
	int x=Log[r-l+1];
	return max(st1[l][x],st1[r-(1<<x)+1][x]);
}
int query2(int l,int r)//min
{
	int x=Log[r-l+1];
	return min(st2[l][x],st2[r-(1<<x)+1][x]);
}
int n,m;
ll sol(int k)
{
	ll ans=0;
	for(int l=1,r=0;l<=n;l++)
	{
		while(r<n&&query1(l,r+1)-query2(l,r+1)<=k)r++;
		ans+=n-r;
	}
	return ans;
}
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n;i++)st1[i][0]=st2[i][0]=a[i]=read();
	Log[1]=0;for(int i=2;i<=1e5;i++)Log[i]=Log[i>>1]+1;
	for(int j=1;j<=Log[n];j++)for(int i=1;i+(1<<j)-1<=n;i++)st1[i][j]=max(st1[i][j-1],st1[i+(1<<j-1)][j-1]);
	for(int j=1;j<=Log[n];j++)for(int i=1;i+(1<<j)-1<=n;i++)st2[i][j]=min(st2[i][j-1],st2[i+(1<<j-1)][j-1]);
	for(int i=1;i<=m;i++)printf("%lld\n",sol(read()));
	return 0;
}

D

对每个 \(a_i<b_j\) 算贡献即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
#define mp make_pair
#define pb push_back
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long ull;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
const int N=5010,mod=1e9+7;
int qpow(int a,int n){int ans=1;while(n){if(n&1)ans=(ll)ans*a%mod;a=(ll)a*a%mod;n>>=1;}return ans;}
int f[N][N],p[N<<1],inv[N<<1];
int binom(int n,int m){return (ll)p[n]*inv[m]%mod*inv[n-m]%mod;}
char a[N],b[N],c[N],d[N];
int g[N][N];
signed main()
{
//	freopen("in.txt","r",stdin);
	scanf("%s%s",a+1,b+1);
	int n=strlen(a+1),m=strlen(b+1);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			f[i][j]=(((ll)f[i-1][j]+(ll)f[i][j-1]-(ll)f[i-1][j-1])%mod+mod)%mod;
			if(a[i]==b[j])f[i][j]+=f[i-1][j-1]+1,f[i][j]%=mod; 
		}
	}
	p[0]=1;for(int i=1;i<=10000;i++)p[i]=(ll)p[i-1]*i%mod;
	inv[10000]=qpow(p[10000],mod-2);
	for(int i=9999;i>=0;i--)inv[i]=(ll)inv[i+1]*(i+1)%mod;
	for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)g[i][j]=binom(i+j,j);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(a[i]>=b[j])continue;
			ans+=(ll)(f[i-1][j-1]+1)*g[n-i][m-j]%mod,ans%=mod;
		}
	}
	printf("%d",ans);
}

B

并没有太读懂题。。直接把官方题解搬上来吧。

首先 \(C\) 最多只用花一次,且可以在最开始花,所以有两种策略:

直接全部打开,代价:\(\sum w_i\)

\(w_i\)​ 升序排序。先花 \(C\)​ 的代价,剩下的就相当于一个随机 01 序列从前往后开,开到一个后缀全是同色的为止。代价:\(C + \sum w_i(1-\dfrac{1}{2^{n-i}})\)

两者取较小值即可。

出题人如果再把题面写成这样我就退钱!!好像并没有交钱

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10;
long double w[N];
int main()
{
	int n;long double c;
	scanf("%d%Lf",&n,&c);
	long double ans1=0,ans2=0,pw=1;
	for(int i=1;i<=n;i++)cin>>w[i],ans1+=w[i];
	sort(w+1,w+n+1);
	for(int i=n;i;i--)ans2-=w[i]*pw,pw*=0.5;
	ans2+=ans1+c;
	printf("%.10Lf\n",min(ans1,ans2));
}
posted @ 2021-07-31 17:28  zzt1208  阅读(74)  评论(0编辑  收藏  举报