【HDU】5957 Query on a graph【分类讨论+bfs序线段树】
来源:互联网 发布:华美淘宝客卷皮7.0 编辑:程序博客网 时间:2024/06/06 14:26
题目链接:Query on a graph
水题
#include <bits/stdc++.h>using namespace std ;typedef long long LL ;typedef pair < int , int > pii ;typedef unsigned long long ULL ;#define clr( a , x ) memset ( a , x , sizeof a )#define root 1 , 1 , tot#define ls o << 1#define rs o << 1 | 1#define lson ls , l , m#define rson rs , m + 1 , rconst int MAXN = 100005 ;LL sum[MAXN << 2] ;LL addv[MAXN << 2] ;vector < int > G[MAXN] ;int pre[MAXN] , vis[MAXN] ;int Q[MAXN] , head , tail ;pii pos[MAXN][3] ;int isroot[MAXN] ;int a[MAXN] , cnt ;int tot ;int n , q ;int get_circle ( int u ) { vis[u] = 1 ; for ( int i = 0 ; i < G[u].size () ; ++ i ) { int v = G[u][i] ; if ( v == pre[u] ) continue ; pre[v] = u ; if ( vis[v] ) { cnt = 0 ; int x = u ; while ( x != v ) { a[++ cnt] = x ; isroot[x] = cnt ; x = pre[x] ; } a[++ cnt] = v ; isroot[v] = cnt ; return 1 ; } if ( get_circle ( v ) ) return 1 ; } return 0 ;}void bfs ( int s ) { head = tail = 0 ; Q[tail ++] = s ; pre[s] = 0 ; while ( head != tail ) { int u = Q[head ++] ; ++ tot ; pos[u][0] = pii ( tot , tot ) ; pos[u][1] = pos[u][2] = pii ( MAXN , -1 ) ; for ( int i = 0 ; i < G[u].size () ; ++ i ) { int v = G[u][i] ; if ( v == pre[u] || isroot[v] ) continue ; pre[v] = u ; Q[tail ++] = v ; } } while ( head ) { int u = Q[-- head] ; int f = pre[u] , g = pre[f] ; if ( f ) { pos[f][1].first = min ( pos[f][1].first , pos[u][0].first ) ; pos[f][1].second = max ( pos[f][1].second , pos[u][0].second ) ; if ( g ) { pos[g][2].first = min ( pos[g][2].first , pos[u][0].first ) ; pos[g][2].second = max ( pos[g][2].second , pos[u][0].second ) ; } } }}void build ( int o , int l , int r ) { addv[o] = 0 ; sum[o] = 0 ; if ( l == r ) return ; int m = l + r >> 1 ; build ( lson ) ; build ( rson ) ;}void up ( int o ) { sum[o] = sum[ls] + sum[rs] ;}void down ( int o , int l , int r ) { if ( addv[o] ) { int m = l + r >> 1 ; addv[ls] += addv[o] ; addv[rs] += addv[o] ; sum[ls] += addv[o] * ( m - l + 1 ) ; sum[rs] += addv[o] * ( r - m ) ; addv[o] = 0 ; }}void update ( int L , int R , int v , int o , int l , int r ) { if ( L <= l && r <= R ) { sum[o] += v * ( r - l + 1 ) ; addv[o] += v ; return ; } down ( o , l , r ) ; int m = l + r >> 1 ; if ( L <= m ) update ( L , R , v , lson ) ; if ( m < R ) update ( L , R , v , rson ) ; up ( o ) ;}LL query ( int L , int R , int o , int l , int r ) { if ( L <= l && r <= R ) return sum[o] ; down ( o , l , r ) ; int m = l + r >> 1 ; if ( R <= m ) return query ( L , R , lson ) ; if ( m < L ) return query ( L , R , rson ) ; return query ( L , R , lson ) + query ( L , R , rson ) ;}void Update ( int x , int k , int d ) { if ( k < 0 ) return ; for ( int i = 0 ; i <= k ; ++ i ) { int l = pos[x][i].first , r = pos[x][i].second ; if ( l > r ) continue ; //printf ( "%d %d %d %d %d %d\n" , x , k , i , l , r , tot ) ; update ( l , r , d , root ) ; }}LL Query ( int x , int k ) { if ( k < 0 ) return 0 ; LL res = 0 ; for ( int i = 0 ; i <= k ; ++ i ) { int l = pos[x][i].first , r = pos[x][i].second ; if ( l > r ) continue ; res += query ( l , r , root ) ; } return res ;}void solve () { scanf ( "%d" , &n ) ; for ( int i = 1 ; i <= n ; ++ i ) { G[i].clear () ; isroot[i] = 0 ; vis[i] = 0 ; } for ( int i = 1 ; i <= n ; ++ i ) { int u , v ; scanf ( "%d%d" , &u , &v ) ; G[u].push_back ( v ) ; G[v].push_back ( u ) ; } pre[1] = 0 ; get_circle ( 1 ) ; tot = 0 ; for ( int i = 1 ; i <= cnt ; ++ i ) { bfs ( a[i] ) ; } build ( root ) ; scanf ( "%d" , &q ) ; while ( q -- ) { char op[10] ; int u , k , d ; scanf ( "%s%d%d" , op , &u , &k ) ; int f = pre[u] , g = pre[f] , now = 1 ; if ( !f ) now = isroot[u] ; else if ( !g ) now = isroot[f] ; int L = now == 1 ? cnt : now - 1 ; int R = now == cnt ? 1 : now + 1 ; int L2 = L == 1 ? cnt : L - 1 ; int R2 = R == cnt ? 1 : R + 1 ; L = a[L] ; R = a[R] ; L2 = a[L2] ; R2 = a[R2] ; //printf ( "%d %d %d %d %d %d\n" , f , g , L , R , L2 , R2 ) ; if ( op[0] == 'M' ) { scanf ( "%d" , &d ) ; if ( f ) { Update ( u , k , d ) ; Update ( f , k - 1 , d ) ; if ( k == 2 ) Update ( u , 0 , -d ) ; if ( g ) Update ( g , k - 2 , d ) ; else { Update ( L , k - 2 , d ) ; Update ( R , k - 2 , d ) ; } } else { Update ( u , k , d ) ; Update ( L , k - 1 , d ) ; Update ( R , k - 1 , d ) ; if ( cnt >= 4 ) { Update ( R2 , k - 2 , d ) ; if ( L2 != R2 ) Update ( L2 , k - 2 , d ) ; } } } else { LL ans = 0 ; if ( f ) { ans += Query ( u , k ) ; ans += Query ( f , k - 1 ) ; if ( k == 2 ) ans -= Query ( u , 0 ) ; if ( g ) ans += Query ( g , k - 2 ) ; else { ans += Query ( L , k - 2 ) ; ans += Query ( R , k - 2 ) ; } } else { ans += Query ( u , k ) ; ans += Query ( L , k - 1 ) ; ans += Query ( R , k - 1 ) ; if ( cnt >= 4 ) { ans += Query ( R2 , k - 2 ) ; if ( L2 != R2 ) ans += Query ( L2 , k - 2 ) ; } } printf ( "%lld\n" , ans ) ; } }}int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) solve () ; return 0 ;}
0 0
- 【HDU】5957 Query on a graph【分类讨论+bfs序线段树】
- [bfs序 线段树] HDU5957. Query on a graph
- HDU-5957 Query on a graph(线段树+树剖)
- hdu 1252 Hike on a Graph(bfs)
- 【HDU】3804 Query on a tree dfs+线段树
- Hdu 3804 Query on a tree 树链剖分+线段树
- 【HDU】4677 Query on Graph 动态树
- HDU 4677 Query on Graph
- hdu 4677 Query on Graph
- bfs hdu 1252 Hike on a Graph--easy
- Query on a string【线段树】
- 计蒜客 Query on a string 线段树
- Query on a string 线段树
- HDU 3804Query on a tree 树链剖分 + 线段树离线操作 好题
- ZOJ 1103 Hike on a Graph(BFS)
- hdu1252 Hike on a Graph ----BFS
- SPOJ - QTREE 375 Query on a tree 树链剖分+线段树
- 【线段树】CSU 1414 Query on a Tree
- 多线程的常见操作
- Not Exists的使用方法
- 数据库基本概念
- NOIP2016 CQ_round 6游记
- C++中使用转换构造函数和运算符重载时需要注意的问题
- 【HDU】5957 Query on a graph【分类讨论+bfs序线段树】
- Java WebService 简单实例
- 交换算法
- Linux图形环境下pycharm的开发环境搭建方案分享
- druid数据库连接池
- 简单的队列操作但是在运行的时候就会有越界
- 从ActionBar,沉浸式 再到ToolBar
- 建筑业黑客马拉松 —— 一场致力于中国建筑业先锋软硬件技术的创新风暴
- 【HDU】-4506-小明系列故事——师兄帮帮忙(快速幂+思维)