codeforces 633G. Yash And Trees dfs序+线段树+bitset
4 seconds
512 megabytes
standard input
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:
- for given node v and integer value x, increase all ai in the subtree of node v by value x
- 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.
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.
For each of the queries of the second type print the number of suitable prime numbers.
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
3
1
1
5 10
8 7 5 1 0
1 2
2 3
1 5
2 4
3
1 1 0
1 1 2
2 2
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的更多相关文章
- 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 ...
- codeforces 620E. New Year Tree dfs序+线段树+bitset
题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #in ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- 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 ...
- Codeforces633G(SummerTrainingDay06-I dfs序+线段树+bitset)
G. Yash And Trees time limit per test:4 seconds memory limit per test:512 megabytes input:standard i ...
- DFS序+线段树+bitset CF 620E New Year Tree(圣诞树)
题目链接 题意: 一棵以1为根的树,树上每个节点有颜色标记(<=60),有两种操作: 1. 可以把某个节点的子树的节点(包括本身)都改成某种颜色 2. 查询某个节点的子树上(包括本身)有多少个不 ...
- CodeForces 620E:New Year Tree(dfs序+线段树)
E. New Year Treetime limit per test3 secondsmemory limit per test256 megabytesinputstandard inputout ...
- CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
随机推荐
- 使用sqlcmd执行连接的时候一直报有语法错误
1.今天在使用sqlcmd进行执行连接操作的时候一直报有语法错误找了半天. 命令 sqlcmd -S 服务器名称 -U 帐户 -P 密码 示例 sqlcmd -S "LOCALHOST&qu ...
- 教你如何利用初级C#语言更改银行存款!!!!
您是否对生活现状不满意? 您是否总是感叹工资太少? 您是否经常发现自己相中的物品又降价了然而自己却还是只能望洋兴叹? 没关系!让我来拯救你的钱包! 接下来进入正题: 要想更改自己的银行存款首先得找到一 ...
- EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数
记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...
- google base之IncomingTaskQueue
如同名称描述的那样,这个类就是个taskqueue,也就是任务队列,添加任务到队列,然后由MessageLoop去执行task,比较关心的函数如下: bool IncomingTaskQueue::A ...
- Oracle EBS-SQL (INV-1):库存货位列表.sql
select inventory_location_id, organization_id, description, subinventory_code, segment1 inventory_lo ...
- eclipse中使用EasyExplorer插件定位文件 [转载]
如果你经常需要在Eclipse里打开相关资源文件所在的文件夹,比较麻烦,要右键,属性,在Location一栏中把所在的文件夹拷贝一下,然后再去资源管理器里输入这个路径,回车,打开它. 解决方法: 用E ...
- UI设计中与字号有关的知识
在我们设计APP.设计前端页面时,免不了要和各种文字大小打交道.字体的大小有多种单位,不明究里的话使用起来很容易出问题.今天整理了这方面的东西做了个图片,方便查看. 图上的资料来自互联网,感谢大家的负 ...
- rsyslog masg和rawmsg的区别
msg the MSG part of the message (aka "the message" ;)) message 的MSG 部分 rawmsg the message ...
- CC++初学者编程教程(1) Visual Stduio2010开发环境搭建
Visual Studio是微软公司推出的开发环境.是目前最流行的Windows平台应用程序开发环境. Visual Studio 2010版本于2010年4月12日上市,其集成开发环境(IDE)的界 ...
- 一个Windows C++的线程类实现
Thread.h [cpp] view plaincopy #ifndef __THREAD_H__ #define __THREAD_H__ #include <string> #inc ...