• poj2182 Lost Cows[BIT二分]


    blog题解鸽了许久了。。本来说好的切一题写一个题解的说


    一个$1 sim n$数列,已知每个数前面比他小的数个数,试确定该序列。


    相当的一道水题。可以发现数列最后一个数是首先可以确定下来的。然后把这个数扔掉,看数列倒数第二个数前面有多少更小的其实就是目前剩下的数中的排名。相当于有一颗$n$个点的$1 sim n$的平衡树,每次查一个排名,找出这个数,并删掉。但是并不想打平衡树。因为这题的操作只涉及简单的删除和查rank操作,可以考虑用BIT代替平衡树。具体是因为BIT本身就是具有树形二分结构的,画图应该可以感觉出来。$C[i]$表示值为i的数有几个(本题中最多$1$个,有些题还要离散化这个$i$),前缀和维护,查rank的时候不断查$C[x]$并二分下去,和平衡树就类似了。有点难讲,不过真的很好理解。

    没了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define dbg(x) cerr<<#x<<" = "<<x<<endl
     8 #define _dbg(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
     9 using namespace std;
    10 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
    11 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
    12 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    13 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    14 template<typename T>inline T read(T&x){
    15     x=0;char c;int f=0;while(!isdigit(c=getchar()))if(c=='-')f=1;
    16     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    17 }
    18 const int N=100000+7;
    19 int C[N],a[N];
    20 int n;
    21 #define lowbit(x) x&(-x)
    22 inline void Update_add(int x,int k){for(;x<=n;x+=lowbit(x))C[x]+=k;}
    23 inline int Query_sum(int x){int ret=0;for(;x;x-=lowbit(x))ret+=C[x];return ret;}
    24 inline int Query_kth(int x){
    25     int i=1<<__lg(n);
    26     while((lowbit(i))^1){
    27         if(x<=C[i])i-=((lowbit(i))>>1);
    28         else x-=C[i],i+=((lowbit(i))>>1);
    29         while(i>n)i-=((lowbit(i))>>1);
    30     }
    31     return C[i]^x?i+1:i;
    32 }
    33 
    34 int main(){//freopen(".in","r",stdin);freopen(".out","w",stdout);
    35     read(n);a[1]=1;
    36     for(register int i=2;i<=n;++i)read(a[i]),++a[i];
    37     for(register int i=1;i<=n;++i)C[i]=lowbit(i);
    38     for(register int i=n;i;--i){
    39         int x=Query_kth(a[i]);
    40         Update_add(x,-1),a[i]=x;
    41     }
    42     for(register int i=1;i<=n;++i)printf("%d
    ",a[i]);
    43     return 0;
    44 }
  • 相关阅读:
    Linux图形界面从登录列表中隐藏用户和开机自动登录
    VMware Workstation报错 : 另一个正在运行的VMware进程可能正在使用配置文件
    Vim命令总结
    Linux常用命令总结
    Oracle使用中的常规操作总结
    Oracle分页查询和SQL server分页查询总结
    Oracle学习总结
    Resharper2019 1.2破解教程
    C#实现RSA加密解密
    windows上git clone命令速度过慢问题的解决
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11409350.html
Copyright © 2020-2023  润新知