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\n", ret);
}
return 0;
}

【BZOJ 4598】【SDOI 2016 Round2 Day1 T3】模式字符串的更多相关文章

  1. 【BZOJ 4515】【SDOI 2016 Round1 Day1 T3】游戏

    考场上写了lct,可惜当时对标记永久化的理解并不是十分深刻,导致调一个错误的程序调了4h+,最后这道题爆0了QwQ 现在写了树链剖分,用标记永久化的线段树维护轻重链,对于$s\rightarrow l ...

  2. 【BZOJ 4518】【SDOI 2016 Round1 Day2 T3】征途

    比较明显的斜率优化DP,省选时因为时间太紧张和斜率DP写得不熟等原因只写了60分的暴力DP,其实当时完全可以对拍来检验标算的正确,但是我当时too naive- 很快打完了,调了将近一晚上QAQ,因为 ...

  3. [BZOJ 4516] [SDOI 2016] 生成魔咒

    Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例 ...

  4. SDOI 2016 Round1 Day1

    储能表 /* 引自zyz大佬的数学思想 */ #include<cstdio> #include<iostream> using namespace std; typedef ...

  5. 【NOIP2016】Day1 T3 换教室(期望DP)

    题目背景 NOIP2016 提高组 Day1 T3 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n 节课程安排在 n 个时间段上. ...

  6. [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)

    [BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...

  7. JOISC 2017 Day1 T3 烟花棒

    JOISC 2017 Day1 T3 烟花棒 题意: ​ 数轴上有\(N\)人在放烟花,一开始只有第\(K\)个人的烟花是点燃的,烟花燃烧的时间为\(T\)秒,求让所有人的烟花都可以点燃的速度的最小值 ...

  8. [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分

    [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...

  9. NOIP2017 Day1 T3 逛公园

    NOIP2017 Day1 T3 更好的阅读体验 题目描述 策策同学特别喜欢逛公园.公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,\(N\)号点 ...

随机推荐

  1. NOIP2010普及组题解 -SilverN

    三国游戏 题目内容不放了 由于电脑总是会拆掉最大的组合,所以玩家最多只能得到数值第二大的组合 那么找出第二大的组合就行了 #include<iostream> #include<cs ...

  2. C#迭代重载等

    迭代器 迭代器是作为一个容器,将要遍历的数据放入,通过统一的接口返回相同类型的值 迭代器代码使用 yield return 语句依次返回每个元素.yield break 将终止迭代 类中实现多个迭代器 ...

  3. win10输入法切换快捷键怎么设置

    win10输入法切换快捷键怎么修改?以前都是习惯使用(Ctrl+Shift) 现在新版的Win10默认的是[Shift+Alt]那要怎么把它改回来呢? http://jingyan.baidu.com ...

  4. Python的高级特性6:使用__slots__真的能省很多内存

    在伯乐在线上看到了这篇文章,用Python的 __slots__ 节省9G内存,于是想测试下,对单个类,用__slots__节省内存效果会不会明显. 看完这个例子后,我们也会明白__slots__是用 ...

  5. ubuntu12.04禁止单用户本地无密码root登录

    1)grub-mkpasswd-pbkdf2 拿到类似grub.pbkdf2.sha512.10000.C093FE6825CDCC2F84934ABC406445E92EE098733C60E6D1 ...

  6. C# Tostring 格式化输出字符串全解

    C 货币 2.5.ToString("C") ¥2.50 D 十进制数 .ToString("D5") E 科学型 .ToString("E" ...

  7. (原创)解决远程桌面连接远程应用时,出现 '应用程序错误: '0x7c931780'指令引用的 '0x89abcdef' 内存。该内存不能为 'read'"

    公司的部分应用为cs结构,没有web版的,这些应用的外部访问基本都是通过使用windows server 2008 r2的远程桌面服务来实现的. 个人感觉微软远程桌面服务问题很多,今天有同事使用Rem ...

  8. NOI2018准备 Day8

    清北学堂入学测试,6道题凑了363分,平均466才能达到省选班的程度,差距不小. 今天突然感觉最大的BOSS是搜索,虽然每次都写崩...... 3个小时写了一道DP没写出来 但我不会忘记,我的首个目标 ...

  9. 浅谈设计模式--组合模式(Composite Pattern)

    组合模式(Composite Pattern) 组合模式,有时候又叫部分-整体结构(part-whole hierarchy),使得用户对单个对象和对一组对象的使用具有一致性.简单来说,就是可以像使用 ...

  10. Android -- View移动的六种方法

    layout() 如果你将滑动后的目标位置的坐标传递给layout(),这样子就会把view的位置给重新布置了一下,在视觉上就是view的一个滑动的效果. public class DragView ...