首页 > 其他分享 >线段树优化建图 拓扑排序 6.22西安集训T1

线段树优化建图 拓扑排序 6.22西安集训T1

时间:2023-06-22 14:11:33浏览次数:62  
标签:nn int 拓扑 T1 建图 6.22 排序 配对 线段

题目链接

有一条无限长的数轴,上面有 nn 个坑,第 ii 个坑的位置为 x_ixi​。你将要在数轴上再放置 nn 个球,第 ii 个将要放到的位置为 y_iyi​。每当有一个球被放上去之后,它就会滚落到离它最近的一个坑里并填上那个坑。如果有两个坑都离它最近,那么它会落到左边的里面。

现在 xuanxuan001 可以决定 nn 个球的放置顺序,为了节省时间,xuanxuan001 希望球的滚动距离总和尽量短,但他太菜了,所以需要你来帮他求出最短总距离并构造一个对应方案。

分析

首先,通过题面给的几组样例,我们可以发现,为了使总距离最小,第一个球一定和第一个坑配对,第二个球一定和第二个坑配对。。。最后一个球和最后一个坑配对。否则,总距离可能变长。我们用  $P_ {i}^{}$  表示与 i 配对的坑。

其次,我们发现在放一个球 $i$ 之前,他的附近可能有比 $P_{i}^{}$ 更近的坑,那么这些更近的坑所配对的球一定要先于 i 放,由此我们想到拓扑排序。一条从i连向j的边表示,只有先放i才能放j,那么跑一遍拓扑排序即可。

但是,建边的最坏复杂度为 $n_{}^{2}$,因此我们需要用线段树优化建边。具体过程见代码,也可以去看P5025 [SNOI2017]炸弹

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e6+55;
int b[N],k[N],n,len;
struct node{
    int l,r,in;
}t[N];
struct edge{
    int to,nex;
}e[N<<2];
int cnt,head[N],dis[N],pos[N],in[N],ans[N],tot;
void adda(int u,int v){
    //cout<<"adda: "<<u<<" "<<v<<endl;
    e[++cnt].to=v;e[cnt].nex=head[u];head[u]=cnt;t[v].in+=1;
}
void build(int u,int L,int R){
    //cout<<u<<" "<<L<<" "<<R<<endl;
    t[u].l=L,t[u].r=R;
    if(L==R){
        pos[L]=u;
        return;
    }
    int M=(L+R)>>1;
    build(u<<1,L,M);build(u<<1|1,M+1,R);
    adda(u<<1,u);adda(u<<1|1,u);
}
void change(int u,int l,int r,int now){
    //cout<<u<<endl;
    int L=t[u].l,R=t[u].r;
    if(L>=l&&R<=r){
        adda(u,now);return;
    }
    if(L>r||R<l) return;
    int M=(L+R)>>1;
    change(u<<1,l,r,now);change(u<<1|1,l,r,now);
}
bool cmp(node a,node b){
    return a.in<b.in;
}
queue<int>q;
signed main(){
    freopen("nameless.in","r",stdin);
    freopen("nameless.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%lld",&k[i]);
    for(int i=1;i<=n;i++){
        scanf("%lld",&b[i]);
        dis[i]=abs(b[i]-k[i]);
        len+=dis[i];
    }
    sort(k+1,k+1+n);sort(b+1,b+1+n);
    build(1,1,n);
    for(int i=1;i<=n;i++){
        int mn=b[i]-dis[i],mx=b[i]+dis[i];
        int r=lower_bound(k+1,k+1+n,mx)-k-1;
        int l=upper_bound(k+1,k+1+n,mn)-k-1;
        if(k[l]<mn) l++;
        if(k[r]>=mx) r--;
        if(l==i) l++;
        if(r==i) r--;
        if(l>r) continue;
        change(1,l,r,pos[i]);        
    }
    for(int i=1;i<=n;i++){
        if(t[pos[i]].in) continue;
        q.push(pos[i]);
        ans[++tot]=i;
    }
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].nex){
            int v=e[i].to;
            t[v].in--;
            if(!t[v].in){
                q.push(v);
                if(t[v].l==t[v].r) ans[++tot]=t[v].l;
            }
        }
    }
    cout<<len<<endl;
    for(int i=1;i<=tot;i++){
        printf("%lld ",ans[i]);
    }
    return 0;
}

 

标签:nn,int,拓扑,T1,建图,6.22,排序,配对,线段
From: https://www.cnblogs.com/DongPD/p/17497708.html

相关文章

  • GB/T17627.1和IEC61180-1标准中脉冲电压测试及瞬态过电压测试的判定
    转载: 在电气测量领域,接触颇多的测试标准,无论欧盟EN或IEC标准、UL标准、JIS标准和我们国标GB标准,其中有诸如“脉冲电压测试”、“冲击电压测试”、“瞬态过电压测试”等测试项目,往往我们比较难分辨或误解,今天我们Delta德尔塔仪器小编就帮大家推荐一款我们开发出的全新智能型......
  • test1
    技术栈选用1.前端技术栈1.Vue.js2.ElementUI3.axios2.后端技术栈1.SpringBoot2.ApacheShiro3.ApacheLog4j24.SpringDataJPA5.SpringDataRedis3.数据库1.MySQL2.Redis登录页面开发注意我们的项目是前后端分离的前后端分离的意思是前后端之间通过RESTfulAP......
  • keyshot10免费下载-keyshot10(3D动画渲染)软件 软件大全
    KeyShot10添加了新的关键帧动画和其他动画功能、用于输出到全彩3D打印、AR/Web交互等的新智能导出选项、新的灯光管理器和用于更好地控制几何和模型的新工具、RealCloth2.0和改进焦散以获得更逼真的材料和照明,以及改进的降噪和萤火虫过滤器以加快视觉创建。KeyShot10继续......
  • BT139-800E-ASEMI代理恩智浦双向可控硅BT139-800E
    编辑:llBT139-800E-ASEMI代理恩智浦双向可控硅BT139-800E型号:BT139-800E品牌:NXP/恩智浦封装:TO-220BT139-800E产品特性:电压性能最高可达800伏平面钝化电压的坚固性和可靠性60Hz半周期内,浪涌性能高达140A在所有四个象限触发BT139-800E描述:BT139-800E系列双向可控硅采用标准TO......
  • BT139-600E-ASEMI代理恩智浦原装可控硅BT139-600E
    编辑:llBT139-600E-ASEMI代理恩智浦原装可控硅BT139-600E型号:BT139-600E品牌:NXP/恩智浦封装:TO-220正向电流:16A反向电压:600V引脚数量:3类型:双向可控硅特性:双向可控硅、恩智浦原装可控硅工作温度:-40°C~150°C封装尺寸:如图BT139-600E产品描述:BT139-600E系列双向可控硅采......
  • mormot1.18 THttpApiServer
    mormot1.18THttpApiServer官方已经推荐使用mormot2,mormot1.18已经进入只修正bug的阶段。THttpApiServer是对windowshttp.sys通信的封装,因此只适用于windows。//cxg2023-2-12//mormot1.18http.sys适用于WINDOWS2003,XPSP2及以后版本unitsock.httpsys;interfaceus......
  • 算法学习day57动态规划part17-516、647
    packageLeetCode.DPpart17;/***516.最长回文子序列*给你一个字符串s,找出其中最长的回文子序列,并返回该序列的长度。*子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。**/publicclassLongestPalindromicSubsequence_51......
  • 算法学习day55动态规划part15-115、392
    packageLeetCode.DPpart15;publicclassDistinctSubsequences_115{publicintnumDistinct(Strings,Stringt){int[][]dp=newint[s.length()+1][t.length()+1];for(inti=0;i<s.length()+1;i++){dp[i][0]=......
  • 算法学习day56动态规划part16-583、72
    packageLeetCode.DPpart16;/***583.两个字符串的删除操作*给定两个单词word1和word2,返回使得word1和word2相同所需的最小步数。*每步可以删除任意一个字符串中的一个字符。**/publicclassDeleteOperationforTwoStrings_583{publicintminDist......
  • s1sh整合实例 Strut1.2+Spring2.6+Hibernate3.2
    [code]开发环境:MyEclipse8.5+Mysql说明:本实例是简单注册程序(只有两个属性)数据库脚本:user.sqlCREATETABLE`user`(`Id`int(11)NOTNULLAUTO_INCREMENT,`username`varchar(255)DEFAULTNULL,`password`varchar(255)DEFAULTNULL,P......