用的是转化成图和倍增。
#include<bits/stdc++.h>
#define ls 2*p
#define rs 2*p+1
using namespace std;
const int N=2e5+25;
int n,m,q;
int p[N],a[N];
int head[N],cnt;
int f[30][N];
inline int get(int u,int step){
for (int i =24;i>=0;i--)
if (step>>i&1)
u=f[i][u];
return u;
}
int k[N];
struct SegmentTree {
int l,r,minn;
}t[N*4];
inline void build(int l,int r,int p){
t[p].l=l,t[p].r=r;
if(l==r) {
t[p].minn=k[l];
return;
}
int mid=(l+r)/2;
build(l,mid,ls);
build(mid+1,r,rs);
t[p].minn=min(t[ls].minn,t[rs].minn);
}
inline int query(int l,int r,int p){
int res=INT_MAX;
if(t[p].l>=l&&t[p].r<=r) {
return t[p].minn;
}
int mid=(t[p].l+t[p].r)/2;
if(l<=mid)res=min(res,query(l,r,ls));
if(r>mid)res=min(res,query(l,r,rs));
return res;
}
map<int,int>mp;
int main(){
cin>>n>>m>>q;
for (int i=1;i<=n;i++)
cin>>p[i];
p[n+1]=p[1];
for(int i=1;i<=n;++i)
mp[p[i]]=p[i+1];
for (int i=1;i<=m;i++)
cin>>a[i];
bool flag=0;
for (int i=1;i<=m;i++){
int t=mp[a[i]];
flag=0;
for (int j=i+1;j<=m;j++)
if(a[j]==t){
f[0][i]=j;
flag=1;
break;
}
if(!flag) {
f[0][i]=m+1;
continue;
}
}
for(int j=1;j<25;j++){
for(int i=m+1;i>=1;i--)
f[j][i]=f[j-1][f[j-1][i]];
}
for (int i=1;i<=m;i++)
k[i]=get(i,n-1);
for(int i=1;i<=m;i++)
cout<<k[i]<<' ';
cout<<endl;
build(1,m,1);
for (int i=1;i<=q;i++) {
int l,r;
cin>>l>>r;
if(query(l,r,1)<=r)cout<<1;
else cout<<0;
}
}