列表

详情


NC15323. 跳一跳,很简单的

描述

有一无限循环字母表:

 

现在有一棵n个节点(编号1-n)的有根树(1为根),树边边权为一个字母θ,在每一时刻θ会向前跳K步变为相应字母(即树边边权改变),如:

n每一时刻会向前跳3步,第1时刻变为q,第2时刻变为t,以此类推。

w每一时刻会向前跳2步,第1时刻变为y,第2时刻变为a,以此类推。

JK会给你Q个询问,让你判断两个节点在t时刻到根节点路径权值(路径权值为该节点到根节点的路径上字母按顺序拼成的字符串)的字典序大小关系。

输入描述

第一行一个整数T(0<T<3),代表测试数据组数。
每一组测试数据第一行给出树的节点数n(1<n<=100000)。
接下去的n-1行的第i行给出一个整数P(1<=P<=n),一个字母θ([a-z])以及字母变换的步数K(0<=K<=10000),表示编号为i+1的节点的父亲节点编号为P,以及边的描述。(输入保证为一棵树)
下一行询问数Q(0<Q<=10000),每个询问一行给出整数u(2<=u<=n),v(2<=v<=n),t(0<=t<=10000),判断编号为u,v两个节点在t时刻到根节点路径权值的字典序大小关系。

输出描述

对每个询问输出一行答案,
编号u到根节点路径权值的字典序小于v的输出“<”,
相等输出“=”,
否则输出“>”。(不包含该引号)

示例1

输入:

1
10
1 a 1
1 a 5
1 c 2
2 f 2
3 a 5
3 e 3
4 b 1
5 z 1
7 o 2
4
5 7 0
5 7 2
9 10 1
8 8 8

输出:

>
<
<
=

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 162ms, 内存消耗: 40036K, 提交时间: 2019-02-28 11:03:05

/*


*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#define ll long long
#define M 100010
#define mmp make_pair
using namespace std;
const int base = 127;

int read() {
	int nm = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
	return nm * f;
}
const int mod = 1000000007;
ll poww[M];
char op[11];
int fa[M][18], b[M], a[M], n, deep[M];
ll hh[27][M];
vector<int> to[M];

void dfs(int now) {
	for(int i = 0; i < to[now].size(); i++) {
		int vj = to[now][i];
		deep[vj] = deep[now] + 1;
		for(int i = 0, ch = a[vj]; i < 26; i++, (ch += b[vj])) {
			if(ch >= 26) ch -= 26;
			hh[i][vj] = (hh[i][now] * base + ch) % mod;
		}
		dfs(vj);
	}
}

int main() {
	poww[0] = 1;
	for(int i = 1; i < M; i++) poww[i] = poww[i - 1] * base % mod;
	int t = read();
	while(t--) {
		n = read();
		for(int i = 2; i <= n; i++) {
			fa[i][0] = read();
			scanf("%s", op);
			b[i] = read();
			to[fa[i][0]].push_back(i);
			a[i] = op[0] - 'a';
			b[i] %= 26;
		}
		for(int i = 1; 1 << i <= n; i++)
			for(int j = 1; j <= n; j++)
				fa[j][i] = fa[fa[j][i - 1]][i - 1];
		dfs(1);
		int q = read();
		while(q--) {
			int vi = read(), vj = read(), v = read() % 26;
			for(int i = 17; i >= 0; i--) {
				if(min(deep[vi], deep[vj]) < (1 << i)) continue;
				ll ih = (hh[v][vi] - hh[v][fa[vi][i]] * poww[1 << i] % mod + mod) % mod;
				ll jh = (hh[v][vj] - hh[v][fa[vj][i]] * poww[1 << i] % mod + mod) % mod;
				if(ih == jh) vi = fa[vi][i], vj = fa[vj][i];
			}
			int aa = (a[vi] + v * b[vi]) % 26, bb = (a[vj] + v * b[vj]) % 26;
			if(aa < bb) puts("<");
			if(aa == bb) puts("=");
			if(aa > bb) puts(">");
		}
		for(int i = 1; i <= n; i++) to[i].clear();
	}
	return 0;
}
/*
2
10
1 a 1
1 a 5
1 c 2
2 f 2
3 a 5
3 e 3
4 b 1
5 z 1
7 o 2
4
5 7 0
5 7 2
9 10 1
8 8 8
10
1 a 1
1 a 5
1 c 2
2 f 2
3 a 5
3 e 3
4 b 1
5 z 1
7 o 2
4
5 7 0
5 7 2
9 10 1
8 8 8
*/

C++11(clang++ 3.9) 解法, 执行用时: 211ms, 内存消耗: 13144K, 提交时间: 2019-02-02 15:28:56

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int gi(){
	int x=0,w=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')w=0,ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
#define ll unsigned long long
const int N=1e5+5;
const ll base=20020415;
int T,n,q,nxt[N],head[N],ch[N],k[N],fa[N][18],u[N],v[N],ans[N];
ll pw[18],hsh[N];char sgn[]={'>','=','<'};
vector<int>id[26];
void dfs(int u){
	for(int j=1;j<18;++j)fa[u][j]=fa[fa[u][j-1]][j-1];
	for(int v=head[u];v;v=nxt[v])dfs(v);
}
void dfs(int u,int t){
	for(int v=head[u];v;v=nxt[v])
		hsh[v]=hsh[u]*base+(ch[v]+k[v]*t)%26+233,dfs(v,t);
}
ll cal(int u,int j){
	return hsh[u]-hsh[fa[u][j]]*pw[j];
}
int main(){
	pw[0]=base;
	for(int i=1;i<18;++i)pw[i]=pw[i-1]*pw[i-1];
	T=gi();while(T--){
		n=gi();memset(head,0,sizeof(head));
		for(int i=2,f;i<=n;++i){
			fa[i][0]=f=gi();ch[i]=getchar()-'a';k[i]=gi()%26;
			nxt[i]=head[f];head[f]=i;
		}
		dfs(1);q=gi();
		for(int i=0;i<26;++i)id[i].clear();
		for(int i=1;i<=q;++i){
			u[i]=gi();v[i]=gi();
			id[gi()%26].push_back(i);
		}
		for(int t=0;t<26;++t){
			dfs(1,t);
			for(int i:id[t]){
				int x=u[i],y=v[i];
				for(int j=17;~j;--j)
					if(cal(x,j)==cal(y,j))
						x=fa[x][j],y=fa[y][j];
				if(cal(x,0)==cal(y,0))ans[i]=1;
				else if(cal(x,0)<cal(y,0))ans[i]=2;
				else ans[i]=0;
			}
		}
		for(int i=1;i<=q;++i)putchar(sgn[ans[i]]),putchar('\n');
	}
	return 0;
}

上一题