Codeforces Round #285 (Div. 2) D. Misha and Permutations Summation 康托展开 + 线段树
生活随笔
收集整理的這篇文章主要介紹了
Codeforces Round #285 (Div. 2) D. Misha and Permutations Summation 康托展开 + 线段树
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
文章目錄
- 題意:
- 思路:
題意:
思路:
首先肯定不能模n!n!n!,所以考慮先將a,ba,ba,b做一個逆康托展開,得到a′,b′a',b'a′,b′數組,以及a′+b′=suma'+b'=suma′+b′=sum數組,讓后我們可以通過這個數組每個位置乘上權(n?i)!(n-i)!(n?i)!得到他的字典序排名,也就是需要模n!n!n!的數,考慮從低位向前遞推,也就是sum[i?1]+=sum[i]mod(n?i+1),sum[i]=sum[i]mod(n?i+1)sum[i-1]+=sum[i]\bmod (n-i+1),sum[i]=sum[i]\bmod (n-i+1)sum[i?1]+=sum[i]mod(n?i+1),sum[i]=sum[i]mod(n?i+1)即可,最后再將其逆回來即可。
// Problem: D. Misha and Permutations Summation // Contest: Codeforces - Codeforces Round #285 (Div. 2) // URL: https://codeforces.com/problemset/problem/501/D // Memory Limit: 256 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") //#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #include<random> #include<cassert> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid ((tr[u].l+tr[u].r)>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6;int n; int a[N],b[N]; LL fun[N]; struct Node {int l,r;int cnt; }tr[N<<2];void pushup(int u) {tr[u].cnt=tr[L].cnt+tr[R].cnt; }void build(int u,int l,int r) {tr[u]={l,r};if(l==r) {tr[u].cnt=1;return;}build(L,l,Mid); build(R,Mid+1,r);pushup(u); }void change(int u,int pos) {if(tr[u].l==tr[u].r) {tr[u].cnt=0;return;}if(pos<=Mid) change(L,pos);else change(R,pos);pushup(u); }int query1(int u,int l,int r) {if(tr[u].l>=l&&tr[u].r<=r) return tr[u].cnt;int ans=0;if(l<=Mid) ans+=query1(L,l,r);if(r>Mid) ans+=query1(R,l,r);return ans; }int query2(int u,int cnt) {if(tr[u].l==tr[u].r) return tr[u].l;if(tr[L].cnt>cnt) return query2(L,cnt);else return query2(R,cnt-tr[L].cnt); }int main() { // ios::sync_with_stdio(false); // cin.tie(0); scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]++;for(int i=1;i<=n;i++) scanf("%d",&b[i]),b[i]++;build(1,1,n);for(int i=1;i<=n;i++) {int cnt=query1(1,1,a[i]-1);change(1,a[i]);a[i]=cnt;}build(1,1,n);for(int i=1;i<=n;i++) {int cnt=query1(1,1,b[i]-1);change(1,b[i]);b[i]=cnt;}for(int i=n;i>=1;i--) {a[i]+=b[i];int t=a[i]/(n-i+1);a[i-1]+=t;a[i]%=(n-i+1);}build(1,1,n);for(int i=1;i<=n;i++) {int pos=query2(1,a[i]);change(1,pos);printf("%d%c",pos-1,i==n? '\n':' ');} return 0; } /**/總結
以上是生活随笔為你收集整理的Codeforces Round #285 (Div. 2) D. Misha and Permutations Summation 康托展开 + 线段树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最新热门手机排行榜:小米14 Pro登顶
- 下一篇: XREAL双11实现7倍增长 AR眼镜销