zoukankan      html  css  js  c++  java
  • 【BZOJ 4598】【SDOI 2016 Round2 Day1 T3】模式字符串

    2016-05-21因为BZOJ上“ 数据文件太过巨大,仅提供前三组数据测试.”所以我考场上写的60分的点分治交上去也A了。

    我的这个点分治的时间复杂度是$O(Tnmlogn)$的,听题解时没听懂$O(Tnlogn)$的标算,还有听说标算要用到字符串哈希,然而我并不会,所以先留个坑,贴上自己的60分代码,满分做法等我学会哈希之后再做

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 1000003;
    void read(int &k) {
    	k = 0; int fh = 1; char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar())
    		if (c == '-') fh = -1;
    	for(; c >= '0' && c <= '9'; c = getchar())
    		k = (k << 1) + (k << 3) + c - '0';
    	k = k * fh;
    }
    
    struct node {int nxt, to;} E[N << 1];
    int n, m, cnt, point[N], root, qu[N], fa[N], t[N], sz[N];
    char c[N], mu[N];
    bool vis[N], bo[N];
    
    void ins(int x, int y) {E[++cnt].nxt = point[x]; E[cnt].to = y; point[x] = cnt;}
    void findrt(int x) {
    	int p = 0, u, q = 1; qu[1] = x; fa[x] = 0;
    	while (p != q) {
    		u = qu[++p]; bo[u] = 1; sz[u] = 1;
    		for(int tmp = point[u]; tmp; tmp = E[tmp].nxt)
    			if (!vis[E[tmp].to] && E[tmp].to != fa[u])
    				qu[++q] = E[tmp].to, fa[E[tmp].to] = u;
    	}
    	for(int i = q; i >= 1; --i) {
    		u = qu[i];
    		if (bo[u] && sz[u] * 2 > q) {root = u; return;}
    		sz[fa[u]] += sz[u];
    		if (sz[u] * 2 > q) bo[fa[u]] = 0;
    	}
    }
    int leftnow, rightnow, leftsum, rightsum, ret;
    void BFSleft(int x) {
    	int p = 0, u, q = 1, tt; qu[1] = x;
    	while (p != q) {
    		u = qu[++p];
    		for(int tmp = point[u]; tmp; tmp = E[tmp].nxt)
    			if (!vis[E[tmp].to] && E[tmp].to != fa[u] && c[E[tmp].to] == mu[tt = ((t[u] - 1 + m) % m)])
    				fa[E[tmp].to] = u, t[E[tmp].to] = tt, qu[++q] = E[tmp].to;
    	}
    	for(int i = 1; i <= q; ++i)
    		if (t[qu[i]] == 0) ++leftnow;
    }
    void BFSright(int x) {
    	int p = 0, u, q = 1, tt; qu[1] = x;
    	while (p != q) {
    		u = qu[++p];
    		for(int tmp = point[u]; tmp; tmp = E[tmp].nxt)
    			if (!vis[E[tmp].to] && E[tmp].to != fa[u] && c[E[tmp].to] == mu[tt = ((t[u] + 1) % m)])
    				fa[E[tmp].to] = u, t[E[tmp].to] = tt, qu[++q] = E[tmp].to;
    	}
    	for(int i = 1; i <= q; ++i)
    		if (t[qu[i]] == (m - 1)) ++rightnow;
    }
    void work(int x) {
    	vis[x] = 1;
    	int tt;
    	for(int to = 0; to < m; ++to)
    		if (c[x] == mu[to]) {
    			leftsum = 0; rightsum = 0; if (to == 0) leftsum = 1; if (to == m - 1) rightsum = 1;
    			for(int i = point[x]; i; i = E[i].nxt)
    				if (!vis[E[i].to]) {
    					leftnow = 0;
    					if (c[E[i].to] == mu[tt = (to - 1 + m) % m])
    						fa[E[i].to] = x, t[E[i].to] = tt, BFSleft(E[i].to);
    					rightnow = 0;
    					if (c[E[i].to] == mu[tt = (to + 1) % m])
    						fa[E[i].to] = x, t[E[i].to] = tt, BFSright(E[i].to);
    					ret += leftsum * rightnow;
    					ret += rightsum * leftnow;
    					leftsum += leftnow; rightsum += rightnow;
    					leftnow = 0; rightnow = 0;
    				}
    		}
    	for(int i = point[x]; i; i = E[i].nxt)
    		if (!vis[E[i].to]) {findrt(E[i].to); work(root);}
    }
    int main() {
    	freopen("pattern.in", "r", stdin);
    	freopen("pattern.out", "w", stdout);
    	int T, u, v;
    	read(T);
    	while (T--) {
    		read(n); read(m);
    		scanf("%s", c + 1);
    		cnt = 0; memset(point, 0, sizeof(point)); memset(vis, 0, sizeof(vis));
    		for(int i = 1; i < n; ++i) {read(u); read(v); ins(u, v); ins(v, u);}
    		scanf("%s", mu);
    		ret = 0;
    		findrt(1);
    		work(root);
    		printf("%d
    ", ret);
    	}
    	return 0;
    }
    
  • 相关阅读:
    js 中的基本包装类型
    js监听浏览器,关闭,刷新(兼容IE6+,Firefox,Chrome,Safari)
    js 中的 && 与 ||
    程序设计模式的工厂(Factory)模式
    关于MOSS首页不能打开提示“根级别上的数据无效
    获取汉字的拼音的首个字母方法
    XmlDocument扩展类
    初次体验Android,过程很艰辛!
    用Python写个翻译工具
    开发经验是修炼设计模式的基石
  • 原文地址:https://www.cnblogs.com/abclzr/p/5514157.html
Copyright © 2011-2022 走看看