这个是要用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的更多相关文章

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

    题目链接:http://codeforces.com/problemset/problem/633/G 大意是一棵树两种操作,第一种是某一节点子树所有值+v,第二种问子树中节点模m出现了多少种m以内的 ...

  2. CF620E New Year Tree 线段树+dfs序+bitset

    线段树维护 dfs 序是显然的. 暴力建 60 个线段树太慢,于是用 bitset 优化就好了 ~ code: #include <bits/stdc++.h> #define M 63 ...

  3. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  4. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  5. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  6. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  7. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  8. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  9. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

随机推荐

  1. Flutter 吐血整理组件继承关系图

    老孟导读:前几天一个读者和我说能不能整理一个各个控件之间的继承关系,这2天抽时间整理了一下,不整理不知道,一整理真的吓一跳啊,仅仅Widget的子类(包括间接子类)就高达353个,今天发群里给大家浏览 ...

  2. Linux远程登陆

    Linux 远程登录 Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的Linux服务器. 这时我们就需要远程登录到Linux服务器来管理维护系统. Linux系统中是通过ss ...

  3. java消除 list重复值及交集,并集,差集

    消除 list重复值 Java代码  public void removeDuplicate(List list) { HashSet h = new HashSet(list); list.clea ...

  4. Java虚拟机类装载的原理及实现(转)

    Java虚拟机类装载的原理及实现(转) 一.引言 Java虚拟机(JVM)的类装载就是指将包含在类文件中的字节码装载到JVM中, 并使其成为JVM一部分的过程.JVM的类动态装载技术能够在运行时刻动态 ...

  5. 线程池:Execution框架

    每问题每线程:在于它没有对已创建线程的数量进行任何限制,除非对客户端能够抛出的请求速率进行限制. 下边 有些图片看不到,清看原地址:http://www.360doc.com/content/10/1 ...

  6. JUC并发编程基石AQS源码之结构篇

    前言 AQS(AbstractQueuedSynchronizer)算是JUC包中最重要的一个类了,如果你想了解JUC提供的并发编程工具类的代码逻辑,这个类绝对是你绕不过的.我相信如果你是第一次看AQ ...

  7. 实例讲解Springboot以Repository方式整合Redis

    1 简介 Redis是高性能的NoSQL数据库,经常作为缓存流行于各大互联网架构中.本文将介绍如何在Springboot中整合Spring Data Redis,使用Repository的方式操作. ...

  8. 详解 Properties类

    (请观看本人博文--<详解 I/O流>) Properties类: 概念: Properties 类的对象 是 一个持久的属性集 Properties 可 保存在流中 或 从流中加载 属性 ...

  9. Java创建对象时的简单内存分析

    简单创建对象的内存分析 主程序: 1 public class Application { 2 public static void main(String[] args) { 3 Animal do ...

  10. (一)PL/SQL简介

    PL/SQL PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL).PL/SQL是Oracle数据库对SQL语句的扩展.在普通SQL语句的使用上增加了编 ...