zoukankan      html  css  js  c++  java
  • 【poj2182】【poj2828】树状数组/线段树经典模型:逆序查找-空位插入法

    poj2182题意:有一个1~n的排列,现在给定每个人前面有多少个人的编号比他大,求这个排列是什么。n<=8000

    poj2182题解:

    逆序做,可以确定二分最后一个是什么,然后删除这个数。树状数组维护每个数前面有多少个数比它小。

    poj2828题意:有 n 个人排队买票,他们依次到来,第 i 个人来的时候会站在第pos[i]个人后面,并且他的编号为v[i]。
    求最后的队列中每个位置人的编号。

    poj2828题解:

    来一个例子模拟:

    0 (3) //编号为3的人插入第0个人后面

    1 (2)

    1 (1)

    0 (4)

    假设已经知道了最后的答案:

    (4)(3)(1)(2)

    类比上一题,我们可以逆序做,然后对于当前的最后一个人,它前面一定有且只有pos[i]个空位,就转化为上一题了。一但确定了一个人,那个空位就被填了,在树状数组上更新一下。

     1 //poj2182
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<iostream>
     7 #include<algorithm>
     8 using namespace std;
     9 
    10 const int N=100010;
    11 int n,a[N],c[N],ans[N];
    12 
    13 void add(int x,int d)
    14 {
    15     for(int i=x;i<=n;i+=(i&(-i))) c[i]+=d;
    16 }
    17 int getsum(int x)
    18 {
    19     int ans=0;
    20     for(int i=x;i>=1;i-=(i&(-i))) ans+=c[i];
    21     return ans;
    22 }
    23 
    24 int main()
    25 {
    26     freopen("a.in","r",stdin);
    27     scanf("%d",&n);
    28     memset(c,0,sizeof(c));
    29     for(int i=1;i<=n;i++) add(i,1);
    30     a[0]=0;
    31     for(int i=2;i<=n;i++)
    32     {
    33         scanf("%d",&a[i]);
    34     }
    35     int l,r,mid;
    36     for(int i=n;i>=1;i--)
    37     {
    38         l=1,r=n;
    39         while(l<r)
    40         {
    41             mid=(l+r+1)/2;
    42             if(getsum(mid-1)>a[i]) r=mid-1; 
    43             else l=mid;
    44         }
    45         ans[i]=l;
    46         add(l,-1);
    47     }
    48     for(int i=1;i<=n;i++) printf("%d
    ",ans[i]);
    49     return 0;
    50 }
    poj2182
     1 //poj2828
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<iostream>
     7 #include<algorithm>
     8 using namespace std;
     9 
    10 const int N=200100;
    11 int n,a[N],val[N],c[N],ans[N];
    12 
    13 void add(int x,int d)
    14 {
    15     for(int i=x;i<=n;i+=(i&(-i))) c[i]+=d;
    16 }
    17 int getsum(int x)
    18 {
    19     int ans=0;
    20     for(int i=x;i>=1;i-=(i&(-i))) ans+=c[i];
    21     return ans;
    22 }
    23 
    24 int main()
    25 {
    26     freopen("a.in","r",stdin);
    27     while(scanf("%d",&n)!=EOF)
    28     {
    29         memset(c,0,sizeof(c));
    30         for(int i=1;i<=n;i++) add(i,1);
    31         for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&val[i]);
    32         int l,r,mid;
    33         for(int i=n;i>=1;i--)
    34         {
    35             l=1,r=n;
    36             while(l<r)
    37             {
    38                 mid=(l+r+1)/2;
    39                 if(getsum(mid-1)>a[i]) r=mid-1; 
    40                 else l=mid;
    41             }
    42             ans[l]=i;
    43             add(l,-1);
    44         }
    45         for(int i=1;i<=n;i++) printf("%d ",val[ans[i]]);printf("
    ");
    46     }
    47     
    48     return 0;
    49 }
    poj2828
  • 相关阅读:
    最近用到mysql和mybatis结合常用的知识点坐下整理
    采用rest接口对接而非webservice
    Linux 下Nginx 的安装及负载均衡的简单配置
    用websocket实现后台推送消息
    maven项目添加websocket
    Java通过几种经典的算法来实现数组排序
    关于 Java 数组的 12 个最佳方法
    Ajax详解及其案例分析之如何获得Ajax对象,使用Ajax对象发送GET和POST请求,校验用户名,POST和GET请求时的乱码处理,实现级联的下拉列表
    Python
    【作业报告】作业5 四则运算 测试与封装 5.1
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/6025906.html
Copyright © 2011-2022 走看看