• uva 1513(线段树)


    题目链接:1513 - Movie collection

    题意:有一堆电影,按1-n顺序排,有m次操作,每次询问第ai个电影之前有多少个电影,然后将其抽出放在堆顶。

    分析:线段树应用。

    因为每次查询后要将电影移至堆顶,所以我们可以将线段树的区间开到maxn+n,[1,maxn]先置0,在[maxn+1,maxn+n]建树将值置为1,线段树每一段区间的值代表该区间的和。

    每次查询后要将该位置的值更新为0,由于要将电影移至堆顶,用一个指针cnt初始化为maxn,记录当前电影可以移到的位置,

    由于位置是变化的,所以要用一个数组indice[]来记录每个电影当前所在的位置,每次移动位置只要indice[x]=cnt--即可。

    查询的时候只要查询[1,indice[x]-1]区间和就行了。

    AC代码如下:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define lson l,m,rt<<1
     6 #define rson m+1,r,rt<<1|1
     7 const int maxn=100000+5;
     8 int add[maxn<<3];
     9 int tree[maxn<<3];
    10 int indice[maxn];
    11 int n,num;
    12 void pushup(int rt)
    13 {
    14     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    15 }
    16 void update(int p,int x,int l,int r,int rt)
    17 {
    18     if(l==r)
    19     {
    20         tree[rt]=x;
    21         return ;
    22     }
    23     int m=(l+r)>>1;
    24     if(p<=m)
    25         update(p,x,lson);
    26     else
    27         update(p,x,rson);
    28     pushup(rt);
    29 }
    30 int query(int L,int R,int l,int r,int rt)
    31 {
    32     if(L<=l&&r<=R)
    33         return tree[rt];
    34     int m=(l+r)>>1;
    35     int ret=0;
    36     if(L<=m)
    37         ret+=query(L,R,lson);
    38     if(R>m)
    39         ret+=query(L,R,rson);
    40     return ret;
    41 }
    42 void build(int l,int r,int rt)
    43 {
    44     if(l==r)
    45     {
    46         num++;
    47         if(num>maxn)
    48             tree[rt]=1;
    49         return ;
    50     }
    51     int m=(l+r)>>1;
    52     build(lson);
    53     build(rson);
    54     pushup(rt);
    55 }
    56 int main()
    57 {
    58     int t,m,i,x,index;
    59     scanf("%d",&t);
    60     while(t--)
    61     {
    62         memset(tree,0,sizeof(tree));
    63         scanf("%d%d",&n,&m);
    64         num=0;
    65         build(1,maxn+n,1);
    66         for(int i=1;i<=n;i++)
    67             indice[i]=maxn+i;
    68         int cnt=maxn;
    69         for(i=0;i<m;i++)
    70         {
    71             scanf("%d",&x);
    72             printf("%d",query(1,indice[x]-1,1,maxn+n,1));
    73             if(i!=m-1) printf(" ");
    74             update(indice[x],0,1,maxn+n,1);
    75             indice[x]=cnt--;
    76             update(indice[x],1,1,maxn+n,1);
    77         }
    78         printf("
    ");
    79     }
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    secureCRT常用设置
    SecureCRT恢复默认字体
    hdu 1515 dfs
    hdu 2216 bfs
    hdu 1973 bfs+素数判断
    hdu 1429 bfs+状压
    poj 3463 次短路
    hdu 2962 最短路+二分
    hdu 2112 最短路
    hdu 3397 线段树
  • 原文地址:https://www.cnblogs.com/frog112111/p/3309170.html
Copyright © 2020-2023  润新知