题解:P7769 「CGOI-1」大师选徒
考虑什么时候
-
a_l=a_b -
特判
若没有第二个条件,可以用后缀数组实现快速比较子串,二分即可。那么直接将排序结果挂到后缀起点对应的值上二分,即可做到
卡了很久,你最好使用小常数 SA。
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l),qwp=(r);i<=qwp;i++)
#define per(i,r,l) for(int i=(r),qwp=(l);i>=qwp;i--)
#define repll(i,l,r) for(ll i=(l),qwp=(r);i<=qwp;i++)
#define perll(i,r,l) for(ll i=(r),qwp=(l);i>=qwp;i--)
#define pb push_back
#define ins insert
#define clr clear
#define rem(S,X) (S).erase((S).find((X)))
#define uset unordered_set
#define umap unordered_map
#define mset multiset
using namespace std;
namespace ax_by_c{
const int MB=1<<20;
struct FastIO{
char ib[MB+100],*p,*q;
char ob[MB+100],*r,stk[128];
int tp;
FastIO(){p=q=ib,r=ob,tp=0;}
~FastIO(){fwrite(ob,1,r-ob,stdout);}
char read_char(){
if(p==q){
p=ib,q=ib+fread(ib,1,MB,stdin);
if(p==q)return 0;
}
return *p++;
}
template<typename T>
void read_int(T& x){
char c=read_char(),l=0;
for(x=0;!isdigit(c);c=read_char())l=c;
for(;isdigit(c);c=read_char())x=x*10-'0'+c;
if(l=='-')x=-x;
}
void write_char(char c){
if(r-ob==MB)r=ob,fwrite(ob,1,MB,stdout);
*r++=c;
}
template<typename T>
void write_int(T x){
if(x<0)write_char('-'),x=-x;
do stk[++tp]=x%10+'0';
while(x/=10);
while(tp)write_char(stk[tp--]);
}
}IO;
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
const int N=8e5+5;
const int LN=20;
namespace SA{
int cnt[N],id[N],ork[N*2];
void bld(int n,int *s,int *rk,int *sa,int *ht){
int m=n;
rep(i,1,n)rk[i]=s[i],cnt[rk[i]]++;
rep(i,1,m)cnt[i]+=cnt[i-1];
rep(i,1,n)sa[cnt[rk[i]]--]=i;
for(int w=1;w<=n;w<<=1){
int idx=0;
rep(i,n-w+1,n)id[++idx]=i;
rep(i,1,n)if(sa[i]>w)id[++idx]=sa[i]-w;
rep(i,1,m)cnt[i]=0;
rep(i,1,n)cnt[rk[i]]++;
rep(i,1,m)cnt[i]+=cnt[i-1];
per(i,n,1)sa[cnt[rk[id[i]]]--]=id[i];
rep(i,1,n)ork[i]=rk[i];
int p=0;
rep(i,1,n){
if(ork[sa[i-1]]!=ork[sa[i]]||ork[sa[i-1]+w]!=ork[sa[i]+w])p++;
rk[sa[i]]=p;
}
if(p==n)break;
m=p;
}
rep(i,1,n){
ht[rk[i]]=max(ht[rk[i-1]]-1,0);
while(s[sa[rk[i]-1]+ht[rk[i]]]==s[sa[rk[i]]+ht[rk[i]]])ht[rk[i]]++;
}
}
}
struct DS1{
int lg2[N],mn[N][LN];
void bld(int n,int *a){
rep(i,2,n)lg2[i]=lg2[i>>1]+1;
rep(i,1,n)mn[i][0]=a[i];
rep(j,1,19)rep(i,1,n-(1<<j)+1)mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
}
int Q(int l,int r){
int x=lg2[r-l+1];
return min(mn[l][x],mn[r-(1<<x)+1][x]);
}
}ST;
int n,q,a[N];
int s[N],hsh[N],hc;
int rk[N],sa[N],ht[N];
set<int>S;
vector<int>pos[N];
bool cmp(int l1,int r1,int l2,int r2){
if(l1==l2)return r1<r2;
int p=ST.Q(min(rk[l1],rk[l2])+1,max(rk[l1],rk[l2]));
if(p<min(r1-l1+1,r2-l2+1))return s[l1+p]<s[l2+p];
return r1-l1+1<r2-l2+1;
}
void slv(int _csid,int _csi){
IO.read_int(n),IO.read_int(q);
rep(i,1,n)IO.read_int(a[i]),S.ins(a[i]);
rep(i,1,n-1)s[i]=a[i]-a[i+1],s[n+i]=a[i+1]-a[i];
rep(i,1,n*2)hsh[++hc]=s[i];
sort(hsh+1,hsh+1+hc),hc=unique(hsh+1,hsh+1+hc)-hsh-1;
rep(i,1,n*2)s[i]=lower_bound(hsh+1,hsh+1+hc,s[i])-hsh;
SA::bld(n*2,s,rk,sa,ht);
ST.bld(n*2,ht);
rep(i,1,n*2)if(n<sa[i]&&sa[i]<n*2)pos[a[sa[i]-n]].pb(sa[i]);
rep(_,1,q){
int ss,l,r;
IO.read_int(ss),IO.read_int(l),IO.read_int(r);
if(l==r){
if(S.count(ss-a[l]))IO.write_char('Y'),IO.write_char('e'),IO.write_char('s'),IO.write_char('\n');
else IO.write_char('N'),IO.write_char('o'),IO.write_char('\n');
continue;
}
if(ss-a[l]<1||n<ss-a[l]||!pos[ss-a[l]].size()){
IO.write_char('N'),IO.write_char('o'),IO.write_char('\n');
continue;
}
int p=0,q=0;
{
int L=0,R=pos[ss-a[l]].size()-1,mid,res=-1;
while(L<=R){
mid=(L+R)>>1;
if(cmp(pos[ss-a[l]][mid],min(pos[ss-a[l]][mid]+r-l-1,n*2),l,r-1))res=mid,L=mid+1;
else R=mid-1;
}
p=res+1;
}
{
int L=0,R=pos[ss-a[l]].size()-1,mid,res=-1;
while(L<=R){
mid=(L+R)>>1;
if(!cmp(l,r-1,pos[ss-a[l]][mid],min(pos[ss-a[l]][mid]+r-l-1,n*2)))res=mid,L=mid+1;
else R=mid-1;
}
q=res;
}
if(p<=q)IO.write_char('Y'),IO.write_char('e'),IO.write_char('s'),IO.write_char('\n');
else IO.write_char('N'),IO.write_char('o'),IO.write_char('\n');
}
}
void main(){
// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T=1,csid=-1;
// scanf("%d",&csid);
// scanf("%d",&T);
// scanf("%d",&csid);
rep(i,1,T)slv(csid,i);
}
}
int main(){
string __name="";
if(__name!=""){
freopen((__name+".in").c_str(),"r",stdin);
freopen((__name+".out").c_str(),"w",stdout);
}
ax_by_c::main();
return 0;
}
/*
g++ -std=c++14 -O2 -Wall -Wextra "-Wl,--stack=200000000" A.cpp -o A.exe
A.exe
*/