【洛谷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\),所以
则 \(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