热身赛:
某题读假题+写假代码,搞了最难题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 }