Tamref love random numbers, but he hates recurrent relations, Tamref thinks that mainstream random generators like the linear congruent generator suck. That's why he decided to invent his own random generator.

As any reasonable competitive programmer, he loves trees. His generator starts with a tree with numbers on each node. To compute a new random number, he picks a rooted subtree and multiply the values of each node on the subtree. He also needs to compute the number of divisors of the generated number (because of cryptographical applications).

In order to modify the tree (and hence create different numbers on the future), Tamref decided to perform another query: pick a node, and multiply its value by a given number.

Given a initial tree T, where Tu corresponds to the value on the node u, the operations can be summarized as follows:

  • RAND: Given a node u compute and count its divisors, where T(u) is the set of nodes that belong to the subtree rooted at u.
  • SEED: Given a node u and a number x, multiply Tu by x.

Tamref is quite busy trying to prove that his method indeed gives integers uniformly distributed, in the meantime, he wants to test his method with a set of queries, and check which numbers are generated. He wants you to write a program that given the tree, and some queries, prints the generated numbers and count its divisors.

Tamref has told you that the largest prime factor of both Tu and x is at most the Tamref's favourite prime: 13. He also told you that the root of T is always node 0.

The figure shows the sample test case. The numbers inside the squares are the values on each node of the tree. The subtree rooted at node 1 is colored. The RAND query for the subtree rooted at node 1 would generate 14400, which has 63 divisors.

Input

The first line is an integer n (1 ≤ n ≤ 105), the number of nodes in the tree T. Then there are n - 1 lines, each line contains two integers u and v (0 ≤ u, v < n) separated by a single space, it represents that u is a parent of v in T. The next line contains n integers, where the i - th integer corresponds to Ti (1 ≤ Ti ≤ 109). The next line contains a number Q (1 ≤ Q ≤ 105), the number of queries. The final Q lines contain a query per line, in the form "RAND u" or "SEED u x" (0 ≤ u < n, 1 ≤ x ≤ 109).

Output

For each RAND query, print one line with the generated number and its number of divisors separated by a space. As this number can be very long, the generated number and its divisors must be printed modulo 109 + 7.

Example

Input
8
0 1
0 2
1 3
2 4
2 5
3 6
3 7
7 3 10 8 12 14 40 15
3
RAND 1
SEED 1 13
RAND 1
Output
14400 63
187200 126 题意:给一颗树共n个点,以及其结点的数值ai,有q次行为,查询询问子树(包括节点)的数值的积,与更新单个节点即乘题给数(一开始以为是整个子树都要更新) 思路:明显的线段树题,但是问题是线段树里存的是什么。如果直接存积,数组开long long也存不下。那么就需要换种思路,存积的质因子的指数。 即把积X=(p1^a)*(p2^b)*(p3^c)*······中的a,b,c用数组记录。又题目给出子树结点的积可以用不超过13的素数的积来表示。则定义一个b[]={2,3,5,7,11,13}。 就能表示所有子树积。这样查询到以后可以直接用快速幂求得第一问,用乘法原理因子数=(a+1)*(b+1)······即得第二问。 想到这里剩下的操作就是套+改线段树dfs序板子了(这里膜一下月老tql)
 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#define lid id<<1
#define rid id<<1|1
#define INF 0x3f3f3f3f
#define LL long long
#define debug(x) cout << "[" << x << "]" << endl
using namespace std;
const int maxn = 1e5+;
int b[]={,,,,,};
int d[maxn][]={};
void cal(int x, int *d)
{
for(int i = ;i < ;i++){
while(x%b[i]==)x/=b[i],d[i]++;
}
}
const int mx = 1e5+;
const int mod = 1e9+;
int L[mx], R[mx], p[mx];
struct tree{
int l, r;
int p[]; //2,3,5,7,11,13
int lazy[];
}tree[mx<<];
vector<int> G[mx];
int cnt;
LL Ans[] = {}; LL qpow(LL x, LL n){ //x^n
LL res = ;
while (n > ){
if (n & ) res = res*x%mod;
x = x*x % mod;
n >>= ;
}
return res;
} void push_up(int id){
for (int i = ; i < ; i++)
tree[id].p[i] = tree[lid].p[i]+tree[rid].p[i];
} void build(int l, int r, int id){
tree[id].l = l;
tree[id].r = r;
for (int i = ; i < ; i++) tree[id].p[i] = ;
if (l == r) return;
int mid = (l+r) >> ;
build(l, mid, lid);
build(mid+, r, rid);
} void dfs(int u){
L[u] = ++cnt;
int len = G[u].size();
for (int i = ; i < len; i++){
int v = G[u][i];
dfs(v);
}
R[u] = cnt;
} void upd(int c, int id, int *x){
if (tree[id].l == c && tree[id].r == c){
for (int i = ; i < ; i++)
tree[id].p[i] += x[i];
return;
}
int mid = (tree[id].l + tree[id].r)>>;
if (c <= mid) upd(c, lid, x);
else upd(c, rid, x);
push_up(id);
} void query(int l, int r, int id){
if (tree[id].l == l && tree[id].r == r){
for (int i = ; i < ; i++)
Ans[i] += tree[id].p[i];
return;
}
int mid = (tree[id].l + tree[id].r)>>;
if (r <= mid) query(l, r, lid);
else if (mid < l) query(l, r, rid);
else {
query(l, mid, lid);
query(mid+, r, rid);
}
} int main(){
int n, u, v, a, q;
cnt = ;
scanf("%d", &n);
for (int i = ; i < n; i++){
scanf("%d%d", &u, &v);
G[u].push_back(v);
p[v] = u;
}
for (int i = ; i < n; i++){
if (!p[i]) {
dfs(i);
break;
}
}
build(, n, );
for (int i = ; i < n; i++){
scanf("%d", &a);
cal(a,d[i]);
upd(L[i], , d[i]);
}
scanf("%d", &q);
while (q--){
char s[];
int d2[] = {};
scanf("%s%d", s, &a);
if (s[] =='R'){
memset(Ans, , sizeof Ans);
query(L[a], R[a], );
LL ans = ;
LL num = ;
for (int i = ; i < ; i++){
num = (num*qpow(b[i], Ans[i]))%mod;
ans = ans*(Ans[i]+)%mod;
}
printf("%lld %lld\n", num, ans);
}
else {
int c;
scanf("%d", &c);
cal(c, d2);
upd(L[a], , d2);
}
}
return ;
}
 

2017 ACM-ICPC, Universidad Nacional de Colombia Programming Contest K - Random Numbers (dfs序 线段树+数论)的更多相关文章

  1. 2020 ICPC Universidad Nacional de Colombia Programming Contest

    2020 ICPC Universidad Nacional de Colombia Programming Contest A. Approach 三分 显然答案可以三分,注意\(eps\)还有两条 ...

  2. 2019 ICPC Universidad Nacional de Colombia Programming Contest C D J

    C. Common Subsequence 题意:给出长度为n两个串,求两个串的最长公共子序列len,如果len>=0.99*n,两个串就是亲兄弟否则不是. 解法:朴素的求LCS的时间复杂度是O ...

  3. 2016 ACM/ICPC Asia Regional Dalian Online HDU 5877 Weak Pair treap + dfs序

    Weak Pair Problem Description   You are given a rooted tree of N nodes, labeled from 1 to N. To the  ...

  4. 2017 Wuhan University Programming Contest (Online Round) D. Events,线段树区间更新+最值查询!

    D. Events 线段树区间更新查询区间历史最小值,看似很简单的题意写了两天才写出来. 题意:n个数,Q次操作,每次操作对一个区间[l,r]的数同时加上C,然后输出这段区间的历史最小值. 思路:在线 ...

  5. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 D 80 Days (线段树查询最小值)

    题目4 : 80 Days 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 80 Days is an interesting game based on Jules Ve ...

  6. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) F dfs序+树状数组

    Performance ReviewEmployee performance reviews are a necessary evil in any company. In a performance ...

  7. The 2019 Asia Nanchang First Round Online Programming Contest C(cf原题,线段树维护矩阵)

    题:https://nanti.jisuanke.com/t/41350 分析:先将字符串转置过来 状态转移,因为只有5个状态,所以 i 状态到 j 状态的最小代价就枚举[i][k]->[k][ ...

  8. 2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路

    transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/1 ...

  9. 2017 ACM ICPC Asia Regional - Daejeon

    2017 ACM ICPC Asia Regional - Daejeon Problem A Broadcast Stations 题目描述:给出一棵树,每一个点有一个辐射距离\(p_i\)(待确定 ...

随机推荐

  1. MVPR下的PHP分页教程

    这个PHP分页其实不难,现在就开始看看核心思路吧. 我习惯从最底层开始看起. 1. 首先用LIMIT偏移QUERY的指针 /* * get hot post by current page * @pa ...

  2. goweb-模板引擎

    模板引擎 Go 为我们提供了 text/template 库和 html/template 库这两个模板引擎,模板引 擎通过将数据和模板组合在一起生成最终的 HTML,而处理器负责调用模板引擎并将引 ...

  3. 第7节 Arrays工具类

    package cn.itcast.day08.demo04; import java.util.Arrays; /*java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法, ...

  4. SQL Link Oracle

    转自:http://www.2cto.com/database/201107/96105.html 做项目过程中常用到数据库同步,现把前一段时间做的一个项目部分,同步过程贴出来,供分享与自己参考! 本 ...

  5. RDD(十)——案例实操

    需求: 数据结构:时间戳,省份,城市,用户,广告,中间字段使用空格分割. 样本如下: 1516609143867 6 7 64 16 1516609143869 9 4 75 18 151660914 ...

  6. servlet 上传文件

    java protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException ...

  7. Python数据分析与展示第3周学习笔记(北京理工大学 嵩天等)

    入门学习马上结束辽. 1.Pandas库 import pandas as pd 两个数据类型:Series,DataFrame Series类型:数据+索引 自定义索引 b = pd.Series( ...

  8. Office 365 共享邮箱/日历

    一.共享邮箱 Office 365共享邮箱对于客户通过电子邮箱提出的问题,共享邮箱是一个很好的处理方式,组织中的多人可以分担监控邮箱和回复的责任,使得客户的问题更快地得到答复,而相关电子邮件都存储在一 ...

  9. Python运维中常用的_脚本

    前言 file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件. ...

  10. 使用java获取手机号归属地等信息httpClient实现

    java获取手机号归属地 一般想获取手机号归属地等信息个人是无法获取的,但是可以通过调用第三方接口获取,具体百度搜索很多这里例子提供一个淘宝的接口 ,该功能已经发布到网站作为一个在线小工具,拿走不谢: ...