G. Yash And Trees 线段树 + dfs序 + bitset
这个是要用bitset 一个大整数的二进制 学习推荐博客
这个题目大意就是:给你n,m 还有一个序列,还有一个一棵树,有一种操作一种询问
操作是给你一个节点 把这个节点及其子节点都加上x
询问是 给你一个节点,问你这个节点以下 小于m的质数有多少种,注意是种,所以要去重,所以需要bitset
这个题目我写了一上午,wa了一下午,在lj的帮助之下终于写出来了。
写法,操作就可以用<< 来代替加上x,但是因为如果超出了m,就要对m取模,所以相当于一个环,这个环的处理要注意。
注意:
我wa的地方:
忘记了update 的push_up 操作,
query的两个区间合起来的时候没有去重。
还有就是 << 这个操作,因为素数一定要小于m,而且每一个数一定小于m,所以<<m,就可以了,而且素数的bitset 只要到m-1就可以了
最后一个最重要的!!!
我建树建错了,这个dfs序之后,如果我想把给的a序列放进来,那么就需要按照dfs序来,所以dfs序,不仅仅要存每一个数映射的位置,而且要存每一个位置存的数。
建树要注意!!! 第一次碰到这个问题,以后希望不要再这样wa一下午了,
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <bitset>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const int mx = ;
bitset<mx>B;
bitset<mx>C;
bitset<mx>ex;
struct node
{
bitset<mx>bt;
ll lazy;
}tree[maxn*];
int n, m, q, p[maxn];
ll a[maxn];
//素数筛
void init() {
for (int i = ; i < maxn; i++) p[i] = ;
for (int i = ; i*i < maxn; i++) {
if (p[i]) {
for (int j = i * i; j < maxn; j += i) {
p[j] = ;
}
}
}
B.reset(); C.reset();
for (int i = ; i < m; i++) {
if (p[i]) B.set(i);//B构造出一个全部都是素数的bitset
C.set(i);
}
}
//v数组记录每一个i的最小质因数,isp记录所有的质数
int er[maxn], el[maxn], tot;
vector<int>G[maxn];
bool vis[maxn];
int num[maxn];
//dfs序 转化成二叉树
void dfs(int x)
{
vis[x] = ;
el[x] = ++tot;
num[tot] = x;
for(int i=;i<G[x].size();i++)
{
int v = G[x][i];
if (vis[v]) continue;
dfs(v);
}
er[x] = tot;
}
//线段树的建树过程
void build(int id,int l,int r)
{
tree[id].lazy = ;
if(l==r)
{
tree[id].bt.set(a[num[l]]);
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
tree[id].bt = tree[id << ].bt | tree[id << | ].bt;
// printf("id=%d l=%d r=%d\n", id, l, r);
// std::cout << tree[id].bt << endl;
}
void push_down(int id)
{
if(tree[id].lazy)
{
ex.reset();
int val = tree[id].lazy;
tree[id << ].bt <<= val;
ex = tree[id << ].bt >> m;
tree[id << ].bt |= ex;
tree[id << ].bt &= C;
tree[id << ].lazy += val;
tree[id << ].lazy %= m;
ex.reset();
tree[id << | ].bt <<= val;
ex = tree[id << | ].bt >> m;
tree[id << | ].bt |= ex;
tree[id << | ].bt &= C;
tree[id << | ].lazy += val;
tree[id << | ].lazy %= m;
tree[id].lazy = ;
}
}
void update(int id,int l,int r,int x,int y,int val)
{
if(x<=l&&y>=r)
{
// printf("1 id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
// std::cout << tree[id].bt << endl;
ex.reset();
tree[id].lazy += val;
tree[id].lazy %= m;
tree[id].bt <<= val;
// printf("2\n");
// std::cout << tree[id].bt << endl;
ex = tree[id].bt >> m;
tree[id].bt |= ex;
// printf("3\n");
// std::cout << tree[id].bt << endl;
tree[id].bt &= C;
// printf("id=%d l=%d r=%d x=%d y=%d val=%d \n", id, l, r, x, y, val);
// std::cout << tree[id].bt << endl;
return;
}
push_down(id);
int mid = (l + r) >> ;
if (x <= mid) update(id << , l, mid, x, y, val);
if (y > mid) update(id << | , mid + , r, x, y, val);
tree[id].bt = tree[id << ].bt | tree[id << | ].bt;
}
bitset<mx> query(int id,int l,int r,int x,int y)
{
if (x <= l && y >= r) {
// printf("id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
// std::cout << tree[id].bt << endl;
return tree[id].bt&B;
}
push_down(id);
int mid = (l + r) >> ;
bitset<mx>ans;
if (x <= mid) ans |= query(id << , l, mid, x, y);
if (y > mid) ans |= query(id << | , mid + , r, x, y);
// printf("id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
// std::cout << ans << endl;
return (ans & B);
}
int main()
{
tot = ;
scanf("%d%d", &n, &m);
init();
for (int i = ; i <= n; i++) scanf("%lld", &a[i]), a[i] %= m;
for(int i=;i<n;i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(vis, , sizeof(vis));
dfs();
build(, , n);
scanf("%d", &q);
while(q--)
{
int opt, v, x;
scanf("%d", &opt);
if(opt==)
{
scanf("%d%d", &v, &x);
x %= m;
update(, , n, el[v], er[v], x);
}
else
{
scanf("%d", &v);
bitset<mx>ans = query(, , n, el[v], er[v]);
printf("%d\n", ans.count());
}
}
return ;
}
/*
3 33
94 21 38
3 1
3 2
9
2 1
2 2
1 3 127
2 2
1 2 381
1 1 275
2 2
2 3
1 1 695
*/
bitset
G. Yash And Trees 线段树 + dfs序 + bitset的更多相关文章
- CF Manthan, Codefest 16 G. Yash And Trees 线段树+bitset
题目链接:http://codeforces.com/problemset/problem/633/G 大意是一棵树两种操作,第一种是某一节点子树所有值+v,第二种问子树中节点模m出现了多少种m以内的 ...
- CF620E New Year Tree 线段树+dfs序+bitset
线段树维护 dfs 序是显然的. 暴力建 60 个线段树太慢,于是用 bitset 优化就好了 ~ code: #include <bits/stdc++.h> #define M 63 ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
题目大意 Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数
R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...
随机推荐
- 《JavaScript 模式》读书笔记(6)— 代码复用模式2
上一篇讲了最简单的代码复用模式,也是最基础的,我们普遍知道的继承模式,但是这种继承模式却有不少缺点,我们下面再看看其它可以实现继承的模式. 四.类式继承模式#2——借用构造函数 本模式解决了从子构造函 ...
- Juli函数
- Alpha-release 总结
因组员一周来事情较多,因此博客更新停滞了一个星期.这周我们已经开始了第二个release的相关工作,首先先对上一个release的工作进行简短总结. 团队在上个星期进行了alpha-release版本 ...
- A - Smith Numbers POJ
While skimming his phone directory in 1982, Albert Wilansky, a mathematician of Lehigh University,no ...
- api_DZFPKJ & api_DZFPCX(get_AES_url代码优化)
通过AES加密网站的接口来传值,不需要手动加密字符串后复制过来传值. #coding:utf-8 import requests import re def get_aes_url(key, text ...
- LeetCode#160-Intersection of Two Linked Lists-相交链表
一.题目 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], l ...
- python 获取的json字符串取值
获取到的json字符串,然后对其取值 {u'result': {u'10.10.10.100': {u'status': u'OK', u'msg': u"{'listen': {'': s ...
- 堆溢出---glibc malloc
成功从来没有捷径.如果你只关注CVE/NVD的动态以及google专家泄露的POC,那你只是一个脚本小子.能够自己写有效POC,那就证明你已经是一名安全专家了.今天我需要复习一下glibc中内存的相关 ...
- tensorflow1.0 placeholder占位符
import tensorflow as tf #(tf.float32,[2,2]) input1 = tf.placeholder(tf.float32) input2 = tf.placehol ...
- UDO、TCP、HTTP、websocket
如图: