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 君的探险 交互 随机 二分 分治 整体二分的更多相关文章

  1. loj3161「NOI2019」I 君的探险(随机化,整体二分)

    loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...

  2. luogu P5471 [NOI2019]弹跳

    luogu 因为是一个点向矩形区域连边,所以可以二维数据结构优化连边,但是会MLE.关于维护矩形的数据结构还有\(KD-Tree\),所以考虑\(KDT\)优化连边,空间复杂度\(m\sqrt n\) ...

  3. Luogu P5469 [NOI2019]机器人 (DP、多项式)

    不用FFT的多项式(大雾) 题目链接: https://www.luogu.org/problemnew/show/P5469 (这题在洛谷都成绿题了海星) 题解: 首先我们考虑,一个序列位置最右边的 ...

  4. Luogu P5468 [NOI2019]回家路线 (斜率优化、DP)

    题目链接: (luogu) https://www.luogu.org/problemnew/show/P5468 题解: 爆long long毁一生 我太菜了,这题这么简单考场上居然没想到正解-- ...

  5. 【题解】Luogu P5072 [Ynoi2015]盼君勿忘

    众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题 我博客里对莫队的简单介绍 既然是莫队,我们就要考虑每多一个数或少一个数对答案的贡献是什么 假 ...

  6. 【题解】Luogu P5471 [NOI2019]弹跳

    原题传送门 先考虑部分分做法: subtask1: 暴力\(O(nm)\)枚举,跑最短路 subtask2: 吧一行的点压到vector中并排序,二分查找每一个弹跳装置珂以到达的城市,跑最短路 sub ...

  7. 【题解】Luogu P5470 [NOI2019]序列

    原题传送门 同步赛上我一开始想了个看似正确却漏洞百出的贪心:按\(a_i+b_i\)的和从大向小贪心 随便想想发现是假的,然后就写了个28pts的暴力dp 杜神后半程说这题就是个贪心,但我没时间写了 ...

  8. 【题解】Luogu P5468 [NOI2019]回家路线

    原题传送门 前置芝士:斜率优化 不会的可以去杜神博客学 这道题我考场上只会拆点跑最短路的70pts做法 后来回家后发现错误的爆搜都能拿满分(刀片) 还有很多人\(O(mt)\)过的,还是要坚持写正解好 ...

  9. Luogu P5470 [NOI2019]序列

    题目 可以直接贪心,但是用模拟费用流推的话会更轻松. 首先有一个显然的建图方式: \(S\)到\(0\)流量为\(k\),费用为\(0\). \(0\)到\(a_i\)流量为\(1\),费用为\(-a ...

随机推荐

  1. 性能测试之Jmeter中场景设置与启动方式

    Jmeter场景设置与启动方式 性能测试场景是用来模拟模拟真实用户操作的工作单元,所以场景设计一定要切合用户的操作逻辑,jmeter主要是通过线程组配合其他组件来一起完成场景的设置. 线程组设置 Jm ...

  2. 【一】美化Linux终端之oh-my-zsh开源项目

    目录 1.查看系统是否装了zsh 2.安装zsh(系统没有查到zsh,则安装) 3.切换shell为zsh 4.重启Linux 5.安装oh my zsh 6.到此就安装完成 7.更换主题 8.生效主 ...

  3. LeetCode 哈希表 380. 常数时间插入、删除和获取随机元素(设计数据结构 List HashMap底层 时间复杂度)

    比起之前那些问计数哈希表的题目,这道题好像更接近哈希表的底层机制. java中hashmap的实现是通过List<Node>,即链表的list,如果链表过长则换为红黑树,如果容量不足(装填 ...

  4. tabBar配置和修改

    1.tabBar(底部导航栏) 属性 默认值 描述 平台支持 color   tab上未被选中时文字的颜色   selectedColor   tab上被选中时文字的颜色   backgroundCo ...

  5. 云开发 VSCode 插件 Cloudbase Toolkit 的正确打开方式

    什么是 Cloudbase Toolkit Tencent CloudBase Toolkit 是云开发的 VS Code(Visual Studio Code)插件.该插件可以让您更好地在本地进行云 ...

  6. Python——操作smb文件服务器(上传和下载)

    最近在做上传和下载,然后文件比较大和多,就用到了文件服务器,文件服务器是实体机 ,不是在本地, 然后用python 通过pysmb模块就可以直接进行操作 mac选择前往.连接服务器去查看文件服务器里都 ...

  7. 11.unity3d 摄像机快速定位到Scene视角

    选中Camera,比如Main Camera摄像机,在菜单选择GameObject->Align With View就可以了.如下图所示,参照前三步操作,第4步是最终效果.

  8. Linux系统安装JDK8

    一.卸载现用的JDK 1.查看Linux自带的JDK是否已安装 查看是否安装openjdk,java  -version (yum安装的 一般都是 OpenJDK     命令:yum install ...

  9. call_user_func的使用

    <?php function demo01($a) { echo $a; } call_user_func("demo01", "hello world" ...

  10. Linux多任务编程之一:任务、进程、线程(转)

    来源:CSDN  作者:王文松  转自:Linux公社 Linux下多任务介绍 首先,先简单的介绍一下什么叫多任务系统?任务.进程.线程分别是什么?它们之间的区别是什么?,从而可以宏观的了解一下这三者 ...