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
原文地址:https://www.cnblogs.com/Xchu/p/11482552.html