洛谷P7518:宝石(倍增、可撤销并查集)

解析

算法一

定义 upx,kup_{x,k}upx,k 为节点 xxx自己的颜色所在位置在返祖链上往后跳 2k2^k2k 个颜色到达的节点。
可以像倍增一样的求解。
这样对于一次询问 (s,t)(s,t)(s,t) 我们就能求出 (s,lca)(s,lca)(s,lca) 这一段能取到哪里了。
对于向下的情况,再处理一个 upx,k′up'_{x,k}upx,k 表示节点 xxx自己的颜色所在位置在返祖链上往2k2^k2k 个颜色到达的节点。
然后二分每一个询问的答案,从答案开始往前跳,看能否与 (s,lca)(s,lca)(s,lca) 相接即可判定是否合法。
时间复杂度 O(nlog⁡n+mlog⁡Clog⁡n)O(n\log n+m\log C\log n)O(nlogn+mlogClogn)

算法二

考虑优化后一段 (lca,t)(lca,t)(lca,t) 的过程。
假设询问 iii(s,lca)(s,lca)(s,lca) 过程中跳到了颜色 ccc,就在 lcalcalca 处增加一个 (i,c)(i,c)(i,c) 的元素,在 ttt 处打一个 (i)(i)(i) 标记。
考虑我们 dfsdfsdfs 过程中需要维护什么:

  1. 插入二元组 (i,c)(i,c)(i,c)
  2. 如果当前节点颜色为 ccc,收集器上的下一个颜色为 sufsufsuf,就使所有 (i,c)→(i,suf)(i,c)\to(i,suf)(i,c)(i,suf)
  3. 查询当前的 iii 元素的特征值。
  4. 撤销当前dfs的影响。

这个东西可以用可撤销并查集维护。
总复杂度 O(nlog⁡n+mlog⁡n)O(n\log n+m\log n)O(nlogn+mlogn)

代码

写的是算法二。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=2e6+100;
const int M=50050;
const int mod=1e9+7;
const double eps=1e-9;inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,C,Mx;struct node{int to,nxt;
}e[N<<1];
int fi[N],cnt;
inline void addline(int x,int y){e[++cnt]=(node){y,fi[x]};fi[x]=cnt;return;
}
int p[N],col[N];int pre[N],up[N][20],pl[N][20],dep[N],suf[N];
void dfs(int x,int f){dep[x]=dep[f]+1;pl[x][0]=f;for(int k=1;pl[x][k-1];k++) pl[x][k]=pl[pl[x][k-1]][k-1];up[x][0]=pre[suf[col[x]]];for(int k=1;up[x][k-1];k++) up[x][k]=up[up[x][k-1]][k-1];int ori=pre[col[x]];pre[col[x]]=x;for(int i=fi[x];~i;i=e[i].nxt){int to=e[i].to;if(to==f) continue;dfs(to,x);}pre[col[x]]=ori;return;
}
inline int Lca(int x,int y){if(dep[x]<dep[y]) swap(x,y);for(int k=17;k>=0;k--){if(dep[pl[x][k]]<dep[y]) continue;x=pl[x][k];}if(x==y) return x;for(int k=17;k>=0;k--){if(pl[x][k]==pl[y][k]) continue;x=pl[x][k];y=pl[y][k];}return pl[x][0];
}
struct query{int s,t,lca,id;
};
vector<query>v[N];
inline int jump(int x,int top){//return color;for(int k=17;k>=0;k--){if(dep[up[x][k]]<dep[top]) continue;x=up[x][k];}return suf[col[x]];
}
struct add{int id,c;
};
vector<add>ad[N];
vector<int>q[N];
void solve1(int x,int f){int ori=pre[col[x]];pre[col[x]]=x;for(query o:v[x]){int s=o.s,t=o.t,lca=o.lca,id=o.id;s=pre[p[1]];if(dep[s]<dep[lca]) ad[lca].push_back((add){id,p[1]});else ad[lca].push_back((add){id,jump(s,lca)});q[t].push_back(id);}for(int i=fi[x];~i;i=e[i].nxt){int to=e[i].to;if(to==f) continue;solve1(to,x);}pre[col[x]]=ori;return;
}
int mx[N],fa[N],siz[N];
struct ope{int op;//1:fa 2:siz 3:mx 4:belint id,ori;
}zhan[N<<3];
int top,nam[N],bel[N],tot;
int find(int x){return fa[x]==x?x:find(fa[x]);
}
inline int New(int val){++tot;fa[tot]=tot;siz[tot]=1;mx[tot]=val;return tot;
}
void merge(int x,int y){x=find(x);y=find(y);if(siz[x]>siz[y]) swap(x,y);zhan[++top]=(ope){1,x,fa[x]};fa[x]=y;zhan[++top]=(ope){2,y,siz[y]};siz[y]+=siz[x];zhan[++top]=(ope){3,y,mx[y]};mx[y]=max(mx[y],mx[x]);return;
}
void del(int tim){while(top!=tim){if(zhan[top].op==1) fa[zhan[top].id]=zhan[top].ori;else if(zhan[top].op==2) siz[zhan[top].id]=zhan[top].ori;else if(zhan[top].op==3) mx[zhan[top].id]=zhan[top].ori;else if(zhan[top].op==4) bel[zhan[top].id]=zhan[top].ori;top--;}return;
}
int ans[N];
int rk[N];
void solve2(int x,int f){int ori=top;for(add o:ad[x]){int id=o.id,c=o.c,now=New(0);nam[id]=now;merge(now,bel[c]);//ans[id]=rk[c];}//assert(mx[find(bel[suf[col[x]]])]==rk[suf[col[x]]]);//assert(mx[find(bel[col[x]])]==rk[col[x]]);merge(bel[col[x]],bel[suf[col[x]]]);//if(mx[find(bel[col[x]])]!=rk[col[x]]+1){//	debug("%d %d\n",mx[find(bel[col[x]])],rk[col[x]]);exit(0);//}//assert(mx[find(bel[col[x]])]==rk[col[x]]+1);zhan[++top]=(ope){4,col[x],bel[col[x]]};bel[col[x]]=New(rk[col[x]]);for(int id:q[x]){int o=nam[id];ans[id]=mx[find(o)];}for(int i=fi[x];~i;i=e[i].nxt){int to=e[i].to;if(to==f) continue;solve2(to,x);}del(ori);
}
int main() {
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read();Mx=read();C=read();for(int i=1;i<=C;i++) p[i]=read();for(int i=1;i<=C;i++) suf[p[i]]=p[i+1],rk[p[i]]=i;rk[0]=C+1;for(int i=0;i<=Mx;i++) bel[i]=New(rk[i]);for(int i=1;i<=n;i++) col[i]=read();for(int i=1;i<n;i++){int x=read(),y=read();addline(x,y);addline(y,x);}dfs(1,0);m=read();for(int i=1;i<=m;i++){int s=read(),t=read(),lca=Lca(s,t);v[s].push_back((query){s,t,lca,i});}solve1(1,0);solve2(1,0);for(int i=1;i<=m;i++) printf("%d\n",ans[i]-1);return 0;
}
/*
1
3 3
1000000 2000000
0 0
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

E - Counting Cliques HDU - 5952

E - Counting Cliques HDU - 5952 题意&#xff1a; 给你n个点&#xff0c;m个边&#xff0c;还有一个s&#xff0c;问这个图中有多少个等于s的点集可以组成一个完全图 题解&#xff1a; 这题。。直接暴力搜索就行 分析复杂度的时候&#xff0c;应该考虑只有1000条边&#…

Docker最全教程之使用TeamCity来完成内部CI、CD流程(十七)

本篇教程主要讲解基于容器服务搭建TeamCity服务&#xff0c;并且完成内部项目的CI流程配置。教程中也分享了一个简单的CI、CD流程&#xff0c;仅作探讨。不过由于篇幅有限&#xff0c;完整的DevOps&#xff0c;我们后续独立探讨。 为了降低容器的使用门槛以及便于大家将容器技…

2021牛客NOIP提高组第二场T2——方格计数(组合数计数)

方格计数descriptionsolutioncodedescription 在左下角是 (&#x1d7ce;, &#x1d7ce;)&#xff0c;右上角是 (W, H)的网格上&#xff0c;有 (W 1) (H 1) 个格点。 现在要在格点上找 N个不同的点&#xff0c;使得这些点在一条直线上。并且在这条直线上&#xff0c; 相邻…

Acwing 1085. 不要62

Acwing 1085. 不要62 题意&#xff1a; 问[n,m]这些数中有多少数不包含4&#xff0c;且不包含连续的62 题解&#xff1a; 经典数位dp&#xff0c;分析过程以前的数位dp博客有写 Acwing 1082. 数字游戏 代码&#xff1a; #include<bits/stdc.h> #define debug(a,b) …

ybtoj洛谷P4406三角形面积并(扫描线)

解析 暴力求出所有三角形之间的所有交点&#xff0c;提出所有的横坐标。 然后任意两个相邻的横坐标之间的面积都是若干个梯形。 那么就可以求出对于每一个横坐标截得的三角形长度的并的和&#xff0c;然后加在一起乘高除以二即可。 在这里插入代码片#include<bits/stdc.h&…

自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference

在前段时间我写了一篇迁移 csproj 格式的博客 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj&#xff0c;不过全过程是手工进行的&#xff0c;而且到最后处理 XAML 问题也非常头疼。现在&#xff0c;我们可以利用工具自动地完成这个过程。…

[NowCoder牛客]2021NOIP提高组模拟赛第二场T3——树数树(启发式合并堆)

树数树descriptionsolutioncodedescription 【题目描述】 牛牛有一棵 n 个点的有根树&#xff0c;根为 1。 我们称一个长度为 m 的序列 a 是好的&#xff0c;当且仅当&#xff1a; • ∀&#x1d456;∈(1,&#x1d45a;]∀&#x1d456;∈(1, &#x1d45a;]∀i∈(1,m]&#…

Acwing1086. 恨7不成妻(未解决)

Acwing1086. 恨7不成妻 题意&#xff1a; 问一个区间内与7无关的整数的平方和 与7有关包括&#xff1a; 1.整数中某一位是 7&#xff1b; 2.整数的每一位加起来的和是 7 的整数倍&#xff1b; 3.这个整数是 7 的整数倍。 题解&#xff1a; 数位dp&#xff0c;有点难。。 这…

模板:拓展kmp(Z函数)

所谓拓展kmp&#xff0c;就是拓展的kmp &#xff08;逃&#xff09; 前言 小清新算法&#xff0c;更像一个trick。 exkmp能够在线性复杂度内求出字符串所有后缀与字符串本身的lcp。 个人感觉这个东西和kmp关系不大&#xff0c;反而有些像马拉车的思想。 之前学的东西&#xf…

牛客NOIP2021提高组OI赛前模拟赛第一场T3——与巨(数学)

与巨descriptionsolutioncodedescription 【题目描述】 定义无穷序列f:f11,fnfn−1∗21f:f_11,f_nf_{n-1}*21f:f1​1,fn​fn−1​∗21 定义函数G(x)min⁡fi≥x(fi)G(x)\min_{f_i\ge x}(f_i)G(x)minfi​≥x​(fi​) 定义dpc,00,dpc,imax⁡(dpc,i−1,[((i∗c)&G(i))i]∗i)…

ASP.NET Core 自定义认证方式--请求头认证

Intro最近开始真正的实践了一些网关的东西&#xff0c;最近写几篇文章分享一下我的实践以及遇到的问题。本文主要介绍网关后面的服务如何进行认证。解决思路网关可以做一部分的认证和授权&#xff0c;服务内部有时候也会需要用户的信息&#xff0c;这时该怎么办呢&#xff0c;我…

2016ICPC沈阳站

2016ICPC沈阳站 题号题目知识点难度AThickest Burger贪心签到BRelative atomic mass贪心签到CRecursive sequence矩阵快速幂快铜DWinning an AuctionECounting Cliquesdfs剪枝稳铜快银FSimilar RotationsGDo not pour outHGuessing the Dice RollIThe ElderJQuery on a graphK…

P7516 [省选联考 2021 A/B 卷] 图函数

解析 纯纯的人类智慧题。 关键性质&#xff1a;vvv 可以在计算 f(u,G)f(u,G)f(u,G) 时产生贡献&#xff0c;当且仅当 GGG 中 u,vu,vu,v 之间可以通过 [v,n][v,n][v,n] 的点互相到达。 充分性较为显然&#xff0c;编号更大的点不会比 vvv 先删去&#xff0c;所以必然在 vvv 时…

开发语言大爆炸的时代,究竟谁主沉浮?

开发语言大爆炸的时代&#xff0c;究竟谁主沉浮&#xff1f;当这个系列本来打算是写人物的&#xff0c;而且是写我们身边那些优秀的开发者&#xff0c;然而当第一篇文章&#xff0c;写的是关于我们长沙.NET社区的优秀开发者邹琼俊&#xff0c;发表在博客园之后&#xff0c;有一…

2021牛客NOIP提高组OI赛前模拟赛第一场T2——牛牛和数组操作(区间dp)

牛牛和数组操作descriptionsolutioncodedescription 【题目描述】 有n 2个整数a0, a1, . . . , an, an1&#xff0c; a0 an1 0。你需要做确切地n次操作&#xff0c;每次 操作为以下形式&#xff1a; 选择一个整数x满足ax ≠ 0&#xff0c;使得ax 0&#xff0c;令lmaxi<…

杜教BM模板(用于求线性递推公式第N项)

通过手动求出线性递推公式的前几项&#xff08;一般要前8项&#xff09;&#xff0c;杜教BM模板可以直接求第n项是多少。。我才知道&#xff0c;离谱。。对于我来说是妙计 //递推公式黑科技 #include<bits/stdc.h> using namespace std; ///#define X first //#define Y…

Asp.NETCore轻松学系列阅读指引目录

前言耗时两个多月&#xff0c;坚持写这个入门系列文章&#xff0c;就是想给后来者更好更快的上手体验&#xff0c;这个系列可以说是从入门到进阶&#xff0c;适合没有 .NETCore 编程经验到小白同学&#xff0c;也适合从 .NET Framework 迁移到 .NETCore 的朋友。本系列从安装环…

P6620 [省选联考 2020 A 卷] 组合数问题(斯特林数、下降幂)

解析 给出 n,x,pn,x,pn,x,p 和一个 mmm 次的多项式 f(k)f(k)f(k)&#xff0c;求解&#xff1a; ∑k0nf(k)xk(nk)modp\sum_{k0}^nf(k)x^k\binom n k\mod pk0∑n​f(k)xk(kn​)modp 把多项式拆成若干个单项式&#xff0c;现在就是要求&#xff1a; ∑k0nkpxk(nk)\sum_{k0}^nk^px…

CF750G New Year and Binary Tree Paths(数位dp二进制+数学)

CF750G New Year and Binary Tree Pathsdescriptionsolutioncodedescription 题目链接 一颗无穷个节点的完全二叉树。 求有多少条树上的简单路径编号和为 s。 s≤1e15s\le 1e15s≤1e15 solution 一条单链的情况 考虑从节点xxx开始走一条节点个数是hhh的链&#xff08;链长为…

eShopOnContainers 知多少[9]:Ocelot gateways

引言客户端与微服务的通信问题永远是一个绕不开的问题&#xff0c;对于小型微服务应用&#xff0c;客户端与微服务可以使用直连的方式进行通信&#xff0c;但对于对于大型的微服务应用我们将不得不面对以下问题&#xff1a;如何降低客户端到后台的请求数量&#xff0c;并减少与…