首页 > 其他分享 >[EC Final 2021] Vision Test

[EC Final 2021] Vision Test

时间:2024-08-08 11:05:13浏览次数:13  
标签:ps int ll tp stk lll Test Final Vision

挺牛题,没做出来,但是参考了 Rainbow 博客之后发现这些套路自己其实都会啊 QwQ。

我提交的翻译:

给定一个长度为 \(n\) 的数组 \(x\),接下来你有 \(q\) 次询问。
第 \(i\) 次询问给出一个区间 \(l,r\),设 \(k=r-l+1\),你提取出 \(x\) 数组下标在 \(l,r\) 之间的区间 \(y_i=x_{i+l}(0\le i<k)\)。
考虑 \(k\) 个点 \((0,y_0),(1,y_1)\dots(k-1,y_{k-1})\)。你需要找到一条直线的三个参数 \(a,b,c\),满足 \(\forall 0\le i<k,y_i=\lfloor \frac{ai+b}{c}\rfloor\)。若有多条这样的直线,输出 \((c,a,b)\) 三元组字典序最小的一个。
保证对于整个数组,即 \(l=1,r=n\) 的询问一定存在一组合法的解。
\(n,q\le 10^5\),多组询问。

突破口在于考虑固定直线的斜率 \(K\),那么截距 \(B\) 就需要满足不等式 \(\max(a_i-Ki)\le B < \min (a_i-Ki) +1\)。当 \(a_i-Ki\) 数组的极差要严格小于 \(1\) 时,取 \(B=\max(a_i-Ki)\) 就是字典序最小的解了。

接下来考虑什么样的 \(K\) 能让极差小于 \(1\)。一个很牛的想法是注意到在 \(K\) 增大的时候,最小值的位置总是在往右边移动,最大值的位置总是往左边移动;而当我们想要减小极差时,如果最小值在最大值左边,那么只有增大 \(K\) 才能减小这个极差。这说明这个 \(K\) 是有可二分性的,在 Stern-Brocot 树上二分即可。

见过无数次经典的技巧,SBT 二分需要倍增优化跳直链。这里我们并不好确定倍增的上界,不过虽然我不会证,既然它要我们输出答案,那么猜测这个答案一定是在 long long 范围内的。直接用倍增试探答案的最高二进制位。

现在考虑询问区间 \(a_i-Ki\) 的极值,这是区间凸包问题。不过我们不能带很多 \(\log\),所以不能直接上线段树做 \(O(n\log n)-O(m\log^2 n)\) 的做法。

考虑用回滚莫队维护凸包,由于斜率已经有序所以直接正常拿栈维护,这样询问就只有一个 \(\log\) 了。

当然另一个 polylog 做法 rainbow 也提了,就是类似猫树一样优化那个线段树的区间凸包做法,目测比回滚莫队难写很多,不管这个做法了。

#include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef __int128 lll;
typedef pair<ll,ll> pll;
int read(){
	char c=getchar();int x=0;
	while(c<48||c>57) c=getchar();
	do x=x*10+(c^48),c=getchar();
	while(c>=48&&c<=57);
	return x;
}
const int N=100003;
const int P=998244353;
int n,q,sq;
int a[N];
int ql[N],qr[N];
inline int bel(int x){return (x-1)/sq+1;}
struct MinHull{
	int stk[N],tp;
	bool check(int x,int y,int z){
		return (ll)(a[z]-a[y])*(z-x)<=(ll)(a[z]-a[x])*(z-y);
	}
	void append(int i){
		while(tp>1&&check(stk[tp-1],stk[tp],i)) --tp;
		stk[++tp]=i;
	}
	int query(ll x,ll y){
		int l=1,r=tp;
		while(l<r){
			int o=(l+r)>>1;
			if((lll)x*(stk[o+1]-stk[o])<(lll)y*(a[stk[o+1]]-a[stk[o]])) r=o;
			else l=o+1;
		}
		return stk[l];
	}
}Mn1,Mn2;
struct MaxHull{
	int stk[N],tp;
	bool check(int x,int y,int z){
		return (ll)(a[z]-a[y])*(z-x)>=(ll)(a[z]-a[x])*(z-y);
	}
	void append(int i){
		if(tp&&a[i]<=a[stk[tp]]) return;
		while(tp>1&&check(stk[tp-1],stk[tp],i)) --tp;
		stk[++tp]=i;
	}
	int query(ll x,ll y){
		int l=1,r=tp;
		while(l<r){
			int o=(l+r)>>1;
			if((lll)x*(stk[o+1]-stk[o])>(lll)y*(a[stk[o+1]]-a[stk[o]])) r=o;
			else l=o+1;
		}
		return stk[r];
	}
}Mx1,Mx2;
int qmn(ll x,ll y){
	int ps=Mn1.query(x,y);
	if(Mn2.tp){
		int nps=Mn2.query(x,y);
		if((lll)y*a[nps]-(lll)x*nps<(lll)y*a[ps]-(lll)x*ps) ps=nps;
	}
	return ps;
}
int qmx(ll x,ll y){
	int ps=Mx1.query(x,y);
	if(Mx2.tp){
		int nps=Mx2.query(x,y);
		if((lll)y*a[nps]-(lll)x*nps>(lll)y*a[ps]-(lll)x*ps) ps=nps;
	}
	return ps;
}
int dir(ll x,ll y){
	int pmn=qmn(x,y);lll vmn=(lll)y*a[pmn]-(lll)x*pmn;
	int pmx=qmx(x,y);lll vmx=(lll)y*a[pmx]-(lll)x*pmx;
	if(vmx-vmn>=y){
		if(pmn>pmx) return -1;
		if(pmn<pmx) return 1;
	}
	return 0;
}
pll sol(ll a,ll b,ll c,ll d){
	int w=dir(a+b,c+d);
	if(w<0){
		int t=0;
		while(dir((a<<(t+1))+b,(c<<(t+1))+d)==w) ++t;
		b+=(a<<t);d+=(c<<t);
		while(t){--t;if(dir((a<<t)+b,(c<<t)+d)==w) b+=(a<<t),d+=(c<<t);}
		return sol(a,b,c,d);
	}
	if(w>0){
		int t=0;
		while(dir((b<<(t+1))+a,(d<<(t+1))+c)==w) ++t;
		a+=(b<<t);c+=(d<<t);
		while(t){--t;if(dir((b<<t)+a,(d<<t)+c)==w) a+=(b<<t),c+=(d<<t);}
		return sol(a,b,c,d);
	}
	return pll(a+b,c+d);
}
ll qa[N],qb[N],qc[N];
int ss[N];
void proc(int i){
	auto [x,y]=sol(0,1,1,0);
	int ps=qmx(x,y);
	qa[i]=x;qb[i]=(lll)y*a[ps]-(lll)x*(ps-ql[i]);qc[i]=y;
}
void build(int l,int r){
	Mn1.tp=Mx1.tp=0;
	for(int i=l;i<=r;++i) Mn1.append(i);
	for(int i=l;i<=r;++i) Mx1.append(i);
}
vector<int> vec[N];
void solve(){
	n=read();
	for(int i=1;i<=n;++i) a[i]=read();
	for(int i=2;i<=n;++i) ss[i]=ss[i-1]+(a[i-1]!=a[i]);
	sq=ceil(sqrt(n));
	q=read();
	for(int i=1;i<=q;++i){
		ql[i]=read(),qr[i]=read();
		if(ss[ql[i]]==ss[qr[i]]){qa[i]=0;qb[i]=a[ql[i]];qc[i]=1;continue;}
		int bl=bel(ql[i]),br=bel(qr[i]);
		if(bl<br) vec[bl].emplace_back(i);
		else Mn2.tp=Mx2.tp=0,build(ql[i],qr[i]),proc(i);
	}
	for(int x=1;x<bel(n);++x){
		sort(vec[x].begin(),vec[x].end(),[](int a,int b){return qr[a]<qr[b];});
		Mn2.tp=Mx2.tp=0;
		int ps=x*sq+1;
		for(int t:vec[x]){
			build(ql[t],x*sq);
			while(ps<=qr[t]) Mn2.append(ps),Mx2.append(ps),++ps;
			proc(t);
		}
		vec[x].clear();
	}
	for(int i=1;i<=q;++i) printf("%lld %lld %lld\n",qa[i],qb[i],qc[i]);
}
int main(){
	int tc=read();
	while(tc--) solve();
	return 0;
}

标签:ps,int,ll,tp,stk,lll,Test,Final,Vision
From: https://www.cnblogs.com/yyyyxh/p/18348514/vision_test

相关文章

  • (未完工)Contest7516 - 平面图
    Contest笔记欧拉定理欧拉定理连通平面图满足\(V-E+F=2\)。有\(C\)个连通块的平面图满足\(V-E+F=C+1\)。简单连通平面图满足\(E\le3V-6\)。重要:平面图满足\(E=O(V)\)。可以用于证明\(K_5\)不是平面图。一个\(V\ge3\)的简单连通平......
  • Nvidia Jetson Xavier NX安装GPU版pytorch与torchvision
    前提是已经安装好了系统,并通过JetPack配置完了cuda、cudnn、conda等库。1.安装GPU版pytorch在base环境上新建环境,python版本3.8,激活并进入。condacreate-npytorch_gpupython=3.8condaactivatepytorch_gpu前往Nvidia论坛,下载JetsonNX专用的pytorch安装包。传送门:ht......
  • [EC Final 2022] Rectangle
    link。数据结构好题,写死我了QwQ……这个题是可以用segbeats做到\(O(n\logn)\)的。先离散化。我们只用考虑三条竖线和两竖一横的情况。三条竖线线性DP一下就行了。两竖一横的情况可以考虑枚举更靠后的那条竖线,首先这条竖线后面还没有被覆盖的区间就只能用横线覆盖了,于......
  • Nginx反向代理,代理H5前端 ,java后端,使用服务器+finalshell+vpn
    使用前确认已经安装好nginx,这里我使用的是普通的nginx,注意不是Docker版本的nginx输入nginx-t查询一下,自己的nginxconfig.nginx在那个包下,方便查询 使用catnginx.conf命令,进入需要配置的conf中(这个是我使用的server[server{listen82;s......
  • 2024.8.7 test
    A一个基环树上,给出每条边可以存在的时间,你还有\(L\)的时间可以分配给边。你要安排边开始存在的时间,使得联通的时间最长,求这个值。\(n\le10^5\)。先不考虑\(L\)。如果是树,那么答案是边存在时间的最小值。如果是基环树,那么把环上次小边加上最小边,并删掉最小边,变成树求最小边......
  • Vision Pro 3D 目标跟踪实战案例:厨房场景应用
    随着苹果公司在增强现实(AR)领域的持续投入和发展,visionOS和ARKit技术已经成为构建沉浸式交互体验的关键工具。visionOS2版本更是为开发者提供了更强大的功能集,使他们能够创造出更加复杂且引人入胜的应用程序。本文将介绍如何利用visionOS2和ARKit技术,在厨房场景中实现......
  • Apple Vision Pro 游戏开发:挑战与反思
     随着AppleVisionPro的推出,许多游戏开发者开始尝试在这个全新的平台上构建沉浸式的虚拟现实体验。然而,开发者们很快发现,在这个新兴领域中面临着不少挑战,包括支付延迟、技术支持不足、设备性能限制等问题。本文将探讨这些挑战,并提出一些开发者需要注意的关键点。支付延迟......
  • VisionPro二次开发笔记6-添加显示工具栏和状态栏
    通过CognexDisplay工具栏,您可以在CognexDisplay控件中操作图像,而CognexDisplay状态栏将显示有关该图像的信息。下图显示了CognexDisplay控件以及工具栏和状态栏:要将工具栏和状态栏添加到VisualStudio.NET应用程序,请执行以下步骤:选择“项目”->“添加引用”,然后添加......
  • Visionpro二次开发学习笔记7-使用CogToolDisplay控件
    CogToolDisplay控件可显示与视觉工具记录相关的图像,图形和其他状态信息。它使用CogRecord和ICogTool接口将图像和图形连接到CogDisplay。图片清单控件的CogComboBox列出当前记录及其子记录中的图像和图形。您可以单击列表并选择要显示的图像或图形。如果记录层次结构仅包......
  • [转]相同CRC不同数据的测试.CRC16 - CRC64 test results on 18.2M dataset
    转载自: http://www.backplane.com/matt/crc64.html  CRC16-CRC64testresultson18.2Mdataset,w/programsourceProgram&TestRunbyMattDillon18.2Mmessage-iddatasetsuppliedbyJoeGrecoIwouldliketothankeveryonewhoofferedtheirhistoryf......