题解:P8925 「GMOI R1-T2」Light
概述原点有一盏灯,左右各一面镜子分别在 -L 与 R,两镜互照产生无穷多个像,T 次询问求左侧或右侧第 x 个像的坐标。x 高达百亿,必须直接算而非逐次反射。观察左侧各像到原点的距离依次交替增加 2R、2L,推得左侧第 x 个像到原点的距离中 L 的系数为 x 除以二向上取整、R 的系数为 x 除以二向下取整,坐标取相反数;右侧对称,交换两系数即可。每次询问 O(1)。
原点处有一盏灯,左、右各有一面镜子,分别位于 −L、R。两镜对照产生无穷多个像。T 次询问,每次求左侧或右侧第 x 个像的坐标。
x 高达 1010,必须直接算出第 x 个像的位置,不能逐次反射。
记左、右镜到原点的距离为 L、R。观察左侧前几个像到原点的距离:2L, 2L+2R, 4L+2R, 4L+4R,…,每往后一个像交替增加 2R、2L。于是左侧第 x 个像到原点的距离为:
2⌈2x⌉L+2⌊2x⌋R
坐标取其相反数。右侧完全对称,把 L、R 的系数互换即可。
整数实现中 ⌈2x⌉ 为 (x+1)/2,⌊2x⌋ 为 x/2。每次询问 O(1) 作答。
时间复杂度为 O(T)。
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
ll l,r;
cin>>t>>l>>r;
while(t--)
{
char c;
ll x;
cin>>c>>x;
ll a=(x+1)/2,b=x/2;
cout<<(c=='L'?-2*(a*l+b*r):2*(a*r+b*l))<<'\n';
}
return 0;
}