[HNOI2015] 接水果(倍增 + 整体二分)

problem

luogu-P3242

solution

本题的难点在于如何判定路径之间是否覆盖。

这里我们尝试树常见的 dfs\text{dfs}dfs 序。

考虑 x−yx-yxy 路径如果要覆盖 u−vu-vuv 路径需要满足怎样的条件。

以下均假设 dfs(u)<dfs(v),dfs(x)<dfs(y)dfs(u)<dfs(v),dfs(x)<dfs(y)dfs(u)<dfs(v),dfs(x)<dfs(y)

  • lca(u,v)≠ulca(u,v)\ne ulca(u,v)=u

    xxx 必须是 uuu 子树内的一点,yyy 必须是 vvv 子树内的一点。

    我们记点 iii 子树内的 dfs\text{dfs}dfs 序列对应连续区间为 [l(i),r(i)][l(i),r(i)][l(i),r(i)]

    则要 l(u)≤l(x)≤r(u)∧l(v)≤l(y)≤r(v)l(u)\le l(x)\le r(u)\wedge l(v)\le l(y)\le r(v)l(u)l(x)r(u)l(v)l(y)r(v)

    其实,我们可以将 (l(x),l(y))(l(x),l(y))(l(x),l(y)) 当成一个点的坐标;

    (l(u),l(v))−(r(u),r(v))(l(u),l(v))-(r(u),r(v))(l(u),l(v))(r(u),r(v)) 看作左下角为 (l(u),l(v))(l(u),l(v))(l(u),l(v)) 右上角为 (r(u),r(v))(r(u),r(v))(r(u),r(v)) 的矩阵。

    发现这个点就是落在这个矩阵内的。

    所以问题就是某个点被若干个矩形包含,求这里面的权值第 kkk 小的矩阵。

  • lca(u,v)=ulca(u,v)=ulca(u,v)=u

    xxx 必须属于 u→vu\rightarrow vuv 走的第一个点子树外的部分,yyy 仍是 vvv 子树内一点。

    即,假设 uuuvvv 的路径经过的 uuu 的儿子为 www,即路径为 u→w→…vu\rightarrow w\rightarrow\dots vuwv

    则要 1≤l(x)<l(w)∨r(w)<l(x)≤n1\le l(x)<l(w)\vee r(w)<l(x)\le n1l(x)<l(w)r(w)<l(x)nl(v)≤l(y)≤r(v)l(v)\le l(y)\le r(v)l(v)l(y)r(v)

    两个条件是独立的。

    • 1≤l(x)<l(w)1\le l(x)<l(w)1l(x)<l(w),对应矩阵 (1,l(v))−(l(w)−1,r(v))(1,l(v))-(l(w)-1,r(v))(1,l(v))(l(w)1,r(v))
    • r(w)<l(x)≤nr(w)<l(x)\le nr(w)<l(x)n,对应矩阵 (l(v),r(w)+1)−(r(v),n)(l(v),r(w)+1)-(r(v),n)(l(v),r(w)+1)(r(v),n)

lcalcalca 和某个点的下面一个点,可以倍增,可以树链剖分,好像是链剖分快点,但我们不需要卡这么点常。

对于一个询问,我们可以二分答案,然后把所有权值不大于答案的矩阵激活,统计包含该询问对应点的被激活的矩阵有多少个,根据和 kkk 的关系移动二分端点。

所以我们可以对所有询问套一个整体二分。

而这个矩阵激活我们就可以扫描线地做。

对于 (x1,y1)−(x2,y2)(x1,y1)-(x2,y2)(x1,y1)(x2,y2) 的矩阵,我们以 xxx 轴做扫描线从左往右扫。

变成 (y1,y2,x1,1)(y1,y2,x1,1)(y1,y2,x1,1)x=x1x=x1x=x1 的时候把 [y1,y2]+1[y1,y2]+1[y1,y2]+1(y1,y2,x2+1,−1)(y1,y2,x2+1,-1)(y1,y2,x2+1,1)x=x2x=x2x=x2 的时候把 [y1,y2]−1[y1,y2]-1[y1,y2]1

数据结构仍然使用树状数组。

由于使用的是扫描线,所以一开始要将所有询问按 xxx 排序,并且将矩阵按权值排序。

且每次整体二分内部都要将权值属于 [l,mid][l,mid][l,mid] 区间的矩阵重新按 xxx 轴排序。

时间复杂度 O(nlog⁡2n)O(n\log^2n)O(nlog2n)

code

#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 40005vector < int > G[maxn];
int dep[maxn], st[maxn], ed[maxn];
int f[maxn][16];
int cnt;void dfs( int u, int fa ) {dep[u] = dep[fa] + 1, f[u][0] = fa, st[u] = ++ cnt;for( int i = 1;i < 16;i ++ ) f[u][i] = f[f[u][i - 1]][i - 1];for( int v : G[u] ) if( v ^ fa ) dfs( v, u );ed[u] = cnt;
}
int lca( int u, int v ) {if( dep[u] < dep[v] ) swap( u, v );for( int i = 15;~ i;i -- ) if( dep[f[u][i]] >= dep[v] ) u = f[u][i];if( u == v ) return u;for( int i = 15;~ i;i -- ) if( f[u][i] ^ f[v][i] ) u = f[u][i], v = f[v][i];return f[u][0];
}
int top( int u, int d ) {for( int i = 15;~ i;i -- ) if( d >> i & 1 ) u = f[u][i]; return u;
}int cntg, n, m1, m2;
int ans[maxn];
struct scan { int l, r, x, op; }s[maxn << 2];
struct matrix { int x1, y1, x2, y2, w; }g[maxn << 2];
struct query { int x, y, k, id; }q[maxn], L[maxn], R[maxn];namespace BIT {int t[maxn];void add( int l, int r, int k ) {for( ;l <= n;l += l & -l ) t[l] += k;for( ;r <= n;r += r & -r ) t[r] -= k;}int ask( int x ) {int sum = 0;for( ;x;x -= x & -x ) sum += t[x];return sum;}
}void solve( int l, int r, int ql, int qr ) {if( ql > qr ) return;if( l == r ) { for( int i = ql;i <= qr;i ++ ) ans[q[i].id] = g[l].w; return; }int mid = l + r >> 1; cnt = 0;for( int i = l;i <= mid;i ++ ) {s[++ cnt] = (scan){ g[i].y1, g[i].y2, g[i].x1, 1 };s[++ cnt] = (scan){ g[i].y1, g[i].y2, g[i].x2 + 1, -1 };}sort( s + 1, s + cnt + 1, []( scan a, scan b ) { return a.x < b.x; } );int cntl = 0, cntr = 0, j = 1;for( int i = ql;i <= qr;i ++ ) {for( ;j <= cnt and s[j].x <= q[i].x;j ++ ) BIT :: add( s[j].l, s[j].r + 1, s[j].op );int k = BIT :: ask( q[i].y );if( q[i].k <= k ) L[++ cntl] = q[i];else q[i].k -= k, R[++ cntr] = q[i]; }for( int i = 1;i < j;i ++ ) BIT :: add( s[i].l, s[i].r + 1, -s[i].op );//不一定把l~mid的矩阵都挂在了树上的for( int i = 1;i <= cntl;i ++ ) q[ql + i - 1] = L[i];for( int i = 1;i <= cntr;i ++ ) q[ql + cntl + i - 1] = R[i];solve( l, mid, ql, ql + cntl - 1 );solve( mid + 1, r, ql + cntl, qr );
}int main() {scanf( "%d %d %d", &n, &m1, &m2 );for( int i = 1, u, v;i < n;i ++ ) {scanf( "%d %d", &u, &v );G[u].push_back( v );G[v].push_back( u );}dfs( 1, 0 );for( int i = 1, u, v, w;i <= m1;i ++ ) {scanf( "%d %d %d", &u, &v, &w );if( st[u] > st[v] ) swap( u, v );int x = lca( u, v );if( x ^ u ) g[++ cntg] = (matrix){ st[u], st[v], ed[u], ed[v], w };else {x = top( v, dep[v] - dep[u] - 1 );if( st[x] ^ 1 ) g[++ cntg] = (matrix){ 1, st[v], st[x] - 1, ed[v], w };if( ed[x] ^ n ) g[++ cntg] = (matrix){ st[v], ed[x] + 1, ed[v], n, w };}}for( int i = 1, u, v, k;i <= m2;i ++ ) {scanf( "%d %d %d", &u, &v, &k );if( st[u] > st[v] ) swap( u, v );q[i] = (query){ st[u], st[v], k, i };}sort( q + 1, q + m2 + 1, [](query a, query b) { return a.x < b.x; } );sort( g + 1, g + cntg + 1, [](matrix a, matrix b){ return a.w < b.w; } );solve( 1, cntg, 1, m2 );for( int i = 1;i <= m2;i ++ ) printf( "%d\n", ans[i] );return 0;
} 

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

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

相关文章

ASP.NET Core使用Jaeger实现分布式追踪

前言最近我们公司的部分.NET Core的项目接入了Jaeger&#xff0c;也算是稍微完善了一下.NET团队的技术栈。至于为什么选择Jaeger而不是Skywalking&#xff0c;这个问题我只能回答&#xff0c;大佬们说了算。前段时间也在CSharpCorner写过一篇类似的介绍Exploring Distributed T…

[SCOI2007] 修车(费用流 + 差分时间段建图)

problem luogu-P2053 solution 假设只有一个工作人员。修车顺序为 p1,p2,...,pnp_1,p_2,...,p_np1​,p2​,...,pn​ 是一个 nnn 的排列。 那么对于第 iii 个被修的车的等待时间应为 Tp1...TpiT_{p_1}...T_{p_i}Tp1​​...Tpi​​。 总的等待时间则是 Tp1(Tp1Tp2)...(Tp1..…

长沙开发者技术大会暨.NET技术社区成立大会倒数第13天

待你扬帆起航&#xff0c;一起精彩纷呈&#xff01;长沙开发者技术大会暨.NET技术社区成立大会倒数第13天&#xff01;2019年4月21日期待与你相聚在.NET技术社区&#xff01;我们今天会完成海报制作和报表表单&#xff0c;海报内容初步如下所示&#xff1a;活动信息 长沙开发者…

[TJOI2011] 卡片(网络流 + 质因子优化建图)

problem luogu-P2065 solution 这个拿走一组共两张卡片的操作其实就是一个匹配。 直接两个数的最大公约数大于 111 就建一条边&#xff0c;跑二分图匹配最大流即可。 然而如果直接枚举两个数然后算他们的 gcd\text{gcd}gcd &#xff0c;时间复杂度 O(Tn2log⁡V)O(Tn^2\log…

C#并行编程(1):理解并行

什么是并行并行是指两个或者多个事件在同一时刻发生。在程序运行中&#xff0c;并行指多个CPU核心同时执行不同的任务&#xff1b;对于单核心CPU,严格来说是没有程序并行的。并行是为了提高任务执行效率&#xff0c;更快的获取结果。与并发的区别&#xff1a;并发是指两个或者多…

P2163 [SHOI2007]园丁的烦恼(二维数点模板题)

P2163 [SHOI2007]园丁的烦恼 题意&#xff1a; 在一个二维平面内有一些点&#xff0c;给你一个左上角和右下角的点&#xff0c;问这个范围内有多少点 题解&#xff1a; 二维数点模板题 我们设F(a,b)表示以(0,0)为左下角&#xff0c;(a,b)为右上角的矩阵内有多少点 如图不难…

[CQOI2017] 小Q的表格(分块 + 整除分块 + 数学 + 前缀和)

problem luogu-P3700 solution f(a,b)f(b,a)f(a,b)f(b,a)f(a,b)f(b,a) 意味着我们只用考虑半个棋盘的信息。 b∗f(a,ab)(ab)∗f(a,b)b*f(a,ab)(ab)*f(a,b)b∗f(a,ab)(ab)∗f(a,b) 会发现修改 f(a,b)f(a,b)f(a,b) 就影响 f(a,ab)f(a,ab)f(a,ab) 进而影响 f(a,a2b)…f(a,a2b)\…

Orleans MultiClient 多个Silo复合客户端

介绍Orleans.MultiClient 是一个 Orleans 复合客户端&#xff0c;只需要简单配置就可以简单高效连接和请求 Orleans 服务。Orleans.MultiClient 可以轻松连接多个不同服务的 Orleans 服务,在请求 Orleans 时会根据请求的接口自动寻找 Orleans 客户端&#xff0c;使用者无需关心…

[kuangbin]各种各样的题单

[kuangbin]各种各样的题单 专题1 简单搜索 POJ 1321 POJ 2251 POJ 3278 POJ 3279 POJ 1426 POJ 3126 POJ 3087 POJ 3414 FZU 2150 UVA 11624 POJ 3984 HDU 1241 HDU 1495 HDU 2612 专题2 搜索进阶 HDU 1043 HDU 3567 HDU 2181 HDU 3533 HDU 1560 ZOJ 2477 HDU 3085 HDU 1067 HD…

[CQOI2017] 小Q的棋盘(贪心 / 树形dp)

problem luogu-P3698 solution1-贪心 显然我们想尽可能地少走回头路&#xff0c;即一直往下走。 所以我们可以都会有个初步地猜测是走最长链。 但很快就会想到万一这是一条单链&#xff0c;链中的点都是二度点&#xff0c;走得越深回头浪费的步数也越多。 然后就可能直接…

ASP.NET Core 进程内(InProcess)托管(6)《从零开始学ASP.NET CORE MVC》:

本文出自《从零开始学ASP.NET CORE MVC》推荐文章&#xff1a;ASP.NET Core 中的 Main方法ASP.NET Core 进程内(InProcess)托管在这个视频中我们将讨论在ASP.NET Core中的进程内(InProcess)托管模型什么是Kestrel服务器当一个 ASP.NET Core 应用程序执行的时候&#xff0c;.NET…

约会安排 HDU - 4553

约会安排 HDU - 4553 题意&#xff1a; 题意又丑又长就不叙述了 题解&#xff1a; 这个题一开始理解错了。。。题目相当于是有三种情况占据时间&#xff0c;分别是学习&#xff0c;女神和屌丝&#xff0c;我们用不同的lazy来表示女神和屌丝&#xff0c;根据优先级去更新状态…

ML.NET机器学习、API容器化与Azure DevOps实践(一):简介

打算使用几篇文章介绍一下.NET下的机器学习框架ML.NET的具体应用&#xff0c;包括一些常用的业务场景、算法的选择、模型的训练以及RESTful API的创建、机器学习服务容器化&#xff0c;以及基于Azure DevOps的容器化部署等等相关的内容。如果你从来没有玩过机器学习&#xff0c…

[TJOI2011] 书架(线段数优化dp + 单调栈)

problem luogu-P1295 首先可以列出一个暴力 dpdpdp 转移。 设 f(i):f(i):f(i): 到 iii 为止划分若干组&#xff0c;每组最大值的和 的最小值。 然后枚举最后一组&#xff0c;即 iii 所在组的开头 jjj&#xff0c;则 f(i)min⁡{f(j−1)max⁡j≤k≤i{ak}}f(i)\min\Big\{f(j-1…

Picture POJ - 1177(矩形周长并))

Picture POJ - 1177 题目&#xff1a; 多个矩阵相交在一起&#xff0c;问新图形的周长是多少 题解&#xff1a; 参考题解 周长分为两部分&#xff1a;横线和竖线 横线计算方法&#xff1a;现在总区间被覆盖的长度和上一次总区间被覆盖的长度之差的绝对值 那么我们只需要从…

聊一聊C# 8.0中的await foreach

很开心今天能与大家一起聊聊C# 8.0中的新特性-Async Streams,一般人通常看到这个词表情是这样.简单说,其实就是C# 8.0中支持await foreach.或者说,C# 8.0中支持异步返回枚举类型async Task<IEnumerable<T>>.好吧,还不懂?Good,这篇文章就是为你写的,看完这篇文章,你…

【学习笔记】同余最短路

同余最短路是用来解决一类 ∑i1naixi∈[L,R]\sum_{i1}^n a_ix_i\in[L,R]∑i1n​ai​xi​∈[L,R] 问题的方法。 其中 L,RL,RL,R 值非常大&#xff0c;而 nnn 不是很大&#xff0c;大概是接受 O(n2)O(n^2)O(n2) 的范围&#xff0c;xix_ixi​ 是自定义的系数。 先差分一下&#…

Codeforces Round #738 (Div. 2)

Codeforces Round #738 (Div. 2) 文章目录A题解&#xff1a;代码&#xff1a;B题意&#xff1a;题解&#xff1a;代码&#xff1a;C题意&#xff1a;题解&#xff1a;代码&#xff1a;D1题意&#xff1a;题解&#xff1a;代码:题号题目知识点AMocha and MathBMocha and Red and…

ASP.NET Core 实现带认证功能的Web代理服务器

引言最近在公司开发了一个项目&#xff0c;项目部署架构图如下&#xff1a;思路如图中文本所述&#xff0c;公司大数据集群不允许直接访问外网&#xff0c;需要一个网关服务器代理请求&#xff0c;本处服务器A就是边缘代理服务器的作用。通常技术人员最快捷的思路是在服务器A上…

[ZJOI2010] 排列计数(dp + 组合数)

problem luogu-P2606 solution 我们对 i−⌊i2⌋i-\lfloor\frac i2\rfloori−⌊2i​⌋ 远没有 i−2∗i,2∗i1i-2*i,2*i1i−2∗i,2∗i1 敏感&#xff0c;这其实就是个二叉树&#xff0c;而且是个小根堆。 每个点的值都小于左右儿子的值&#xff08;如果有左右儿子&#xff0…