分治专题
来源:互联网 发布:java身份证号判断性别 编辑:程序博客网 时间:2024/06/07 00:25
涉及题目: poj2299 //http://poj.org/problem?id=2299
poj1741 //http://poj.org/problem?id=1741
数列分治
复杂度O(nlogn)
#include <cstdio>#include <cstring>#include <iostream>#include <vector>using namespace std ;typedef long long ll ;vector <int> A ;ll merge_count( vector<int> & a){ int n = a.size() ; if( n <= 1 ) return 0 ; ll cnt = 0 ; vector<int> b(a.begin() , a.begin() + n/2); vector<int> c(a.begin() + n/2 , a.end()); cnt += merge_count(b) ; cnt += merge_count(c) ; // b c have been sorted int ai = 0 , bi = 0 , ci = 0 ; while( ai < n ){ if( bi < b.size() && (ci == c.size() || b[bi] <= c[ci])){ a[ai ++] = b[bi ++]; }else{ cnt += n/2 - bi ; a[ai ++] = c[ci ++ ]; } } return cnt ;}void solve(vector<int> & A){ ll ans = merge_count(A) ; printf("%lld\n" , ans) ;}vector<int> save ;int main(){ int n ,a ; while( ~ scanf("%d",&n) && n ){ save.clear() ; for(int i = 0 ; i < n ; i ++ ){ scanf("%d" , &a); save.push_back( a ) ; } solve(save) ; } return 0 ;}
树形分治
对于这道题目
O(n log2 n) ;
#include <cstdio>#include <cstring>#include <iostream>#include <vector>#include <algorithm>using namespace std ;typedef long long ll ;const int MAX_N = 10000+5 ;const int INT_MAX = 100000000+7 ;struct edge{ int to , length ;};int N , K ;vector<edge> G[MAX_N] ;bool centroid[MAX_N] ;int subtree_size[MAX_N] ;int ans ;int compute_subtree_size( int v , int p ){ int c = 1 ; for( int i = 0 ; i < G[v].size() ; i ++ ){ int w = G[v][i].to ; if(w == p || centroid[w]) continue ; c += compute_subtree_size( w , v ) ; } subtree_size[v] = c ; return c ;}pair<int , int > search_centroid(int v , int p , int t){ pair<int , int > res = make_pair(INT_MAX , -1 ) ; int s = 1 , m = 0 ; for( int i = 0 ; i < G[v].size() ; i ++ ){ int w = G[v][i].to ; if( w == p || centroid[w]) continue ; res = min(res , search_centroid(w , v , t)) ; m = max(m , subtree_size[w] ) ; s += subtree_size[w] ; } m = max( m , t - s ); res = min( res , make_pair(m , v )) ; return res ;}void enumerate_paths( int v , int p , int d , vector<int> &ds ){ ds.push_back(d) ; for( int i = 0 ; i < G[v].size() ; i ++ ){ int w = G[v][i].to ; if( w == p || centroid[w] ) continue ; enumerate_paths(w , v , d + G[v][i].length , ds) ; }}int count_pairs(vector<int> &ds){ int res = 0 ; sort( ds.begin() , ds.end()) ; int j = ds.size() ; for(int i = 0 ; i < ds.size() ; i ++ ){ while( j > 0 && ds[i] + ds[j-1] > K ) -- j ; res += j - ( j > i ? 1 : 0 ) ; } return res / 2 ;}void solve_subproblem(int v ){ compute_subtree_size(v , -1) ; int s = search_centroid( v , -1 , subtree_size[v]).second ; centroid[s] = true ; for( int i = 0 ; i < G[s].size() ; i ++) { if(centroid[ G[s][i].to]) continue ; solve_subproblem( G[s][i].to ); } vector<int> ds ; ds.push_back(0) ; for( int i = 0 ; i < G[s].size() ; i ++ ){ if( centroid[G[s][i].to]) continue ; vector<int> tds ; enumerate_paths(G[s][i].to , s , G[s][i].length , tds) ; ans -= count_pairs(tds) ; ds.insert(ds.end() , tds.begin() , tds.end()) ; } ans += count_pairs(ds) ; centroid[s] = false ;}void solve(){ ans = 0 ; solve_subproblem(0) ; printf("%d\n" , ans );}int main(){ int n ; while( ~ scanf("%d %d",&N , &K) ){ if( !N && !K) break ; for( int i = 0 ; i <= N ; i ++ ) G[i].clear() ; memset( centroid , 0 , sizeof( centroid )) , memset(subtree_size , 0 , sizeof(subtree_size)) ; int a , b , c; edge temp ; for(int i = 0 ; i < N - 1 ; i ++ ){ scanf("%d %d %d" , &a , &b , &c); a -- , b -- ; temp.length = c , temp.to = b ; G[a].push_back(temp) ; temp.to = a ; G[b].push_back(temp) ; } solve() ; } return 0 ;}
阅读全文
1 0
- 分治专题
- 分治法专题
- cdq分治专题
- 关于分治的入门专题
- vjudge 贪心+分治专题-N题
- 点分治专题——bzoj 1468 &bzoj 2152 题解
- CQD(陈丹琦)分治 & 整体二分——专题小结
- 专题:迷之消维——CDQ分治
- 分治专题(二分查找与快速幂)
- 分治
- 分治
- 分治
- 分治
- 分治
- 分治
- 分治
- 分治
- 分治
- Linux虚拟化与容器化
- c++ map的用法
- Android探索之HttpURLConnection网络请求
- 调整数组顺序使基数位于偶数前面java实现
- Halcon相机标定
- 分治专题
- 大数据建模分析--举哥
- VOFM例程开发实现定价增强
- 关于通过H5页面唤Native户端的介绍
- java排序算法:冒泡排序、选择排序、插入排序
- Tomcat安装
- ibatis中实体类和数据库字段名不一致,该怎么映射?
- win7 python-ssh
- 检查数据库、坏表修复