社区讨论

求问第4片题解的复杂度如何计算

P4770[NOI2018] 你的名字参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo9mwybz
此快照首次捕获于
2023/10/28 14:01
2 年前
此快照最后确认于
2023/10/28 14:01
2 年前
查看原帖
这里的向上跳fail的复杂度如何计算?为啥是线性复杂度qwq
C
In ll calc(char* s)
  {
    ll ret = 0;
    int m = strlen(s);
    for(int i = 0, l = 0, p = 0, pos = 0; i < m; ++i)
      {
		int c = s[i] - 'a';
		while(~p && (!tra[p][c] || (pos = query(root[tra[p][c]], 0, n - 1, L, R)) == -1))
		  p = link[p], l = len[p];	//没有转移边或者[L, R]内没有endpos,就一直失配 
		if(p == -1) p = l = 0;
		else
		  {
		    ++l, p = tra[p][c];
		    int tp = min(l, pos - L + 1);
		    if(tp > ha[i]) ret += tp - ha[i];
		    if(l > pos - L + 1)	//匹配长度仍受L的限制 
		      {
				int tp3 = max(tp, ha[i]), q = link[p], l2 = len[q];
				while(~q)
				  {
				    int pos2 = query(root[q], 0, n - 1, L, R), tp2 = min(l2, pos2 - L + 1);
				    if(tp2 > tp3) ret += tp2 - tp3;
				    else if(l2 <= pos2 - L + 1) break;	//匹配长度不受L的限制了,退出 
				    q = link[q], l2 = len[q], tp3 = max(tp2, ha[i]);
				  }
		      }
		  }
      }
    return ret;
  }

回复

1 条回复,欢迎继续交流。

正在加载回复...