ICode9

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

ARC143 题解

2022-06-27 20:31:08  阅读:205  来源: 互联网

标签:dbinom read 题解 ll long times ARC143 Operation


太弱小了,仅 A 的一题还是在后辈 ly 的指导下才成功的。\(\sout{我被单调队列了}\)

\(\sout{tnnd,刚才忘记保存了重新写一遍。}\)

T1 Three Integers

题意

有三个数 \(A,B,C\) , 有两种操作

Operation 1:选择个数并 \(-1\)
Operation 2:选择个数并 \(-1\)

使得这三个数全变成 \(0\) ,如果不行请输出 \(-1\) 。

做时思路

因为肯定 Operation 2 肯定更优一点,所以对于大数据肯定有很多 Operation 2 。然后猜大数据是小数据的 Operation 2 的变化过来的。

但是错了

题解

首先说一个推论:

每次操作肯定操作到最大值。

为什么?思考一下什么时候不会操作到最大值。就是对于 Operation 1 操作最小的两个数。显然不优。

ly 的推断办法:

假如说 \(A ,B, C\) 已经排好顺序了。根据 \(\sout{相对论}\) 只有一种操作,就是选一个数 \(+1\) 这样的话肯定不可能给 \(C\) 加。

代码

#include <bits/stdc++.h>
#define debug puts("I love Newhanser forever!!!!!");
#define pb push_back
using namespace std;
template <typename T>inline void read(T& t){
    t=0; register char ch=getchar(); register int fflag=1;
    while(!('0'<=ch&&ch<='9')){if(ch=='-') fflag=-1;ch=getchar();}
    while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;
}
template <typename T,typename... Args> inline void read(T& t, Args&... args){read(t);read(args...);}
const int MAXN=800;
long long A,B,C,ans;
long long min(long long A,long long B){return (A<B)?A:B;}
int main(){
    read(A,B,C);
    long long a[]={A,B,C};
    sort(a,a+3);
    if(a[0]+a[1]<a[2]) puts("-1");
    else cout<<a[2]<<endl;
    return 0;
}
//Welcome back,Chtholly.

T2 Counting Grids

赛时猜到正解,代码写错了,误以为是错解。

题意

就是一个 \(n\times n\) 的网格,你要把 \(1-n\times n\) 的数字填进去。然后不存在任意一个数是行里的最小值也是列里的最大值。

赛时思路 & 正解

考试的时候想到从容斥定理的角度考虑,因为如果正着填的话会遇到很多限制条件,如果反着填的话限制条件比较多。

既然反着做,那么把行里的最小值和列里的最大值叫做坏的元素。

这里给出一个结论:

只可能有一个坏的元素

为什么,非常的简单,但是昨天太拉了,没有想着去证明。

jVIRln.png

明显有两个方格矛盾了。

那怎么推柿子呢?

明显发现,每个格子都是等价的,所以这里假设第一个格子就是坏的元素。这里对答案的乘法贡献是 \(n^2\)

假如说第一个格子填的是 \(x\) ,那么这样的话行里面可以填的数字数量就是 \(\dbinom{n^2-x}{n-1}\) ,列里可以填的数字数量就是 \(\dbinom{x-1}{n-1}\) 。然后行里面可以交换位置,列里面可以交换位置。先把到目前柿子列出来 :

\[n^2 \times ((n-1)!)^2 \times \sum\limits _{i=1}^{n^2} \dbinom{n^2-i}{n-1} \dbinom{i-1}{n-1} \]

不要让战斗停下来,我们还少了一点东西,就是除了我们填完的这一行一列我们还有一些东西可以交换,就是剩下的。他们对答案的贡献是 \((n^2-2*n+1)!\)

答案就是

\[((n-1)^2)! \times (n!)^2 \times \sum\limits _{i=1}^{n^2} \dbinom{n^2-i}{n-1} \dbinom{i-1}{n-1} \]

\(n^2\) 和 \((n-1)^2\) 合起来了。

因为 \(\dbinom{n}{k} = \frac{n!}{(n-k)!k!}\) 组合数还是比较大的, exgcd 又比较的 ex ,所以这里用欧拉定理求逆元啦。

因为预处理了逆元等等东西,所以总的时间复杂度是 \(\mathbb{O}(n^2)\) 。

代码

#include <bits/stdc++.h>
#define debug puts("I love Newhanser forever!!!!!");
#define pb push_back
using namespace std;
template <typename T>inline void read(T& t){
    t=0; register char ch=getchar(); register int fflag=1;
    while(!('0'<=ch&&ch<='9')){if(ch=='-') fflag=-1;ch=getchar();}
    while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;
}
template <typename T,typename... Args> inline void read(T& t, Args&... args){read(t);read(args...);}
const int MAXN=250005;
const long long mod=998244353;
typedef long long ll;
ll n,ans=1,A[MAXN],B[MAXN],inv[MAXN],p=1,c=1;
ll fac[MAXN];
ll quick_pow(ll x,ll y){
    ll res=1;
    while(y){
        if(y&1) res=(x*res)%mod;
        x=(x*x)%mod;
        y>>=1;
    }
    return res;
}
ll C(ll n,ll k){
    if(k==0) return 1;
    if(k>n) return 0;
    return fac[n]*inv[n-k]%mod*inv[k]%mod;
}
int main(){
    read(n);
    fac[0]=inv[0]=1;
    for(int i=1;i<=n*n;++i){
        fac[i]=fac[i-1]*i%mod;
        inv[i]=quick_pow(fac[i],mod-2)%mod;
    }
    p=fac[(n-1)*(n-1)]%mod*fac[n]%mod*fac[n]%mod;
    ans=fac[n*n];
    for(int i=n;i<=n*n-n+1;++i) ans=(ans-p*C(n*n-i,n-1)%mod*C(i-1,n-1)%mod+2*mod)%mod;
    cout<<ans<<endl;
    return 0;
}
//Welcome back,Chtholly.

标签:dbinom,read,题解,ll,long,times,ARC143,Operation
来源: https://www.cnblogs.com/Mercury-City/p/16417431.html

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

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

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

ICode9版权所有