(CF1902D)我个人认为STL是个【】
Senior_Young · · 题解
前言
STL。虽然但是比大数据结构强喵。
题意
有一个无限的平面直角坐标系。最初,机器人站在点
思路
我们考虑把上下左右分别看成
现在我们考虑翻转,那么我们就要考虑翻转后的前缀和,也就是考虑后缀和。我们以横坐标
我们发现,翻转区间
- 考虑
l=1,r=n 时,f'_{i}=g_{n-i+1} ,把一个序列翻转,后缀和变成前缀和,这个是显然的。 - 考虑
l=1 时,f'_{i}=g_{{\color{pink}r}-i+1}-g_{r+1} ,因为当我们将r 后面的所有元素删除就转化为了上一种情况,此时所有i\le r 的g_{i} 就都需要减去g_{r+1} 。注意经过转化后,粉色部分是r 而不是n 。 - 考虑一般情况,则我们的上一个式子相当于将
l 前面的所有元素删去,那么f'_{i} 就比实际少f'_{l-1} ,而根据我们刚才的结论,f'_{l-1}=f_{l-1} ,所以f'_{i}=g_{r-i+{\color{pink}l}}-g_{r+1}+f_{l-1} 。注意经过转化后,粉色部分是l 而不是1 。
所以当
当然
那么我们如果要在
当然如果我们要找的是一个数对 map 开成 map<pair<int,int>,int> 就好了。
提示
依照现在的思路是过不了的,因为可能有两个点相同,也就是 map 可能会被重复赋值。
那么我们就可以开 vector 记录与 map 存储的点相同的点,在里面二分即可。对于
代码
:::success[在这里喵]
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=5e5+5;
map<PII,int> mp;
map<PII,int> mp2;
map<PII,int> mp3;
int a[N],f[N],g[N];
int b[N],p[N],q[N];
vector<int> v[N];
string s;
int n,Q;
void man(){
int x,y,l,r;
cin>>x>>y>>l>>r;
if(x==0&&y==0){
cout<<"YES\n";
return;
}
int k=mp2[{x,y}];
if(k>r){
cout<<"YES\n";
return;
}
k=mp3[{x,y}];
if(k&&k<l){
cout<<"YES\n";
return;
}
x-=f[l-1];
y-=p[l-1];
x+=g[r+1];
y+=q[r+1];
k=mp[{x,y}];
auto it=lower_bound(v[k].begin(),v[k].end(),l);
if(it==v[k].end()||*it>r) cout<<"NO\n";
else cout<<"YES\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>Q;
cin>>s;
for(int i=1;i<=n;i++){
if(s[i-1]=='R') a[i]=1;
else if(s[i-1]=='L') a[i]=-1;
else if(s[i-1]=='U') b[i]=1;
else if(s[i-1]=='D') b[i]=-1;
f[i]=f[i-1]+a[i];
p[i]=p[i-1]+b[i];
mp2[{f[i],p[i]}]=i;
}
for(int i=n;i>=1;i--){
g[i]=g[i+1]+a[i];
q[i]=q[i+1]+b[i];
mp3[{f[i],p[i]}]=i;
}
for(int i=1;i<=n;i++){
auto tmp=make_pair(g[i],q[i]);
if(mp[tmp]==0) mp[tmp]=i;
v[mp[tmp]].push_back(i);
}
while(Q--) man();
return 0;
}
:::
后记
都看到这里了喵,点个赞好不好喵~