P6177-Count on a tree II/[模板]树分块

正题

题目链接:https://www.luogu.com.cn/problem/P6177


题目大意

nnn个点的一棵树mmm次询问树上颜色。
强制在线

1≤n≤4×105,1≤m≤105,0≤vali<2311\leq n\leq 4\times 10^5,1\leq m\leq 10^5,0\leq val_i<2^{31}1n4×105,1m105,0vali<231


解题思路

把所有深度为n\sqrt nn并且下面至少有n\sqrt nn的深度的点标记,这样保证关键点数量不超过n\sqrt nn

然后每个点到他周围关键点的距离也不会超过 n\sqrt nn

这样可以处理出关键点两两之间的颜色bitsetbitsetbitset,然后每次路径找两个最近的关键点爆做就好了。

时间复杂度O((m+n)(n+nω))O((m+n)(\sqrt n+\frac{n}{\omega}))O((m+n)(n+ωn))


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cmath>
using namespace std;
const int N=41000,T=300,M=(4e4)/T+10;
struct node{int to,next;
}a[N<<1];
int n,m,tot,cnt,sum,fa[N],v[N],top[N],ls[N],d[N],dep[N],w[N],b[N],mark[N],dfn[N],ed[N],g[M][M];
bitset<N> f[M][M],bt;
void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void dfs(int x){for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x])continue;dep[y]=dep[x]+1;fa[y]=x;dfs(y);d[x]=max(d[x],d[y]+1);}if(dep[x]%T==0&&d[x]>=T)mark[x]=++cnt;return;
}
void dFs(int x){if(mark[x])top[x]=x;dfn[x]=++cnt;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x])continue;top[y]=top[x];dFs(y);}ed[x]=cnt;return;
}
void calc(int x,int p,int fa){if(!v[w[x]])bt[w[x]]=1,sum++;v[w[x]]++;if(mark[x])f[p][mark[x]]=bt,g[p][mark[x]]=sum;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa)continue;calc(y,p,x);}v[w[x]]--;if(!v[w[x]])bt[w[x]]=0,sum--;return;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&w[i]),b[i]=w[i];sort(b+1,b+1+n);int L=unique(b+1,b+1+n)-b-1;for(int i=1;i<=n;i++)w[i]=lower_bound(b+1,b+1+L,w[i])-b;for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}dfs(1);cnt=0;dFs(1);for(int i=1;i<=n;i++)if(mark[i])calc(i,mark[i],i);int last=0;while(m--){int x,y;scanf("%d%d",&x,&y);x^=last;if(top[x]==top[y]){int xx=x,yy=y,ans=0;while(x!=y){if(dep[x]<dep[y])swap(x,y);if(!v[w[x]])ans++,v[w[x]]=1;x=fa[x];}if(!v[w[x]])ans++,v[w[x]]=1;printf("%d\n",ans);last=ans;x=xx;y=yy;while(x!=y){if(dep[x]<dep[y])swap(x,y);v[w[x]]=0;x=fa[x];}v[w[x]]=0;}else{if(dfn[x]>=dfn[y]&&dfn[x]<=ed[y])swap(x,y);if(dfn[y]>=dfn[x]&&dfn[y]<=ed[x]){int z=top[y];while(top[fa[z]]!=top[x])z=top[fa[z]];bt=f[mark[z]][mark[top[y]]];int ans=g[mark[z]][mark[top[y]]];while(y!=top[y]){if(!bt[w[y]])ans++,bt[w[y]]=1;y=fa[y];}while(z!=x){if(!bt[w[z]])ans++,bt[w[z]]=1;z=fa[z];}if(!bt[w[z]])ans++,bt[w[z]]=1;printf("%d\n",ans);last=ans;}else{bt=f[mark[top[x]]][mark[top[y]]];int ans=g[mark[top[x]]][mark[top[y]]];while(x!=top[x]){if(!bt[w[x]])ans++,bt[w[x]]=1;x=fa[x];}while(y!=top[y]){if(!bt[w[y]])ans++,bt[w[y]]=1;y=fa[y];}printf("%d\n",ans);last=ans;}}}return 0;
}

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

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

相关文章

eShopOnContainers 看微服务③:Identity Service

引言通常&#xff0c;服务所公开的资源和 API 必须仅限受信任的特定用户和客户端访问。那进行 API 级别信任决策的第一步就是身份认证——确定用户身份是否可靠。在微服务场景中&#xff0c;身份认证通常统一处理。一般有两种实现形式&#xff1a;基于API 网关中心化认证&#…

P2168 [NOI2015] 荷马史诗(哈夫曼编码树)

传送门 文章目录题目描述解析细节代码题目描述 解析 其实就是构造一棵树 另所有带权点都为叶子节点 其代价为权值与深度的乘积 求最小代价及最小代价下的最小深度 可以看成一开始有n棵小树 每次把k棵合并在一起 最后合成一棵大树就行了 每次合并的代价是k棵树的权值和 看到这…

B-Suffix Array

B-Suffix Array 题意&#xff1a; 一个字符串只含有a和b&#xff0c;先给出b数组的构造方式&#xff1a; 对于每个位置i来说&#xff1a; 如果存在一个位置j&#xff0c;使得j<i,且s[j] s[i],则b[i]i-j否则b[i]0 现在对字符串每个后缀都构造B数组&#xff0c;并按照字典…

Wannafly挑战赛10F-小H和遗迹【Trie,树状数组】

正题 题目链接:https://ac.nowcoder.com/acm/contest/72/F 题目大意 nnn个字符串&#xff0c;包括小写字母和#\##。其中#\##可以替换为任意字符串。求有多少对字符串可能相同。 保证每个字符串至少有一个#\##。 2≤n≤500000,∑i1n∣si∣≤1062\leq n\leq 500000,\sum_{i1}^n…

线段树合并、分裂

基本概念&#xff1a; 如果需要维护许多个大小为 \(10^5\) 级别的多重集&#xff0c;可以看做给每一个多重集建立一棵线段树。线段树的合并、分裂就是多重集的累加、分开。 这里使用动态开点的方式存储线段树树。 如果一个节点为空&#xff0c;那么它的编号为 \(0\) 。 变量释义…

(神奇的)虚树(初步了解)

参考文献&#xff1a; 博文1 博文2 博文3 引入 在一类树上动态规划问题中,题目给出的询问往往包含树上的很多各节点,并保证总的点数规模小于某个值. 如果我们直接在整颗树上进行dp的话,时间复杂度与询问的次数有关,这显然是不可接受的,如果我们可以找到一种动态规划的方法,使…

P2048 [NOI2010] 超级钢琴(RMQ 贪心)

文章目录题目描述解析代码传送门题目描述 解析 首先&#xff0c;如果只有一个和弦&#xff0c;那么问题显然简单了 用前缀和结合ST表随便做做即可 然而 这次要求前k大的 怎么办呢&#xff1f; 参照之前有一道序列合并的做法 我们想到&#xff0c;可以先建一个优先队列&#xf…

微服务架构基础之Service Mesh

ServiceMesh(服务网格) 概念在社区里头非常火&#xff0c;有人提出 2018 年是 ServiceMesh 年&#xff0c;还有人提出 ServiceMesh 是下一代的微服务架构基础。那么到底什么是 ServiceMesh&#xff1f;它的诞生是为了解决什么问题&#xff1f;企业是否适合引入 ServiceMesh&…

[SDOI2011]消耗战

[SDOI2011]消耗战 题意&#xff1a; 给出n个点的一棵带有边权的树,以及q个询问.每次询问给出k个点,询问这使得这k个点与1点不连通所需切断的边的边权和最小是多少. 题解&#xff1a; 树型dp虚树 dp[x]:切断x及其子树上询问点的最小代价 预处理出minv[pos]代表从11到pos路径…

【做题记录】CF1428E Carrots for Rabbits—堆的妙用

CF1428E Carrots for Rabbits 题意&#xff1a; 有 \(n\) 个萝卜&#xff0c;每个萝卜的初始大小为 \(a_i\) 。现在要把这些萝卜切为为 \(k\) 个。吃每一个萝卜的时间为这个萝卜的大小的平方&#xff0c;求吃完所有萝卜的最小时间&#xff0c;即 \(\sum_{i1}^{k}{a_i^2}\) 最小…

P4716-[模板]最小树形图

正题 题目链接:https://www.luogu.com.cn/problem/P4716 题目大意 给出nnn个点mmm条边的一张有向图&#xff0c;求以rrr为根的最小外向树。 1≤n≤100,1≤m≤1041\leq n\leq 100,1\leq m\leq 10^41≤n≤100,1≤m≤104 解题思路 考虑一种贪心&#xff0c;对于每个点我们先选出…

P1081 [NOIP2012 提高组] 开车旅行(倍增)(动态规划)

洛谷传送门 文章目录题目描述解析代码题目描述 解析 利用倍增&#xff0c;设计dp慢慢敲即可。。。 注意距离累加在一起会爆int&#xff0c;需要ll 特判条件非常之复杂。。。 心力交瘁&#xff0c;就酱了 代码 #include <bits/stdc.h> using namespace std; #define ll…

dotnet core调试docker下生成的dump文件

最近公司预生产环境.net core应用的docker容器经常出现内存暴涨现象&#xff0c;有时会突然吃掉几个G,触发监控预警&#xff0c;造成容器重启。分析了各种可能原因&#xff0c;修复了可能发生的内存泄露&#xff0c;经测试本地正常&#xff0c;但是发到预生产还是会有内存暴涨现…

【做题记录】区间排序—线段树

1. CF558E A Simple Task 题意&#xff1a; 给定由小写字母组成的字符串 \(s\) 每一次操作如下&#xff1a; \(opt0\) &#xff1a;将 \([l,r]\) 降序排序 \(opt1\) &#xff1a;将 \([l,r]\) 升序排序 输出最终字符串 题解&#xff1a; 大致思想为&#xff0c;建 \(26\) 棵线…

Quadratic Form

Quadratic Form 题意&#xff1a; 一个n * n 的正定矩阵和一个n维的向量b&#xff0c;现在找一个x1&#xff0c;x2&#xff0c;…xn满足以下条件&#xff1a; 求这个式子&#xff0c;最后输出P * Q-1 mod 998244353. 题解&#xff1a; 参考 线性代数学过n阶正定的实矩阵等…

P3426-[POI2005]SZA-Template【KMP】

正题 题目链接:https://www.luogu.com.cn/problem/P3426 题目大意 给出一个长度为nnn的字符串sss&#xff0c;求一个长度最小的字符串ttt使得sss所有ttt和ttt匹配的位置能覆盖串sss。 1≤n≤51051\leq n\leq 5\times 10^51≤n≤5105 解题思路 首先答案肯定是原串的一个borde…

8分钟学会Consul集群搭建及微服务概念

Consul介绍&#xff1a;Consul 是由 HashiCorp 公司推出的开源软件&#xff0c;用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案&#xff0c;Consul 的方案更“一站式”&#xff0c;内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Valu…

取模除法(逆元)(费马小定理)(线性求逆元)

文章目录引言逆元费马小定理内容应用证明线性求逆元thanks for reading&#xff01;引言 我们做题时经常会由于答案过大&#xff0c;被要求使答案对一个质数取模 我们都知道&#xff0c;加和乘对取模是没有影响的 减法也只需要写一个&#xff1a; int mod_minus(int a,int b)…

数学基础知识(高精、快速幂、龟速乘……)

压位高精 模板代码 龟速乘 ll ch(ll x,ll y) {ll ret0;while(y){if(y&1) ret(retx)%m;x(xx)%m,y>>1;}return ret; }

P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包

P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包 题目&#xff1a; 给定一些点&#xff0c;问围住所有点所用的围栏的长度 题解&#xff1a; 凸包模板题 凸包详细 代码&#xff1a; #include<iostream> #include<algorithm> #include<cstdio&g…