• P3273 【[SCOI2011]棘手的操作】


    此题用可并堆勉强过,需加输入优化,但是这里有个问题就是set总是过不了一组数据,用multiset时间有点高,不懂这个问题,请懂此问题的给我留言。

    左偏树+并查集

    下面上代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <string>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <cstdlib>
      7 #include <utility>
      8 #include <map>
      9 #include <set>
     10 #include <queue>
     11 #include <vector>
     12 #include <iostream>
     13 #include <stack>
     14 using namespace std;
     15 #define INF 0x3f3f3f3f
     16 #define eps 1e-6
     17 #define CLR( a, v ) memset ( a, v, sizeof ( a ) )
     18 #define LL long long
     19 #define DBUG printf ( "here!!!\n" )
     20 #define rep( i, a, b ) for ( int i = ( a ); i < ( b ); i ++ )
     21 #define PB push_back
     22 #define ULL unsigned long long
     23 #define PI acos ( -1.0 )
     24 #define lson l, m, rt << 1
     25 #define rson m+1, r, rt << 1 | 1
     26 #define lowbit( x ) ( ( x )&( -x ) )
     27 #define CASE int Test; scanf ( "%d", &Test ); for ( int cas = 1; cas <= Test; cas ++ )
     28 #define ALL( x ) x.begin ( ), x.end ( )
     29 #define INS( x ) x, x.begin ( )
     30 typedef pair < int, int > Pii;
     31 typedef pair < double, double > Pdd;
     32 typedef set < int > Set;
     33 const int maxn = 300005;
     34 int read_int ( ) {
     35     int res = 0, f = 1;
     36     int ch = getchar ( );
     37     while ( ch < '0' || ch > '9' ) {
     38         if ( ch == -1 )
     39             return -1;
     40         if ( ch == '-' )
     41             f = -1;
     42         ch = getchar ( );
     43     }
     44     while ( ch >= '0' && ch <= '9' ) {
     45         res = res*10+( ch-'0' );
     46         ch = getchar ( );
     47     }
     48     return res*f;
     49 }
     50 int rt[maxn], ch[maxn][2], sum[maxn], S[maxn], c;
     51 int con[maxn], fa[maxn], a[maxn], dis[maxn];
     52 int find ( int x ) {
     53     return con[x] == x ? x : con[x] = find ( con[x] );
     54 }
     55 void PushDown ( int u ) {
     56     if ( sum[u] ) {
     57         if ( ch[u][0] ) {
     58             sum[ ch[u][0] ] += sum[u];
     59             a[ ch[u][0] ] += sum[u];
     60         }
     61         if ( ch[u][1] ) {
     62             sum[ ch[u][1] ] += sum[u];
     63             a[ ch[u][1] ] += sum[u];
     64         }
     65         sum[u] = 0;
     66     }
     67 }
     68 void PushAll ( int x ) {
     69     c = 0;
     70     while ( x ) {
     71         S[c ++] = x;
     72         x = fa[x];
     73     }
     74     while ( c > 0 )
     75         PushDown ( S[-- c] );
     76 }
     77 int Merge ( int u, int v ) {
     78     if ( u == 0 )
     79         return v;
     80     if ( v == 0 )
     81         return u;
     82     if ( a[u] < a[v] )
     83         swap ( u, v );
     84     PushDown ( u );
     85     ch[u][1] = Merge ( ch[u][1], v );
     86     fa[ ch[u][1] ] = u;
     87     if ( dis[ ch[u][0] ] < dis[ ch[u][1] ] )
     88         swap ( ch[u][0], ch[u][1] );
     89     dis[u] = dis[ ch[u][1] ]+1;
     90     return u;
     91 }
     92 void remove ( int u ) {
     93     PushAll ( u );
     94     int p = fa[u];
     95     int x = Merge ( ch[u][0], ch[u][1] );
     96     fa[x] = p;
     97     ch[p][ ch[p][1] == u ] = x;
     98     while ( p ) {
     99         if ( dis[ ch[p][0] ] < dis[ ch[p][1] ] )
    100             swap ( ch[p][0], ch[p][1] );
    101         if ( dis[ ch[p][1] ]+1 == dis[p] )
    102             break ;
    103         dis[p] = dis[ ch[p][1] ]+1;
    104         p = fa[p];
    105     }
    106 }
    107 multiset < int > vis;
    108 void solve ( ) {
    109     int n, Q, x, v, fx, fy, all = 0;
    110     char op[5];
    111     dis[0] = -1;
    112     n = read_int ( );
    113     vis.clear ( );
    114     for ( int i = 1; i <= n; i ++ ) {
    115         a[i] = read_int ( );
    116         rt[i] = con[i] = i;
    117         vis.insert ( a[i] );
    118     }
    119     Q = read_int ( );
    120     while ( Q -- ) {
    121         scanf ( "%s", op );
    122         if ( op[0] == 'U' ) {
    123             x = read_int ( ), v = read_int ( );
    124             fx = find ( x ), fy = find ( v );
    125             if ( fx == fy )
    126                 continue ;
    127             con[fx] = fy;
    128             vis.erase ( vis.find ( min ( a[ rt[fx] ], a[ rt[fy] ] ) ) );
    129             rt[fy] = Merge ( rt[fy], rt[fx] );
    130             fa[ rt[fy] ] = 0;
    131         } else if ( op[0] == 'A' ) {
    132             if ( op[1] == '1' ) {
    133                 x = read_int ( ), v = read_int ( );
    134                 fx = find ( x );
    135                 vis.erase ( vis.find ( a[ rt[fx] ] ) );
    136                 if ( x != rt[fx] )
    137                     remove ( x );
    138                 else {
    139                     PushDown ( x );
    140                     rt[fx] = Merge ( ch[x][0], ch[x][1] );
    141                     fa[ rt[fx] ] = 0;
    142                 }
    143                 sum[x] = fa[x] = ch[x][0] = ch[x][1] = 0;
    144                 a[x] += v;
    145                 rt[fx] = Merge ( rt[fx], x );
    146                 vis.insert ( a[ rt[fx] ] );
    147                 fa[ rt[fx] ] = 0;
    148             } else if ( op[1] == '2' ) {
    149                 x = read_int ( ), v = read_int ( );
    150                 fx = find ( x );
    151                 vis.erase ( vis.find ( a[ rt[fx] ] ) );
    152                 a[ rt[fx] ] += v;
    153                 vis.insert ( a[ rt[fx] ] );
    154                 sum[ rt[fx] ] += v;
    155             } else if ( op[1] == '3' ) {
    156                 v = read_int ( );
    157                 all += v;
    158             }
    159         } else if ( op[0] == 'F' ) {
    160             if ( op[1] == '1' ) {
    161                 x = read_int ( );
    162                 PushAll ( x );
    163                 printf ( "%d\n", a[x]+all );
    164             } else if ( op[1] == '2' ) {
    165                 x = read_int ( );
    166                 fx = find ( x );
    167                 printf ( "%d\n", a[ rt[fx] ]+all );
    168             } else if ( op[1] == '3' )
    169                 printf ( "%d\n", *( -- vis.find ( INF ) )+all );
    170         }
    171     }
    172 }
    173 int main ( ) {
    174     solve ( );
    175     return 0;
    176 }
    View Code
  • 相关阅读:
    HDU_2047——EOF字符串排序排列问题,递推
    HDU_2046——骨牌铺放问题,递推
    HDU_2045——RPG问题,递推
    HDU_2044——蜜蜂走蜂房,递推
    HDU_2043——判断密码是否安全
    HDU_2042——递归反推
    单例模式
    抽象工厂模式
    工厂方法模式
    C#调用C++DLL传递结构体数组的终极解决方案
  • 原文地址:https://www.cnblogs.com/Xchu/p/11482552.html
Copyright © 2020-2023  润新知