CF 293 E Close Vertices (树的分治+树状数组)
来源:互联网 发布:阿里云os应用中心 编辑:程序博客网 时间:2024/06/06 02:58
分类: ACM_杂物2013-08-09 20:35 486人阅读 评论(6) 收藏 举报
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目:给出一棵树,问有多少条路径权值和不大于w,长度不大于l。
http://codeforces.com/contest/293/problem/E
有男人八题很相似,但是多了一个限制。
同样 还是点分治,考虑二元组(到根的路径权值和,到根的路径长度)。
按第一维度排序之后,可以用two points查询权值小不大于w的,然后 用树状数组维护路径长度。
也就是第一个条件用two points,第二个条件用树状数组维护。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <vector>
- #define lson step << 1
- #define rson step << 1 | 1
- #define pb(a) push_back(a)
- #define mp(a,b) make_pair(a , b)
- #define lowbit(x) (x & (-x))
- #pragma comment(linker, "/STACK:1024000000,1024000000")
- using namespace std;
- typedef long long LL;
- const int N = 100005;
- struct Edge {
- int v , w , next;
- }e[N << 1];
- int n , l , w , tot , start[N];
- int del[N] = {0} , size[N];
- LL ans = 0LL;
- void _add (int u , int v , int w) {
- e[tot].v = v ; e[tot].next = start[u];
- e[tot].w = w;
- start[u] = tot ++;
- }
- void add (int u , int v , int w) {
- _add (u , v , w);
- _add (v , u , w);
- }
- void calsize (int u , int pre) {
- size[u] = 1;
- for (int i = start[u] ; i != -1 ; i = e[i].next) {
- int v = e[i].v;
- if (v == pre || del[v]) continue;
- calsize (v , u);
- size[u] += size[v];
- }
- }
- int totalsize , maxsize , rootidx;
- void dfs (int u , int pre) {
- int mx = totalsize - size[u];
- for (int i = start[u] ; i != -1 ; i = e[i].next) {
- int v = e[i].v;
- if (v == pre || del[v]) continue;
- mx = max (mx , size[v]);
- dfs (v , u);
- }
- if (mx < maxsize) maxsize = mx , rootidx = u;
- }
- int search (int r) {
- calsize (r , -1);
- totalsize = size[r];
- maxsize = 1 << 30;
- dfs (r , -1);
- return rootidx;
- }
- vector<pair<int,int> > sub[N] , all;
- int idx , dist[N] , cnt[N];
- void gao (int u , int pre) {
- all.pb(mp(dist[u] , cnt[u]));
- sub[idx].pb(mp(dist[u] , cnt[u]));
- for (int i = start[u] ; i != -1 ; i = e[i].next) {
- int v = e[i].v , w = e[i].w;
- if (v == pre || del[v]) continue;
- dist[v] = dist[u] + w;
- cnt[v] = cnt[u] + 1;
- gao (v , u);
- }
- }
- int s[N] , up;
- void add (int x , int val) {
- for (int i = x ; i <= up ; i += lowbit (i)) {
- s[i] += val;
- }
- }
- int ask (int x) {
- int ret = 0;
- for (int i = x ; i > 0 ; i -= lowbit (i)) {
- ret += s[i];
- }
- return ret;
- }
- LL fuck (vector<pair<int , int> > &v) {
- LL ret = 0;
- up = 0;
- for (int i = 0 ; i < v.size() ; i ++)
- up = max (up , v[i].second);
- for (int i = 1 ; i <= up ; i ++)
- s[i] = 0;
- for (int i = 0 ; i < v.size() ; i ++)
- add (v[i].second , 1);
- for (int i = 0 , j = v.size() - 1 ; i < v.size() ; i ++) {
- while (j >= i && v[i].first + v[j].first > w) {
- add (v[j].second , -1);
- j --;
- }
- if (j < i) break;
- ret += ask (min(up , (l - v[i].second)));
- add (v[i].second , -1);
- }
- return ret;
- }
- void solve (int root) {
- root = search (root);
- del[root] = 1;
- if (totalsize == 1) return ;
- idx = 0 ;all.clear();
- for (int i = start[root] ; i != -1 ; i = e[i].next) {
- int v = e[i].v , w = e[i].w;
- if (del[v]) continue;
- sub[idx].clear();
- dist[v] = w ; cnt[v] = 1;
- gao (v , -1);
- sort (sub[idx].begin() , sub[idx].end());
- idx ++;
- }
- sort (all.begin() , all.end());
- ans += fuck (all);
- for (int i = 0 ; i < idx ; i ++) {
- for (int j = 0 ; j < sub[i].size() ; j ++) {
- if (sub[i][j].first <= w && sub[i][j].second <= l) {
- ans ++;
- }
- }
- ans -= fuck (sub[i]);
- }
- for (int i = start[root] ; i != -1 ; i = e[i].next) {
- int v = e[i].v;
- if (del[v]) continue;
- solve (v);
- }
- }
- int main () {
- // freopen ("input.txt" , "r" , stdin);
- // freopen ("output.txt" , "w" , stdout);
- tot = 0;memset (start , -1 , sizeof(start));
- scanf ("%d %d %d" , &n , &l , &w);
- for (int i = 1 ; i < n ; i ++) {
- int p , d;
- scanf ("%d %d" , &p , &d);
- add (i + 1 , p , d);
- }
- solve (1);
- printf ("%I64d\n" , ans);
- return 0;
- }
0 1
- CF 293 E Close Vertices (树的分治+树状数组)
- CF 293 E Close Vertices (树的分治+树状数组)
- 【codeforces】293E. Close Vertices 点分治+树状数组
- CodeForces 293E Close Vertices(点分治+Two Point法+树状数组)
- codeforces293E Close Vertices -- 点分治+树状数组
- 【线段树】【树状数组】【CF 121E】幸运数列
- CF 121E Lucky Array 【树状数组】
- poj3109 Inner Vertices(树状数组)
- poj3109 Inner Vertices 扫描线+树状数组
- poj 3109 Inner Vertices(树状数组)
- POJ 3109 Inner Vertices 树状数组
- CF - 61E - Enemy is weak(树状数组)
- CF 232 div2 E On Changing Tree 树状数组
- CF 369E - Valera and Queries(树状数组)
- CF 121E - Lucky Array(树状数组裸题)
- cf#368-E. Garlands-(二维树状数组)
- CF 669E CDQ分治
- Codeforces293E-Close Vertices
- http://docs.oracle.com/cd/E18283_01/server.112/e17766/framework_errormessages.htm
- STL 树
- 自制jquery插件
- error:unknow filesystem grub rescue 的解决
- hdu-1142 A Walk Through the Forest
- CF 293 E Close Vertices (树的分治+树状数组)
- android listview中smoothscrolltoposition的问题
- socket.io+angular.js+express.js做个聊天应用(一)
- 动态规划解决01背包问题
- OX2D 自然的旋转到一个指定角度
- TI_DSP_corePac_带宽管理 - 1.3(仲裁寄存器default值)
- BZOJ 2001([Hnoi2010]City 城市建设-CDQ重构图-动态最小生成树)
- 在四位共阴极数码上显示“2 3 5 8”四个数字
- 好的编程习惯(一)