• CF 501D,树状数组+数学分析


    题目大意:给你两个长度相同的排列,把他们的ord(就是是到底是所有排列当中字典序第几)求和取模,再逆转求出对应的排列。

    解:对于一个ord,很直观的从计算上可以看出一个表示方法 A(n-1)! + B(n-2)! + ..... + Z0!,然后在这种表示法下合并,然后进位,最后再最高位把系数模一下n就行。所以我们需要选取数据结构来维护这一个过程。求取右侧有多少个数可以由树状数组来维护,而选取剩下的第k个空位也可以由树状数组来维护,以前做这个问题是套了一个二分,但是wty告诉我并不用,然后yy了一下,仿照树状数组求区间最大的方式写了一个选取第k个空位,意识流证了了一下这个过程是logn的,这个过程封装在了take里面。

      1 #include <cstdio>
      2 #include <string>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <cstring>
      7 #include <complex>
      8 #include <set>
      9 #include <vector>
     10 #include <map>
     11 #include <queue>
     12 #include <deque>
     13 #include <ctime>
     14 
     15 using namespace std;
     16 
     17 const double EPS = 1e-8;
     18 
     19 #define ABS(x) ((x)<0?(-(x)):(x))
     20 #define SQR(x) ((x)*(x))
     21 #define MIN(a,b) ((a)<(b)?(a):(b))
     22 #define MAX(a,b) ((a)>(b)?(a):(b))
     23 
     24 #define LSON(x) ((x)<<1)
     25 #define RSON(x) (((x)<<1)+1)
     26 #define LOWBIT(x) ((x)&(-(x)))
     27 #define MAXS 1111
     28 #define MAXN 222222
     29 #define VOIDPOINT 0
     30 #define LL long long
     31 #define OO 214748364
     32 
     33 struct TreeArreay{
     34     int tree[MAXN], n;
     35     int f[MAXN];
     36     void clear(int nn = MAXN - 20) {
     37         n = nn;
     38         memset(tree, 0, sizeof(tree[0])*(n+10));
     39         memset(f, 0, sizeof(f[0])*(n+10));
     40     }
     41     void add(int x, int num = 1) {
     42         f[x] += num;
     43         while (x <= n) {
     44             tree[x] += num;
     45             x += LOWBIT(x);
     46         }
     47     }
     48     int get(int x) {
     49         int res = 0;
     50         while (x > 0) {
     51             res += tree[x];
     52             x -= LOWBIT(x);
     53         }
     54         return res;
     55     }
     56     int take(int x, int k) { //树状数组二分前面第k个1的位置尝试,类似区间查询
     57         int res = 0, sum = 0;
     58         sum = get(x);
     59         while (sum) {
     60             if (sum == k && f[x]) {
     61                 res = x; break;
     62             }
     63             if (sum - tree[x] >= k) {
     64                 sum -= tree[x];
     65                 x -= LOWBIT(x);
     66             } else {
     67                 if (f[x]) sum -= f[x];
     68                 --x;
     69             }
     70         }
     71         add(res, -1);
     72         return res;
     73     }
     74 } Tree;
     75 
     76 int a[MAXN], b[MAXN], n, ka[MAXN], kb[MAXN];
     77 
     78 void make(int *a, int *ka) {
     79     for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
     80     Tree.clear(n);
     81     for (int i = n-1; i >= 0; --i) {
     82         ka[i] = Tree.get(a[i]);
     83         Tree.add(a[i]+1); // 0 
     84     }
     85 }
     86 
     87 int main() {
     88 //    freopen("test.txt", "r", stdin);
     89     scanf("%d", &n);
     90     make(a, ka);
     91     make(b, kb);
     92     for (int i = n-2, j = 2; i >= 0; --i, ++j) {
     93         ka[i] += kb[i];
     94         if (i && ka[i] >= j) {
     95             ka[i-1] += ka[i] / j;
     96             ka[i] %= j;
     97         }
     98         else ka[i] %= j;
     99     }
    100     Tree.clear(n);
    101     for (int i = 1; i <= n; ++i) Tree.add(i);
    102     for (int i = 0; i < n; ++i) {
    103         a[i] = Tree.take(n, ka[i]+1);
    104     }
    105     for (int i = 0; i < n; ++i) {
    106         printf("%d%c", a[i]-1, i+1 == n ? '
    ' : ' ');
    107     }
    108 
    109     return 0;
    110 }
    CF 501D
  • 相关阅读:
    Hbase架构与原理(转)
    Hbase的表结构中rowkey的设计---避免热点问题
    mysql之my.cnf详解
    MongoDB CPU利用率很高,怎么破(转)
    数据库设计(2/9):域,约束和默认值(Domains, Constraints and Defaults)
    数据库设计(1/9):数据元(Data Elements)
    SQL Server安全(11/11):审核(Auditing)
    VARCHAR列上的索引
    SQL Server 2016里的sys.dm_exec_input_buffer
    在SQL Server里禁用聚集索引——真的好么?
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/5676875.html
Copyright © 2020-2023  润新知