Alesya and Discrete Mat

题解

首先,我们应该很容易想到一种贪心的思路。
它这个Ln\frac{L}{n}nL​相当于恰好将整个LLL分成nnn段,显然,对于每一个函数,值域段上的一段肯定就对应定义域上的一段。
我们相当于要将这些段选出来不交,容易发现,是一定存在一种选法的。
我们先将所有函数中第一段右端点最小的函数选出来,此时,其它函数就只用选择第222段到第nnn段了。而且这些函数对应的定义域上区间绝对都是在第一个函数对应区间的右边的,所以我们之后相当于是一个n−1n-1n−1的子问题。
当n=1n=1n=1的时候是一定有解的,而其它问题都可以被这样收缩到n=1n=1n=1,所以也一定有解。

当然,如果直接这样暴力做的话,能过就有鬼了。
我们可以考虑用分治的方法进行优化。
比如说,我们可以将一个nnn的问题规约成两个n2\frac{n}{2}2n​的问题,这样就会稍微快以点了,但这样也就意味着我们要找的是第n2\frac{n}{2}2n​大的n2\frac{n}{2}2n​位置的分割点。
一种方法是通过二分求出每个n2\frac{n}{2}2n​分割点的位置,再将它们排序。
但是这种方法询问次数是O(nlog⁡2n)O\left(n\log^2 n\right)O(nlog2n),过不了这道题。
没事,我们可以考虑别的方法。
比如说就像nth_elementnth\_elementnth_element去找这个点。
每次随机一个点,找到它的分割点位置,与别的点判断,别的分割点是在它的前面还是后面。
判断别的点在它前面还是后面,只需要看这个点在分割点位置是大于n2\frac{n}{2}2n​还是小于n2\frac{n}{2}2n​。
如果在它前面的比在它后面的多,说明我们想要的排名n2\frac{n}{2}2n​的点应该是在前面这些点中,往左递归。后面比前面多同理。
这样,每次需要检验的数期望长度是减半的,所以我们这部分的询问次数大概是O(Tlog⁡n+n)O\left(T\log n+n\right)O(Tlogn+n)。
容易发现,TTT是随着区间长度逐渐减小的,总共加起来还是O(n)O\left(n\right)O(n)的级别吧…
反正这样就可以做到O(nlog⁡n)O\left(n\log n\right)O(nlogn)了。

源码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
#define MAXN 2005
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lowbit(x) (x&-x)
const int mo=1e9+7;
const int inv2=5e8+4;
const int jzm=2333;
const int zero=200000;
const int INF=0x3f3f3f3f;
const double eps=1e-12;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1;}return t;}
int n,id[MAXN],tl[MAXN],tr[MAXN],td[MAXN],totl,totr,totd;
LL a[MAXN],len,L[MAXN],R[MAXN],las;
mt19937 e(time(0));
uniform_int_distribution<int> gx(0,1000000000);
LL ask(int i,LL x){printf("? %d %lld\n",i,x);fflush(stdout);LL res;read(res);return res;
}
void sakura(int l,int r,LL al,LL ar){if(l==r){LL t=ask(id[l],las),dl=las,dr=1e18;while(dl<dr){LL md=dl+dr>>1;if(ask(id[l],md)>=t+len/n)dr=md;else dl=md+1;}L[id[l]]=las;R[id[l]]=las=dl;return ;}int mid=l+r>>1,i=l-1,j=r+1;LL bl=al,br=ar;while(i+1<j){int x=i+gx(e)%(j-i-1)+1;LL dl=bl,dr=br;totl=totr=totd=0;while(dl<dr){LL md=dl+dr>>1;if(ask(id[x],md)>=a[mid])dr=md;else dl=md+1;}for(int k=i+1;k<j;k++){LL tmp=ask(id[k],dl);if(tmp>a[mid])tl[++totl]=id[k];if(tmp<a[mid])tr[++totr]=id[k];if(tmp==a[mid])td[++totd]=id[k];}while(i+totl<mid&&totd)tl[++totl]=td[totd--];while(j-totr>mid+1&&totd)tr[++totr]=td[totd--];for(int k=1;k<=totl;k++)id[i+k]=tl[k];for(int k=1;k<=totr;k++)id[j-k]=tr[k];if(i+totl<=mid)i+=totl,bl=dl;if(j-totr>mid)j-=totr,br=dr;}sakura(l,mid,al,bl);sakura(mid+1,r,br,ar);
}
int main(){read(n);read(len);for(int i=1;i<=n;i++)a[i]=len/n*i,id[i]=i;las=0;sakura(1,n,0LL,(LL)1e18);puts("!");for(int i=1;i<=n;i++)printf("%lld %lld\n",L[i],R[i]);fflush(stdout);return 0;
}

谢谢!!!

[CF1179E]Alesya and Discrete Mat相关推荐

  1. OpenCV 笔记(08)— 二维点、三维点、基于 Mat 的 std::vector 等常用数据结构的定义和输出

    1. 定义和输出二维点 Point2f p2(3, 4);cout << "[二维点] is "<< endl << p2 << e ...

  2. OpenCV 笔记(07)— Mat 对象输出格式设置(Python 格式、CSV 格式、NumPy 格式、C 语言格式)

    首先是下面代码中将要使用的 r 矩阵的定义.需要注意,我们可以通过用 randu 函数产生的随机值来填充矩阵, 需要给定一个上限和下限来确保随机值在期望的范围内. Mat r = Mat(2, 3, ...

  3. OpenCV 笔记(06)— Mat 结构、像素值存储方法、创建 Mat 对象各种方法、Mat 对象的运算

    数字图像中的每个点都称为像素(对于图像元素),并且每个像素可以存储一个或多个值,这取决于它是否是仅存储一个值的黑白图像(也称为二进制图像,比如只存储0或1),还是存储两个值的灰度图像,或者是存储三个值 ...

  4. 【OpenCV】将单通道的Mat对象转换为三通道的Mat

    在项目中遇到一个问题,调用别人编好的库需要传入三通道的彩色图像.但是我的图像经过处理后已经是二值化的图像了,所以得想想办法了. 分析:三通道的彩色图像就是R,G,B三个通道,那么将我的单通道黑白图复制 ...

  5. 图像指针与矩阵格式转换——Mat转uchar*及uchar*转Mat代码实现

    本篇文章实现RGB3通道图像Mat转uchar及uchar转Mat,编程环境:vs2013,opencv2.4.13 ,由于OpenCV读入和显示都是BGR类型,本文显示图像也用的BGR格式,若需换成 ...

  6. OpenCV中图像Mat,二维指针和CxImage类之间的转换

    在做图像处理中,常用的函数接口有Opencv中的Mat图像类,有时候需要直接用二维指针开辟内存直接存储图像数据,有时候需要用到CxImage类存储图像.本文主要是总结下这三类存储方式之间的图像数据的转 ...

  7. OpenCV Mat矩阵(图像Mat)初始化及访问方法

    一.Mat初始化 1.使用Mat构造函数 //方法一: Mat M( 2, 2, CV_8UC3, Scalar(0,255,0) );//其实是2*6的矩阵,因为每个元素有3个通道. Mat M1( ...

  8. Mat,Iplimage,vector,vector_vector_Point2f等类型之间的相互转换

    在mfc c++ 以及opencv 编写程序当中,很多常用的类型转换,现在总结一下.(注意加相应的头文件,这里不罗嗦) 提纲: 1. Mat ---> Iplimage 2. Iplimage  ...

  9. Mat矩阵基本操作与示例 OpenCV

    OpenCV的基本矩阵操作与示例 OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建.初始化以及基本矩阵操作,给出了示例代码,主要内容包括: 创建与初始化 矩阵加减法 矩阵乘法 矩阵转置 矩阵求逆 ...

最新文章

  1. (四)Asp.net web api中的坑-【api的返回值】
  2. Linux配置Nginx与PHP-FPM出现[error] 80143#0: *1 connect() failed (111: Connection refused) while connectin
  3. 单链表的头插法和尾插法实现代码(无头结点)
  4. 【CVPR2019】 教程 Tutorials List
  5. 微软彻底告别移动操作系统!
  6. N720 拨号上网遇到的问题 /var/lock/LCK
  7. 老旧笔记本电脑变服务器(笔记本电脑+内网穿透)
  8. 新手如何Reverces(基础ctf教程篇)
  9. autoconf 报错
  10. c++ 反射_实现光时域反射仪中的应用原理基于飞凌FETA40i-C核心板
  11. 防止你的WP7手机偷跑流量——系统设置篇
  12. 51kid页面卡死解决办法
  13. 阿里巴巴“相信小的伟大”:用普世情怀传播小力量
  14. UML中的九种建模图
  15. AWS EC2部署SpringBoot
  16. 用hexo中的matery主题搭建个人博客(完整版)
  17. 路面附着系数估计_无迹扩展卡尔曼滤波(UKF EKF)
  18. iPhone App创建与审核步骤二:如何在developer.apple.com网站中设置App预览和截屏以完成App上架
  19. 服务器ubuntu重启后不自动进入桌面【服务器维护(一)】
  20. Kepware OPC与欧姆龙PLC通讯

热门文章

  1. BigDecimal 运算及取小数位
  2. ijkplayer基于rtsp直播延时的深度优化
  3. 人工智能机器人的可操作性应用法则
  4. 你一定想不到,动物和AI之间的联系如此深刻!
  5. adb命令模拟Android电量
  6. 医院wifi覆盖解决方案
  7. 六度分离理论、150法则与弱链接 (转载)
  8. 简繁转换API接口,免费好用
  9. Android 设置壁纸被拉伸(固定壁纸 )
  10. THz:通信系统的研究现状与应用展望