此题用可并堆勉强过,需加输入优化,但是这里有个问题就是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 }