前天网上打的比赛了。。
由于实力不够,变成手速场。。
最终结果
rank120左右,做了A,B,C,D,E。G没有做出来,赛后更正了。。
F还没做,但最近也不打算做。。以后再做吧
直接看一下哪一个数字出现地最少,输出来即可
预处理一些前缀和和后缀和
暴力枚举在哪里叫醒他就可以了
考虑到只有4个矩阵,所以我们可以用 4! 4 ! 的时间来枚举排列方案
然后显然最终合法的矩阵只有两种
一种是左上角是0,另外一种是左上角是1
然后枚举完一个暴力check就好了
我一开始dfs都写错了
考虑找到一个点x
x满足和1,2不共线
那么只有三种情况
1,2为一条直线
2,x为一条直线
1,x为一条直线
然后暴力判断就可以了
容易发现条件等价于
x<y且a[y]>=x且a[x]>=y x < y 且 a [ y ] >= x 且 a [ x ] >= y
让y单调递减地询问,那么就可以让合法的x放入,最后查询即可
这个可以用树状数组维护
一开始想错方向了
想到了这样一个式子
这样就只需要求两个斯特林数
直接同通项公式,O(m)来求就可以了
考虑到这题我不会,于是给出代码
其实CF的代码都是公布了。。如果想要,去CF拿就可以了
CODE:
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
const LL N=200005;
LL n,k;
LL w[N];
LL sum=0;
LL JC[N],inv[N];
LL pow (LL x,LL y)
{
if (y==1) return x;
LL lalal=pow(x,y>>1);
lalal=lalal*lalal%MOD;
if (y&1) lalal=lalal*x%MOD;
return lalal;
}
LL C (LL x,LL y)
{
if (x<y) return 0;
// printf("%I64d %I64d %I64d %I64d %I64d %I64d\n",x,y,JC[x],inv[y],inv[x-y],JC[x]*inv[y]%MOD*inv[x-y]%MOD);
return JC[x]*inv[y]%MOD*inv[x-y]%MOD;
}
LL s (LL x,LL y)
{
LL t=1,lalal=0;
for (int k=0;k<=y;k++)
{
lalal=lalal+t*C(y,k)%MOD*pow(y-k,x)%MOD;
lalal=lalal%MOD;
t*=(-1);
}
lalal=(lalal+MOD)%MOD;
lalal=lalal*inv[y]%MOD;
// printf("%I64d %I64d %I64d\n",x,y,lalal);
return lalal;
}
int main()
{
// freopen("a.in","r",stdin);
scanf("%I64d%I64d",&n,&k);
JC[0]=1;for (LL u=1;u<=200000;u++) JC[u]=JC[u-1]*u%MOD;
inv[200000]=pow(JC[200000],MOD-2);
for (LL u=200000-1;u>=1;u--) inv[u]=inv[u+1]*(u+1)%MOD;inv[0]=1;
for (LL u=1;u<=n;u++)
{
scanf("%I64d",&w[u]);
sum=sum+w[u];
sum%=MOD;
}
if (k==1)
{
printf("%I64d\n",sum*n%MOD);
return 0;
}
LL lalal=(s(n,k)+(n-1)*s(n-1,k)%MOD)%MOD;
printf("%I64d\n",sum*lalal%MOD);
return 0;
}