题目连接
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3032
完全照着大白抄的,没什么好说的。。
不过一个地方打错了,RE了好久%>_<%
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<queue> #include<map> #include<set> #include<cstdlib> using namespace std; #define inf 0x3f3f3f3f #define eps 1e-8 #define LL long long #define ULL unsigned long long #define MP make_pair const int mxc = 1000000 + 10; const int mxn = 200000 + 10; const int mxm = 600000 + 10; struct node { node *ch[10]; int r, v, s; node( int v ): v( v ) { ch[0] = ch[1] = NULL; r = rand(); s = 1; } bool operator < ( const node &b ) const { return r < b.r; } int cmp( int x ) const { if( v == x ) return -1; return x < v ? 0 : 1; } void mt() { s = 1; if( ch[0] ) s += ch[0] -> s; if( ch[1] ) s += ch[1] -> s; } }; void rt( node *&o, int d ) { node *k = o -> ch[d^1]; o -> ch[d^1] = k -> ch[d]; k -> ch[d] = o; o -> mt(); k -> mt(); o = k; } void insert( node *&o, int x ) { if( o == NULL ) o = new node( x ); else { int d = x < o -> v ? 0 : 1; insert( o -> ch[d], x ); if( o -> ch[d] -> r > o -> r ) { rt( o, d ^ 1 ); } } o -> mt(); } void remove( node *&o, int x ) { int d = o -> cmp( x ); if( d == -1 ) { node *u = o; if( o -> ch[0] && o -> ch[1] ) { int d2 = ( o -> ch[0] -> r > o -> ch[1] -> r ? 1 : 0 ); rt( o, d2 ); remove( o -> ch[d2], x ); } else { if( o -> ch[0] == NULL ) o = o -> ch[1]; else o = o -> ch[0]; delete u; } } else remove( o -> ch[d], x ); if( o ) o -> mt(); } struct Com { char type; int x, p; Com(){} Com( char type, int x, int p ): type( type ), x( x ), p( p ) {} }com[mxc]; int n, m, w[mxn], from[mxm], to[mxm], vis[mxm]; int fa[mxn]; int findset( int x ) { if( fa[x] != x ) fa[x] = findset( fa[x] ); return fa[x]; } node *root[mxn]; int kth( node *o, int k ) { if( o == NULL || k <= 0 || k > o -> s ) return 0; int s = ( o -> ch[1] == NULL ? 0 : o -> ch[1] -> s ); if( k == s + 1 ) return o -> v; if( k <= s ) return kth( o -> ch[1], k ); return kth( o -> ch[0], k - s - 1 ); } void merge( node *&i, node *&j ) { if( i -> ch[0] ) merge( i -> ch[0], j ); if( i -> ch[1] ) merge( i -> ch[1], j ); insert( j, i -> v ); delete i; i = NULL; } void removetree( node *& x ) { if( x -> ch[0] ) removetree( x -> ch[0] ); if( x -> ch[1] ) removetree( x -> ch[1] ); delete x; x = NULL; } void add_edge( int x ) { int u = findset( from[x] ), v = findset( to[x] ); if( u != v ) { if( root[u] -> s < root[v] -> s ) { fa[u] = v; merge( root[u], root[v] ); } else { fa[v] = u; merge( root[v], root[u] ); } } } int qc; LL qt; void query( int x, int k ) { qc ++; qt += kth( root[findset(x)], k ); } void update( int x, int v ) { int u = findset( x ); remove( root[u], w[x] ); insert( root[u], v ); w[x] = v; } int main() { int cas = 0; while( scanf( "%d%d", &n, &m ) == 2 && n ) { for( int i = 1; i <= n; ++i ) scanf( "%d", &w[i] ); for( int i = 1; i <= m; ++i ) scanf( "%d%d", &from[i], &to[i] ); memset( vis, 0, sizeof( vis ) ); int c = 0; while( 1 ) { char type; int x, p = 0, v = 0; scanf( " %c", &type ); if( type == 'E' ) break; scanf( "%d", &x ); if( type == 'D' ) vis[x] = 1; if( type == 'Q' ) scanf( "%d", &p ); if( type == 'C' ) { scanf( "%d", &v ); p = w[x]; w[x] = v; } Com tem( type, x, p ); com[c++] = tem; } for( int i = 1; i <= n; ++i ) { fa[i] = i; if( root[i] ) removetree( root[i] ); root[i] = new node( w[i] ); } for( int i = 1; i <= m; ++i ) if( !vis[i] ) add_edge( i ); qt = qc = 0; for( int i = c - 1; i >= 0; -- i ) { if( com[i].type == 'D' ) add_edge( com[i].x ); if( com[i].type == 'Q' ) query( com[i].x, com[i].p ); if( com[i].type == 'C' ) update( com[i].x, com[i].p ); } printf( "Case %d: %.6lf\n", ++cas, qt / ( double ) qc ); } return 0; }