2019牛客暑期多校训练营 (第一场)
被F弄自闭了啊
这啥啊,推半天投了
然后发现过了这么多了
然后猜测结论很简单
然后开始猜 10/18 12/18 14/18...
(队友:为什么不试试奇数啊 我:不可能的,我觉得一定是偶数!)
-19
我:"啊我还是暴力吧"
撒了100w个点进去发现好像都输出0.6111...
这个是几啊
11/18
我:"?????"
队友:"你他么......"
E:
/* 先确定基本是个dp 然后状态 一开始想的f[i][j]表示构成i个AB,j个BA的方案数 但是不能表示前面有几个活动的A B 我们倒着思考,如果给一个串,让我们判断能不能分成x个AB y个BA 这个比较简单,就是贪心的,遇到一个A,就把它当成AB,这样后面有一个B任意选 同理,遇到B,把她当成BA,这样后面有一个A任意选 也就是说,前缀的AB一定都是匹配过的,只要后面有对应的就行 因此我们的状态可以不管到i这个位置是不是全匹配完全了 只需要知道有几个A和B匹配过了,check一下后面有没有足够的B和A f[i][j]表示 用了i个A,j个B 的方案数 假设现在填一个A i<=n : 那么这个A就可以作为AB的A先填上 B后面再找 j>=i-n : 必须以BA的形式填这个A 也就是B够用 f[i][j]+=f[i-1][j] B同理 */ #include<cstdio> #define maxn 4010 #define mod 1000000007 #define ll long long using namespace std; ll n,m,f[maxn][maxn]; int main(){ while(~scanf("%d%d",&n,&m)){ for(ll i=0;i<=n+m;i++) for(ll j=0;j<=n+m;j++) f[i][j]=0; f[0][0]=1; for(ll i=0;i<=n+m;i++) for(ll j=0;j<=n+m;j++){ if(i<=n||j>=i-n)if(i)f[i][j]+=f[i-1][j]; if(j<=m||i>=j-m)if(j)f[i][j]+=f[i][j-1]; f[i][j]%=mod; } printf("%d\n",f[n+m][n+m]); } return 0; }
B:
/* 看到给出的积分式,乘积肯定是积不出来,想办法变成求和的形式 原式是好多项乘积分之一,我们把他拆成每一项分之xx求和,就是第一个式子 然后待定系数,化简,带入x 最后求和的积分的时候注意求逆元 */ #include<cstdio> #include<cstring> #include<iostream> #define ll long long #define maxn 1010 #define mod 1000000007 using namespace std; ll n,a[maxn],c[maxn],ans; ll Qc(ll a,ll b){ ll res=1; while(b){ if(b&1)res=res*a%mod; a=a*a%mod;b>>=1; } return res; } int main(){ while(~scanf("%lld",&n)){ for(ll i=1;i<=n;i++)scanf("%lld",&a[i]); for(ll i=1;i<=n;i++){ c[i]=1;for(ll j=1;j<=n;j++) if(i!=j)c[i]=((a[j]*a[j]-a[i]*a[i])%mod+mod)%mod*c[i]%mod; c[i]=c[i]*2%mod*a[i]%mod; } ans=0; for(ll i=1;i<=n;i++){ ans=(ans+Qc(c[i],mod-2))%mod; } printf("%lld\n",ans); } return 0; }