社区讨论
萌新初学OI,求救
P4770[NOI2018] 你的名字参与者 11已保存回复 11
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 11 条
- 当前快照
- 1 份
- 快照标识符
- @mi7wz2kr
- 此快照首次捕获于
- 2025/11/21 04:58 4 个月前
- 此快照最后确认于
- 2025/11/21 06:36 4 个月前
哪里写错了啊。。
CPP#include <bits/stdc++.h>
#define il inline
const int segn = 1e6 * 20;
const int maxn = 5e5 + 5;
typedef long long ll;
using namespace std;
namespace Fast_Input {
template<class T> il void read(T& res) {
res = 0; char ch; bool sign = 0;
do { ch = getchar(); sign |= ch == '-'; } while(!isdigit(ch));
while(isdigit(ch)) res = (res << 1) + (res << 3) + (ch & 15),ch = getchar();
(sign) && (res = -res);
}
}
using Fast_Input::read;
int n,m,i,j,k;
il int _max(int x,int y) {
return x > y ? x : y;
}
struct Segment_Tree {
int root[segn],rson[segn],lson[segn]; int cnt,n;
Segment_Tree() { memset(root,0,sizeof(root)); memset(rson,0,sizeof(rson)); memset(lson,0,sizeof(lson)); cnt = n = 0; }
il void set_len(int len) { n = len; }
void insert(int l,int r,int k,int& o) {
if(!o) o = ++cnt; if(l == r) return;
int mid = (l + r) >> 1;
if(k <= mid) insert(l,mid,k,lson[o]);
else insert(mid + 1,r,k,rson[o]);
}
il int New(int x) {
int t = ++cnt;
insert(1,n,k,cnt);
return t;
}
int merge(int u,int v) {
if(!u) return v; if(!v) return u;
int t = ++cnt;
lson[t] = merge(lson[u],lson[v]);
rson[t] = merge(rson[u],rson[v]);
return t;
}
bool ask(int ql,int qr,int l,int r,int o) {
if(!o) return 0;
int mid = (l + r) >> 1; bool res = 0;
if(ql <= mid) res |= ask(ql,qr,l,mid,lson[o]);
if(mid < qr) res |= ask(ql,qr,mid + 1,r,rson[o]);
return res;
}
} segt;
template<int samn>
struct Saffix_Automaton {
int len[samn],fa[samn],son[samn][26],root[samn],mn[samn]; int cnt,last;
il void clear() {
memset(len,0,sizeof(len));
memset(fa,0,sizeof(fa));
memset(son,0,sizeof(son));
memset(root,0,sizeof(root));
cnt = last = 1;
}
Saffix_Automaton() {
memset(len,0,sizeof(len));
memset(fa,0,sizeof(fa));
memset(son,0,sizeof(son));
memset(root,0,sizeof(root));
cnt = last = 1;
}
il void extend(int ch,int val) {
int p = last,np = last = ++cnt; mn[np] = len[np] + len[p] + 1;
if(val) segt.New(val); memset(son[np],0,sizeof(son[np]));
for(;p && !son[p][ch];p = fa[p]) son[p][ch] = np;
if(!p) { fa[np] = 1; return; }
int q = son[p][ch];
if(len[q] + 1 == len[p]) { fa[np] = q; return; }
int nq = ++cnt; len[nq] = len[p] + 1; mn[nq] = mn[q]; fa[nq] = fa[q];
memcpy(son[nq],son[q],sizeof(son[q])); fa[np] = fa[q] = np;
for(;p && son[p][ch] == q;p = fa[p]) son[p][ch] = nq;
}
il void get(int gl,int gr,int ch,int& x,int& p) {
while(1) {
if(son[p][ch] && segt.ask(gl + x,gr,1,segt.n,root[son[p][ch]])) {
++x; p = son[p][ch]; return;
}
if(!x) return; if(--x == len[fa[p]]) p = fa[p];
}
}
il ll calc(int* p) {
ll res = 0ll;
for(int i = 2;i <= cnt;i++) {
res += _max(0,len[i] - _max(len[fa[i]],p[mn[i]]));
}
return res;
}
};
char s1[maxn],s2[maxn << 1];
int p[maxn << 1],tg[maxn],rnk[maxn << 1];
Saffix_Automaton<1000001> S1;
Saffix_Automaton<2000001> S2;
int main() {
scanf("%s",s1 + 1); int sle = strlen(s1 + 1); segt.set_len(sle);
for(int i = 1;i <= sle;i++) S1.extend(s1[i] - 'a',i);
for(int i = 1;i <= S1.cnt;i++) tg[S1.len[i]]++;
for(int i = 1;i <= sle;i++) tg[i] += tg[i - 1];
for(int i = 1;i <= S1.cnt;i++) rnk[--tg[S1.len[i]]] = i;
for(int i = S1.cnt;i >= 1;i--) {
S1.root[S1.fa[rnk[i]]] = segt.merge(S1.root[S1.fa[rnk[i]]],S1.root[rnk[i]]);
}
int Task; read(Task);
for(int l,r;Task;Task--) {
S2.clear(); scanf("%s %d %d",s2 + 1,&l,&r);
int s2l = strlen(s2 + 1),t = 1;
for(int i = 1;i <= s2l;i++) {
p[i] = p[i - 1]; S1.get(l,r,s2[i] - 'a',t,p[i]);
S2.extend(s2[i] - 'a',0);
}
printf("%lld\n",1ll * S2.calc(p));
}
}
回复
共 11 条回复,欢迎继续交流。
正在加载回复...