• P3960 列队


    ${color{cyan}{>>Question}}$

    线段树并不支持动态的删除,常见的方法是提前预留位置,并维护区间内实际留存的个数($sz$)

    对于这道题,维护$n+1$棵线段树,前$n$棵对应$n$行,第$n+1$棵对应最后一列,动态开点,便可维护

    时间复杂度 $O(q*log (m+q))$

    空间复杂度 $O(q*log (m+q))$

    $sz$的维护采用的是标记永久化中的写法

    还有一个比较重要的地方是新开的点的$sz$的维护

    第一次打这种预留位置的题,很不熟悉

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 #define ll long long
     6 using namespace std; 
     7 
     8 template <typename T> void in(T &x) {
     9     x = 0; T f = 1; char ch = getchar();
    10     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    11     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
    12     x *= f;
    13 }
    14 
    15 template <typename T> void out(T x) {
    16     if(x < 0) x = -x , putchar('-');
    17     if(x > 9) out(x/10);
    18     putchar(x%10 + 48);
    19 }
    20 //-------------------------------------------------------------
    21 
    22 const int N = 3e5+7;
    23 
    24 int n,m,q,x,y,now,maxn;
    25 int end[N];
    26 
    27 struct node {
    28     int lc,rc,sz;ll val;
    29 }t[6000000];int cnt,rt[N];
    30 
    31 int get_sz(int l,int r) {
    32     if(now == n + 1) {
    33         if(r <= n) return r - l + 1;
    34         if(l <= n) return n - l + 1;
    35         return 0;
    36     }
    37     if(r <= m-1) return r - l + 1;
    38     if(l <= m-1) return (m-1)-l+1;
    39     return 0;
    40 }
    41 
    42 ll get_val(int j) {
    43     return (now == n+1) ? (1ll*j*m) : (1ll*(now-1)*m+j);
    44 }
    45 
    46 ll D(int &u,int l,int r,int k) {
    47     if(!u) {
    48         u = ++cnt; t[u].sz = get_sz(l,r);
    49         if(l == r) t[u].val = get_val(l);
    50     }
    51     --t[u].sz;
    52     if(l == r) return t[u].val;
    53     int mid = (l+r)>>1;
    54     int l_sz = (t[u].lc ? t[t[u].lc].sz : get_sz(l,mid));
    55     if(k <= l_sz) return D(t[u].lc,l,mid,k);
    56     else return D(t[u].rc,mid+1,r,k-l_sz);
    57 }
    58 
    59 void A(int &u,int l,int r,int pos,ll w) {
    60     if(!u) {
    61         u = ++cnt; 
    62         t[u].sz = get_sz(l,r);
    63     }
    64     ++t[u].sz;//标记永久化的写法 
    65     if(l == r) {
    66         t[u].val = w; return;
    67     }
    68     int mid = (l+r)>>1;
    69     if(pos <= mid) A(t[u].lc,l,mid,pos,w);
    70     else A(t[u].rc,mid+1,r,pos,w);
    71 }
    72 
    73 int main() {
    74     freopen("0.in","r",stdin);
    75     //freopen("my19.out","w",stdout);
    76     ll id; in(n); in(m); in(q);//debug ll -> int
    77     maxn = max(m,n)+q;//debug max(m,n) -> m!!!!!
    78     int ans = 0;
    79     while(q--) {
    80         in(x); in(y);
    81         cout << ++ans << ':' << ' ';
    82         if(y == m) {
    83             now = n+1; id = D(rt[n+1],1,maxn,x); out(id),putchar('
    ');
    84             A(rt[n+1],1,maxn,n+(++end[n+1]),id);
    85         }
    86         else {
    87             now = x; id = D(rt[x],1,maxn,y); out(id),putchar('
    ');
    88             now = n+1; A(rt[n+1],1,maxn,n+(++end[n+1]),id);
    89             now = n+1; id = D(rt[n+1],1,maxn,x);
    90             now = x; A(rt[x],1,maxn,m-1+(++end[x]),id);
    91         }
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    BZOJ1212 [HNOI2004]L语言
    BZOJ1202 [HNOI2005]狡猾的商人
    BZOJ1295 [SCOI2009]最长距离
    BZOJ1266 [AHOI2006]上学路线
    BZOJ1297 [SCOI2009]迷路
    php declare (ticks = N)
    使用 trait 时报PHP Parse error: syntax error, unexpected 'use' (T_USE) 这个错误
    yii2 and short_open_tag
    Nginx负载均衡配置实例详解
    Could not fetch https://api.github.com/repos/RobinHerbots/jquery
  • 原文地址:https://www.cnblogs.com/mzg1805/p/11412672.html
Copyright © 2020-2023  润新知