1 条题解
-
0
思路:
容易发现,区间 中 与 等价的充分必要条为:
-
两个序列中所有元素对于在区间 内的出现集合组成的集合相等。
-
这样才可以使得存在一种对应的映射方案使得等价。
考虑哈希判定。
设 表示 出现的位置的集合,则设 $\operatorname{Hash}(S_x) = \sum\limits_{i \in S_x} base^i$,$\operatorname{Hash}(A/B) = \sum\limits_{i=1}^m \operatorname{Hash}(S_i)$。
固定左端点 时,容易发现 具有单调性,考虑求出 表示以 为左端点的最长等价区间,使用双指针算法;
设当前加入的数为 ,则重新计算下 即可,删除同理。
因为当前是单哈希,且基本都是加法哈希,可以双哈希 稳固一下。
时间复杂度为 。
完整代码:
#include<bits/stdc++.h> #define Add(x,y) (x+y>=mod)?(x+y-mod):(x+y) #define lowbit(x) x&(-x) #define pi pair<ll,ll> #define pii pair<ll,pair<ll,ll>> #define iip pair<pair<ll,ll>,ll> #define ppii pair<pair<ll,ll>,pair<ll,ll>> #define fi first #define se second #define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x #define Full(a) memset(a,0,sizeof(a)) #define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout); #define For(i,l,r) for(int i=l;i<=r;i++) #define _For(i,l,r) for(int i=r;i>=l;i--) using namespace std; typedef long double lb; typedef double db; typedef unsigned long long ull; typedef long long ll; bool Begin; const ll N=2e5+10,M=6e5+10; const ull base=127; inline ll read(){ ll x=0,f=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9'){ x=(x<<1)+(x<<3)+(c^48); c=getchar(); } return x*f; } inline void write(ll x){ if(x<0){ putchar('-'); x=-x; } if(x>9) write(x/10); putchar(x%10+'0'); } mt19937_64 R(time(0)); ull h1,h2; int n,m,q,p,l,r; int len[N],a[N][3],b[N][3]; ull f[N],s1[M],s2[M]; inline ull Hash(ull x){ return x*f[x%(N-1)+1]; } inline void insert1(int x,int id){ h1-=Hash(s1[x]); s1[x]+=f[id]; h1+=Hash(s1[x]); } inline void insert2(int x,int id){ h2-=Hash(s2[x]); s2[x]+=f[id]; h2+=Hash(s2[x]); } inline void del1(int x,int id){ h1-=Hash(s1[x]); s1[x]-=f[id]; h1+=Hash(s1[x]); } inline void del2(int x,int id){ h2-=Hash(s2[x]); s2[x]-=f[id]; h2+=Hash(s2[x]); } inline void insert(int x){ For(i,0,2){ insert1(a[x][i],x); insert2(b[x][i],x); } } inline void del(int x){ For(i,0,2){ del1(a[x][i],x); del2(b[x][i],x); } } bool End; int main(){ //open("A.in","A.out"); n=read(),m=read(),q=read(); f[0]=1; For(i,1,N-1) f[i]=f[i-1]*base; For(i,1,n) For(j,0,2) a[i][j]=read(); For(i,1,n) For(j,0,2) b[i][j]=read(); for(int l=1,r=0;l<=n;){ while(r<l){ ++r; insert(r); } while(r<=n&&h1==h2){ r++; insert(r); } del(r--); len[l]=r; del(l++); } while(q--){ l=read(),r=read(); if(r>len[l]) puts("No"); else puts("Yes"); } cerr<<'\n'<<abs(&Begin-&End)/1048576<<"MB"; return 0; } -
- 1
信息
- ID
- 7388
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者