热身赛:

某题读假题+写假代码,搞了最难题1h未果之后跑路了

rk200+,感觉状态血差,正赛要寄(反向flag++

 

正赛:

刚把基本的板子打完发现edgnb已经被过穿了(edgnb!

签到后yfz说能写M,于是写写写,写完过不了样例,似乎做法假了

换我写签到题B,很快啊就WA了,又改一个很明显的错误之后收获-2,半小时了还是1题,感觉要完

然后就是两个队友分别写F、J两道签到题,我在旁边看我的代码怎么看怎么对

此时已经发现了数组开小,但一直很疑惑为什么不给返回RE

直到zzx已经开始不那么签到的I题+自己又看了20min无果,决定改一下MAXN重交一次,一下就过了

被自己气晕.jpg

 

在旁边发现了看上去和假期多校一道点双贪心很像的边双贪心H,讨论了一下感觉十分正确

正好zzx不负众望的过了I(除了中途因为复数除法写错一起看了至少20min

我直接进行一个H的写,写完进行了一些加强样例的测,交上去1a了(get第二个正赛1a 好耶

看了眼排名rk22,L也会写了,感觉前途一片光明(flag++

zzx写完了一部分后让我写另一部分树dp,我说可以,写完发现和样例好像差的有点远

重新理了一遍思路之后发现不但一个很基本的式子推错了,而且开始的容斥还假了

最后改完发现只有容斥+树dp+简单式子了,测了测之后收获一个WA

yfz再次用sa做M,旁边发现我的树dp写麻烦了,不是很确定这个dp的正确性

纠结的时候突然发现树的大小是$2n$,所以数组又双叒叕开小了,改了一下之后又过了

人麻了.jpg

 

想看榜的时候失败的时候才意识到已经封榜了,从来没感觉过时间过的这么快(?

最后半小时经历了sa板子出错,改板子+各种修改未果,最后还是没能通过M

 

赛后:

刚结束就被告知卡线金了,感觉十分魔幻

亲眼看了一下榜发现2min险胜银首,属于是幸运拉满了

同时发现M和桂林的J好像几乎完全一致,但桂林的J我们vp时我用了后缀树(队友不会后缀树,我不会sa,完美错过.jpg

没能8题还是挺可惜的,感觉这8题都不是那么难

不过还是Au了 好!

 

补题:

$M$

首先有结论每次查询串的右端点一定是当前的点

对反串建后缀树,按经典方法对儿子字典序排序

倒着扫反串,容易知道每个点有可能成为最大值仅当该点$x$的$pos_x-mxlen_{fa[x]}$在范围内

对$pos$取一个$max$即可

 1 #include<bits/stdc++.h>
 2 #define inf 2139062143
 3 #define ll long long
 4 #define db double
 5 #define ld long double
 6 #define ull unsigned long long
 7 #define MAXN 2001001
 8 #define MOD 998244353
 9 #define Fill(a,x) memset(a,x,sizeof(a))
10 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
11 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
12 #define ren for(int i=fst[x];i;i=nxt[i])
13 #define pii pair<int,int>
14 #define fi first
15 #define se second
16 #define pb push_back
17 using namespace std;
18 inline ll read()
19 {
20     ll x=0,f=1;char ch=getchar();
21     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
22     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
23     return x*f;
24 }
25 namespace CALC
26 {
27     inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
28     inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
29     inline int mul(int a,int b){return (1LL*a*b)%MOD;}
30     inline void inc(int &a,int b){a=pls(a,b);}
31     inline void dec(int &a,int b){a=mns(a,b);}
32     inline void tms(int &a,int b){a=mul(a,b);}
33     inline int qp(int x,int t,int res=1)
34         {for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
35     inline int Inv(int x){return qp(x,MOD-2);}
36 }
37 using namespace CALC;
38 char s[MAXN];
39 vector<pii> G[MAXN];
40 int m,n,sum[MAXN<<2],ans[MAXN],len[MAXN],stp,dfn[MAXN];
41 int rt,las,tot,mxl[MAXN],fa[MAXN],pos[MAXN],g[MAXN];
42 int tr[MAXN][26];
43 ll c[MAXN],num[MAXN];
44 void extend(int c,int id)
45 {
46     int p=las,np=las=++tot;mxl[np]=mxl[p]+1;pos[np]=id;
47     for(;p&&!tr[p][c];p=fa[p]) tr[p][c]=np;
48     if(!p) {fa[np]=rt;return ;}int q=tr[p][c];
49     if(mxl[q]==mxl[p]+1) {fa[np]=q;return ;}
50     int nq=++tot;mxl[nq]=mxl[p]+1;pos[nq]=pos[q];
51     memcpy(tr[nq],tr[q],sizeof(tr[nq]));
52     fa[nq]=fa[q],fa[np]=fa[q]=nq;
53     for(;p&&tr[p][c]==q;p=fa[p]) tr[p][c]=nq;
54 }
55 void dfs(int x)
56 {
57     dfn[x]=++stp;sort(G[x].begin(),G[x].end());
58     for(auto e:G[x]) dfs(e.se),pos[x]=max(pos[x],pos[e.se]);
59 }
60 inline int getw(int x){return pos[x]-mxl[fa[x]];}
61 bool cmp(int x,int y){return getw(x)<getw(y);}
62 int main()
63 {
64     rt=las=tot=1;scanf("%s",s+1);n=strlen(s+1);
65     reverse(s+1,s+n+1);
66     rep(i,1,n) extend(s[i]-'a',i);int mx=0,res=0,j=tot;
67     rep(i,2,tot) G[fa[i]].pb({s[pos[i]-mxl[fa[i]]]-'a',i});
68     dfs(1);rep(i,1,tot) g[i]=i;sort(g+1,g+tot+1,cmp);
69     dwn(i,n,1)
70     {
71         for(;getw(g[j])>=i&&j;j--)
72             if(dfn[g[j]]>mx) res=g[j],mx=dfn[g[j]];
73         printf("%d %d\n",!res?1:n-pos[res]+1,n-i+1);
74     }
75 }
View Code

相关文章: