Annoying problem

Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5296


Mean:

给你一个有根树和一个节点集合S,初始S为空,有q个操作,每个操作要么从树中选一个结点加入到S中(不删除树中节点),要么从S集合中删除一个结点。你需要从树中选一些边组成集合E,E中的边能够是S中的节点连通。对于每一个操作,输出操作后E中所有边的边权之和。

analyse:

首先是构图,把树看作一个无向图,使用邻接表存图。

处理出从1号结点的dfs序存储起来。

添加点u操作:查找S集合中的点与添加的点dfs序在前面且编号最大的点,以及dfs序在后面且编号最小的点,设这两个点是x,y。

那么增加的花费是:dis[u]-dis[lca[(x,u)] - dis [lca(y,u)] + dis[lca(x,y) ]; 其中dis代表该点到根节点的距离。

对于删除点u操作:先把点从集合中删除,然后再计算减少花费,计算公式和增加的计算方法一样。

也是看了题解才撸出来的。

Time complexity: O(N)

Source code: 

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-07-22-11.22
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define LL long long
#define ULL unsigned long long
#define rep(i,n) for(int i=0;i<n;++i)
using namespace std; const int N = 100010,D=20;
int st[N], ori[N], dfs_clock;
vector<pair<int, int> > G[N];
int shortcut[D][N], dep[N];
int *fa;
int get_lca( int a, int b )
{
if( dep[a] < dep[b] )
swap( a, b );
for( int i = D - 1; ~i; --i )
{
if( dep[a] - dep[b] >> i & 1 )
a = shortcut[i][a];
}
if( a == b ) return a;
for( int i = D - 1; ~i; --i )
{
if( shortcut[i][a] != shortcut[i][b] )
{
a = shortcut[i][a];
b = shortcut[i][b];
}
}
return fa[a];
} int dis[N];
void dfs( int u, int father )
{
st[u] = ++dfs_clock;
ori[dfs_clock] = u;
vector<pair<int, int> > :: iterator it;
for( it = G[u].begin(); it != G[u].end(); ++it )
{
int v = ( *it ).first;
int w = ( *it ).second;
if( v == father )continue;
fa[v] = u;
dep[v] = dep[u] + 1;
dis[v] = dis[u] + w;
dfs( v, u );
}
} void prepare( int n )
{
for( int j = 1; j < D; ++j )
{
rep( i, n )
{
int &res = shortcut[j][i];
res = shortcut[j - 1][i];
if( ~res ) res = shortcut[j - 1][res];
}
}
} set<int> nodes;
int get_dis( int a, int b )
{
return dis[a] + dis[b] - 2 * dis[get_lca( a, b )];
} int add( int u )
{
if( !nodes.empty() )
{
set<int>::iterator low, high;
low = nodes.lower_bound( st[u] );
high = low;
if( low == nodes.end() || low == nodes.begin() )
{
low = nodes.begin();
high = nodes.end();
high--;
}
else low--;
int x = ori[*low];
int y = ori[*high];
int res = get_dis( x, u ) + get_dis( y, u ) - get_dis( x, y );
return res;
}
return 0;
} int main()
{
ios_base::sync_with_stdio( false );
cin.tie( 0 );
int T, n, q, u, v, w;
scanf( "%d", &T );
rep( cas, T )
{
scanf( "%d %d", &n, &q );
rep( i, n ) G[i].clear();
dfs_clock = 0;
rep( i, n - 1 )
{
scanf( "%d %d %d", &u, &v, &w );
u--;
v--;
G[u].push_back( make_pair( v, w ) );
G[v].push_back( make_pair( u, w ) );
}
fa = shortcut[0];
fa[0] = -1;
dfs( 0, -1 );
prepare( n );
nodes.clear();
printf( "Case #%d:\n", cas + 1 );
int ans = 0;
while( q-- )
{
int op;
scanf( "%d %d", &op, &u );
u--;
if( op == 1 ) // add
{
if( nodes.find( st[u] ) == nodes.end() )
{
ans += add( u );
nodes.insert( st[u] );
}
}
else // delete
{
if( nodes.find( st[u] ) != nodes.end() )
{
nodes.erase( st[u] );
ans -= add( u );
}
}
printf( "%d\n", ans >> 1 );
}
}
return 0;
}
/* */

  

2015 Multi-University Training Contest 1 - 1009 Annoying problem的更多相关文章

  1. 2015 Multi-University Training Contest 5 1009 MZL's Border

    MZL's Border Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5351 Mean: 给出一个类似斐波那契数列的字符串序列 ...

  2. 2014 Multi-University Training Contest 9#1009

    Just a JokeTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Tot ...

  3. hdu 6394 Tree (2018 Multi-University Training Contest 7 1009) (树分块+倍增)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=6394 思路:用dfs序处理下树,在用分块,我们只需要维护当前这个点要跳出这个块需要的步数和他跳出这个块去 ...

  4. HDU 4608 I-number 2013 Multi-University Training Contest 1 1009题

    题目大意:输入一个数x,求一个对应的y,这个y满足以下条件,第一,y>x,第二,y 的各位数之和能被10整除,第三,求满足前两个条件的最小的y. 解题报告:一个模拟题,比赛的时候确没过,感觉这题 ...

  5. 2015 Multi-University Training Contest 9-1007 Travelling Salesman Problem

    Problem Description Teacher Mai is in a maze with n rows and m columns. There is a non-negative numb ...

  6. ACM多校联赛7 2018 Multi-University Training Contest 7 1009 Tree

    [题意概述] 给一棵以1为根的树,树上的每个节点有一个ai值,代表它可以传送到自己的ai倍祖先,如果不存在则传送出这棵树.现在询问某个节点传送出这棵树需要多少步. [题解] 其实是把“弹飞绵羊”那道题 ...

  7. 2019 Multi-University Training Contest 2 - 1009 - 回文自动机

    http://acm.hdu.edu.cn/showproblem.php?pid=6599 有好几种实现方式,首先都是用回文自动机统计好回文串的个数. 记得把每个节点的cnt加到他的fail上,因为 ...

  8. 2019 Multi-University Training Contest 1 - 1009 - String - 贪心

    不知道错在哪里. 是要把atop改成stop!两个弄混了.感谢自造样例. #include<bits/stdc++.h> using namespace std; typedef long ...

  9. 2015 Multi-University Training Contest 3 hdu 5324 Boring Class

    Boring Class Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

随机推荐

  1. DataTable添加行和列数据

    protected void Page_Load() { DataTable newdtb = new DataTable(); newdtb.Columns.Add("Id", ...

  2. LCLFramework框架之开发约束

    Entity编写 1:所有的实体类都必须继承DomainEntity 2:所有的表都必须有 ID 3:所有表的关系字段必须是ID [Serializable] public class User: D ...

  3. 高吞吐量的分布式发布订阅消息系统Kafka-- 管理工具 Kafka Manager

    一.概述 Kafka在雅虎内部被很多团队使用,媒体团队用它做实时分析流水线,可以处理高达20Gbps(压缩数据)的峰值带宽. 为了简化开发者和服务工程师维护Kafka集群的工作,构建了一个叫做Kafk ...

  4. adding validation annotators to model classes 在linq to EntityFrame的Model中添加前台验证validation annotators

    The same solution can be applied for LINQ to SQL. The snippet the article shows for using the Metada ...

  5. Openvswitch原理与代码分析(5): 内核中的流表flow table操作

      当一个数据包到达网卡的时候,首先要经过内核Openvswitch.ko,流表Flow Table在内核中有一份,通过key查找内核中的flow table,即可以得到action,然后执行acti ...

  6. C# 读取JSON

    引用 Newtonsoft.Json.dll //C# 读取JSON Newtonsoft.Json.Linq.JObject jsonStr = Newtonsoft.Json.Linq.JObje ...

  7. JavaScript 事件——“事件类型”中“复合事件”和“变动事件”的注意要点(转)

    复合事件 复合事件是DOM3级事件中心添加的一类事件,用于处理IME的输入序列. compositionstart.compositionupdate.compositionend 复合事件有以下三中 ...

  8. Web服务器性能监控分析与优化

    Web服务器性能监控分析与优化 http://www.docin.com/p-759040698.html

  9. IIS 日志文件分析

    先安装下文参考资料中的log parser studio 然后就可以针对日志文件进行sql语句的查询了. 各页面访问量排行 ) FROM '[LOGFILEPATH]' where cs-uri-st ...

  10. SAP S4 Finance6个支持企业实时财务管理的主要创新领域

    本文将讲述下 SAP Simple Finance里面6个支持企业实时财务管理的主要创新领域. Simple Finance 在以下几个方面具有自己独特的优势: ● 更加简洁的用户体验,可以让用户在任 ...