其他分享
首页 > 其他分享> > 【洛谷P7099】灼

【洛谷P7099】灼

作者:互联网

题目

题目链接:https://www.luogu.com.cn/problem/P7099

这里是 NS05,勒本星球已无生命反应,请求救援!普尔!——你听得到吗?我会一直在这里,等待你的归来。

扶苏被困在了勒本星球,灼闻羽驾驶着一架宇宙飞船正打算穿越虫洞到达勒本星球拯救扶苏。
在一条数轴上有 \(n\) 个虫洞,第 \(i\) 个虫洞的坐标为 \(x_i\)。进入这些虫洞的任意一个都可以直接到达勒本星球拯救扶苏。飞船到达数轴所在直线上后,会因为磁场的效应失去操控能力,飞船每秒会等概率向左或向右移动一个单位长度。
灼闻羽非常焦急,他给出了 \(q\) 个飞船进入数轴所在直线的初始坐标,对于每个坐标,他想知道期望需要多少秒才能到达一个虫洞。
如果你计算出的期望是个分数,你需要求出这个分数对 \(998244353\) 取模的答案。有关分数取模的定义你可以参考「提示」中的内容。
为了避免输出过大,你只需要输出四个整数,分别表示你所有回答(对 \(998244353\) 取模之后,下同)的按位异或之和、你共有多少次回答的答案是奇数,你的所有答案中的最大值、你的所有答案中的最小值。

\(n\leq10^5,q\leq 5\times 10^6,1\leq x_i,y_i\leq 10^9,y_i\leq y_{i+1}\)。

思路

设 \(f_i\) 表示位置 \(i\) 到达左右的虫洞之一的期望步数。
那么必然有 \(f_i=\frac{f_{i+1}+f_{i-1}}{2}+1\)。等价于 \(2f_i=f_{i+1}+f_{i-1}+2\),等价于 \((f_{i+1}-f_i)-(f_i-f_{i-1})=-2\)。
发现 \(f\) 的二阶差分是一个定值,所以 \(f\) 应该是一个二次函数。
设 \(f(x)=ax^2+bx+c\),那么 \(f(x+1)=a(x^2+2x+1)+b(x+1)+c,f(x-1)=a(x^2-2x+1)+b(x-1)+c\)。
那么 \((f(x+1)-f(x))-(f(x)-f(x-1))=2a=-2\),所以 \(a=2\)。
对于一个点 \(x\),找到左右最近的两个虫洞 \(l,r\),因为 \(f(l)=f(r)=0\),所以

\[\left\{\begin{matrix}-l^2+bl+c=0 \\ -r^2+br+c=0 \end{matrix}\right. \]

则 \(b(r-l)=r^2-l^2,b=l+r\)。最后带入 \(x=l\) 得到 \(c=-lr\)。
所以我们得到了 \(f(x)=-x^2+(l+r)x-lr\)。将虫洞排序后每次询问可以做到 \(O(1)\) 回答。
时间复杂度 \(O(n\log n+Q)\)。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=100010,MOD=998244353;
int n,Q,a[N];
ll ans1,ans2,ans3,ans4;

int read()
{
	int d=0; char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) d=(d<<3)+(d<<1)+ch-48,ch=getchar();
	return d;
}

int main()
{
	read(); n=read(); Q=read();
	for (int i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+1+n);
	ans4=9e18;
	for (int i=1,j=1;i<=Q;i++)
	{
		int x=read();
		while (j<n && a[j+1]<=x) j++;
		ll res=((-1LL*x*x+1LL*(a[j]+a[j+1])*x-1LL*a[j]*a[j+1])%MOD+MOD)%MOD;
		ans1^=res; ans2+=res&1; ans3=max(ans3,res); ans4=min(ans4,res);
	}
	cout<<ans1<<"\n"<<ans2<<"\n"<<ans3<<"\n"<<ans4;
	return 0;
}

标签:ch,洛谷,数轴,int,leq,勒本,星球,P7099
来源: https://www.cnblogs.com/stoorz/p/14999834.html