P3644 [APIO2015]八邻旁之桥(中位数、堆)
前言
卡了很长时间的一个题。
一开始 k=1 的关键性质把握就跑偏了,后面基本在硬做…
关键就是一直把每个人当成一条线段作为整体在看,使问题很复杂…
最后用 three-pointers
磕磕绊绊搞出来了。
但是根本不用!
解析
这题关键就在于:k=1k=1k=1 怎么做?
我直接暴力枚举桥的位置,因此 k=2k=2k=2 就没了。
这个贡献可以拆分为 家-桥-公司。
所以问题转化成:给出 2n 个点,求一个点使所有点到其距离和最小。
显然是中位数。
接下来考虑 k=2k=2k=2 怎么做?
我们尝试维护两座桥对应的集合,一开始A为空、B为全集,不断把B集合的元素扔到A里,动态维护代价和取min即可。
手玩一下,不难发现按照左右端点坐标和为关键字排序扔即可。
然后就是动态维护中位数了。维护两个堆即可轻松实现动态添加元素维护中位数,B集合的删除也可以反着做化删为加。
然而懒得写了,还是贴的 three pointers
。
代码
#include<bits/stdc++.h>
#include<string>
using namespace std;
#define ll long long
#define ull unsigned ll
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}const int N=2e5+100;
const int mod=998244353;
const int inf=1e9;bool mem1;inline ll ksm(ll x,ll k){ll res=1;while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res;
}int n,m;int q[N],cnt;
int x[N],y[N];
char c1[N],c2[N];ll bas,ans=1e18;
struct seg{int l,r,id;
}p[N];
bool operator < (const seg &x,const seg &y){return q[x.l]+q[x.r]<q[y.l]+q[y.r];
}
int num;
vector<seg>l[N],r[N];
int num0l[N],num0r[N],num1l[N],num1r[N];
bool tag[N];
void work1(){ll sl(0),sr(0),nl(0),nr(0);for(int i=1;i<=cnt;i++){nr+=num0l[i];for(seg o:l[i]){sr+=q[o.l];}}for(int i=1;i<=cnt;i++){nr-=num0l[i-1];for(seg o:l[i-1]){sr-=q[o.l];}nl+=num0r[i];for(seg o:r[i]){sl+=q[o.r];} ans=min(ans,sr-nr*q[i]+nl*q[i]-sl);//printf("i=%d nl=%lld sl=%lld nr=%lld sr=%lld ans=%lld\n",q[i],nl,sl,nr,sr,ans);}printf("%lld\n",ans*2+bas);
}
void work2(){ll sxl(0),nxl(0),sxr(0),nxr(0),syl(0),nyl(0),syr(0),nyr(0),x=1,y=1;sort(p+1,p+1+num);for(int i=1;i<=num;i++){if(p[i].l>1){syr+=q[p[i].l];nyr++;} }while(y<cnt&&nyl+num0r[y]<nyr){for(seg o:r[y]){syl+=q[o.r];nyl++;}++y;for(seg o:l[y]){syr-=q[o.l];nyr--;}}for(int i=1;i<=num;i++){tag[p[i].id]=1;if(p[i].r<y){syl-=q[p[i].r];nyl--;}if(p[i].l>y){syr-=q[p[i].l];nyr--;}if(p[i].l>x){sxr+=q[p[i].l];nxr++;}if(p[i].r<x){sxl+=q[p[i].r];nxr--;}num0r[p[i].r]--;num1r[p[i].r]++;num0l[p[i].l]--;num1l[p[i].l]++;//printf(" (%lld %lld) (%lld %lld)\n",nyl,syl,nyr,syr);while(y<cnt&&nyl+num0r[y]<nyr){for(seg o:r[y]){if(tag[o.id]) continue;syl+=q[o.r];nyl++;}++y;for(seg o:l[y]){if(tag[o.id]) continue;syr-=q[o.l];nyr--;}}while(x<cnt&&nxl+num1r[x]<nxr){ for(seg o:r[x]){if(!tag[o.id]) continue;sxl+=q[o.r];nxl++;}++x;for(seg o:l[x]){if(!tag[o.id]) continue;sxr-=q[o.l];nxr--;}//printf("")}ans=min(ans,syr-nyr*q[y]+nyl*q[y]-syl+sxr-nxr*q[x]+nxl*q[x]-sxl);//printf("(%d %d) x=%d y=%d %lld %lld\n",q[p[i].l],q[p[i].r],q[x],q[y],syr-nyr*q[y]+nyl*q[y]-syl,sxr-nxr*q[x]+nxl*q[x]-sxl);//printf(" (%lld %lld) (%lld %lld) ans=%lld\n",nxl,sxl,nxr,sxr,ans); //puts("");}debug("ans=%lld\n",ans);printf("%lld\n",ans*2+bas);
}bool mem2;
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endif//debug("mem=%.4lf\n",abs(&mem2-&mem1)/1024./1024);m=read();n=read();for(int i=1;i<=n;i++){scanf(" %c%d %c%d",&c1[i],&x[i],&c2[i],&y[i]);if(x[i]>y[i]) swap(x[i],y[i]);q[++cnt]=x[i];q[++cnt]=y[i];}sort(q+1,q+1+cnt);cnt=unique(q+1,q+1+cnt)-q-1; for(int i=1;i<=n;i++){x[i]=lower_bound(q+1,q+1+cnt,x[i])-q;y[i]=lower_bound(q+1,q+1+cnt,y[i])-q;bas+=q[y[i]]-q[x[i]];if(c1[i]!=c2[i]){++bas;num0l[x[i]]++;num0r[y[i]]++;++num;l[x[i]].emplace_back((seg){x[i],y[i],num});r[y[i]].emplace_back((seg){x[i],y[i],num});p[num]=(seg){x[i],y[i],num};}}if(m==1) work1();else work2();return 0;
}
P3644 [APIO2015]八邻旁之桥(中位数、堆)相关推荐
- 76. Leetcode 295. 数据流的中位数 (堆-技巧一-固定堆)
技巧一 - 固定堆这个技巧指的是固定堆的大小 k 不变,代码上可通过每 pop 出去一个就 push 进来一个来实现.而由于初始堆可能是0,我们刚开始需要一个一个 push 进堆以达到堆的大小为k,因 ...
- C++STL(set……)
set 底层实现是用红黑树. set 建立 set<int> s; // 不可重,默认升序 set<int,less> s; // 不可重,升序 set<int,grea ...
- 2018年10月训练记录(10.1~10.23)
前言 这篇博客记录的是我在201820182018年101010月的刷题列表. 由于时间比较匆忙,可能会有一些空链接,但我会尽快将它们补齐的. (目前链接已补至Oct7thOct\ 7thOct 7t ...
- 有趣题目和认知合集(持续更新)
写写对一些算法的理解,挂几个有意思的题,可能也会挂几个板子题 算法理解偏向于能懂即可,没有严格的证明 快乐几何 [1.2]Volatile Kite 点到直线 快乐搜与暴力 [2.4]Short Co ...
- APIO20152014题解
传送门:似乎uoj都有 思路: APIO2015: 巴厘岛的雕塑: 看到位运算,又要求结果最小,最外层肯定是个从高位到低位的按位贪心 这里有两个部分分, task1:N<=100,1<=A ...
- [总结]2019年9月 OI学习/刷题记录
从现在开始记录一下每天的学习情况.主力LOJ? 2019/9/5 LibreOJ #2543. 「JXOI2018」排序问题 答案显然是\(\frac{(n+m)!}{Cnt_1!Cnt_2!\cdo ...
- 【数学建模】【APIO2015】Palembang Bridges
Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...
- (016) 反射 API
理证线术是斯劳克业量院联东半知号制斯争太党号式九领经整没分十火商里革办须素加价体级展不热料领车些院满北级通几效加群听车采声许采们级结把动米采照事类变为织市界事物农各转查研八由越众运市导特选江万解老技规 ...
- semantic-ui semantic.json配置
点具发要金总人别区高部拉量必济却或类等发反东那品规打研改强等布商王么影专风路还它快方要指属县族非料酸证位电种老按满传约海还大二术因表得张着阶再国身活报状青战中育布六民观同月除算是长问按消力毛连标片素于 ...
最新文章
- 第四范式陈雨强:万字深析工业界机器学习最新黑科技
- Linux System Programming --Chapter Seven
- nodejs express 路由与view创建多级目录
- IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的......
- a律13折线pcm编码例题_a律13折线pcm编码例题
- 7.IDA-创建结构体
- Gsoap在QT工程里如何调用
- 测试oracle中set arraysize xx对性能的影响
- 玩转ansys——悬臂梁质量块的实体建模与仿真
- ODL之VTN详解-Mac Map
- 高通功耗调试17之TLOC DEAMON导致待机/亮屏电流异常问题
- 凯斯西储大学计算机科学排名,凯斯西储大学排名计算机工程,超牛干货分解
- 在 SQL 中计算总行数的百分比
- Redis 实现热度统计和已读未读功能
- MySQL50题-第6-10题
- 论文《Image Recoloring Based on Object Color Distributions》整理笔记
- TI电量计--BQ34Z100踩坑总结
- 写给通信年轻人的27个忠告
- 火绒安全v5.0.45 附单文件版
- int计算机考试,全国计算机等级考试是什么程序执行?
热门文章
- 求生之路2 服务器 修改难度,《求生之路2》服务器指令及难度参数设置难度篇.pdf...
- stm32项目平衡车详解(stm32F407)下
- 论文笔记:Multi-level Alignment Network for Domain Adaptive Cross-modal Retrieval
- 一本通OJ 1034:计算三角形面积
- newman执行测试_newman执行postman脚本
- Go语言 -- 关于nil的幺蛾子
- js常见创建对象的三种方式
- 秋nbsp;季nbsp;雨
- sdio wifi 移植
- 汪国真:只要热爱生命,一切都在意料之中