zoukankan      html  css  js  c++  java
  • SYSU-5, POJ 2131, 树状数组+二分

    题目大意:给出n个人,顺序对位置进行请求,如果第i个人请求的位置上有人,则让这个人顺延,如果顺延的位置继续有人,递归进行,问最后所有人的位置。

    解:这题貌似可以用平衡树+并查集搞定,但是我队友强烈安利树状数组的做法。赛场上没出,赛后结合discuz想了一下,作一下处理。

    首先如果是一个请求第a[i]个有空位置的问题,那么这个问题显然可以用树状数组维护前缀和即可。所以我们现在考虑将原问题转化成这个问题。

    考虑终态,把没有人的位置去掉,剩下的n个座位排在一起,显然转化成上面模型的形式

    第i个询问时,如果我们记b[i] = 前i-1个询问里1~a[i]-1上有多少座位被请求,那么显然倒过来处理时,b[i]+1个位置即为所求位置(因为前面的人不会和后面的人抢位置,后面的人更优先确定,所以他的位置只取决于前面有多少空的,而他占掉座位后,如果前面的人请求了原意义上的同一位置,那么就在转化后的位置顺延即可,其实就是我们所提希望的转化模型,n个椅子,每次请求第b[i]个空椅子)

    但是平衡树的做法真的很快(毕竟省一个二分的log),10s的时限我写了9.8s = =b,如果写完计算几何还有力气就琢磨一下平衡树的写法吧!

      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 MAXN 311111
     28 #define LL long long
     29 #define OO 214748364
     30 
     31 int a[MAXN], b[MAXN], f[MAXN], fa[MAXN];
     32 int n, m;
     33 
     34 struct TreeArray{
     35     int tree[MAXN], n;
     36     void clear(int lim = MAXN-10) {
     37         memset(tree, 0, sizeof(tree[0])*(lim+10));
     38         n = lim;
     39     }
     40     void add(int x, int num) {
     41         while (x <= n) {
     42             tree[x] += num;
     43             x += LOWBIT(x);
     44         }
     45     }
     46     int get(int x) {
     47         int res = 0;
     48         while (x) {
     49             res += tree[x];
     50             x -= LOWBIT(x);
     51         }
     52         return res;
     53     }
     54 } treeArray;
     55 
     56 int get(int x) {
     57 //    return x == fa[x] ? x : fa[x] = get(fa[x]);
     58     int t = x; while (t != fa[t]) t = fa[t];
     59     for (int i = x, j; i != t; i = j) {
     60         j = fa[x]; fa[x] = t;
     61     }
     62     return t;
     63 }
     64 
     65 int main() {
     66     freopen("test.txt", "r", stdin);
     67     scanf("%d%d", &n, &m); 
     68     treeArray.clear(n+m);
     69     for (int i = 1; i <= n+m; ++i) fa[i] = i;
     70     for (int i = 1; i <= n; ++i) {
     71         scanf("%d", a+i); 
     72         int t = get(a[i]); ++f[t];
     73         b[i] = treeArray.get(a[i]-1);
     74         treeArray.add(t, 1);
     75         fa[t] = t + 1; 
     76     }
     77 
     78     treeArray.clear(n+m);
     79     for (int i = 1; i <= n+m; ++i) {
     80         if (f[i] == 0) continue;
     81         treeArray.add(i, 1);
     82     }
     83 
     84     memset(a, 0, sizeof(a));
     85     for (int i = n; i; --i) {
     86         int l = 1, r = n+m, mid, t;
     87         while (l <= r) {
     88             mid = (l+r)>>1;
     89             if ((t = treeArray.get(mid)) == b[i]+1 && f[mid] == 1) {
     90                 treeArray.add(mid, -1); f[mid] = 0;
     91                 a[mid] = i; break;
     92             } else if (t < b[i]+1) {
     93                 l = mid + 1;
     94             } else {
     95                 r = mid - 1;
     96             }
     97         }
     98     }
     99     for (int i = MAXN-1; i; --i) if (a[i]) {
    100         printf("%d
    ", i);
    101         for (int j = 1; j <= i; ++j) printf("%d%c", a[j], j == i ? '
    ' : ' ');
    102         break;
    103     }
    104     
    105     return 0;
    106 }
    POJ 2131
  • 相关阅读:
    如何下载网络图片资源
    经典排序之快速排序(含红黑树)
    经典排序之归并排序
    node微信公众号开发---自动回复
    koa2的文件上传
    async await的用法
    Generator yield语法和 co模块
    CentOS 7 下安装 Nginx
    windows下nginx的安装及使用方法入门
    linux下nodejs安装以及如何更新到最新的版本
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/5641864.html
Copyright © 2011-2022 走看看