• ExaWizards 2019


      AB:div 3 AB???

      C:div 1 C???场内自闭的直接去看D。事实上是个傻逼题,注意到物品相对顺序不变,二分边界即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 200010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    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 n,m,a[N],tot;
    char s[N],b[N];
    bool check(int k,int op)
    {
    	for (int i=1;i<=m;i++)
    	if (b[i]==s[k])
    	{
    		if (a[i]==0) k--;
    		else k++;
    		if (k==0)
    		{
    			if (op==0) return 1;
    			else return 0;
    		}
    		if (k==n+1)
    		{
    			if (op==1) return 1;
    			else return 0;
    		}
    	}
    	return 0;
    }
    signed main()
    {
    	tot=n=read(),m=read();
    	scanf("%s",s+1);
    	for (int i=1;i<=m;i++)
    	{
    		b[i]=getc();a[i]=getc()=='R';
    	}
    	int l=1,r=n,ans=0;
    	while (l<=r)
    	{
    		int mid=l+r>>1;
    		if (check(mid,0)) ans=mid,l=mid+1;
    		else r=mid-1;
    	}
    	tot-=ans;
    	l=1,r=n;ans=n+1;
    	while (l<=r)
    	{
    		int mid=l+r>>1;
    		if (check(mid,1)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	tot-=n+1-ans;
    	cout<<tot;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:显然对小模数取模后,大模数不会再产生影响。于是将模数从大到小排序,设f[i][j]为考虑了前i大模数后当前值是j的概率,转移考虑第i个模数是否在前缀单调栈中,若在则转移对其取模,在栈中相当于其要在比它小的所有数的前面,概率显然为1/(n-i+1)。场上莫名其妙的认为这个概率是1/(n-i+1)!,然后就自闭了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 210
    #define M 100010
    #define P 1000000007 
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    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 n,m,a[N],f[N][M],fac[N],inv[N];
    signed main()
    {
    	freopen("d.in","r",stdin);
    	freopen("d.out","w",stdout);
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	sort(a+1,a+n+1);reverse(a+1,a+n+1);
    	fac[0]=1;for (int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%P;
    	inv[0]=inv[1]=1;for (int i=2;i<=n;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
    	f[0][m]=1;
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=0;j<=m;j++)
    		{
    			f[i][j]=(f[i][j]+1ll*f[i-1][j]*(P+1-inv[n-i+1]))%P;
    			f[i][j%a[i]]=(f[i][j%a[i]]+1ll*f[i-1][j]*inv[n-i+1])%P;
    		}
    	}
    	int ans=0;
    	for (int j=0;j<=m;j++) ans=(ans+1ll*f[n][j]*fac[n]%P*(j%a[n]))%P;
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E:最后5分钟才看这个题,然后发现是个一眼题。考虑黑白球哪个先被拿完,不妨设是白球,然后见注释。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define P 1000000007
    #define N 200010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    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 n,m,f[N],fac[N],inv[N];
    int ksm(int a,int k)
    {
    	int s=1;
    	for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
    	return s;
    }
    int Inv(int a){return ksm(a,P-2);}
    int C(int n,int m){if (m>n) return 0;return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
    signed main()
    {
    	freopen("e.in","r",stdin);
    	freopen("e.out","w",stdout);
    	n=read(),m=read();
    	fac[0]=fac[1]=1;for (int i=1;i<=n+m;i++) fac[i]=1ll*fac[i-1]*i%P;
    	inv[0]=inv[1]=1;for (int i=2;i<=n+m;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
    	for (int i=2;i<=n+m;i++) inv[i]=1ll*inv[i-1]*inv[i]%P;
    	for (int i=m;i<n+m;i++)
    	{
    		int p=1ll*C(i-1,m-1)*Inv(ksm(2,i))%P;
    		f[1]=(f[1]+1ll*(i-m)*Inv(i-1)%P*p)%P;
    		f[i]=(f[i]+P-1ll*(i-m)*Inv(i-1)%P*p%P)%P;
    		f[i+1]=(f[i+1]+p)%P;
    	}
    	for (int i=n;i<n+m;i++)
    	{
    		int p=1ll*C(i-1,n-1)*Inv(ksm(2,i))%P;
    		f[1]=(f[1]+1ll*(n-1)*Inv(i-1)%P*p)%P;
    		f[i]=(f[i]+P-1ll*(n-1)*Inv(i-1)%P*p%P)%P;
    		f[i]=(f[i]+p)%P;
    		f[i+1]=(f[i+1]+P-p)%P;
    	}
    	//白球是在第i次被拿完的 之前黑白球都存在 则每次拿黑白球概率均等 其概率为C(i-1,m-1)/2^i
    	//考虑该情况下第j次拿黑球的概率 显然第i次不可能
    	//对j<i和j>i分别考虑
    	//j<i时,概率为(i-m)/(i-1)
    	//j>i时,概率为1
    	//若白球是最后一次被拿完的 再考虑黑球是什么时候被拿完的
    	//类似 
    	for (int i=1;i<=n+m;i++) f[i]=(f[i]+f[i-1])%P;
    	for (int i=1;i<=n+m;i++) printf("%d
    ",f[i]);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      F:咕

  • 相关阅读:
    [翻译] FreeStreamer 在线流媒体播放
    [转] 每个程序员都必须遵守的编程原则
    iOS7以下设备获取mac地址
    iOS中alloc与init
    ON、WHERE、HAVING的区别
    在SQL语言中,join什么时候用,什么时候不用啊?请高手举例解释一下。谢谢
    你能识别这些科技公司的真假logo吗?
    in 和 exist 区别
    union和union all的区别
    Mysql避免全表扫描sql查询优化 .
  • 原文地址:https://www.cnblogs.com/Gloid/p/10629779.html
Copyright © 2020-2023  润新知