QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#268407 | #7748. Karshilov's Matching Problem II | 1L1YA | WA | 3ms | 16480kb | C++14 | 2.6kb | 2023-11-28 17:02:45 | 2023-11-28 17:02:46 |
Judging History
answer
//1L1YA
#include<bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2")
using namespace std;
#define ll long long
#define Pb push_back
#define dokme(x) cout << x << endl, exit(0)
#define pll pair<ll,ll>
#define F first
#define S second
#define endl '\n'
#define sep ' '
#define all(x) x.begin(),x.end()
#define FastIO ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define lc id<<1
#define rc lc|1
const ll mod=1e9+7;
const ll oo=4e18;
const int N=3e5+23;
const int lg=23;
int n,q,a[N],z[N],lps[N];
ll dp[N],sum[N],cnt[N];
pll seg[N<<2];
vector<int> adj[N];
string s,t;
inline void Z(string s){
int m=s.length();
int k=0,mx=0;
for(int i=0;i<m;i++){
if(i<mx)
z[i]=min(mx-i,z[i-k]);
while(i+z[i]<m && s[z[i]]==s[i+z[i]])
z[i]++;
if(i+z[i]>mx)
mx=i+z[i],k=i;
}
}
inline void KMP(string s){
int i=1,j=0;
int n=s.length();
while(i<n)
if(s[i]==s[j])
lps[i++]=++j;
else if(j)
j=lps[j-1];
else
lps[i++]=0;
}
void modify(int pos,pll val,int id=1,int l=1,int r=n+1){
if(r-l==1){
seg[id]=val;
return;
}
int mid=l+r>>1;
if(pos<mid) modify(pos,val,lc,l,mid);
else modify(pos,val,rc,mid,r);
seg[id].F=max(seg[lc].F,seg[rc].F);
seg[id].S=seg[lc].S+seg[rc].S;
}
pll get(int ql,int qr,int id=1,int l=1,int r=n+1){
if(qr<=l || ql>=r) return {0,0};
if(ql<=l && r<=qr) return seg[id];
int mid=l+r>>1;
pll pl=get(ql,qr,lc,l,mid),pr=get(ql,qr,rc,mid,r);
return {max(pl.F,pr.F),pl.S+pr.S};
}
void dfs(int v){
cnt[v]+=a[v];
for(int u: adj[v]){
cnt[u]=cnt[v];
dfs(u);
}
}
int main(){
FastIO
cin >> n >> q >> s >> t;
for(int i=1;i<=n;i++)
cin >> a[i],sum[i]=sum[i-1]+a[i];
Z(s+'#'+t);
for(int i=1;i<=n;i++)
modify(i,{i+z[i+n],sum[z[i+n]]});
KMP(s);
for(int i=0;i<n;i++)
adj[lps[i]].Pb(i+1);
dfs(0);
for(int i=1;i<=n;i++)
dp[i]=dp[i-1]+cnt[i];
while(q--){
int l,r;
cin >> l >> r;
int L=l-1,R=r+1;
if(z[l]+l>r){
L=l-1,R=l;
}
else
while(R-L>1){
int mid=L+R>>1;
if(get(l,mid+1).F<=r) L=mid;
else R=mid;
}
cout << (l==R?0:get(l,R).S)+dp[r-L] << endl;
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 16480kb
input:
8 5 abbabaab aababbab 1 2 4 8 16 32 64 128 1 1 2 3 3 5 4 7 1 8
output:
1 3 3 16 38
result:
ok 5 lines
Test #2:
score: -100
Wrong Answer
time: 3ms
memory: 11636kb
input:
15 4 heheheheehhejie heheheheheheheh 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 2 3 4 8 2 6 1 15
output:
4 13 25 174
result:
wrong answer 1st lines differ - expected: '3', found: '4'