图论当中:
1、Dijistra+Heap 求最短路
2、Floyd 求最短路
3、SPFA 求最短路
4、Prim 求最小生成树
5、Kruskal 求最小生成树
6、Tarjan 求强连通分量
7、Tarjan 求双连通分量
8、Tarjan 求桥
9、Tarjan 求割点
10、Kosaraju 求强连通分量
11、Dinic 求最大流
12、SPFA 求费用流
树论当中:
1、Tarjan 求最近公共祖先
2、倍增法 求最近公共祖先
3、Splay 伸展树
4、Treap 随机平衡树
5、树状数组
6、线段树
// 题目来源: NOI 2010 // 题目大意: 超级钢琴( 详见原题 ) // 解决方法: 区间分离 + ST算法 + 堆 // 代码时间: 2013 4 6 #include <cstdio> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define N 500002 using namespace std; int n, k, L, R, t, cnt, ans; int c[2*N], l[2*N], r[2*N], p[2*N], b[2*N], v[2*N], heap[2*N], f[N][20]; void up ( int ); void down ( int ); void push ( int, int, int ); int main( ) { freopen( "piano.in", "r", stdin ); freopen( "piano.out", "w", stdout ); scanf( "%d%d%d%d", &n, &k, &L, &R ); for( int i = 1; i <= n; i++ ) { scanf( "%d", &c[i] ); c[i] += c[i-1]; } for( int i = 1; i <= n; i++ ) f[i][0] = i; for( int j = 1; j < 20; j++ ) for( int i = 0; i <= n; i++ ) { if( i + ( 1 << j ) - 1 > n ) break; int temp = i + ( 1 << j-1 ); f[i][j] = ( c[ f[i][j-1] ] < c[ f[temp][j-1] ] )? f[i][j-1]: f[temp][j-1]; } for( int i = 1; i <= n; i++ ) push( max( i - R, 0 ), i - L, i ); for( int i = 1; i < k; i++ ) { int num = heap[1]; ans += v[num]; swap( heap[1], heap[cnt] ); cnt--; down( 1 ); push( l[num], b[num]-1, p[num] ); push( b[num]+1, r[num], p[num] ); } printf( "%d", ans + v[ heap[1] ] ); return 0; } void up( int i ) { int D = i >> 1, data = heap[i]; while( D && v[data] > v[ heap[D] ] ) { heap[i] = heap[D]; i = D; D = i >> 1; } heap[i] = data; } void down( int i ) { int S = i << 1, data = heap[i]; while( S <= cnt ) { if( S < cnt && v[ heap[S+1] ] > v[ heap[S] ] ) S++; if( v[ heap[S] ] < v[ data ] ) break; i = S; S = i << 1; } heap[i] = data; } void push( int L, int R, int P ) { l[++t] = max( L, 0 ); r[t] = R; p[t] = P; if( r[t] < 0 || l[t] > r[t] ) return void( --t ); int lg = int( log( r[t] - l[t] + 1 ) / log( 2 ) ), temp = r[t] - ( 1 << lg ) + 1; b[t] = ( c[ f[ l[t] ][lg] ] < c[ f[temp][lg] ] )? f[ l[t] ][lg]: f[temp][lg]; v[t] = c[ p[t] ] - c[ b[t] ]; heap[++cnt] = t; up( cnt ); }