UOJ#24. 【IOI2014】Rail 交互题
原文链接www.cnblogs.com/zhouzhendong/p/UOJ24.html
题解
我们将 C 型车站称为 左括号 '(', D 型车站称为右括号 ')' ,设括号 i 的位置为 p[i] 。
首先,我们用点 0 把所有位置都询问一遍,那么距离最近的那个点一定是在 0 右边的第一个 ')' 。
设 0 位置为 x ,距离 0 最近的 )为 y,那么在 x 与 y 之间只可能有( 。
现在我们可以将所有括号分成 3 类: x 左侧的, x 与 y 之间的,y 右侧的。
对于一个括号 i ,如果 dis(x,y) + dis(y,i) = dis(x,i) ,那么 i 一定在 y 的左边,否则一定在 y 的右边。
当 i 在 y 的左边时,由于 x 与 y 之间只有( ,所以当 dis(x,y) > dis(y,i) 时, i 在 x 与 y 之间,否则 i 在 x 左侧。
注意到在 x 与 y 之间的都是可以直接确定类型和位置的,所以我们考虑左侧和右侧。
由于左侧和右侧的两个子问题是对称的,做法类似,所以这里只介绍右侧的:
我们把剩下的括号按照与 x 的距离排序。然后从小到大依次处理:
假设当前最右侧的 )为 r (初始 r = y)。假设当前处理到括号 i ,由于是排过序的,所以 i 只有两种情况:
1. i 在 r 的右边,是 )。
2. i 在 r 的左边,是( 。
假装 i 在 r 的左边,那么从 x 到 i 必然要经过一个 ),而且是在 i 右边距离 i 最近的 )。那么 r 距离它多少呢?
$$len = \cfrac{dis(x,r)+dis(r,i)-dis(x,i)}{2}$$
那么如果 i 在 r 的右边,这个式子表示什么?——是 r 到它左边距离它最近的( 的距离,它可能没有被访问过,但它一定不是 )。
那么我们注意到,p[i] - len 这个位置如果是 ),那么它由于它距离 x 更近,所以它已经被访问过了。所以,如果 p[i] - len 位置上是一个已经被访问过的 ),那么 i 在 r 的左边,否则i 一定在 r 的右边。
于是我们就可以在 3(n-1) 次询问的限制内解决这个问题了。
代码
#include "rail.h"
#pragma GCC optimize("Ofast","inline")
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
typedef vector <int> vi;
const int N=5005;
#define C(a,b) (type[a]=1,p[a]=b,vis[a]=1)
#define D(a,b) (type[a]=2,p[a]=b,vis[a]=1)
unordered_map <int,int> Dis[N];
int Ask(int a,int b){
if (a==b)
return 0;
if (Dis[a][b])
return Dis[a][b];
return Dis[a][b]=Dis[b][a]=getDistance(a,b);
}
int x,y;
vi dx,dy,ids;
int vis[N];
set <int> SL,SR;
bool cmpD(int a,int b){
return dx[a]<dx[b];
}
void findLocation(int n,int p0,int *p,int *type){
For(i,0,n-1)
Dis[i].clear();
dx.resize(n);
dy.resize(n);
ids.clear();
clr(vis);
x=0;
For(i,0,n-1)
dx[i]=Ask(x,i),ids.pb(i);
sort(ids.begin(),ids.end(),cmpD);
y=ids[1];
C(x,p0);
if (n==1)
return;
D(y,p0+dx[y]);
For(i,0,n-1)
dy[i]=Ask(y,i);
int l=x,r=y,MaxM=0;
for (auto i : ids)
if (!vis[i]&&dx[y]+dy[i]==dx[i]&&dy[i]<dx[y]){
C(i,p[y]-dy[i]);
MaxM=max(MaxM,p[i]-p[x]);
}
int sy=p[y]-(dx[y]-MaxM)*2;
SL.clear(),SL.insert(dy[x]);
SR.clear(),SR.insert(dx[y]);
for (auto i : ids)
if (!vis[i]){
if (dx[y]+dy[i]==dx[i]){
int len=(dy[l]+Ask(l,i)-dy[i])/2;
if (!SL.count(dy[l]-len)){
C(i,p[y]-dy[i]);
SL.insert(dy[i]);
l=i;
}
else
D(i,p[l]+Ask(l,i));
}
else {
int len=(dx[r]+Ask(r,i)-dx[i])/2;
if (!SR.count(dx[r]-len)){
D(i,p[x]+dx[i]);
SR.insert(dx[i]);
r=i;
}
else
C(i,p[r]-Ask(r,i));
}
}
}
UOJ#24. 【IOI2014】Rail 交互题的更多相关文章
- UOJ.26.[IOI2014]Game(交互 思路)
题目链接 \(Description\) 有一张\(n\)个点的图.M每次询问\((u,v)\),你需要回答图中\((u,v)\)间是否有边.如果M可以用\(<n(n-1)/2\)次询问确定图中 ...
- UOJ #206. 【APIO2016】Gap【交互题】
参考:https://blog.csdn.net/clover_hxy/article/details/70767653 人生第一次交互题...不是很难但是思维和传统题差别挺大的(以及并不会本地测试= ...
- Codeforces Round #812 (Div. 2) D. Tournament Countdown(交互题)
记录一下第一次写交互题 题目大意:一共有1<<n个人参加一场竞标赛,需要你通过比较两人的胜场来判断谁晋级,最终获得第一名 最多1/3*2^(n+1)次询问,每次询问query(a,b),如 ...
- 交互题[CF1103B Game with modulo、CF1019B The hat、CF896B Ithea Plays With Chtholly]
交互题就是程序与电脑代码的交互. 比如没有主函数的程序,而spj则给你一段主函,就变成了一个整体函数. 还有一种就是程序和spj之间有互动,这个用到fflush(stdout);这个函数就可以实现交互 ...
- 3.24网络攻防选拔题部分write up
20175221 3.24网络攻防选拔题部分write up Q1:百度一下,你就知道 解压题目得到一个文件夹和一个网址 打开文件夹,有三张图片 用winhex和stegsolve查看三张图片,没有 ...
- CF1114E Arithmetic Progression(交互题,二分,随机算法)
既然是在CF上AC的第一道交互题,而且正是这场比赛让我升紫了,所以十分值得纪念. 题目链接:CF原网 题目大意:交互题. 有一个长度为 $n$ 的序列 $a$,保证它从小到大排序后是个等差数列.你不知 ...
- Codeforces 1137D - Cooperative Game - [交互题+思维题]
题目链接:https://codeforces.com/contest/1137/problem/D 题意: 交互题. 给定如下一个有向图: 现在十个人各有一枚棋子(编号 $0 \sim 9$),在不 ...
- Gym - 101375H MaratonIME gets candies 交互题
交互题介绍:https://loj.ac/problem/6 题意:输出Q X ,读入><= 来猜数,小于50步猜出就算过样例 题解:根本不需要每次输出要打cout.flush()... ...
- Codeforces Round #523 (Div. 2) F. Katya and Segments Sets (交互题+思维)
https://codeforces.com/contest/1061/problem/F 题意 假设存在一颗完全k叉树(n<=1e5),允许你进行最多(n*60)次询问,然后输出这棵树的根,每 ...
随机推荐
- (二)初探Maven之设置代理和阿里云镜像
引言: 在许多公司,可能因为安全性的要求配置了代理服务器,用户无法直接访问外网,所以在项目中使用Maven必须设置好代理才能下载依赖. 并且直接从中央仓库下载依 ...
- 基本DFS与BFS算法(C++实现)
样图: DFS:深度优先搜索,是一个不断探查和回溯的过程,每探查一步就将该步访问位置为true,接着在该点所有邻接节点中,找出尚未访问过的一个,将其作为下个探查的目标,接着对这个目标进行相同的操作,直 ...
- angular Observable
1.回调函数 /** 1.设计实现函数 */ print_msg(msg) { console.log(msg); } /** 2.设计调用函数,param1:实现函数参数,param2:实现函数本身 ...
- django数据库迁移报错
当输入C:\Users\太阳之泪\b2p\my_pro>python manage.py makemigrations shop 出现一下情况 然后输入C:\Users\太阳之泪\b2p\my_ ...
- A previous installation of Qt5 Visual Studio Add-in was detected. Please uninstall it before running this installer解决办法
前段时间在安装Qt Visual Studio插件的时候,安装到一半不小心中止了,结果后来怎么安装都不行,提示已经安装了,要先卸载, 可是到哪里都找不到有卸载的,因为压根就没有安装完成.这可害苦我了. ...
- AI应用开发实战(转)
AI应用开发实战 - 从零开始配置环境 与本篇配套的视频教程请访问:https://www.bilibili.com/video/av24421492/ 建议和反馈,请发送到https://git ...
- Revit二次开发封装族的替代方法
使用草图平面:
- HDU 3966 树链剖分后线段树维护
题意: 一棵树, 操作1.$path(a,b)$之间的点权$+k$ 操作2.单点查询 题解: 树链剖分即可,注意代码细节,双向映射 主要是记录一下板子 #include <string.h> ...
- Jenkins构建自动化脚本执行无界面解决方法
场景: jenkins构建selenium自动化用例的时候,会有jenkins自带服务后台运行自动化脚本,可无界面运行IE.Chrome.Firefox. 然而运行IE浏览器时候(IE比较特殊),Je ...
- python学习之re (?P...)通过关键字获取组以及( P=name)
和其他的RE表达式一样,但是匹配的子串可以通过group的名字 name来获取.即 result.group('name') (提示,字符串数字都是常量,所以关键字都可以被视为整型(hash结果) ...