题解:P14321 「ALFR Round 11」D Adjacent Lifting, Fewest Rounds
fish_love_cat · · 题解
诶诶,这好像是第一次场切紫诶(?
首先操作一免费,于是两个数字在经过若干次操作一后不同当且仅当奇偶性不同。
于是就变成了只考虑奇偶性的问题。
因此操作二等价于相邻位反转。
我们可以通过操作二将
给的是排列,而
而奇数个数无法全部消灭成另一个数,所以转化的方向性得到了保证。
接下来考虑计算贡献。
我们假设待消灭数字有
如果不考虑这
考虑一个
然后你会发现有几种方案使得固定的某个
如果每个
然后最后还有
这样就解决了单个
假设现在我们知道了
根据全排列的定义,显然将每一个排列中
然后交换以后
那么也就是说每一个
所以我们只需要求出一个的答案再乘上
千万不要忘记移到相邻位置后消灭还需要一步哇 qwq
于是做完了。
#include<bits/stdc++.h>
#define int long long
#define N 10000000
int mod;
using namespace std;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
int A[N+5],inv[N+5];
void solve(){
int n;
cin>>n;
int x=n/2;
if(x&1)x++;
cout<<(A[x]*(n-x)%mod*(x/2)%mod*A[n]%mod*inv[x+1]%mod+A[n]*(x/2)%mod)%mod<<'\n';
}
signed main(){
int t;
cin>>t>>mod;
A[0]=1;
for(int i=1;i<=N;i++)
A[i]=A[i-1]*i%mod;
inv[N]=qpow(A[N],mod-2);
for(int i=N;i;i--)
inv[i-1]=inv[i]*i%mod;
while(t--)solve();
return 0;
}
//「大家,对不起。」
// 正因为周遭没有任何人,她才能坦率地说出口。
//「我最喜欢你们了。」
// 也才能将无法告诉他们本人的话语抛在原地,继续迈步前进。
// 朝向最后。
// 朝向终结。
// 只是一味向前。
upd:补充了关于贡献相同的说明。