luogu P5473 [NOI2019]I 君的探险 交互 随机 二分 分治 整体二分
LINK:I 君的探险
神仙题!
考虑一个暴力的做法 每次点亮一个点 询问全部点 这样询问次数为 \(\frac{n\cdot (n-1)}{2}\) 可以通过前5个点.
考虑都为A的部分分 发现一个点只会和另外一个点进行连边.
且询问次数要求\(nlogn\) 需要分治 二分等方法。
一个想法是 每次点亮一个再询问全部太浪费了 可以进行分治.
即每次点亮\(\frac{1}{4}\)数量的点 然后观察 如果两个点是一组的那么他们的状态相同 按照状态来划分区域再进行分治下去.
每次可以rand选点 然后就可以通过A的部分了。询问次数不太清楚。。
这部分其实是有标算的 考虑二进制 枚举某个二进制位 将为1的都点亮 询问所有灯 可以发现 自己和之前的状态相同当且仅当和自己相连的灯的二进制位和自己相同这个可以直接的进行计算。询问次数\(nlogn\)
考虑为B的部分分 每个点的父亲都小于儿子的编号 容易想到二分 而单调性还不存在。
不过把0~mid的灯全点亮然后check当前 这个是存在单调性的。
逐一二分过不去 可以考虑整体二分 询问次数\(nlogn\)
然后C,D 都不太会写且跟正解没有多大关系。
正解是 强上整体二分 然后发现只能求出和前面连边为奇数的那些点的边.
每次求出一部分然后random_shuffle 利用check来进行合理剪枝即可。
确实玄学。。不过这个随机的思路也不太难想。
code
//#include "explore.h"
//#include "grader.cpp"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include<bits/stdc++.h>
#define ll long long
#define db double
#define INF 10000000000000000ll
#define inf 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<(int)n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-4
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
using namespace std;
void modify(int x);
int query(int x);
void report(int x,int y);
int check(int x);
int n,m;
inline void sc(int x,int y){report(x,y);}
const int MAXN=200010;
vector<int>g[MAXN],s,res;
int vis[MAXN],ans[MAXN];
inline void solve(int l,int r,vector<int> f)
{
if(l==r)
{
vep(0,f.size(),j)
{
sc(f[j],s[r]);
g[f[j]].pb(s[r]);
g[s[r]].pb(f[j]);
}
return;
}
int mid=(l+r)>>1;
vector<int>ql,qr;
rep(l,mid,i)
{
modify(s[i]);
vep(0,g[s[i]].size(),j)vis[g[s[i]][j]]^=1;
}
rep(mid+1,r,i)if(vis[s[i]]^query(s[i]))ql.pb(s[i]);
vep(0,f.size(),i)if(vis[f[i]]^query(f[i]))ql.pb(f[i]);
else qr.pb(f[i]);
rep(l,mid,i)
{
modify(s[i]);
vep(0,g[s[i]].size(),j)vis[g[s[i]][j]]^=1;
}
solve(l,mid,ql);
solve(mid+1,r,qr);
}
inline void solve1()
{
int lim=1;
while((1<<lim)<n)++lim;
rep(0,lim-1,j)
{
vep(0,n,i)
{
if(i&(1<<(j)))modify(i);
}
vep(0,n,i)
{
int ww=query(i);
if(ww!=vis[i])
{
vis[i]=ww;
ans[i]|=(i&1<<(j))^(1<<(j));
}
else ans[i]|=(i&1<<(j));
}
}
//cout<<lim<<endl;
vep(0,n,i)
{
if(i<ans[i])sc(i,ans[i]);
//cout<<ans[i]<<endl;
}
}
inline void solve2()
{
solve(0,s.size()-1,vector<int>());
}
void explore(int N, int M)
{
n=N;m=M;
if(n<=1000)
{
rep(0,N-2,i)
{
modify(i);
rep(i+1,N-1,j)
{
int ww=query(j);
if(vis[j]!=ww)
{
vis[j]=ww;
sc(i,j);
}
}
}
return;
}
if(m==n/2)
{
solve1();
return;
}
vep(0,n,i)s.pb(i);
srand(time(0));
if(n==99997||n==199997)
{
solve2();
return;
}
while(s.size())
{
random_shuffle(s.begin(),s.end());
solve(0,s.size()-1,vector<int>());
vep(0,s.size(),j)if(!check(s[j]))res.pb(s[j]);
s=res;res.clear();
}
return;
}
也同时从中学到了一些交互调试的技巧。
luogu P5473 [NOI2019]I 君的探险 交互 随机 二分 分治 整体二分的更多相关文章
- loj3161「NOI2019」I 君的探险(随机化,整体二分)
loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...
- luogu P5471 [NOI2019]弹跳
luogu 因为是一个点向矩形区域连边,所以可以二维数据结构优化连边,但是会MLE.关于维护矩形的数据结构还有\(KD-Tree\),所以考虑\(KDT\)优化连边,空间复杂度\(m\sqrt n\) ...
- Luogu P5469 [NOI2019]机器人 (DP、多项式)
不用FFT的多项式(大雾) 题目链接: https://www.luogu.org/problemnew/show/P5469 (这题在洛谷都成绿题了海星) 题解: 首先我们考虑,一个序列位置最右边的 ...
- Luogu P5468 [NOI2019]回家路线 (斜率优化、DP)
题目链接: (luogu) https://www.luogu.org/problemnew/show/P5468 题解: 爆long long毁一生 我太菜了,这题这么简单考场上居然没想到正解-- ...
- 【题解】Luogu P5072 [Ynoi2015]盼君勿忘
众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题 我博客里对莫队的简单介绍 既然是莫队,我们就要考虑每多一个数或少一个数对答案的贡献是什么 假 ...
- 【题解】Luogu P5471 [NOI2019]弹跳
原题传送门 先考虑部分分做法: subtask1: 暴力\(O(nm)\)枚举,跑最短路 subtask2: 吧一行的点压到vector中并排序,二分查找每一个弹跳装置珂以到达的城市,跑最短路 sub ...
- 【题解】Luogu P5470 [NOI2019]序列
原题传送门 同步赛上我一开始想了个看似正确却漏洞百出的贪心:按\(a_i+b_i\)的和从大向小贪心 随便想想发现是假的,然后就写了个28pts的暴力dp 杜神后半程说这题就是个贪心,但我没时间写了 ...
- 【题解】Luogu P5468 [NOI2019]回家路线
原题传送门 前置芝士:斜率优化 不会的可以去杜神博客学 这道题我考场上只会拆点跑最短路的70pts做法 后来回家后发现错误的爆搜都能拿满分(刀片) 还有很多人\(O(mt)\)过的,还是要坚持写正解好 ...
- Luogu P5470 [NOI2019]序列
题目 可以直接贪心,但是用模拟费用流推的话会更轻松. 首先有一个显然的建图方式: \(S\)到\(0\)流量为\(k\),费用为\(0\). \(0\)到\(a_i\)流量为\(1\),费用为\(-a ...
随机推荐
- 前端性能优化_css加载会造成哪些阻塞现象?
css的加载是不会阻塞DOM的解析,但是会阻塞DOM的渲染,会阻塞link后面js语句的执行.这是由于浏览器为了防止html页面的重复渲染而降低性能,所以浏览器只会在加载的时候去解析dom树,然后等在 ...
- 线性dp—奶牛渡河
题目 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木筏上 ...
- Centos8 - 图形界面和命令行切换
查看目前默认的启动方式 systemctl get-default 命令行模式:multi-user.target 图形界面模式:graphical.target 设置为图形界面模式 systemct ...
- day36 作业
客户端 import struct import json from socket import * client=socket(AF_INET,SOCK_STREAM) # client.conne ...
- Ubuntu systemctl 查看管理系统启动项
Ubuntu systemctl 查看系统启动项 列出所有启动项: sudo systemctl list-unit-files 会列出开启的和未开启的: 使用grep过滤一下开启的grep enab ...
- HDFS客户端环境准备
一.下载Hadoop jar包至非中文路径 下载链接:https://hadoop.apache.org/releases.html 解压至非中文路径 二.配置Hadoop环境变量 配置HADOOP_ ...
- 用前端姿势玩docker【三】基于nvm的前端环境构建技巧
前言 安装docker啥的就不说了,这里重点强调一下,docker的环境问题.本人的环境: 虚拟机centos => docker => NAT => container 因为需要不 ...
- JavaScript图形实例:平面镶嵌图案
用形状.大小完全相同的一种或几种平面图形进行拼接,彼此之间不留空隙.不重叠地铺成一片,就叫做这几种图形的平面镶嵌. 1.用一种多边形实现的平面镶嵌图案 我们可以采用正三角形.正方形或正六边形实现平面镶 ...
- Go Pentester - HTTP CLIENTS(3)
Interacting with Metasploit Early-stage Preparation: Setting up your environment - start the Metaspl ...
- Ethical Hacking - Web Penetration Testing(2)
INFORMATION GATHERING IP address. Domain name Info. Technologies used. Other websites on the same se ...