您的位置:首页 > Web前端

[USACO11FEB]牛线Cow Line【康托展开与逆康托展开 模板题】

2019-08-06 20:29 381 查看

P3014 [USACO11FEB]牛线Cow Line

  就是简单的模板题了,这里分别用了BIT来进行优化,用了线段树来求第K小,用了树状数组去维护有多少“>”它本身的数。二进制优化时间。

  但是别忘了初始化树状数组,不然要出事的!

[code]#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 21;
int trie[maxN], N, Q;
inline void add(int i)
{
while(i <= N)
{
trie[i]++;
i += lowbit(i);
}
}
inline ll sum(int x)
{
ll ans = 0;
while(x)
{
ans += trie[x];
x -= lowbit(x);
}
return ans;
}
ll jc[maxN];
ll Cantor(int len, int *a)
{
ll tmp, ans = 0;
for(int i=len-1; i>=0; i--)
{
tmp = sum(a[i]);
ans += tmp * jc[len - i - 1];
add(a[i]);
}
return ans + 1;
}
int tree[maxN<<2];
void buildTree(int rt, int l, int r)
{
if(l == r) { tree[rt] = 1; return; }
int mid = HalF;
buildTree(Lson); buildTree(Rson);
tree[rt] = tree[lsn] + tree[rsn];
}
int query(int rt, int l, int r, int kth)
{
tree[rt]--;
if(l == r) return l;
int mid = HalF;
if(kth <= tree[lsn]) return query(Lson, kth);
else return query(Rson, kth - tree[lsn]);
}
inline void re_Cantor(ll kth)
{
buildTree(1, 1, N);
for(int i=N; i>=1; i--)
{
ll tmp = kth / jc[i-1] - (kth % jc[i-1] == 0 ? 1 : 0);
printf("%d%c", query(1, 1, N, (int)tmp + 1), i == 1 ? '\n' : ' ');
if(kth > tmp * jc[i-1]) kth -= tmp * jc[i-1];
}
}
ll qes;
int s[maxN];
char op[3];
int main()
{
jc[0] = jc[1] = 1;
for(ll i=2; i<=20; i++) jc[i] = jc[i-1] * i;
scanf("%d%d", &N, &Q);
while(Q--)
{
scanf("%s", op);
if(op[0] == 'Q')
{
for(int i=0; i<N; i++) scanf("%d", &s[i]);
memset(trie, 0, sizeof(trie));
printf("%lld\n", Cantor(N, s));
}
else
{
scanf("%lld", &qes);
re_Cantor(qes);
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: