zoukankan      html  css  js  c++  java
  • bzoj 1171 并查集优化顺序枚举 | 线段树套单调队列

    详见vfleaking在discuss里的题解.

    收获: 当我们要顺序枚举一个序列,并且跳过某些元素,那么我们可以用并查集将要跳过的元素合并到一起,这样当一长串元素需要跳过时,可以O(1)跳过.

    暴力:

     1 /**************************************************************
     2     Problem: 1171
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:1908 ms
     7     Memory:6732 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #define min(a,b) ((a)<(b)?(a):(b))
    13 #define max(a,b) ((a)>(b)?(a):(b))
    14 #define oo 0x3f3f3f3f
    15 #define N 250010
    16  
    17 int n, L;
    18 int x[N], y[N], d[N];
    19 int dp[N], fa[N], qu[N], bg, ed;
    20  
    21 int find( int i ) {
    22     return i==fa[i] ? i : fa[i]=find(fa[i]);
    23 }
    24 int main() {
    25     scanf( "%d%d", &n, &L );
    26     d[1] = 0;
    27     x[1] = 0;
    28     y[1] = 2000000000;
    29     for( int i=2; i<=n; i++ )
    30         scanf( "%d%d%d", x+i, y+i, d+i );
    31     for( int i=1; i<=n; i++ )
    32         fa[i] = i;
    33     memset( dp, 0x3f, sizeof(dp) );
    34  
    35     dp[1] = 0;
    36     qu[bg=ed=1] = 1;
    37     while( bg<=ed ) {
    38         int i=qu[bg++];
    39         for( int j=find(i)+1; j<=n && d[j]-d[i]<=L; j=find(j)+1 ) {
    40             if( dp[j]!=oo ) continue;
    41             int xx = max( x[i], x[j] );
    42             int yy = min( y[i], y[j] );
    43             if( xx<=yy ) {
    44                 dp[j] = dp[i]+1;
    45                 qu[++ed] = j;
    46                 if( dp[j-1]!=oo ) fa[j-1]=j;
    47                 if( dp[j+1]!=oo ) fa[j]=j+1;
    48             }
    49         }
    50     }
    51     for( int i=2; i<=n; i++ )
    52         printf( "%d
    ", dp[i]==oo ? -1 : dp[i] );
    53 }
    View Code

    线段树套单调队列:

     1 #include <cstdio>
     2 #include <list>
     3 #include <algorithm>
     4 #define N 250010
     5 #define oo 0x3f3f3f3f
     6 using namespace std;
     7 
     8 struct Pair {
     9     int d, v;
    10     Pair( int d, int v ):d(d),v(v){}
    11 };
    12 struct Queue {
    13     list<Pair> q;
    14     void push( const Pair &p ) {
    15         while( !q.empty() && q.back().v >= p.v ) q.pop_back();
    16         q.push_back( p );
    17     }
    18     int pop( int d ) {
    19         while( !q.empty() && q.front().d<d ) q.pop_front();
    20         return q.empty() ? oo : q.front().v;
    21     }
    22 };
    23 struct Node {
    24     Queue qa, qb;
    25     int lf, rg;
    26     Node *ls, *rs;
    27     void modify( int L, int R, const Pair &p ) {
    28         qb.push(p);
    29         if( L<=lf && rg<=R ) {
    30             qa.push(p);
    31             return;
    32         }
    33         int mid=(lf+rg)>>1;
    34         if( L<=mid ) ls->modify(L,R,p);
    35         if( R>mid ) rs->modify(L,R,p);
    36     }
    37     int query( int L, int R, int d ) {
    38         if( L<=lf && rg<=R ) return qb.pop(d);
    39         int rt = qa.pop(d);
    40         int mid=(lf+rg)>>1;
    41         if( L<=mid ) {
    42             int t = ls->query(L,R,d);
    43             rt = min( rt, t );
    44         }
    45         if( R>mid ) {
    46             int t = rs->query(L,R,d);
    47             rt = min( rt, t );
    48         }
    49         return rt;
    50     }
    51 }pool[N*2*3], *tail=pool, *root;
    52 
    53 int n, L;
    54 int x[N], y[N], d[N];
    55 int disc[N*2], dtot;
    56 
    57 Node *build( int lf, int rg ) {
    58     Node *nd = ++tail;
    59     nd->lf=lf, nd->rg=rg;
    60     if( lf==rg ) {
    61         return nd;
    62     } else {
    63         int mid=(lf+rg)>>1;
    64         nd->ls = build( lf, mid );
    65         nd->rs = build( mid+1, rg );
    66         return nd;
    67     }
    68 }
    69 int main() {
    70     scanf( "%d%d", &n, &L );
    71     x[1] = 0;
    72     y[1] = 2000000000;
    73     disc[++dtot] = x[1];
    74     disc[++dtot] = y[1];
    75     d[1] = 0;
    76     for( int i=2; i<=n; i++ ) {
    77         scanf( "%d%d%d", x+i, y+i, d+i );
    78         disc[++dtot] = x[i];
    79         disc[++dtot] = y[i];
    80     }
    81     sort( disc+1, disc+1+dtot );
    82     dtot = unique( disc+1, disc+1+dtot ) - disc - 1;
    83     for( int i=1; i<=n; i++ ) {
    84         x[i] = lower_bound( disc+1, disc+1+dtot, x[i] ) - disc;
    85         y[i] = lower_bound( disc+1, disc+1+dtot, y[i] ) - disc;
    86     }
    87     root = build( 1, dtot );
    88     root->modify( x[1], y[1], Pair(0,0) );
    89     for( int i=2; i<=n; i++ ) {
    90         int ans = root->query( x[i], y[i], d[i]-L );
    91         if( ans==oo ) {
    92             printf( "-1
    " );
    93         } else {
    94             ans++;
    95             printf( "%d
    ", ans );
    96             root->modify( x[i], y[i], Pair(d[i],ans) );
    97         }
    98     }
    99 }
    View Code
  • 相关阅读:
    Python学习笔记(十一)
    Python学习笔记(十)
    Python学习笔记(九)
    Fatal error in launcher:Unable to create process using '"'
    通过xrdp服务实现windows远程桌面连接树莓派
    Python学习笔记(七)
    Python 杂集
    Python入门小练习
    Python标准库
    [Chrome](CSS) 解决Chrome font-size 小于 12px 无效
  • 原文地址:https://www.cnblogs.com/idy002/p/4573846.html
Copyright © 2011-2022 走看看