zoukankan      html  css  js  c++  java
  • [NOI2014][洛谷P2375]动物园(KMP)

    题面

    https://www.luogu.com.cn/problem/P2375

    题解

    可以构建该字符串的一棵next树,即每个点向自己的next连一条边。
    如果没有“不重叠”的限制条件,所求num[i]即为next树上点i的深度。
    有该条件后,只需要维护位置mid,设当前dfs到点i,则mid为i到根路径上,<=i/2的最大者
    所求num[i]即为dfs到i时对应mid的深度
    mid全程移动的路程小于i全程移动的路程O(n)

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 1000000
    #define ll long long
    #define mod 1000000007 
    #define rg register
    
    inline int read(){
    	int s = 0,ww = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-')ww = -1;ch = getchar();}
    	while('0' <= ch && ch <= '9'){s = 10 * s + ch - '0';ch = getchar();}
    	return s * ww;
    }
    
    int n,cnt;
    char s[N+5];
    int head[N+5],nx[N+5];
    
    struct node{
    	int next,des;
    }e[N+5];
    
    inline void addedge(int a,int b){
    	cnt++;
    	e[cnt].des = b;
    	e[cnt].next = head[a];
    	head[a] = cnt;
    }
    
    inline void prepro(){
    	nx[1] = 0;
    	int p = 0;
    	for(rg int i = 2;i <= n;i++){
    		while(p && s[p+1] != s[i])p = nx[p];
    		if(s[p+1] == s[i])p++;
    		nx[i] = p;
    	}
    }
    
    int S[N+5],dep[N+5],num[N+5];
    int top,mid;
    
    inline void dfs(int u){
    	S[++top] = u;
    	if(u)while((S[mid+1]<<1) <= u)mid++;
    	num[u] = dep[S[mid]];
    	for(rg int i = head[u];i;i = e[i].next){
    		int v = e[i].des;
    		dep[v] = dep[u] + 1;
    		int temp = mid;
    		dfs(v);
    		mid = temp;
    	}
    	top--;
    }
    
    int main(){
    	int T = read();
    	while(T--){
    		memset(head,0,sizeof(head));
    		cnt = 0;
    		scanf("%s",s + 1);
    		n = strlen(s + 1);
    		prepro();
    		for(rg int i = 1;i <= n;i++)addedge(nx[i],i);
    		top = mid = 0;
    		dfs(0);
    		ll ans = 1;
    		for(rg int i = 1;i <= n;i++)ans = ans * (ll)(num[i] + 1) % mod;
    		cout << ans << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    [LeetCode] 85. 最大矩形
    [LeetCode] 84. 柱状图中最大的矩形
    [LeetCode] 83. 删除排序链表中的重复元素
    [LeetCode] 81. 搜索旋转排序数组 II
    [LeetCode] 82. 删除排序链表中的重复元素 II
    [LeetCode] 80. 删除排序数组中的重复项 II
    [LeetCode] 79. 单词搜索
    [LeetCode] 77. 组合
    转:快乐Node码农的十个习惯
    转:zookeeper3.4.5安装笔记
  • 原文地址:https://www.cnblogs.com/xh092113/p/12239694.html
Copyright © 2011-2022 走看看