HDOJ多校联合第六场
先一道一道题慢慢补上,
1009.题意,一棵N(N<=50000)个节点的树,每个节点上有一个字母值,给定一个串S0(|S0| <=30),q个询问,(q<=50000),每次询问经过两个点u,v之间的路径上的字母构成字符串S,问S0在S中作为序列出现了多少次。
分析:对于每次询问需要知道其LCA,设w = LCA(u, v),可以用tarjan处理出来,或者倍增法也行。然后w会将S0分成两部分,记做S1,S2,然后分别考虑S1在u->w的路径出现次数,以及S2在v->w出现的次数。
S1(x) = S0[1....x],1<=x<=|S0|.
以S1为例,需要预处理出来u到根节点的路径上对应S0[i,j]序列出现的次数,设为dp1[u][i][j],然后S1(x)在u->w出现的次数记为t1[x],那么
t1[x] = dp1[u][1][x] - sum{t1[a-1]*dp1[fa[w]][a][x]} (1<=a<=x)
而dp1[u][1][x] 可以在tarjan求LCA时候预处理出来,转移dp1[u][i][j] = dp1[fa[u]][i][j] + (nd[u] == S0[i])*dp1[fa[u]][i+1][j];
对于S2也是可以同样考虑的。
注意:占用内存很大,需要用16位节省内存,dfs的话还需要扩栈,实现时发现不能随便用unsigned short,因为变成负数的话会相当于mod 2^16这个是会导致WA的。
代码:
- #pragma comment(linker, "/STACK:16777216")
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #include <string>
- #include <cstdlib>
- #include <algorithm>
- #include <vector>
- #include <queue>
- #include <map>
- #include <set>
- #define in freopen("solve_in.txt", "r", stdin);
- #define Rep(i, base, n) for(int i = (base); i < n; i++)
- #define REP(i, n) for(int i = 0; i < (n); i++)
- #define VREP(i, n, base) for(int i = (n); i >= (base); i--)
- #define SET(a, n) memset(a, (n), sizeof(a));
- #define pb push_back
- #define mp make_pair
- using namespace std;
- typedef vector<unsigned short> VI;
- typedef pair<unsigned short, unsigned short> PII;
- typedef vector<PII> VII;
- typedef long long LL;
- const int maxn = + ;
- const int maxm = ;
- const int M = ;
- short dp1[maxn][maxm][maxm], dp2[maxn][maxm][maxm];
- bool vis[maxn];
- int len;
- char s[maxm], nd[maxn];
- unsigned short pa[maxn];
- VI g[maxn];
- unsigned short lca[maxn];
- VII que[maxn];
- VII qq;
- unsigned short findset(unsigned short x) {
- return x == pa[x] ? x : pa[x] = findset(pa[x]);
- }
- void init(int n) {
- qq.clear();
- REP(i, n+) {
- que[i].clear();
- g[i].clear();
- vis[i] = false;
- REP(j, maxm) REP(k, maxm) {
- dp1[i][j][k] = , dp2[i][j][k] = ;
- if(j > k)
- dp1[i][j][k] = ;
- if(j < k)
- dp2[i][j][k] = ;
- }
- }
- }
- int n, m;
- short t1[maxm], t2[maxm];
- void tarjan(int u, int fa) {
- pa[u] = u;
- if(!fa) {
- Rep(i, , len+)
- if(s[i] == nd[u]) {
- dp1[u][i][i] = dp2[u][i][i] = ;
- }
- } else {
- int v = u;
- u = fa;
- Rep(i, , len+) Rep(j, , len+) {
- if(i >= j) {
- dp2[v][i][j] = (dp2[v][i][j] + dp2[u][i][j] + (nd[v] == s[i])*(dp2[u][i-][j]))%M;
- }
- if(dp2[v][i][j] < )
- dp2[v][i][j] += M;
- if(i <= j) {
- dp1[v][i][j] = (dp1[v][i][j] + dp1[u][i][j] + (nd[v] == s[i])*(dp1[u][i+][j]))%M;
- }
- if(dp1[v][i][j] < )
- dp1[v][i][j] += M;
- }
- u =v;
- }
- vis[u] = true;
- REP(i, g[u].size()) {
- int v = g[u][i];
- if(v == fa)
- continue;
- tarjan(v, u);
- pa[v] = u;
- }
- REP(i, que[u].size()) {
- int v = que[u][i].first;
- int id = que[u][i].second;
- if(!vis[v])
- continue;
- lca[id] = findset(v);
- }
- }
- void solve() {
- REP(ii, m) {
- int w = lca[ii];
- int u = qq[ii].first;
- int v = qq[ii].second;
- if(u == v) {
- printf("%d\n", len == && s[] == nd[u]);
- continue;
- }
- SET(t1, );
- SET(t2, );
- t1[] = t2[len+] = ;
- if(w != u) {
- Rep(i, , len+) {
- int tmp = ;
- Rep(x, , i+) {
- tmp = (tmp + ((LL)t1[x-]*dp1[w][x][i])%M)%M;
- }
- t1[i] = (dp1[u][][i]-tmp)%M;
- if(t1[i] < )
- t1[i] += M;
- }
- }
- if(w != v) {
- VREP(i, len, ) {
- int tmp = ;
- VREP(x, len, i) {
- tmp = (tmp + ((LL)t2[x+]*dp2[w][x][i])%M)%M;
- }
- t2[i] = (dp2[v][len][i] - tmp)%M;
- if(t2[i] < )
- t2[i] += M;
- }
- }
- int ans = ;
- REP(i, len+) {
- if(s[i] == nd[w])
- ans = (ans + ((LL)t1[i-]*t2[i+])%M)%M;
- ans = (ans + ((LL)t1[i]*t2[i+])%M)%M;
- if(ans < )
- ans += M;
- }
- if(ans < )
- ans += M;
- printf("%d\n", ans);
- }
- }
- int main() {
- int T;
- for(int t = scanf("%d", &T); t <= T; t++) {
- scanf("%d%d", &n, &m);
- init(n);
- REP(i, n-) {
- int u, v;
- scanf("%d%d", &u, &v);
- g[u].pb(v);
- g[v].pb(u);
- }
- s[] = '\0';
- scanf("%s%s", nd+, s+);
- len = strlen(s+);
- REP(i, m) {
- int u, v;
- scanf("%d%d", &u, &v);
- qq.pb(mp(u, v));
- que[u].pb(mp(v, i));
- que[v].pb(mp(u, i));
- }
- tarjan(, );
- solve();
- }
- return ;
- }
HDOJ多校联合第六场的更多相关文章
- HDU 5793 A Boring Question (逆元+快速幂+费马小定理) ---2016杭电多校联合第六场
A Boring Question Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- HDU 5795 A Simple Nim (博弈) ---2016杭电多校联合第六场
A Simple Nim Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- HDOJ多校联合第五场
1001 Inversion 题意:求逆序对,然后交换k次相邻的两个数,使得剩下的逆序对最少. 分析:题目用到的结论是:数组中存在一对逆序对,那么可以通过交换相邻两个数使得逆序对减少1,交换k次,可以 ...
- HDOJ多校联合第四场
B题: C题:仅由'A','G','C','T',4个字母组成,给定一个字符串S,|S|<=15,给定一个整数m,以m为长度且仅含4种字母的字符串T,求LCS(S,T)为0,1,2,3....| ...
- hdu5379||2015多校联合第7场1011 树形统计
pid=5379">http://acm.hdu.edu.cn/showproblem.php? pid=5379 Problem Description Little sun is ...
- HDU 5831 Rikka with Parenthesis II (贪心) -2016杭电多校联合第8场
题目:传送门. 题意:T组数据,每组给定一个长度n,随后给定一个长度为n的字符串,字符串只包含'('或')',随后交换其中两个位置,必须交换一次也只能交换一次,问能否构成一个合法的括号匹配,就是()( ...
- HDU 5821 Ball (贪心排序) -2016杭电多校联合第8场
题目:传送门. 题意:T组数据,每组给定一个n一个m,在给定两个长度为n的数组a和b,再给定m次操作,每次给定l和r,每次可以把[l,r]的数进行任意调换位置,问能否在转换后使得a数组变成b数组. 题 ...
- HDU 5762 Teacher Bo (鸽笼原理) 2016杭电多校联合第三场
题目:传送门. 题意:平面上有n个点,问是否存在四个点 (A,B,C,D)(A<B,C<D,A≠CorB≠D)使得AB的横纵坐标差的绝对值的和等于CD的横纵坐标差的绝对值的和,n<1 ...
- HDU 5752 Sqrt Bo (思维题) 2016杭电多校联合第三场
题目:传送门. 题意:一个很大的数n,最多开5次根号,问开几次根号可以得到1,如果5次还不能得到1就输出TAT. 题解:打表题,x1=1,x2=(x1+1)*(x1+1)-1,以此类推.x5是不超过l ...
随机推荐
- linux文件系统评估之inode
存储系统上线前要做资源评估,通常需要在性能(即iops.带宽等)和容量维度进行业务评估:而具体到本地文件系统存储的容量时,需要根据具体业务对文件系统的可用数据空间和可用inode数进行评估,作者通过工 ...
- Oracle连接配置以及实例的备份和恢复
背景:一个团队项目开发,不可能每个人都架设自己本地的数据库,大多数情况下是统一用服务器上的数据库,这时候就需要进行远程数据库的连接.而且有时候还需要进行数据库搬迁 ,这时候就需要进行数据库的备份和恢复 ...
- jQuery 源码分析 7: sizzle
jQuery使用的是sizzle这个选择器引擎,这个引擎以其高速著称,其实现十分精妙但是也足够复杂,下面现简单分析一下相关的代码. 在jQuery的部分API接口是直接引用了Sizzle的方法,这些接 ...
- 16_会话技术_Session案例
[购物车中的信息保存] [Book.java] package com.Higgin.shopping; public class Book { private String id; private ...
- (CodeForces 510C) Fox And Names 拓扑排序
题目链接:http://codeforces.com/problemset/problem/510/C Fox Ciel is going to publish a paper on FOCS (Fo ...
- java.util.AbstractStringBuilder源码分析
AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大 ...
- mysql与Navicat for MySQL的衔接配置问题【原创】
首先改一下php的配置文件: 这里主要该两个地方:Cirl + F 查找到mysql.dll 然后去掉前面的";" 然后是修改路径:Cirl + F 查找到extension_di ...
- 简单改造 starling 中的 AssetManager 让其更适合 批次加载纹理
API文档参考:http://doc.starling-framework.org/core/starling/utils/AssetManager.html 项目想以不改动starling的情况下对 ...
- DataNavigator之分页
前言 做客户端也有两个月了,先前做列表都没有分页,可能考虑数据也不是很多,昨天做了一个页面,考虑到了数据的问题,所以改为分页查询.因为也是第一次用dev,用哪个控件分页呢,还是要去搜一下,得出的事Da ...
- 重新开始学习c#啦,希望能坚持下去!
过了这么多年,还是感觉自己喜欢C#,喜欢编程,虽然自己什么技术也没有:做的项目也不算是项目: