Gym - 100962F: Frank Sinatra (树上莫队+bitset)
题意:给定一棵树,带边权。然后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)的更多相关文章
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
- SP10707 COT2 - Count on a tree II (树上莫队)
大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可. #include <iostream> #include <algorithm> #include < ...
- 2018CCPC女生赛(树上莫队)
签到题这里久懒得写了. B - 缺失的数据范围 Total Submission(s): 2602 Accepted Submission(s): 559 题意:求最大的N,满足N^a*[log ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)
2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...
- 【BZOJ-3757】苹果树 块状树 + 树上莫队
3757: 苹果树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1305 Solved: 503[Submit][Status][Discuss] ...
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- 树上莫队 wowow
构建:像线性的莫队那样,依旧是按sqrt(n)为一块分块. int dfs(int x){ ; dfn[x]=++ind; ;i<=;i++) if (bin[i]<=deep[x]) f ...
- BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
随机推荐
- 记录一次在生成数据库服务器上出现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 ...
- linux_FHS初遇--良好清晰条理的文件存储习惯
1. 建议根目录(/)所在分区理论上越小越好,原因一为保证性能,二为易恢复与操作. 2.建议应用程序安装软件不要与根目录放在同一个分区内 3. 建议根目录(/)下应该存在的子目录: /bin 放置在单 ...
- 阿里云配置DDoS高防
- Java并发编程: CountDownLatch、CyclicBarrier和 Semaphore
java 1.5提供了一些非常有用的辅助类来帮助并发编程,比如CountDownLatch,CyclicBarrier和Semaphore. 1.CountDownLatch –主线程阻塞等待,最后完 ...
- linux中常用命令alias
1.查看系统中所有的命令别名 alias 2.查看指定的别名 alias 别名 2.设定别名 alias 别名='原命令' 3.删除别名 unalias 别名 4.使别名永久生效 vi ~/.bash ...
- InheritableThreadLocal详解
InheritableThreadLocal详解 https://www.jianshu.com/p/94ba4a918ff5 InheritableThreadLocal——父线程传递本地变 ...
- 整理:WPF中XmlDataProvider的用法总结
原文:整理:WPF中XmlDataProvider的用法总结 一.目的:了解XmlDataProvider中绑定数据的方法 二.绑定方式主要有三种: 1.Xaml资源中内置: <!--XPath ...
- Lombok简介、使用、工作原理、优缺点
1.Lombok简介官方介绍 Project Lombok is a java library that automatically plugs into your editor and build ...
- C# VB .net读取识别条形码线性条码codabar
codabar是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取codabar条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速 ...
- Python3字典与集合
一.Python3字典 字典是另一种可变容器模型,且可存储任意类型对象字典的每个键值(key=>value)对用冒号":"分割,每个键值对之间用逗号"," ...