题意:

给定一棵n个点和有向边构成的树,其中一些边是合法边,一些边是非法边,

经过非法边需要1的费用,并且经过之后费用翻倍。

给定一个长为m的序列,问从点1开始按顺序移动到序列中对应点的总费用。

1<=n<=10^5,

1<=m<=10^6

题解:

还是比较水的…

正解是各种方法求LCA,在点上打标记,最后DFS一遍就可以得到答案。

用tarjan求LCA可以做到总复杂度O(n*α)…

我傻傻地见树就剖,强行O(n log n log n)碾过去了…

每次把起点终点之间的路径的经过次数加一,最后统计非法边对应的点,

对答案的贡献是 2^(次数)-1 。

ZKW线段树的常数还是比较可以接受的…虽然Codeforces机子本来就快…

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <cstdio>
#include <cstring>
#define fore(p) for(int pt=h[p];pt;pt=e[pt].nx)
typedef long long lint;
const int N = , MO = ;
inline int read()
{
int s = ; char c; while((c=getchar())<'0'||c>'9');
do{s=s*+c-'0';}while((c=getchar())>='0'&&c<='9');
return s;
}
int n,q,aa,bb,tot,ttot,cur,tg,curd,tim,ans,ql,qr,S,p2[],h[N],top[N],d[N],hs[N],f[N],iw[N];
bool il[N],il2[N],qv;
struct eg{int dt,nx;bool le;}e[N*];
struct segt
{
int tr[N*];
int query(int p){ int s = ; for(int i=S+p;i>=;i>>=) s += tr[i]; return s; }
void db(int l,int r)
{
for(l=l+S-,r=r+S+;l^r^;l>>=,r>>=)
{
if(~l&) tr[l^]++;
if( r&) tr[r^]++;
}
}
}tr1,tr2;
inline void link(int b)
{
e[++tot].nx = h[aa]; e[tot].dt = bb; e[tot].le = ; h[aa] = tot;
e[++tot].nx = h[bb]; e[tot].dt = aa; e[tot].le = b; h[bb] = tot;
}
int dfs1(int p,int ff)
{
f[p] = ff, d[p] = ++curd;
int sz = ,nx,t,mx=;
fore(p)
{
if((nx=e[pt].dt)==ff) continue;
if(e[pt^].le) il[nx] = ;
if(e[pt].le) il2[nx] = ;
t = dfs1(nx,p);
if(t>mx) mx = t, hs[p] = nx;
}
curd--;
return sz;
}
void dfs2(int p,int tp)
{
top[p] = tp;
iw[p] = ++tim;
if(hs[p]) dfs2(hs[p],tp);
fore(p)
if(e[pt].dt!=f[p]&&e[pt].dt!=hs[p])
dfs2(e[pt].dt,e[pt].dt);
}
void calc(int aa,int bb)
{
if(aa==bb) return;
while(top[aa]!=top[bb])
{
if(d[top[aa]]>d[top[bb]]) tr1.db(iw[top[aa]],iw[aa]), aa = f[top[aa]];
else tr2.db(iw[top[bb]],iw[bb]), bb = f[top[bb]];
}
if(d[aa]>d[bb]) tr1.db(iw[bb]+,iw[aa]);
else tr2.db(iw[aa]+,iw[bb]);
}
int main()
{
int i,j;
n = read();
for(S=;S<=n+;S<<=);
for(i=,tot=;i<=n;i++) aa = read(), bb = read(), link(!read());
dfs1(,); dfs2(,); q = read();
for(p2[]=,i=;i<=q;i++) p2[i] = ((lint)p2[i-]<<1ll)%MO;
for(cur=;q--;cur=tg)
tg = read(), calc(cur,tg);
for(i=;i<=n;i++)
{
if(!il[i]) ans = ((lint)ans+p2[tr1.query(iw[i])]+MO-)%MO;
if(!il2[i]) ans = ((lint)ans+p2[tr2.query(iw[i])]+MO-)%MO;
}
printf("%d\n",ans);
return ;
}

补上O(n*α)的做法:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <cstdio>
#include <cstring>
#define fore(p) for(int pt=h[p];pt;pt=e[pt].nx)
typedef long long lint;
const int N = , MO = ;
inline int read()
{
int s = ; char c; while((c=getchar())<'0'||c>'9');
do{s=s*+c-'0';}while((c=getchar())>='0'&&c<='9');
return s;
}
int n,q,aa,bb,tot,qtot,cur,tg,curd,tim,ans,p2[],h[N],qh[N],rp[N],f[N],w[N],w2[N],mx;
bool il[N],il2[N],b[N],qv;
struct eg{int dt,nx;bool le;}e[N*];
struct qu{int dt,nx;}qs[N*];
inline void link(int b)
{
e[++tot].nx = h[aa]; e[tot].dt = bb; e[tot].le = ; h[aa] = tot;
e[++tot].nx = h[bb]; e[tot].dt = aa; e[tot].le = b; h[bb] = tot;
}
inline void linkq()
{
if(aa==bb) return;
qs[++qtot].nx = qh[aa]; qs[qtot].dt = bb; qh[aa] = qtot;
qs[++qtot].nx = qh[bb]; qs[qtot].dt = aa; qh[bb] = qtot;
w[aa]++; w2[bb]++;
}
int findf(int p){ return f[p]==p?p:(f[p]=findf(f[p])); }
void dfs(int p)
{
b[p] = ;
for(int nx,pt=qh[p];pt;pt=qs[pt].nx)
if(b[qs[pt].dt])
nx = findf(qs[pt].dt), w[nx]--, w2[nx]--;
for(int nx,pt=h[p];pt;pt=e[pt].nx)
if(!b[nx=e[pt].dt])
{
if(e[pt^].le) il[nx] = ;
if(e[pt].le) il2[nx] = ;
dfs(nx);
f[nx] = p;
w[p] += w[nx];
w2[p] += w2[nx];
}
if(w[p]>mx) mx = w[p];
if(w2[p]>mx) mx = w2[p];
}
int main()
{
int i,j;
for(n=read(),i=,tot=,f[]=;i<=n;i++) aa = read(), bb = read(), link(!read()), f[i] = i;
for(q=read(),i=,qtot=,aa=;i<=q;i++,aa=bb) bb = read(), linkq();
dfs();
for(p2[]=,i=;i<=mx;i++) p2[i] = ((lint)p2[i-]<<1ll)%MO;
for(i=;i<=n;i++)
{
if(!il[i]) ans = ((lint)ans+p2[w[i]]-)%MO;
if(!il2[i]) ans = ((lint)ans+p2[w2[i]]-)%MO;
}
printf("%d\n",ans);
return ;
}

Bubble Cup 8 finals B. Bribes (575B)的更多相关文章

  1. Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 C. Jumping Transformers 我会状压 DP! 用 \(dp[x][y][ ...

  2. Bubble Cup 11 - Finals [Online Mirror, Div. 1]题解 【待补】

    Bubble Cup 11 - Finals [Online Mirror, Div. 1] 一场很好玩的题啊! I. Palindrome Pairs 枚举哪种字符出现奇数次. G. AI robo ...

  3. Codeforces Bubble Cup 8 - Finals [Online Mirror] B. Bribes lca

    题目链接: http://codeforces.com/contest/575/problem/B 题解: 把链u,v拆成u,lca(u,v)和v,lca(u,v)(v,lca(u,v)是倒过来的). ...

  4. Bubble Cup 8 finals I. Robots protection (575I)

    题意: 有一个正方形区域, 要求支持两个操作: 1.放置三角形,给定放置方向(有4个方向,直角边与坐标轴平行),直角顶点坐标,边长 2.查询一个点被覆盖了多少次 1<=正方形区域边长n<= ...

  5. Bubble Cup 8 finals H. Bots (575H)

    题意: 简单来说就是生成一棵树,要求根到每个叶子节点上的路径颜色排列不同, 且每条根到叶子的路径恰有n条蓝边和n条红边. 求生成的树的节点个数. 1<=n<=10^6 题解: 简单计数. ...

  6. Bubble Cup 8 finals G. Run for beer (575G)

    题意: 给定一个带权无向图,每条边的代价为边权/当前速度,每次到达一个新节点,速度都会除以10. 求0号点到n-1号点的最小代价,如果多解输出点数最少的解,输出代价.路径点数.路径经过的点. 1< ...

  7. Bubble Cup 8 finals F. Bulbo (575F)

    题意: 给定初始位置,查询n次区间,每次查询前可以花费移动距离的代价来移动, 查询时需要花费当前位置到区间内最近的点的距离,求最小代价. 1<=n<=5000,1<=所有位置< ...

  8. Bubble Cup 8 finals E. Spectator Riots (575E)

    题意: 一个长宽是100000单位的球场上有很多暴动的观众,每个观众都有一个速度v, 在一秒内,观众会等概率地移动到与原位置的曼哈顿距离<=v的地方(不会移动到界外). 你需要选取三个位置,这三 ...

  9. Bubble Cup 8 finals D. Tablecity (575D)

    题意: (无输入,纯输出题) 一个城市用1000列2行的格子表示,一个小偷藏在城市的某一处. 在每一小时的开始, 在(X, Y)位置的小偷可以移动到 (X - 1, Y), (X + 1, Y),(X ...

随机推荐

  1. 在Ubuntu X64上编译Hadoop

    在之前的文章中介绍了如何直接在Ubuntu中安装Hadoop.但是对于64位的Ubuntu来说,官方给出的Hadoop包是32位的,运行时会得到警告: WARN util.NativeCodeLoad ...

  2. 让OData和NHibernate结合进行动态查询

    OData是一个非常灵活的RESTful API,如果要做出强大的查询API,那么OData就强烈推荐了.http://www.odata.org/ OData的特点就是可以根据传入参数动态生成Ent ...

  3. PL/SQL连接错误:ora-12705:cannot access NLS data files or invalid environment specified

    适合自己的解决方法: 排查问题: 1. 你没有安装Oracle Client软件.这是使用PL/SQL Developer的必须条件.安装Oracle Client后再重试.2. 你安装了多个Orac ...

  4. JavaScript代码段整理笔记系列(一)

    30段JavaScript代码——上篇 1.如何区分IE及非IE浏览器: if(!+[1,]){ //IE 11 不支持 alert("这是 IE 浏览器"): }else{ al ...

  5. c#中多线程同步Lock(锁)的研究以及跨线程UI的操作

    本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧. 其实多线程的同步,使用 ...

  6. 【原创】Chrome最新版(53-55)再次爆出BUG!

    前言 今年十月份,我曾发布一篇文章<Chrome53 最新版惊现无厘头卡死 BUG!>,不过那个BUG在最新的 Chrome 54 中已经修正. 而今天即将发布的Chrome弱智BUG: ...

  7. C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper

    前言:之前学习过很多的Bootstrap组件,博主就在脑海里构思:是否可以封装一套自己Bootstrap组件库呢.再加上看到MVC的Razor语法里面直接通过后台方法输出前端控件的方式,于是打算仿照H ...

  8. 【C#】安装windows服务

    参考:http://blog.csdn.net ,http://blog.csdn.net/dyzcode 1.新建 visual studio insaller 项目2.添加 [文件系统]3.添加 ...

  9. CentOS升级openssl

    才设置了http2,结果蓝狗说我网站不安全,检测一下发现openssl有漏洞,于是准备升级一下openssl 检测网站: www.ssllabs.com/ssltest/analyze.html # ...

  10. com.panie 项目开发随笔(NoF)_环境搭建(2016.12.29)

    (一) 最近做的框架一直在 spring + springmvc + mybatis 的基础上,使用框架的好处自然是 简化了自己的开发工作,定义好大的结构体系后就在里面套用方法了! 可是框架的毛病同样 ...