APIO2015 八邻旁之桥/巴邻旁之桥
时间:2019-06-26
本文章向大家介绍APIO2015 八邻旁之桥/巴邻旁之桥,主要包括APIO2015 八邻旁之桥/巴邻旁之桥使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目描述:
题解:
贪心+权值线段树。
$K=1$的时候,答案为$\sum |x-l| + |x-r|$,所以所有端点排序后取中位数即可。
$K=2$的时候,一定是左边的一些走左边的桥,右边的一些走右边的桥。
问题是按什么顺序排序。
答案是按线段中点排序。
原因是,对于河两岸的一对点和两座桥,选择的一定是离线段中点近的那个。
考虑如何快速计算答案,我们可以用权值线段树维护区间和与中位数。(当然也可以用平衡树)
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 100050; const int M = 100*N; template<typename T> inline void read(T&x) { T f = 1,c = 0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} x = f*c; } int K,n; ll ans; char op1[2],op2[2]; struct Point { int l,r; Point(){} Point(int l,int r):l(l),r(r){} bool operator < (const Point&a)const{return l+r<a.l+a.r;} }p[N]; int s[N<<1],tl; const int inf = 2000000001; struct segtree { int rt,tot,ls[M],rs[M],siz[M]; ll sum[M]; void insert(int l,int r,int&u,int qx) { if(!u)u=++tot;siz[u]++,sum[u]+=qx; if(l==r)return ; int mid = (l+r)>>1; if(qx<=mid)insert(l,mid,ls[u],qx); else insert(mid+1,r,rs[u],qx); } void erase(int l,int r,int u,int qx) { siz[u]--,sum[u]-=qx;if(l==r)return ; int mid = (l+r)>>1; if(qx<=mid)erase(l,mid,ls[u],qx); else erase(mid+1,r,rs[u],qx); } int query(int l,int r,int u,int rk) { if(!u)return -1; if(l==r)return l; int mid = (l+r)>>1; if(rk<=siz[ls[u]])return query(l,mid,ls[u],rk); else return query(mid+1,r,rs[u],rk-siz[ls[u]]); } ll query(int l,int r,int u,int ql,int qr) { if(!u||ql>qr)return 0; if(l==ql&&r==qr)return sum[u]; int mid = (l+r)>>1; if(qr<=mid)return query(l,mid,ls[u],ql,qr); else if(ql>mid)return query(mid+1,r,rs[u],ql,qr); else return query(l,mid,ls[u],ql,mid)+query(mid+1,r,rs[u],mid+1,qr); } ll Query(int l,int r,int u,int ql,int qr) { if(!u||ql>qr)return 0; if(l==ql&&r==qr)return siz[u]; int mid = (l+r)>>1; if(qr<=mid)return Query(l,mid,ls[u],ql,qr); else if(ql>mid)return Query(mid+1,r,rs[u],ql,qr); else return Query(l,mid,ls[u],ql,mid)+Query(mid+1,r,rs[u],mid+1,qr); } ll query(int siz) { int mid = query(0,inf,rt,siz); ll ql = query(0,inf,rt,0,mid-1),qr = query(0,inf,rt,mid+1,inf),tmp = (Query(0,inf,rt,mid+1,inf)-Query(0,inf,rt,0,mid-1)); return qr-ql-tmp*mid; } }tr[2]; int main() { // freopen("tt.in","r",stdin); read(K),read(n); for(int x,y,i=1;i<=n;i++) { scanf("%s",op1),read(x),scanf("%s",op2),read(y); if(x>y)swap(x,y); if(op1[0]==op2[0]) { ans+=y-x; i--,n--; }else p[i]=Point(x,y); } ans+=n; if(!n) { printf("%lld\n",ans); return 0; } if(K==1) { for(int i=1;i<=n;i++) s[++tl]=p[i].l,s[++tl]=p[i].r; sort(s+1,s+tl+1); int mid = (s[tl/2]+s[tl/2+1])/2; int i; for(i=1;s[i]<=mid;i++)ans+=mid-s[i]; for(;i<=tl;i++)ans+=s[i]-mid; printf("%lld\n",ans); return 0; } sort(p+1,p+1+n); for(int i=1;i<=n;i++) tr[1].insert(0,inf,tr[1].rt,p[i].l),tr[1].insert(0,inf,tr[1].rt,p[i].r); ll mx = 0x3f3f3f3f3f3f3f3fll; for(int i=1;i<=n;i++) { tr[0].insert(0,inf,tr[0].rt,p[i].l),tr[0].insert(0,inf,tr[0].rt,p[i].r); tr[1].erase (0,inf,tr[1].rt,p[i].l),tr[1].erase (0,inf,tr[1].rt,p[i].r); mx=min(mx,tr[0].query(i)+tr[1].query(n-i)); } printf("%lld\n",ans+mx); return 0; }
原文地址:https://www.cnblogs.com/LiGuanlin1124/p/11094530.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- MySQL数据库——数据库的设计(多表之间的关系与三大范式)与备份还原
- JavaWeb——JSP入门学习(JSP基本概念、JSP脚本、JSP内置对象)
- MySQL数据库——数据库CRUD之基本DML增删改表操作及DQL查表操作
- JavaWeb——AJAX异步技术实现方式与案例实战(原生的JS方式、使用JQuery方式)
- JavaWeb——一文带你入门Servlet(生命周期、注解配置方法、IDEA与tomcat的相关配置)
- JavaWeb——JQuery之基础案例实战(实现表格隔行换色、实现全选全不选、QQ表情选择、下拉列表选中条目左右选择功能)
- JavaWeb——JQuery之DOM操作应用及实践案例总结(DOM内容操作、DOM属性操作、CRUD操作)
- JavaWeb——Filter过滤器快速入门与是否登录验证&过滤敏感词汇案例实战(Filter配置方式、执行流程、生命周期方法、过滤器链)
- JavaWeb——会话技术之Session快速入门与验证码登录案例实战(Session实现原理、使用细节、快速入门、Session的特点)
- Nginx配置文件服务器
- JavaWeb——会话技术之Cookie快速入门与案例实战(详细讲解了Cookie实现原理、Cookie使用细节、Cookie的特点及作用)
- docker安装kibana
- JavaWeb——ServletContext对象的使用及文件下载案例实战
- (最新 9000 字 )Spring Boot 配置特性解析
- JavaWeb——HTTP响应协议及Response对象使用方法一点通及案例实战(重定向、输出字符/字节数据到浏览器、验证码实现)