题目链接

G. Yash And Trees
time limit per test

4 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Yash loves playing with trees and gets especially excited when they have something to do with prime numbers. On his 20th birthday he was granted with a rooted tree of n nodes to answer queries on. Hearing of prime numbers on trees, Yash gets too intoxicated with excitement and asks you to help out and answer queries on trees for him. Tree is rooted at node 1. Each node i has some value aiassociated with it. Also, integer m is given.

There are queries of two types:

  1. for given node v and integer value x, increase all ai in the subtree of node v by value x
  2. for given node v, find the number of prime numbers p less than m, for which there exists a node u in the subtree of v and a non-negative integer value k, such that au = p + m·k.
Input

The first of the input contains two integers n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ 1000) — the number of nodes in the tree and value mfrom the problem statement, respectively.

The second line consists of n integers ai (0 ≤ ai ≤ 109) — initial values of the nodes.

Then follow n - 1 lines that describe the tree. Each of them contains two integers ui and vi (1 ≤ ui, vi ≤ n) — indices of nodes connected by the i-th edge.

Next line contains a single integer q (1 ≤ q ≤ 100 000) — the number of queries to proceed.

Each of the last q lines is either 1 v x or 2 v (1 ≤ v ≤ n, 0 ≤ x ≤ 109), giving the query of the first or the second type, respectively. It's guaranteed that there will be at least one query of the second type.

Output

For each of the queries of the second type print the number of suitable prime numbers.

Examples
input
8 20
3 7 9 8 4 11 7 3
1 2
1 3
3 4
4 5
4 6
4 7
5 8
4
2 1
1 1 1
2 5
2 4
output
3
1
1
input
5 10
8 7 5 1 0
1 2
2 3
1 5
2 4
3
1 1 0
1 1 2
2 2
output
2

题目给的第二个操作, Ai = p+k*m就相当于问Ai%m是不是素数, 想到这个就好做了....每一个节点一个bitset, 然后查询完之后结果与一个素数表进行&操作, 看还剩下几个值, 答案就是几。
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 1e5+;
int in[maxn], out[maxn], dfs_clock, mod, add[maxn<<];
bitset <> sum[maxn<<], prime;
int head[maxn*], num, a[maxn], b[maxn], vx[];
struct node
{
int to, nextt;
}e[maxn*];
void addd(int u, int v) {
e[num].to = v, e[num].nextt = head[u], head[u] = num++;
}
void init() {
num = ;
mem1(head);
}
void dfs(int u, int fa) {
in[u] = ++dfs_clock;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(v == fa)
continue;
dfs(v, u);
}
out[u] = dfs_clock;
}
inline void pushUp(int rt) {
sum[rt] = sum[rt<<]|sum[rt<<|];
}
inline void change(int rt, int val) {
sum[rt] = (sum[rt]<<val)|(sum[rt]>>(mod-val));
}
void pushDown(int rt) {
if(add[rt]) {
change((rt<<), add[rt]);
change((rt<<|), add[rt]);
add[rt<<] = (add[rt]+add[rt<<])%mod;
add[rt<<|] = (add[rt]+add[rt<<|])%mod;
add[rt] = ;
}
}
void build(int l, int r, int rt) {
if(l == r) {
sum[rt][b[l]] = ;
return ;
}
int m = l+r>>;
build(lson);
build(rson);
pushUp(rt);
}
void update(int L, int R, int val, int l, int r, int rt) {
if(L<=l&&R>=r) {
change(rt, val);
add[rt] = (val+add[rt])%mod;
return ;
}
pushDown(rt);
int m = l+r>>;
if(L<=m)
update(L, R, val, lson);
if(R>m)
update(L, R, val, rson);
pushUp(rt);
}
bitset<> query(int L, int R, int l, int r, int rt) {
if(L<=l&&R>=r) {
return sum[rt];
}
pushDown(rt);
bitset<> ret;
ret.reset();
int m = l+r>>;
if(L<=m)
ret |= query(L, R, lson);
if(R>m)
ret |= query(L, R, rson);
return ret;
}
int main()
{
int n, u, v, q, x, y, z;
scanf("%d%d", &n, &mod);
init();
for(int i = ; i<=n; i++) {
scanf("%d", &a[i]);
a[i] %= mod;
}
for(int i = ; i<n; i++) {
scanf("%d%d", &u, &v);
addd(u, v);
addd(v, u);
}
for(int i = ; i<mod; i++)
{
if(vx[i])
continue;
prime[i] = ;
for(int j = i; j<mod; j+=i)
vx[j]=;
}
dfs(, -);
for(int i = ; i<=n; i++) {
b[in[i]] = a[i];
}
build(, n, );
scanf("%d", &q);
while(q--) {
scanf("%d%d", &x, &y);
if(x == ) {
scanf("%d", &z);
z %= mod;
update(in[y], out[y], z, , n, );
} else {
bitset<> tmp = query(in[y], out[y], , n, );
tmp &= prime;
printf("%d\n", tmp.count());
}
}
return ;
}

codeforces 633G. Yash And Trees dfs序+线段树+bitset的更多相关文章

  1. Manthan, Codefest 16 G. Yash And Trees dfs序+线段树+bitset

    G. Yash And Trees 题目连接: http://www.codeforces.com/contest/633/problem/G Description Yash loves playi ...

  2. codeforces 620E. New Year Tree dfs序+线段树+bitset

    题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #in ...

  3. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  4. Codeforces Round #169 (Div. 2) E. Little Girl and Problem on Trees dfs序+线段树

    E. Little Girl and Problem on Trees time limit per test 2 seconds memory limit per test 256 megabyte ...

  5. Codeforces633G(SummerTrainingDay06-I dfs序+线段树+bitset)

    G. Yash And Trees time limit per test:4 seconds memory limit per test:512 megabytes input:standard i ...

  6. DFS序+线段树+bitset CF 620E New Year Tree(圣诞树)

    题目链接 题意: 一棵以1为根的树,树上每个节点有颜色标记(<=60),有两种操作: 1. 可以把某个节点的子树的节点(包括本身)都改成某种颜色 2. 查询某个节点的子树上(包括本身)有多少个不 ...

  7. CodeForces 620E:New Year Tree(dfs序+线段树)

    E. New Year Treetime limit per test3 secondsmemory limit per test256 megabytesinputstandard inputout ...

  8. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  9. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

随机推荐

  1. js基础——cssText

    以前,只知道设置css里的属性都是通过  元素.style.属性名 = 属性值  的方式,此时经常遇到的情况就是类似这样: var head= document.getElementById(&quo ...

  2. TreeSet类的排序问题

     http://www.cnblogs.com/lixiaolun/archive/2012/12/25/2832775.html TreeSet支持两种排序方法:自然排序和定制排序.TreeSet默 ...

  3. Git 系列(一):什么是 Git

    欢迎阅读本系列关于如何使用 Git 版本控制系统的教程!通过本文的介绍,你将会了解到 Git 的用途及谁该使用 Git. 如果你刚步入开源的世界,你很有可能会遇到一些在 Git 上托管代码或者发布使用 ...

  4. 关于webapp中的文字单位的一些捣腾

    前言 文字是网页内容的一枚大将,我们无时无刻都在看着它,只要是你盯屏幕上的任何一个地方都会有文字.地铁上无时无刻都在盯着屏幕上的人对于文字更为敏感,太大不行,太小TN又看不清上面到底在说什么,有时候车 ...

  5. python相似模块用例(一)

    一:threading VS Thread 众所周知,python是支持多线程的,而且是native的线程,其中threading是对Thread模块做了包装,可以更加方面的被使用,threading ...

  6. sim卡中电话本(ADN)的简要格式

    ADN的格式 ADN存放于sim卡下面3f00/7f10/6f3a,记录文件格式,其最小记录格式为14,最长为255(?),记录个数最大为255(?) 其后数14个字节是必有的,其前12个字节是电话号 ...

  7. Android中pendingIntent的深入理解

    pendingIntent字面意义:等待的,未决定的Intent.要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, Intent, i ...

  8. poj2636---Electrical Outlets(插线板)

    #include <stdio.h> #include <stdlib.h> int main() { int n,nc,i; scanf("%d",&am ...

  9. 顺序栈之C++实现

    顺序栈就是用顺序表(数组)实现的栈.其组织形式如下图所示: 下面介绍下我用C++实现的顺序栈,在VC6下调试通过.不足之处还请指正. 1.文件组织 2.ss.h栈类的声明及宏的定义 #ifndef _ ...

  10. word-wrap,white-space和text-overflow属性

    (1) //在断点处换行 word-wrap: normal; //允许在长单词进行换行 word-wrap: break-word; (2) white-space:怎么处理元素间的空白 white ...