1 条题解
-
0
自动搬运
来自洛谷,原作者为

FFTotoro
龙猫搬运于
2025-08-24 22:47:12,当前版本为作者最后更新于2023-05-02 08:52:32,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
本题需要使用分类讨论。
这道题我们需要分 种情况讨论:
-
当重排前存在 满足 :
重排后要使得答案最小,则必须把满足 的元素放在排列的第一项,让后面的数都没有贡献,所以第一问的答案是 ;
把 固定在开头后,后面 个元素可以任意排列,第二问的方案数共有 种。
-
当重排前不存在 满足 :
重排后要使得答案最小,则必须把 的一项或 的一项放在排列的第一项;
不妨设把 放在第一项, 必然会比它前头的数大,只有排列第一项产生 的贡献和 产生的至少为 的贡献,第一问答案是 ;
如果我们把 放在第一项,那么考虑 怎么放才能产生正好为 的贡献:只要不把大于 的数放在 的前面即可(因为如果我们这么做,那么会再产生若干贡献),方案数即为 。对称地,考虑把 放在第一项的情况,总方案数即为 。
除法可以用乘法逆元实现。
放代码:
#include<bits/stdc++.h> #define int long long using namespace std; typedef pair<int,int> pii; const int mod=998244353; int f(int n){ int s=1; for(int i=2;i<=n;i++) (s*=i)%=mod; return s; } int qpow(int a,int b){ int r=1; while(b){ if(b&1)r=r%mod*a%mod; a=a%mod*a%mod; b>>=1; } return r; } int inv(int x){return qpow(x,mod-2);} // 快速幂求逆元 main(){ ios::sync_with_stdio(false); int n,x,y; cin>>n; vector<pii> a(n); for(auto &i:a)cin>>i.first; for(auto &i:a)cin>>i.second; for(auto [p,q]:a){ if(p==n)x=q; if(q==n)y=p; } // 找到 q[i] 和 p[j] if(x==n)cout<<"2 "<<f(n-1)<<endl; // 第一种情况 else cout<<"3 "<<f(n-1)*((inv(n-x)+inv(n-y))%mod)%mod<<endl; // 第二种情况 return 0; } -
- 1
信息
- ID
- 7881
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者