結果
問題 |
No.271 next_permutation (2)
|
ユーザー |
|
提出日時 | 2025-05-26 10:40:13 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,118 ms / 2,000 ms |
コード長 | 2,252 bytes |
コンパイル時間 | 1,531 ms |
コンパイル使用メモリ | 163,856 KB |
実行使用メモリ | 9,672 KB |
最終ジャッジ日時 | 2025-05-26 10:40:21 |
合計ジャッジ時間 | 7,731 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 21 |
ソースコード
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=400010,mod=1000000007; const LL inf=2000000000000000000ll; LL mem[N],jiec[N],K; int n,arr[N],ans; void next_per() { for(int i=n-1;i>=1;--i) { if(arr[i]<arr[i+1]) { reverse(arr+i+1,arr+n+1); for(int j=i+1;j<=n;++j) { if(arr[j]>arr[i]) { swap(arr[j],arr[i]); return ; } } return ; } } reverse(arr+1,arr+n+1); } int inc(int x) { return x>=mod ? x-mod : x; } struct BIT_tree { int Val[N]; inline int lowbit(int x) { return x & (-x); } void change(int x,int v) { while(x<N) { Val[x]+=v; x+=lowbit(x); } } int query(int x) { int ans=0; while(x) { ans+=Val[x]; x-=lowbit(x); } return ans; } int query(int L,int R) { return query(R)-query(L-1); } }B; int calc(int lth) { int L=n-lth+1; int ans=0; for(int i=1;i<=L-1;++i) { int V=B.query(arr[i]+1,n); ans=inc(ans+V); B.change(arr[i],1); } for(int i=L;i<=n;++i) { int V=B.query(arr[i]+1,n); ans=inc(ans+V); } ans=(LL)ans*(jiec[lth]%mod)%mod; ans=inc(ans+mem[lth]); for(int i=1;i<=L-1;++i)//clear 操作 { B.change(arr[i],-1); } return ans; } int main() { int maxi=0; jiec[0]=1; for(int i=1;;++i) { __int128 P=(__int128)jiec[i-1]*i; if(P>=inf) { jiec[i]=inf; maxi=i; break; } jiec[i]=P; } mem[2]=1; for(int i=3;i<=maxi;++i) { mem[i]=(LL)(mem[i-1]+((__int128)jiec[i-1]*(i-1)/2)%mod)*i%mod; } // for(int i=1;i<=maxi;++i) // { // cout<<i<<' '<<jiec[i]<<' '<<mem[i]<<'\n'; // } cin>>n>>K; for(int i=1;i<=n;++i) cin>>arr[i]; while(K) { int maxlth=0; for(int i=1;i<=maxi;++i) { if(K>=jiec[i]) maxlth=i; else break; } for(int i=n-1;i>=0;--i) { if(i==0) { maxlth=min(maxlth,n); break; } if(arr[i]>arr[i+1]) { maxlth=min(maxlth,n-i); break; } } // cerr<<maxlth<<'\n'; if(K>=jiec[maxlth]&&maxlth==n) { LL P=(K/jiec[maxlth])%mod; // cerr<<"P:"<<P<<'\n'; ans=inc(ans+(LL)P*mem[maxlth]%mod); K%=jiec[maxlth]; continue; } int V=calc(maxlth); ans=inc(ans+V); reverse(arr+n-maxlth+1,arr+n+1); next_per(); K-=jiec[maxlth]; } cout<<ans; return 0; } /* 1 1000000000000000000 1 2 1 */