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 ...
随机推荐
- CodeForces 1293 C NEKO's Maze Game
[题目链接] [题目大意] 有一个2 ∗ n的地图,小女孩从(1,1)想移动到(2,n) 有q次询问,每次询问更改一个格子状态(是否可以通过) 只能上下左右移动而不能斜着移动,问每次操作后,是否可以移 ...
- kubernetes系列(十二) - 存储之Secret
1. Secret简介 2. Secret类型 3. Service Account 4. Opaque 4.1 Opaque类型说明 4.2 Opaque创建方式 4.2.1 命令行创建 4.2.2 ...
- 一篇文章教会你如何将DOM转换为virtual DOM
[一.Virtual DOM简介] Virtual DOM是虚拟节点,它通过Javascript的Object对象模拟DOM中的节点,然后通过特定的render方法将其渲染成真实的DOM节点. 浏览器 ...
- Linux多任务编程之六:编写多进程程序及其代码(转)
来源:CSDN 作者:王文松 转自Linux公社 ------------------------------------------------------------------------- ...
- MYSQL 之 JDBC(七):增删改查(五) DAO设计模式
Data Access Object,数据访问对象 what:访问数据信息的类.包含了对数据的CRUD(create.read.update.delete,增删改查)操作,而不包含任何业务相关的信息. ...
- scrapy 基础组件专题(七):scrapy 调度器、调度器中间件、自定义调度器
一.调度器 配置 SCHEDULER = 'scrapy.core.scheduler.Scheduler' #表示scrapy包下core文件夹scheduler文件Scheduler类# 可以通过 ...
- Unity-内存
editor 和runtime的内存管理分开的 unity检测不到native内存容量 如c++,lua 一个asset一个ab的问题在于 每个asset都有对应的文件头,并不划算 IL2CPP抛弃了 ...
- bzoj3223Tyvj 1729 文艺平衡树
bzoj3223Tyvj 1729 文艺平衡树 题意: 一个数列,支持区间翻转操作. 题解: splay裸题.注意涉及到区间操作的一般用splay不用treap. 代码: #include <c ...
- JavaScript动画实例:曲线的绘制
在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例.这些曲线都是根据其曲线方程,在[0,2π]区间取一系列角度值,根据给定角度值计算对应的各点坐标,然后在计算出 ...
- typedef struct 指针结构体使用方法
A>>>>>>>>>>>>>>>>>>>>>>>> ty ...