题意:给定一棵树,带边权。然后Q次询问,每次给出(u,v),求这个路径上最小的未出现的边权。

思路:树上莫队,求mex可以用分块或者bitset,前者可能会快一点。   莫队过程:求出欧拉序,即记录dfs的in和out时间戳。 然后摊平成数组,在数组上进行莫队。

一般的莫队需要单独考虑LCA,因为LCA不在这个区间里。 但是由于这里是边权,用儿子代替边权,所以LCA本来就不用考虑。

这个序列里,有效的部分是出现奇数次的,所以用vis记录奇偶性,如果是奇,表示加; 偶表示删。

如果想再快一点,可以把bitset改为分块; 以及,用王室联邦分块法(即后序遍历,这样可以保证一个块更近一些)。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
bitset<maxn>S; int num[maxn],val[maxn],ans[maxn];
int Laxt[maxn],Next[maxn],To[maxn],len[maxn],cnt;
int p[maxn],L[maxn],R[maxn],times,B,N,Q,vis[maxn];
struct in{
int l,r,id;
bool friend operator <(in w,in v){
if(w.l/B!=v.l/B) return w.l<v.l;
return w.r<v.r;
}
}s[maxn];
void add(int u,int v,int w)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; len[cnt]=w;
}
void dfs(int u,int f)
{
p[++times]=u; L[u]=times;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i]; if(v==f) continue;
val[v]=len[i]; dfs(v,u);
}
p[++times]=u; R[u]=times;
}
void fcy(int pos)
{
pos=p[pos];
if(val[pos]>N) return ;
vis[pos]^=;
if(vis[pos]) {
num[val[pos]]++;
if(num[val[pos]]==) S[val[pos]]=;
}
else {
num[val[pos]]--;
if(num[val[pos]]==) S[val[pos]]=;
}
}
void solve()
{
sort(s+,s+Q+);
int l=s[].l,r=s[].l-;
rep(i,,Q){
while(l<s[i].l) fcy(l++);
while(l>s[i].l) fcy(--l);
while(r<s[i].r) fcy(++r);
while(r>s[i].r) fcy(r--);
ans[s[i].id]=S._Find_first();
}
}
int main()
{
int u,v,w;
S.set(); //没出现的就是1
scanf("%d%d",&N,&Q);
B=(int)sqrt(N+N);
rep(i,,N-){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dfs(,); val[]=N+;
rep(i,,Q) {
scanf("%d%d",&u,&v);
if(L[u]>L[v]) swap(u,v);
s[i].l=R[u]; s[i].r=L[v]; s[i].id=i;
}
solve();
rep(i,,Q) printf("%d\n",ans[i]);
return ;
}

王室联邦写法: 但跑出来这个更慢?

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
bitset<maxn>S; int num[maxn],val[maxn],ans[maxn];
int Laxt[maxn],Next[maxn],To[maxn],len[maxn],cnt;
int p[maxn],L[maxn],R[maxn],times,B,N,Q,vis[maxn];
int q[maxn],top,g[maxn],group;
struct in{
int l,r,id;
bool friend operator <(in w,in v){
if(g[p[w.l]]!=g[p[v.l]]) return g[p[w.l]]<g[p[v.l]];
return g[p[w.r]]<g[p[v.r]];
}
}s[maxn];
void add(int u,int v,int w)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; len[cnt]=w;
}
void dfs(int u,int f)
{ p[++times]=u; L[u]=times;
int now=top;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i]; if(v==f) continue;
val[v]=len[i]; dfs(v,u);
if(top-now>=B){
group++;
while(top!=now) g[q[top--]]=group;
}
}
q[++top]=u;
p[++times]=u; R[u]=times;
}
void fcy(int pos)
{
pos=p[pos];
if(val[pos]>N) return ;
vis[pos]^=;
if(vis[pos]) {
num[val[pos]]++;
if(num[val[pos]]==) S[val[pos]]=;
}
else {
num[val[pos]]--;
if(num[val[pos]]==) S[val[pos]]=;
}
}
void solve()
{
sort(s+,s+Q+);
int l=s[].l,r=s[].l-;
rep(i,,Q){
while(l<s[i].l) fcy(l++);
while(l>s[i].l) fcy(--l);
while(r<s[i].r) fcy(++r);
while(r>s[i].r) fcy(r--);
ans[s[i].id]=S._Find_first();
}
}
int main()
{
int u,v,w;
S.set(); //没出现的就是1
scanf("%d%d",&N,&Q);
B=(int)sqrt(N+N);
rep(i,,N-){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
dfs(,); val[]=N+;
while(top) g[q[top--]]=group;
rep(i,,Q) {
scanf("%d%d",&u,&v);
if(L[u]>L[v]) swap(u,v);
s[i].l=R[u]; s[i].r=L[v]; s[i].id=i;
}
solve();
rep(i,,Q) printf("%d\n",ans[i]);
return ;
}

Gym - 100962F: Frank Sinatra (树上莫队+bitset)的更多相关文章

  1. spoj COT2 - Count on a tree II 树上莫队

    题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的,  受益匪浅.. #include <iostream> #include < ...

  2. SP10707 COT2 - Count on a tree II (树上莫队)

    大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可. #include <iostream> #include <algorithm> #include < ...

  3. 2018CCPC女生赛(树上莫队)

    签到题这里久懒得写了. B - 缺失的数据范围 Total Submission(s): 2602    Accepted Submission(s): 559 题意:求最大的N,满足N^a*[log ...

  4. P4074 [WC2013]糖果公园 树上莫队带修改

    题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...

  5. 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)

    2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...

  6. 【BZOJ-3757】苹果树 块状树 + 树上莫队

    3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1305  Solved: 503[Submit][Status][Discuss] ...

  7. [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】

    题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...

  8. 树上莫队 wowow

    构建:像线性的莫队那样,依旧是按sqrt(n)为一块分块. int dfs(int x){ ; dfn[x]=++ind; ;i<=;i++) if (bin[i]<=deep[x]) f ...

  9. BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]

    传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...

随机推荐

  1. 记录一次在生成数据库服务器上出现The timeout period elapsed prior to completion of the operation or the server is not responding.和Exception has been thrown by the target of an invocation的解决办法

    记一次查询超时的解决方案The timeout period elapsed...... https://www.cnblogs.com/wyt007/p/9274613.html Exception ...

  2. linux_FHS初遇--良好清晰条理的文件存储习惯

    1. 建议根目录(/)所在分区理论上越小越好,原因一为保证性能,二为易恢复与操作. 2.建议应用程序安装软件不要与根目录放在同一个分区内 3. 建议根目录(/)下应该存在的子目录: /bin 放置在单 ...

  3. 阿里云配置DDoS高防

  4. Java并发编程: CountDownLatch、CyclicBarrier和 Semaphore

    java 1.5提供了一些非常有用的辅助类来帮助并发编程,比如CountDownLatch,CyclicBarrier和Semaphore. 1.CountDownLatch –主线程阻塞等待,最后完 ...

  5. linux中常用命令alias

    1.查看系统中所有的命令别名 alias 2.查看指定的别名 alias 别名 2.设定别名 alias 别名='原命令' 3.删除别名 unalias 别名 4.使别名永久生效 vi ~/.bash ...

  6. InheritableThreadLocal详解

    InheritableThreadLocal详解     https://www.jianshu.com/p/94ba4a918ff5 InheritableThreadLocal——父线程传递本地变 ...

  7. 整理:WPF中XmlDataProvider的用法总结

    原文:整理:WPF中XmlDataProvider的用法总结 一.目的:了解XmlDataProvider中绑定数据的方法 二.绑定方式主要有三种: 1.Xaml资源中内置: <!--XPath ...

  8. Lombok简介、使用、工作原理、优缺点

    1.Lombok简介官方介绍 Project Lombok is a java library that automatically plugs into your editor and build ...

  9. C# VB .net读取识别条形码线性条码codabar

    codabar是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取codabar条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速 ...

  10. Python3字典与集合

    一.Python3字典 字典是另一种可变容器模型,且可存储任意类型对象字典的每个键值(key=>value)对用冒号":"分割,每个键值对之间用逗号"," ...