QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#720294#9406. TriangleDaiRuiChen007ML 7ms36508kbC++173.3kb2024-11-07 11:41:362024-11-07 11:41:36

Judging History

你现在查看的是最新测评结果

  • [2024-11-07 11:41:36]
  • 评测
  • 测评结果:ML
  • 用时:7ms
  • 内存:36508kb
  • [2024-11-07 11:41:36]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=3e5+5;
struct SA {
	int n,str[MAXN],sa[MAXN],rk[MAXN],wt[MAXN],len[MAXN],f[MAXN][20];
	int bit(int x) { return 1<<x; }
	void add(int c) { str[++n]=c; }
	void build() {
		iota(sa+1,sa+n+1,1);
		sort(sa+1,sa+n+1,[&](int x,int y){ return str[x]<str[y]; });
		for(int i=1,j;i<=n;) {
			for(j=i;j<n&&str[sa[j+1]]==str[sa[i]];++j);
			len[i]=j-i+1;
			while(i<=j) rk[sa[i++]]=j;
		}
		for(int k=1;k<=n;k<<=1) {
			for(int l=1,r;l<=n;++l) if(len[l]>1) {
				r=l+len[l]-1;
				for(int i=l;i<=r;++i) wt[sa[i]]=(sa[i]+k>n?0:rk[sa[i]+k]);
				sort(sa+l,sa+r+1,[&](int x,int y){ return wt[x]<wt[y]; });
				for(int i=l,j;i<=r;) {
					for(j=i;j<r&&wt[sa[j+1]]==wt[sa[i]];++j);
					len[i]=j-i+1;
					while(i<=j) rk[sa[i++]]=j;
				}
				l=r;
			}
		}
		for(int i=1,k=0;i<=n;++i) {
			k=max(0,k-1);
			while(str[i+k]==str[sa[rk[i]-1]+k]) ++k;
			f[rk[i]][0]=k;
		}
		for(int k=1;k<20;++k) for(int i=1;i+bit(k)-1<=n;++i) {
			f[i][k]=min(f[i][k-1],f[i+bit(k-1)][k-1]);
		}
	}
	int lcp(int x,int y) {
		int l=min(rk[x],rk[y])+1,r=max(rk[x],rk[y]),k=__lg(r-l+1);
		return min(f[l][k],f[r-bit(k)+1][k]);
	}
}	sa;
struct FenwickTree {
	int tr[MAXN],s,n;
	void init(int N) { n=N,fill(tr,tr+n+1,0); }
	void add(int x,int v) { for(;x<=n;x+=x&-x) tr[x]+=v; }
	int qry(int x) { for(s=0;x;x&=x-1) s+=tr[x]; return s; }
}	fw;
string s[MAXN];
int n,N,cnt[MAXN],st[MAXN],ord[MAXN],rk[MAXN];
struct Trie {
	int tot,tr[MAXN][26],id[MAXN];
	void init() {
		for(int i=0;i<=tot;++i) memset(tr[i],0,sizeof(tr[i])),id[i]=0;
		tot=0;
	}
	int ins(const string &str) {
		int p=0;
		for(auto c:str) {
			if(!tr[p][c-'a']) tr[p][c-'a']=++tot;
			p=tr[p][c-'a'];
		}
		if(!id[p]) id[p]=n+1;
		return id[p];
	}
}	tr;
bool cmp(int x,int y) {
	if(s[x].size()>s[y].size()) return !cmp(x,y);
	int k=sa.lcp(st[x],st[y]);
	if(k<(int)s[x].size()) return s[x][k]<s[y][k];
	int q=sa.lcp(st[y],st[y]+k);
	if(k+q>=(int)s[y].size()) return false;
	return s[y][q]<s[y][k+q];
}
struct opr { int l,r; ll c; };
vector <opr> Q[MAXN];
void solve() {
	cin>>N,n=sa.n=0,tr.init();
	for(int i=1;i<=N;++i) {
		string str;
		cin>>str;
		int x=tr.ins(str);
		if(x>n) {
			n=x,s[x]=str,cnt[x]=1,st[x]=sa.n+1;
			for(auto c:str) sa.add(c);
			sa.add(-n);
		} else ++cnt[x];
	}
	sa.build();
	iota(ord+1,ord+n+1,1);
	sort(ord+1,ord+n+1,cmp);
	for(int i=1;i<=n;++i) rk[ord[i]]=i,Q[i].clear();
	ll ans=0;
	for(int x=1;x<=n;++x) {
		int p=0;
		for(int i=0;i<(int)s[x].size();++i) {
			p=tr.tr[p][s[x][i]-'a'];
			if(!tr.id[p]) continue;
			int y=tr.id[p],o=rk[y],l=sa.rk[st[x]+i+1],r=sa.rk[st[x]];
			if(l>=r) continue;
			if(x!=y) {
				if(r-l>1) Q[o].push_back({l+1,r-1,1ll*cnt[x]*cnt[y]});
				if(l<sa.rk[st[y]]&&sa.rk[st[y]]<r) ans+=1ll*cnt[y]*(cnt[y]-1)/2*cnt[x];
				if(rk[x]<o&&l<r) ans+=1ll*cnt[x]*(cnt[x]-1)/2*cnt[y];
			} else {
				if(r-l>1) Q[o].push_back({l+1,r-1,1ll*cnt[x]*(cnt[x]-1)/2});
				ans+=1ll*cnt[x]*(cnt[x]-1)*(cnt[x]-2)/6;
			}
		}
	}
	fw.init(sa.n);
	for(int i=1;i<=n;++i) {
		for(auto q:Q[i]) ans+=q.c*(fw.qry(q.r)-fw.qry(q.l-1));
		fw.add(sa.rk[st[ord[i]]],cnt[ord[i]]);
	}
	cout<<ans<<"\n";
}
signed main() {
	ios::sync_with_stdio(false);
	int T; cin>>T;
	while(T--) solve();
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 7ms
memory: 36508kb

input:

3
6
cbaa
cb
cb
cbaa
ba
ba
3
sdcpc
sd
cpc
1
ccpc

output:

16
0
0

result:

ok 3 lines

Test #2:

score: -100
Memory Limit Exceeded

input:

14
1
lfpbavjsm
2
pdtlkfwn
mbd
3
dvqksg
dvqksg
uhbhpyhj
4
ombwb
ombwb
ombwb
ombwb
5
oztclz
oztclz
oztclz
oztclz
kul
6
vco
vco
vco
dtktsqtinm
vco
vco
7
tb
tb
kowbsu
ygkfphcij
tb
uvei
tb
8
vxxtxssht
abnsxbf
bydaae
bydaae
udalyvmcef
bydaae
bydaae
bydaae
9
aaze
zvyonw
qjfv
mmhkef
qjfv
qjfv
qjfv
mmhkef
qj...

output:

0
0

result: