• POJ 2828.Buy Tickets-完全版线段树(单点更新、逆序遍历查询)


    POJ2828.Buy Tickets

    这个题是插队问题,每次有人插队的时候,其后的所有数据都要进行更新,如果我们反着推,就可以把所有的数据都安排好并且不用再对已插入的数据进行更新,因为逆序处理的话所有的位置都是确定的,第i个人插进来,这个人前面一定有i个空位。逆序遍历一遍查询更新线段树就可以。

    这个题简直要写哭了,本来是个基础题,但是我自己的线段树模板的左儿子lson是l,m,右儿子rson是m+1,r,程序直接跑崩了,右儿子改成m,r就可以过,并不是很懂为什么。要了学长的代码,学长写的是我模板那样的,但是我稍微改一下,将update和query合成一个就出问题了,很烦,改代码改了两天,还是不知道为什么,写的我好难过,想哭。难受。

    先贴一下rson是m,r的,再贴一下rson是m+1,r的

    代码1:

     1 //E
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<cstdlib>
     8 #include<queue>
     9 #include<stack>
    10 using namespace std;
    11 typedef long long ll;
    12 const int inf=0x3f3f3f3f;
    13 const double eps=1e-5;
    14 const int maxn=5*1e5+10;
    15 #define lson l,m,rt<<1
    16 #define rson m,r,rt<<1|1
    17 struct node{
    18     int pos,val;
    19 }a[maxn];
    20 
    21 int tree[maxn<<2],ans[maxn];
    22 
    23 void build(int l,int r,int rt){
    24     tree[rt]=r-l;
    25     if(tree[rt]==1)
    26         return ;
    27 
    28     int m=(l+r)>>1;
    29     build(lson);
    30     build(rson);
    31 }
    32 
    33 void update(int pos,int val,int l,int r,int rt){
    34     --tree[rt];
    35     if(r-l==1){
    36         ans[l]=val;
    37         return ;
    38     }
    39     int m=(l+r)>>1;
    40     if(pos<tree[rt<<1]) update(pos,val,lson);
    41     else update(pos-tree[rt<<1],val,rson);
    42 }
    43 
    44 int main(){
    45     int n;
    46     while(~scanf("%d",&n)){
    47         for(int i=0;i<n;i++)
    48             scanf("%d%d",&a[i].pos,&a[i].val);
    49         build(0,n,1);
    50         for(int i=n-1;i>=0;i--)
    51             update(a[i].pos,a[i].val,0,n,1);
    52         for(int i=0;i<n;i++){
    53             if(i==0)printf("%d",ans[i]);
    54             else printf(" %d",ans[i]);
    55         }
    56         cout<<endl;
    57     }
    58     return 0;
    59 }

    代码2:

     1 //自己手贱改一改试试
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<string>
     7 #include<algorithm>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<stack>
    12 #include<sstream>
    13 using namespace std;
    14 #define lson l,m,rt<<1
    15 #define rson m+1,r,rt<<1|1
    16 typedef long long ll;
    17 const int maxn=2*1e5+10;
    18 const int inf=0x3f3f3f3f;
    19 const int mod=998244353;
    20 const double eps=1e-5;
    21 typedef long long ll;
    22 using namespace std;
    23 struct node{
    24     int pos,val;
    25 }a[maxn];
    26 int ans[maxn],vis[maxn];
    27 int tree[maxn<<2];
    28 int p,v;
    29 void PushUp(int rt){
    30     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    31 }
    32 void update(int l,int r,int rt)
    33 {
    34     int m=l+(r-l)/2;
    35     if(l==r)tree[rt]+=v;
    36     else
    37     {
    38         if(p<=m)update(lson);
    39         else update(rson);
    40         PushUp(rt);
    41     }
    42 }
    43 int query(int pos,int l,int r,int rt)
    44 {
    45     int m=l+(r-l)/2;
    46     if(tree[rt]==pos&&!vis[r])
    47         return r;
    48     if(tree[rt<<1]>=pos)
    49         return query(pos,lson);
    50     else
    51         return query(pos-tree[rt<<1],rson);
    52 }
    53 int main()
    54 {
    55     int n;
    56     while(~scanf("%d",&n))
    57     {
    58         memset(tree,0,sizeof(tree));
    59         memset(vis,0,sizeof(vis));
    60         for(int i=0;i<n;i++)
    61         {
    62             v=1;p=i;
    63             update(0,n-1,1);
    64         }
    65         for(int i=0;i<n;i++)
    66         {
    67             scanf("%d%d",&a[i].pos,&a[i].val);
    68         }
    69 
    70         for(int i=n-1;i>=0;i--)
    71         {
    72             int ret=query(a[i].pos+1,0,n-1,1);
    73             ans[ret]=a[i].val;
    74             vis[ret]=1;
    75             v=-1;p=ret;
    76             update(0,n-1,1);
    77         }
    78         for(int i=0;i<n;i++)
    79             printf("%s%d",i==0?"":" ",ans[i]);
    80         printf("
    ");
    81     }
    82     return 0;
    83 }

    这5道线段树的题就先这样吧。

    真的是难过,可这就是生活。

  • 相关阅读:
    plsql excel导入报错:未发现数据源名称并且未指定默认驱动程序
    exception java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    Android DiskLruCache 源代码解析 硬盘缓存的绝佳方案
    uestc 360(区间合并)
    UI_UITabBarController
    【C++ Primer】用于大型程序的工具
    Java 从基础到进阶学习之路---类编写以及文档凝视.
    Android 项目的代码混淆,Android proguard 使用说明
    android:Activity四种启动模式简单介绍
    已有数据库(单机)部署Database Vault
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9729097.html
Copyright © 2020-2023  润新知