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 < ...
随机推荐
- C编程遇到的一些小细节
1 typedef int ElemType --> typedef int ElemType; 此处要加分行(:),要区别 #defin a 20 此处不需要加分号:#define是预 ...
- Android -- SEGV_MAPERR,SEGV_ACCERR
Per siginfo.h: SEGV_MAPERR means you tried to access an address that doesn’t map to anything. SEGV_A ...
- npm是干什么的(转)
原文:https://zhuanlan.zhihu.com/p/24357770 网上的 npm 教程主要都在讲怎么安装.配置和使用 npm,却不告诉新人「为什么要使用 npm」.今天我就来讲讲这个话 ...
- MVVM模式理解(转)
原文https://www.cnblogs.com/goloving/p/8520030.html MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心 ...
- Logstash配置文件修改自动加载和指定目录进行启动
检查配置并启动Logstash,修改后自动加载 指定配置文件目录并启动Logstash
- Linux学习笔记之详解linux软连接和硬链接
0x00 链接文件 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [软连接] 另外一种连接称之为符 ...
- fail fast和fail safe策略
优先考虑出现异常的场景,当程序出现异常的时候,直接抛出异常,随后程序终止 import java.util.ArrayList; import java.util.Collections; impor ...
- dotnet core 之 CORS使用示例
这里列举几个经过验证的可用的CORS使用示例, 方便在需要的时候可以直接使用 示例1 #region snippet2 public void ConfigureServices(IServiceCo ...
- asp.net core MVC 过滤器之ExceptionFilter过滤器(一)
简介 异常过滤器,顾名思义,就是当程序发生异常时所使用的过滤器.用于在系统出现未捕获异常时的处理. 实现一个自定义异常过滤器 自定义一个异常过滤器需要实现IExceptionFilter接口 publ ...
- div不换行的三种方法
原文:https://www.cnblogs.com/zouwangblog/p/11149621.html float <div class="div1">123&l ...