QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#468761 | #8079. Range Periodicity Query | wuzihan | RE | 2ms | 9772kb | C++14 | 3.9kb | 2024-07-09 00:25:51 | 2024-07-09 00:25:53 |
Judging History
answer
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
// #define endl '\n'
#pragma GCC optimize(2)
using namespace std;
struct strhash{
typedef long long LL;
std::vector<LL> h1,h2;
std::vector<LL> p;
LL base=131,mod=33951943;
string str;
int len;
void build(string s){
str=s;
len=s.size();
h1=std::vector<LL>(len+1);
h2=std::vector<LL>(len+2);
p=std::vector<LL>(len+1);
p[0]=1;
for(int i=0;i<len;i++){
h1[i+1]=(h1[i]*base+s[i])%mod;
h2[len-1-i]=(h2[len-i]*base+s[len-i-1])%mod;
p[i+1]=p[i]*base%mod;
}
}
LL prehash(int l,int r){
return (h1[r+1]-h1[l]*p[r-l+1]%mod+mod)%mod;
}
LL sufhash(int l,int r){
return (h2[l]-h2[r+1]*p[r-l+1]%mod+mod)%mod;
}
/*
时间复杂度为O(n),空间为O(3*n)
prehash用于求前缀的哈希,即从左到右
sufhash用于求后最的哈希,即从右到左
用前先对需要的字符串进行一次build(s)
本模板由于出现正反哈希,所以主要用于回文串一类的字符串哈希,
或者用于单哈希也ok,懒得再去写单哈希了
注:本板用于字符串/01串(即单个进制只有一个字符)
*/
}str;
typedef pair<int,int> PII;
const int N=500010,inf=1e18;
PII S[N];
int a[N];
struct Node
{
int l,r,mi;
}tr[N*4];
void pushup(int u)
{
tr[u].mi=min(tr[u<<1].mi,tr[u<<1|1].mi);
}
void build(int u,int l,int r)
{
if(l==r)
{
tr[u]={l,r,inf};
return;
}
tr[u]={l,r,inf};
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
void modify(int u,int k,int x)
{
if(tr[u].l==tr[u].r)
{
tr[u].mi=x;
return;
}
int mid=(tr[u].l+tr[u].r)>>1;
if(k<=mid) modify(u<<1,k,x);
else modify(u<<1|1,k,x);
pushup(u);
}
int query(int u,int l,int r)
{
if(tr[u].l>=l && tr[u].r<=r) return tr[u].mi;
int mid=(tr[u].l+tr[u].r)>>1;
if(r<=mid) return query(u<<1,l,r);
if(l>mid) return query(u<<1|1,l,r);
return min(query(u<<1,l,r),query(u<<1|1,l,r));
}
struct Query
{
int l,r,id;
};
int ans[N];
bool check(int p,int i)
{
if(i==p) return 1;
int t=i-p;
PII tp=S[i];
if(str.prehash(tp.x,tp.x+t-1)==str.prehash(tp.y-t+1,tp.y)) return 1;
return 0;
}
void solve()
{
int n;
cin >> n;
vector<char> s(3*n+1000);
int l=n+7,r=l-1;
for(int i=1;i<=n;i++)
{
char c;
cin >> c;
if(c>='A' && c<='Z') s[++r]=c-'A'+'a';
else s[--l]=c;
S[i]={l,r};
}
string ss="#";
for(int i=l;i<=r;i++) ss+=s[i];
str.build(ss);
for(int i=1;i<=n;i++) S[i].x-=l-1,S[i].y-=l-1;//cout << i << ' ' << S[i].x << ' ' << S[i].y << endl;
int m;
cin >> m;
vector<int> v[n+1];
for(int i=1;i<=m;i++)
{
cin >> a[i];
v[a[i]].push_back(i);
}
build(1,1,m);
vector<int> out[n+1];
for(int i=1;i<=n;i++)
{
int l=i,r=n;
while(l<r)
{
int mid=(l+r+1)>>1;
if(check(i,mid)) l=mid;
else r=mid-1;
}
l++;
// cout << S[l].x << ' ' << S[l].y << ' ' << i << "!!" << endl;
out[l].push_back(i);
}
vector<Query> q[n+1];
int Q;
cin >> Q;
for(int i=1;i<=Q;i++)
{
int k,l,r;
cin >> k >> l >> r;
q[k].push_back({l,r,i});
}
for(int i=1;i<=n;i++)
{
for(auto t:v[i]) modify(1,t,i);
for(auto t:out[i])
for(auto tp:v[t]) modify(1,tp,inf);
for(auto t:q[i]) ans[t.id]=query(1,t.l,t.r);
}
for(int i=1;i<=Q;i++)
{
if(ans[i]==inf) cout << -1 << endl;
else cout << ans[i] << endl;
}
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int T;
T=1;
while(T--) solve();
}
/*
7
AABAAba
9
4 3 2 1 7 5 3 6 1
1
5 4 7
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 9772kb
input:
7 AABAAba 9 4 3 2 1 7 5 3 6 1 6 1 4 4 2 1 4 2 1 3 3 3 5 5 4 7 7 8 9
output:
1 1 2 -1 3 6
result:
ok 6 lines
Test #2:
score: -100
Runtime Error
input:
200000 BAbBbBabBBbbABbbaBbaaabaBBAbBbBAAAAABBaBaAAabBAAbABaaBABAabAAAbabbAaBABAbabbAAAbbbbabBBAbbBaabBAAAbBBBbBbbAbbbBabbBABaBAaAAAbBbaABabBAbAAbBbbAbAbBaabAbBBbaaaaBaBbbABBBaaabBaBABAbBabBbbAABBbaBAbaBAbAAABABAbaabbaAAaBAbAbAbBBbaaaAaBaaABBbBAAaAAAaaABbbaAbAaBbaAaaababbaBbaAAAAAAabbBaAabbbaBBAAaABb...