先考虑弱化版,若是不考虑编号怎么办。
这个问题有一个很经典的结论,碰撞等同穿过,所以直接算出每个点按照指定方向走,在 \(t\) 秒后的位置即可。
现在多了一个编号,因为是碰撞,所以两个点的相对位置是相同的,即 \(x\) 号点原来是 \(y\) 号点顺时针方向的第几个点,它最终还是 \(x\) 顺时针方向的第几个点。那么我们只要找到一个点的位置,就可以找到其它所有点的位置。假定我们确定的是第一个点的位置,感性理解一下,每有一个点逆时针穿过 \(0\),它的排名会减 \(1\),反之会加 \(1\)。直接算就好了。
tips:算的时候注意精度问题。
点击查看代码
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define int __int128
#define pdi pair<double,int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define eps 1e-9
using namespace std;
namespace IO{
template<typename T>
inline void read(T &x){
x=0;
int f=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
x=(f==1?x:-x);
}
template<typename T>
inline void write(T x){
if(x<0){
putchar('-');
x=-x;
}
if(x>=10){
write(x/10);
}
putchar(x%10+'0');
}
template<typename T>
inline void write_endl(T x){
write(x);
putchar('\n');
}
template<typename T>
inline void write_space(T x){
write(x);
putchar(' ');
}
}
using namespace IO;
const int N=3e5+10;
int n,ed[N],l,t,pos,id[N],p[N],st[N],ans[N];
bool cmp(int x,int y){
return st[x]<st[y];
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
read(n),read(l),read(t);
for(int i=0;i<n;i++){
id[i]=i;
char opt;
read(st[i]);
opt=getchar();
while(opt!='1'&&opt!='2'){
opt=getchar();
}
if(opt=='2'){
ed[i]=st[i]-t;
}
else{
ed[i]=st[i]+t;
}
int x=floor((long double)ed[i]/l);
pos=(x%n+n+pos)%n;
ed[i]=(ed[i]%l+l)%l;
}
sort(id,id+n,cmp);
for(int i=0;i<n;i++){
p[id[i]]=i;
}
sort(ed,ed+n);
for(int i=0;i<n;i++){
ans[i]=ed[(i+pos)%n];
}
for(int i=0;i<n;i++){
write_endl(ans[p[i]]);
}
return 0;
}