【HDOJ】4601 Letter Tree
挺有意思的一道题,思路肯定是将图转化为Trie树,这样可以求得字典序。
然后,按照trie的层次求解。一直wa的原因在于将树转化为线性数据结构时要从原树遍历,从trie遍历就会wa。不同结点可能映射为trie上的同一结点,如
1->2 (a) 1->3(a) 2->4(b), 这是trie的结构是RT->a->b。然而,从结点3不能找到权重为b的路径。
用RMQ求满足边界的rank最大值,通过sa找到该最大值对应的trie上的根。从而求解。
/* 4601 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
// #define DEBUG typedef struct {
int u, v, w;
int nxt;
} edge_t; typedef struct ques_t {
int u, m, id; ques_t() {}
friend bool operator< (const ques_t& a, const ques_t& b) {
if (a.m == b.m)
return a.id < b.id;
return a.m < b.m;
} } ques_t; const int mod = 1e9+;
const int maxn = 1e5+;
const int maxv = maxn;
const int maxe = maxv * ;
int head[maxv], m;
edge_t E[maxe];
int nxt[maxn][], l;
int Pos[maxv], Rank[maxv], sa[maxv];
__int64 Base[maxn];
__int64 Val[maxn];
int deep[maxv];
int fr[maxv], to[maxv];
int dfs_clock;
vi layer[maxn];
int maxd;
int n, qn, q;
ques_t Qu[maxn];
int ans[maxn];
int dp[][maxn];
int D[maxn]; void Init() {
Base[] = ;
rep(i, , maxn)
Base[i] = Base[i-] * % mod;
} void init() {
memset(head, -, sizeof(head));
m = ;
memset(nxt[], , sizeof(nxt[]));
l = ;
dfs_clock = ;
maxd = ;
rep(i, , n+)
layer[i].clr();
} int newNode() {
++l;
memset(nxt[l], , sizeof(nxt[l]));
Val[l] = ;
return l;
} void addEdge(int u, int v, int w) {
E[m].v = v;
E[m].w = w;
E[m].nxt = head[u];
head[u] = m++; E[m].v = u;
E[m].w = w;
E[m].nxt = head[v];
head[v] = m++;
} void Build_Trie(int u, int fa, int rt) {
int v, k, p; Pos[u] = rt;
for (k=head[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (v == fa)
continue; int id = E[k].w;
p = nxt[rt][id];
if (!p)
p = nxt[rt][id] = newNode();
Build_Trie(v, u, p);
}
} void Mark_Rank(int rt, int d) {
int p; Rank[rt] = ++dfs_clock;
sa[dfs_clock] = rt;
rep(i, , ) {
p = nxt[rt][i];
if (p) {
Val[p] = (Val[rt]* + i) % mod;
Mark_Rank(p, d+);
}
}
} void calDepth(int u, int fa, int rt) {
int v, k, p; D[++dfs_clock] = Rank[rt];
fr[u] = dfs_clock + ;
maxd = max(deep[u], maxd);
layer[deep[u]].pb(dfs_clock);
for (k=head[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (v == fa)
continue;
deep[v] = deep[u] + ;
p = nxt[rt][E[k].w];
calDepth(v, u, p);
}
to[u] = dfs_clock;
} void init_RMQ(int d, int n) {
int i, j; for (i=; i<n; ++i)
dp[][i] = D[layer[d][i]];
for (j=; (<<j)<=n; ++j)
for (i=; i+(<<j)-<n; ++i)
dp[j][i] = max(dp[j-][i], dp[j-][i+(<<(j-))]);
} int RMQ(int l, int r) {
if (l > r)
swap(l, r); int k = ; while ((<<(k+)) <= r-l+)
++k; return max(dp[k][l], dp[k][r-(<<k)+]);
} int calc(int qid, int d) {
int u = Qu[qid].u;
int rt = Pos[u];
int b = fr[u];
int e = to[u];
int l = lower_bound(all(layer[d]), b) - layer[d].begin();
int r = upper_bound(all(layer[d]), e) - layer[d].begin();
--r; if (l > r)
return -; int mxrank = RMQ(l, r);
int mxrt = sa[mxrank];
int delta = d - deep[u];
int ret = (Val[mxrt] - Val[rt] * Base[delta] % mod + mod) % mod; return ret;
} void solve() {
Build_Trie(, , );
Mark_Rank(, );
dfs_clock = ;
deep[] = ;
calDepth(, , ); scanf("%d", &q);
qn = ;
rep(i, , q) {
scanf("%d %d", &Qu[qn].u, &Qu[qn].m);
int deepu = deep[Qu[qn].u];
if (Qu[qn].m == ) {
ans[i] = ;
} else if (deepu+Qu[qn].m > maxd) {
ans[i] = -;
} else {
Qu[qn].m += deepu;
Qu[qn].id = i;
++qn;
}
} if (qn) {
sort(Qu, Qu+qn);
int j = ;
rep(i, , maxd+) {
if (i < Qu[j].m)
continue;
int sz = SZ(layer[i]);
init_RMQ(i, sz);
while (j<=qn && Qu[j].m==i) {
int id = Qu[j].id;
ans[id] = calc(j, i);
++j;
}
if (j == qn)
break;
}
} rep(i, , q) {
if (ans[i] == -)
puts("IMPOSSIBLE");
else
printf("%d\n", ans[i]);
}
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t;
int u, v;
char ws[]; Init();
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
init();
rep(i, , n) {
scanf("%d %d %s", &u, &v, ws);
addEdge(u, v, ws[]-'a');
}
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}
数据发生器。
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 10
bound = 10**3
lc = list(string.lowercase)
fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(300, 500)
fout.write("%d\n" % (n))
ust = [1]
vst = range(2, n+1)
for i in xrange(1, n):
uid = randint(0, len(ust)-1)
vid = randint(0, len(vst)-1)
u = ust[uid]
v = vst[vid]
ust.append(v)
vst.remove(v)
idx = randint(0, 25)
c = lc[idx]
fout.write("%d %d %s\n" % (u, v, c))
q = randint(400, 600)
fout.write("%d\n" % (q))
for i in xrange(q):
u = randint(1, n+1)
m = randint(0, 10)
fout.write("%d %d\n" % (u, m)) def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()
【HDOJ】4601 Letter Tree的更多相关文章
- 【HDOJ】1504 Disk Tree
文件可以重名.先按字典序将路径排序,再过滤掉公共前缀.其中的问题是'\'的ASCII比[A-Z0-9]大,将它替换为空格.否则字典序有问题. /* 1504 */ #include <iostr ...
- 【数据结构】B-Tree, B+Tree, B*树介绍 转
[数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LG3690 【模板】Link Cut Tree (动态树)
题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测
UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...
- (RE) luogu P3690 【模板】Link Cut Tree
二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
- 【LeetCode】199. Binary Tree Right Side View 解题报告(Python)
[LeetCode]199. Binary Tree Right Side View 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/probl ...
随机推荐
- 用Unitils测试BaseDao遇到的问题总结
<Spring 3.0就这么简单>.(陈雄华,林开雄)第8章,对如何用Unitils进行测试简单介绍,下面是我用Unitils进行单元测试过程中遇到的问题的总结. 1.设置好pom.xml ...
- preventDefault()、stopPropagation()、return false 之间的区别
“return false”之所以被误用的如此厉害,是因为它看起来像是完成了我们交给它的工作,浏览器不会再将我们重定向到href中的链接,表单也不会被继续提交,但这么做到底有什么不对呢? 可能在你刚开 ...
- centos 7 lNMP 安装之php 篇
1.准备工作 安装依赖包 yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype ...
- aliexpress 上传图
首先,图片转化为字节流 public byte[] ImagefileToByte(string srcImagePath) { System.IO.MemoryStream m = new Syst ...
- oracle闪回表详解
--- 说明闪回数据库 --- 使用闪回表将表内容还原到过去的特定时间点 --- 从删除表中进行恢复 --- 使用闪回查询查看截止到任一时间点的数据库内容 --- 使用闪回版本查询查看某一行在一段时间 ...
- 视网膜New iPad与普通分辨率iPad页面的兼容处理
一.这是篇经验分享 就算不是果粉也应该知道,iPad2与new iPad的重大区别之一就是显示屏的分辨率.new iPad显示屏被称之为“视网膜显示屏”,其设备分辨比(之前有详细介绍,点击这里查看)是 ...
- [译] ASP.NET 生命周期 – ASP.NET 上下文对象(八)
使用 HttpResponse 对象 HttpResponse 对象是与 HttpRequest 对象相对应的,用来表示构建中的响应.它当中提供了方法和属性可供我们自定义响应,有一些在使用 MVC 视 ...
- IOS UIVIEW layer动画 总结(转)
转发自:http://www.aichengxu.com/article/%CF%B5%CD%B3%D3%C5%BB%AF/16306_12.html IOS UIVIEW layer动画 总结, ...
- DB天气 Alpha版使用说明
一 产品介绍 DB天气是一款能够准确预报天气的软件,它的特点在于它的简洁的设计风格,以及贴心的预报方式.是一款非主流的小清新的天气APP. 二 功能介绍 下面介绍一下DB天气的主界面以及天气功能的实现 ...
- redis 在windows 上的安装与使用
1.redis-windows 最近在做一个抢拍模块,由于过于平凡的insert与update I/O受不了,故只好把东西放内存里,等拍卖结束了,在写入磁盘. 至于为什么要用window呢? 因为服务 ...