Random Numbers Gym - 101466K dfs序+线段树
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
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
14400 63
187200 126
题意:
给你一棵有n个节点的树,根节点始终为0,有两种操作:
1.RAND:查询以u为根节点的子树上的所有节点的权值的乘积x,及x的因数个数。
2.SEED:将节点u的权值乘以x。
看清楚题目啊 素因子最大为13
知道这个用dfs序处理一下 然后建立线段树就OK了
这题还用来 唯一分解定理 https://www.cnblogs.com/qldabiaoge/p/8647130.html
再用快速幂处理一下就搞定了
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <bits/stdc++.h>
#define pi acos(-1.0)
#define eps 1e-6
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a,b) memset(a,b,sizeof(a))
#define fuck(x) cout<<"["<<x<<"]"<<endl
#define f(a) a*a
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define pf printf
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define FIN freopen("DATA.txt","r",stdin)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) x&-x
#pragma comment (linker,"/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x7fffffff;
const LL LLINF = 0x3f3f3f3f3f3f3f3fll;
const int maxn = 1e6 + ;
const int mod = 1e9 + ;
int n, m, x, y, tot, dfscnt, head[maxn], L[maxn], R[maxn], val[maxn];
int prime[] = {, , , , , }, cnt[], ans[];
struct Edge {
int v, nxt;
} edge[maxn << ];
void init() {
tot = ;
mem(head, -);
}
void add(int u, int v) {
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
void dfs(int u, int fa) {
L[u] = ++dfscnt;
for (int i = head[u]; ~i ; i = edge[i].nxt) {
int v = edge[i].v;
if (v != fa) dfs(v, u);
}
R[u] = dfscnt;
}
struct node {
int l, r, num[];
int mid() {
return (l + r) >> ;
}
} tree[maxn << ];
void pushup(int rt) {
for (int i = ; i < ; i++)
tree[rt].num[i] = (tree[rtl].num[i] + tree[rtr].num[i]) % mod;
}
void build(int l, int r, int rt) {
tree[rt].l = l, tree[rt].r = r;
mem(tree[rt].num, );
if (l == r) {
for (int i = ; i < ; i++) {
while(val[l] % prime[i] == ) {
val[l] /= prime[i];
tree[rt].num[i]++;
}
}
return ;
}
int m = (l + r) >> ;
build(l, m, rtl);
build(m + , r, rtr);
pushup(rt);
}
void update(int pos, int rt) {
if (tree[rt].l == pos && tree[rt].r == pos) {
for (int i = ; i < ; i++)
tree[rt].num[i] = (tree[rt].num[i] + cnt[i]) % mod;
return ;
}
int m = tree[rt].mid();
if (pos <= m) update(pos, rtl);
else update(pos, rtr);
pushup(rt);
}
void query(int L, int R, int rt) {
if (tree[rt].l == L && tree[rt].r == R) {
for (int i = ; i < ; i++)
ans[i] = (ans[i] + tree[rt].num[i]) % mod;
return ;
}
int m = tree[rt].mid();
if (R <= m) query(L, R, rtl);
else if (L > m) query(L, R, rtr);
else {
query(L, m, rtl);
query(m + , R, rtr);
}
}
int expmod(int a, int b) {
int ret = ;
while(b) {
if(b & ) ret = 1LL * ret * a % mod;
a = 1LL * a * a % mod;
b = b >> ;
}
return ret;
}
int main() {
sf(n);
init();
for (int i = ; i < n ; i++) {
int u, v;
sff(u, v);
u++, v++;
add(u, v);
add(v, u);
}
dfs(, -);
for (int i = ; i <= n ; i++) {
sf(x);
val[L[i]] = x;
}
build(, n, );
sf(m);
while(m--) {
char op[];
scanf("%s", op);
if (op[] == 'R') {
sf(x);
x++;
mem(ans, );
query(L[x], R[x], );
LL ans1 = , ans2 = ;
for (int i = ; i < ; i++) {
ans1 = (ans1 * expmod(prime[i], ans[i]) % mod) % mod;
ans2 = (ans2*((ans[i]+)%mod)) % mod;
}
printf("%lld %lld\n", ans1, ans2);
} else {
sff(x, y);
x++;
for (int i = ; i < ; i++) {
cnt[i] = ;
while(y % prime[i] == ) {
cnt[i]++;
y /= prime[i];
}
}
update(L[x], );
}
}
return ;
}
Random Numbers Gym - 101466K dfs序+线段树的更多相关文章
- dfs序线段树
dfs序+线段树,啥?如果在一棵树上,需要你修改一些节点和查询一些节点,如果直接dfs搜的话肯定超时,那用线段树?树结构不是区间啊,怎么用?用dfs序将树结构转化为一个区间,就能用线段树进行维护了. ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- POJ 3321 DFS序+线段树
单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4: 5: #include < ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- F - Change FZU - 2277 (DFS序+线段树)
题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...
随机推荐
- C 计算员工工资
#include <stdio.h> int main(int argc, char **argv) { //定义四个变量 g每小时固定的工资 40 固定工作时间 pay工资 hours员 ...
- 【json提取器】- 提取数据的方法
json 提取器的使用 方法 json 提取器 提取的结果 我用调试取样器进行查看
- 参数为json格式的接口
1.参数为json格式,需要添加一个header信息web_add_header("Content-type", "application/json"); 2. ...
- JAVA基础学习之路(三)类定义及构造方法
类的定义及使用 一,类的定义 class Book {//定义一个类 int price;//定义一个属性 int num; public static int getMonney(int price ...
- Paper Reading - Learning like a Child: Fast Novel Visual Concept Learning from Sentence Descriptions of Images ( ICCV 2015 )
Link of the Paper: https://arxiv.org/pdf/1504.06692.pdf Innovations: The authors propose the Novel V ...
- 第一周 Welcome
什么是机器学习 您也许一天用它几十次都不知道,每次你用google或者bing搜索网页感觉很厉害,因为他们用机器学习软件来设计网页排名,当你用Facebook或Apple的照片软件而它们知道照片里面哪 ...
- [C++] OOP - Virtual Functions and Abstract Base Classes
Ordinarily, if we do not use a function, we do not need to supply a definition of the function. Howe ...
- 【转】CentOS: 开放80、22、3306端口操作
#/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT#/sbin/iptables -I INPUT -p tcp --dport 22 -j AC ...
- 使用HTML5制作loading图
昨天发了一篇使用HTML5 canvas写的时钟的文章,今天发一篇关于使用HTML5制作loading图的文章. <!DOCTYPE html> <html> <head ...
- 一步步学敏捷开发:1、敏捷开发及Scrum介绍
敏捷开发之 历史背景 20世纪60年代:软件作坊,软件规模小,以作坊式开发为主:70年代:软件危机,硬件飞速发展,软件规模和复杂度激增,引发软件危机:80年代:软件过程控制,引入成熟生产制造管理方法, ...