好题好题。


难点在建图,因为图的边数将会决定最小生成树的时间复杂度。我们肯定希望能够只建 \(O(n)\) 级别的边,这样时间复杂度就可以做到 \(O(n\log n)\)。

观察到当 \(i,j,k\) 三个区间能够互相连边时(这里假设 \(a_i<a_j<a_k\)),我们绝对不会连 \((i,k)\) 这条边。

那么假如我们将所有区间按 \(a\) 值大小从小到大排序,每次将当前区间与该区间中所有颜色连边,然后再将这个区间染上新颜色,我们就能保证不会连上述所谓的 \((i,k)\) 边。这很明显是可以珂学解决的。

考虑证明珂朵莉树时间复杂度正确性(实际上也是在证明边数正确性)。

假设原先有 \(x\) 个颜色段,若连 \(y\) 条边,则至少减少 \(y-3\) 个颜色段(除最左边的颜色和最右边的颜色外,中间所有颜色块都一定会被删去,同时全部更新为一个新的颜色段),假如 \(y\) 很小,那么本次操作的单次时间复杂度可忽略不计;假如 \(y\) 很大,则本次操作减少的颜色段数将与花费的时间复杂度在一个量级,就相当于这些参与连边操作的颜色段将不会再次花费时间复杂度,总体时间复杂度依旧正确。

所以我们 极端口胡的 证明了边数级别就是 \(O(n)\),那么珂朵莉树时间复杂度就是 \(O(n\log n)\)。

最小生成树就不用说了。

最终时间复杂度 \(O(n\log n)\),可以通过。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e6+5;
int t,n,m,k,ans,fa[N];
struct edge{int x,y,w;}ed[N];
struct line{int l,r,a;}ln[N];
int cmp(edge x,edge y){
return x.w<y.w;
}int cmp2(line x,line y){
return x.a<y.a;
}struct odt{
int l,r;
mutable int v;
bool operator<(const odt &c)const{
return l<c.l;
}
};set<odt>st;
#define iter set<odt>::iterator
struct chtholly{
iter spilt(int x){
iter it=st.lower_bound({x,0,0});
if(it!=st.end()&&(*it).l==x) return it;
it--;if((*it).r<x) return st.end();
int l=(*it).l,r=(*it).r,v=(*it).v;
st.erase(it);st.insert({l,x-1,v});
return st.insert({x,r,v}).first;
}void assign(int l,int r,int v){
iter tr=spilt(r+1),tl=spilt(l);
st.erase(tl,tr);st.insert({l,r,v});
}void con(int l,int r,int id){
iter tr=spilt(r+1),tl=spilt(l);
for(iter it=tl;it!=tr;it++) if((*it).v)
ed[++m]={id,(*it).v,ln[id].a-ln[(*it).v].a};
}
}seniorious;
void init(){
for(int i=1;i<=n;i++) fa[i]=i;
}int find(int x){
return fa[x]=(fa[x]==x?x:find(fa[x]));
}void solve(){
cin>>n,init(),m=ans=0,k=n;
for(int i=1;i<=n;i++)
cin>>ln[i].l>>ln[i].r>>ln[i].a;
sort(ln+1,ln+n+1,cmp2);
st.clear(),st.insert({1,(int)1e9,0});
for(int i=1;i<=n;i++){
seniorious.con(ln[i].l,ln[i].r,i);
seniorious.assign(ln[i].l,ln[i].r,i);
}sort(ed+1,ed+m+1,cmp);
for(int i=1;i<=m;i++){
int x=find(ed[i].x);
int y=find(ed[i].y);
if(x==y) continue;
k--,fa[x]=y,ans+=ed[i].w;
if(k==1){
cout<<ans<<"\n";
return;
}
}cout<<"-1\n";
}signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--) solve();
return 0;
}/*
In this world where the sun dips in the west.
Set in the heavenly forest.
When this war is over.
The people who do not return and the multitudes who look on.
In the name of justice.
A past that will never die,The fading future.
I'm back.Even if the sun is fading.
Even if I can't see the future.
The light of this moment.
I hope you won't forget.
---- The Happiest Girl in the World
*/

[CF1981E] Turtle and Intersected Segments 题解的更多相关文章

  1. POJ3304:Segments——题解

    http://poj.org/problem?id=3304 题目大意:给n条线段,求是否存在一条直线,将所有线段投影到上面,使得所有投影至少交于一点. ——————————————————————— ...

  2. [CF846C]Four Segments题解

    我们暴力枚举一下\(delim_{1}\) 然后对于每个\(delim_{1}\),O(n)扫一遍+前缀和求出最大\(delim_{0}\)和\(delim_{2}\),然后记录一下它们的位置就行啦 ...

  3. Codeforces Round #535(div 3) 简要题解

    Problem A. Two distinct points [题解] 显然 , 当l1不等于r2时 , (l1 , r2)是一组解 否则 , (l1 , l2)是一组合法的解 时间复杂度 : O(1 ...

  4. Codeforces Round #690 (Div. 3)

    第一次 ak cf 的正式比赛,不正式的是寒假里 div4 的 Testing Round,好啦好啦不要问我为什么没有 ak div4 了,差一题差一题 =.= 不知不觉已经咕了一个月了2333. 比 ...

  5. 题解-CF1389F Bicolored Segments

    题面 CF1389F Bicolored Segments 给 \(n\) 条线段 \([l_i,r_i]\),每条有个颜色 \(t_i\in\{0,1\}\),求最多选出多少条线段,使没有不同颜色的 ...

  6. CodeForces 430A Points and Segments (easy)(构造)题解

    题意:之前愣是没看懂题意...就是给你n个点的坐标xi,然后还规定了Li,Ri,要求给每个点染色,每一组L,R内的点红色和黑色的个数不能相差大于1个,问你能不能染成功,不能输出-1,能就按照输入的顺序 ...

  7. LeetCode题解之Number of Segments in a String

    1.题目描述 2.题目分析 找到字符串中的空格即可 3.代码 int countSegments(string s) { ){ ; } vector<string> v; ; i < ...

  8. PAT甲题题解-1104. Sum of Number Segments (20)-(水题)

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  9. 【题解】CF1426D Non-zero Segments

    题目戳我 \(\text{Solution:}\) 若\([l,r]\)子段和是\(0,\)则\(sum[r]=sum[l-1].\) 于是我们可以考虑维护当前哪一个前缀和出现过.对于区间\([l,r ...

  10. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并

    D. Vika and Segments     Vika has an infinite sheet of squared paper. Initially all squares are whit ...

随机推荐

  1. httpclient 连接池测试

    为什么需要使用http连接池 1.降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗, ...

  2. manim边做边学--多面体

    在Manim中,对于多面体,有一系列封装好的类可以直接使用. 使用它们,可以方便快速的构建正多面体: Polyhedron:通过顶点和面的参数构建任意多面体 Tetrahedron:四面体 Octah ...

  3. shp转featureclass

    public void ConvertShapefileToFeatureClass() { // Create a name object for the source (shapefile) wo ...

  4. 前端跨平台调试代理神器Whistle

    概述 抓包一直是平时开发中经常要做的,有一款好用的抓包工具可以让开发体验更棒,以前一直用fiddler,fiddler虽然强悍,但是入手有一定难度,而且较笨重,今天介绍另一款抓包工具:Whistle. ...

  5. docker启动所有容器命令

    启动所有容器 docker start $(docker ps -a | awk '{ print $1}' | tail -n +2) 关闭所有容器 docker stop $(docker ps ...

  6. Nginx基础使用

    Nginx Nginx是一个WEB服务 [1].安装nginx 1.官网安装 2.使用默认的仓库安装,版本较低 3.编译方式安装,需要其他功能模块的时候 自定义安装 # 基于官网仓库的安装方式,版本较 ...

  7. .NET Aspire 中的服务发现

    .NET Aspire 中的服务发现 https://www.nuget.org/packages/Microsoft.Extensions.ServiceDiscovery .NET Aspire ...

  8. 禅道bug增加自定义字段

    禅道版本 18.9 需求 给禅道的bug模块,增加自定义字段. 目前主要增加"发现阶段"."所属环境"."出现频率" 增加bug的类型 在b ...

  9. Uninstall or delete MariaDB completely for re-installation

    I am new to this forum so pse forgive me if I am asking a question which already has been answered. ...

  10. P10936 导弹防御塔 题解

    题目链接 题目大意 城堡有 m 个敌人.n 个能发射导弹的防御塔.导弹的速度固定,都为 v.导弹需要 T1 秒发射,T2 分钟冷却,还需要防御塔到敌人距离的 dis/v 的时间.给定防御塔和敌人的坐标 ...