QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#527416 | #7512. Almost Prefix Concatenation | Oo | WA | 12ms | 19320kb | C++20 | 5.7kb | 2024-08-22 15:08:59 | 2024-08-22 15:08:59 |
Judging History
answer
//#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define i128 __int128
#define db long double
#define pb push_back
#define popb pop_back
#define fi first
#define se second
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
const int N=1e6+10;
//const int M=;
//const int inf=(int)1e9;
//const ll INF=(ll)1e18;
#define int long long
const int MOD[2] = {998244353, 1000000007};
const int Seed = 13331; // 注意对数字hash时,数字是否会大于进制?
long long base[2][N];
struct Hash {
int len;
string s;
// int has[2][N];
vector< vector<int> > has;
Hash(string _s) {
//s = '?' + _s;
//len = _s.size();
s = _s;
len = _s.size() - 1;
has.resize(2);
has[0].resize(len + 1);
has[1].resize(len + 1);
for (int i = 0; i < 2; i++)
for (int j = 1; j <= len; j++)
has[i][j] = (1ll * has[i][j - 1] * Seed % MOD[i] + s[j]) %MOD[i]; // attention: -'a' or -'A' or -'0' or null ?
}
void init(string _s) {
//s = '?' + _s;
//len = _s.size();
s = _s;
len = _s.size() - 1;
has.resize(2);
has[0].resize(len + 1);
has[1].resize(len + 1);
for (int i = 0; i < 2; i++)
for (int j = 1; j <= len; j++)
has[i][j] = (1ll * has[i][j - 1] * Seed % MOD[i] + s[j]) %MOD[i]; // attention: -'a' or -'A' or -'0' or null ?
}
void insert(char c) { // attention: -'a' or -'A' or -'0' or null ?
s += c;
len++;
for (int i = 0; i < 2; i++) {
int _has = 1ll * has[i].back() * Seed % MOD[i] + (c) %MOD[i];
has[i].push_back(_has);
}
}
pair<int, int> Get(int l, int r) {
if (l > r) return {0, 0};
pair<int, int> info;
info.first =
(1ll * has[0][r] - 1ll * has[0][l - 1] * base[0][r - l + 1] % MOD[0] + MOD[0]) % MOD[0];
info.second =
(1ll * has[1][r] - 1ll * has[1][l - 1] * base[1][r - l + 1] % MOD[1] + MOD[1]) % MOD[1];
return info;
}
};
void init(int n = 1e6 + 5) {
base[0][0] = 1;
base[1][0] = 1;
for (int i = 0; i < 2; i++)
for (int j = 1; j <= n; j++) base[i][j] = 1ll * base[i][j - 1] * Seed % MOD[i];
}
int lowbit(int x) { return x & -x; }
#define MOD MOD[1]
struct Bit
{
int n;
vector<ll> sum;
vector<vector<ll>> tr;
Bit() {}
Bit(int _n) { init(_n); }
Bit(const int *a, int _n)
{
init(_n);
for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i]; // mod
}
Bit(const vector<int> &a)
{
init(a.size() - 1);
for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i]; // mod
}
void init(int _n)
{
n = _n;
sum.assign(n + 1, 0);
tr.resize(2);
tr[0].assign(n + 1, 0);
tr[1].assign(n + 1, 0);
}
private:
void Add(int k, int x, ll y)
{
if (x > n)
return;
for (; x <= n; x += lowbit(x))
tr[k][x] = (tr[k][x] + y)%MOD; // mod
}
ll Ask(int k, int x)
{
if (x == 0)
return 0;
ll res = 0;
for (; x; x -= lowbit(x))
res =(res+ tr[k][x])%MOD; // mod
return res;
}
public:
void add(int l, int r, ll d)
{
Add(0, l, d);
Add(0, r + 1, -d);
Add(1, l, l * d % MOD); // mod
Add(1, r + 1, (-(r + 1) * d %MOD + MOD)%MOD); // mod
}
ll ask(int x) // x的前缀和
{
if(x < 0) return 0;
return sum[x] + ((x + 1) * Ask(0, x) % MOD - Ask(1, x) + MOD) % MOD; // mod
}
ll ask(int l, int r) // [l, r] 的和
{
return (ask(r) - ask(l - 1) + MOD)%MOD; // mod
}
};
signed main()
{
// freopen("","r",stdin);
// freopen("","w",stdout);
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout<<fixed<<setprecision();
init();
string s,t;
cin>>s>>t;
int n=s.size(),m=t.size();
Hash S('?'+s),T('?'+t);
vector<int> match(n+1);
for(int i=1;i<=n;i++)
{
auto check=[&](int l,int L,int len)
{
int r=l+len-1,R=L+len-1;
assert(r<=n&&R<=m);
return S.Get(l,r)==T.Get(L,R);
};
int l=1,r=min(n-i+1,m);
while(l+1<r)
{
int mid=(l+r)/2;
if(check(i,1,mid)) l=mid;
else r=mid;
}
int tmp=0;;
if(check(i,1,r)) tmp=r;
else if(check(i,1,l)) tmp=l;
if(i+tmp-1!=n) tmp++;
match[i]+=tmp;
if(match[i]==m || i+match[i]>n) continue;
l=1,r=min(n-(i+tmp)+1,m-(tmp+1)+1);
while(l+1<r)
{
int mid=(l+r)/2;
if(check(i+tmp,tmp+1,mid)) l=mid;
else r=mid;
}
if(check(i+tmp,tmp+1,r)) match[i]+=r;
else if(check(i+tmp,tmp+1,l)) match[i]+=l;
}
for(int i=1;i<=n;i++) match[i]+=i-1;
// for(int i=1;i<=n;i++) cout<<i<<' '<<match[i]<<'\n';
// vector<vector<int>> dp(n+1,vector<int>(3));
// for(int i=1;i<=n;i++)
// {
// int l=i,r=match[i];
// for(int j=l;j<=r;j++)
// {
// if(dp[l-1][0]==0)
// {
// dp[j][0]++;
// dp[j][1]++;
// dp[j][2]++;
// }
// else{
// dp[j][0]+=dp[l-1][0];
// dp[j][1]+=dp[l-1][1]+dp[l-1][0];
// dp[j][2]+=dp[l-1][2]+2*dp[l-1][1]+dp[l-1][0];
// }
// }
// }
// cout<<dp[n][2]<<'\n';
vector<Bit> dp(3);
for(int i=0;i<=2;i++) dp[i].init(n);
for(int i=1;i<=n;i++)
{
int l=i,r=match[i];
int zero=dp[0].ask(i-1,i-1);
int one=dp[1].ask(i-1,i-1);
int two=dp[2].ask(i-1,i-1);
if(zero==0) // 0->1
{
dp[0].add(l,r,1);
dp[1].add(l,r,1);
dp[2].add(l,r,1);
}
else
{
dp[0].add(l,r,zero);
dp[1].add(l,r,(one+zero)%MOD);
dp[2].add(l,r,(two+one*2+zero)%MOD);
}
}
cout<<dp[2].ask(n,n);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 19272kb
input:
ababaab aba
output:
473
result:
ok 1 number(s): "473"
Test #2:
score: 0
Accepted
time: 12ms
memory: 19268kb
input:
ac ccpc
output:
5
result:
ok 1 number(s): "5"
Test #3:
score: -100
Wrong Answer
time: 11ms
memory: 19320kb
input:
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq...
output:
927618643
result:
wrong answer 1st numbers differ - expected: '75038697', found: '927618643'