社区讨论

萌新初学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 条回复,欢迎继续交流。

正在加载回复...