bitset+DFS序+线段树 Codeforces633G Yash And Trees
来源:互联网 发布:南宁java培训多少钱 编辑:程序博客网 时间:2024/05/19 20:45
传送门:点击打开链接
题意:给你一棵树,根节点为1
有2种操作,第一种是给u节点所在的子树的所有节点的权值+x
第二种是询问,假设v是子树u中的节点,有多少种质数满足av = p + m·k
其中p<m
思路:首先用DFS序,把树弄成线段树来表示,这种做法十分常见就不多讲了
因为m<=1000,我们用bitset保存av%m的值
每次对子树增加权值的时候,只需要修改懒惰标记,来记录增加的大小
然后直接把bitset利用位运算来完成循环移动就行了。
这道题只要能熟练运用bitset,对DFS序的线段树有一定的了解,应该是没很大问题的。
#include<map>#include<set>#include<cmath>#include<ctime>#include<stack>#include<queue>#include<cstdio>#include<cctype>#include<bitset>#include<string>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define fuck(x) cout<<"["<<x<<"]"#define FIN freopen("input.txt","r",stdin)#define FOUT freopen("output.txt","w+",stdout)using namespace std;typedef long long LL;const int MX = 1e5 + 5;const int INF = 0x3f3f3f3f;const int mod = 1e9 + 7;const int M = 1005;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1int n, m, Q;int DL[MX], DR[MX], DFN;int A[MX], B[MX], sum[MX << 2];bitset<M>stu[MX << 2], temp, pr;int Head[MX], erear;struct Edge { int v, nxt;} E[MX * 2];void edge_init() { erear = 0; memset(Head, -1, sizeof(Head));}void edge_add(int u, int v) { E[erear].v = v; E[erear].nxt = Head[u]; Head[u] = erear++;}bool prime_is(int x) { for(int i = 2; i * i <= x; i++) { if(x % i == 0) return false; } return true;}void prime_init() { pr = 0; for(int i = 2; i < m; i++) { if(prime_is(i)) pr.set(i); }}void DFS(int u, int f) { DL[u] = ++DFN; B[DFN] = A[u]; for(int i = Head[u]; ~i; i = E[i].nxt) { int v = E[i].v; if(v == f) continue; DFS(v, u); } DR[u] = DFN;}void push_up(int rt) { stu[rt] = stu[rt << 1] | stu[rt << 1 | 1];}void func_right(int rt, int x) { stu[rt] = (stu[rt] << x) | (stu[rt] >> (m - x));}void push_down(int rt) { if(sum[rt]) { sum[rt << 1] += sum[rt]; sum[rt << 1] %= m; sum[rt << 1 | 1] += sum[rt]; sum[rt << 1 | 1] %= m; func_right(rt << 1, sum[rt]); func_right(rt << 1 | 1, sum[rt]); sum[rt] = 0; }}void build(int l, int r, int rt) { sum[rt] = 0; if(l == r) { stu[rt].reset(); stu[rt].set(B[l] % m); return; } int m = (l + r) >> 1; build(lson); build(rson); push_up(rt);}void add(int L, int R, int x, int l, int r, int rt) { if(L <= l && r <= R) { sum[rt] = (sum[rt] + x) % m; func_right(rt, x); return; } int m = (l + r) >> 1; push_down(rt); if(L <= m) add(L, R, x, lson); if(R > m) add(L, R, x, rson); push_up(rt);}bitset<M> query(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) { return stu[rt]; } int m = (l + r) >> 1; push_down(rt); bitset<M> ret; if(L <= m) ret |= query(L, R, lson); if(R > m) ret |= query(L, R, rson); return ret;}int main() { //FIN; while(~scanf("%d%d", &n, &m)) { DFN = 0; edge_init(); prime_init(); for(int i = 1; i <= n; i++) { scanf("%d", &A[i]); } for(int i = 1; i <= n - 1; i++) { int u, v; scanf("%d%d", &u, &v); edge_add(u, v); edge_add(v, u); } DFS(1, -1); build(1, n, 1); scanf("%d", &Q); while(Q--) { int op, a, b; scanf("%d%d", &op, &a); if(op == 1) { scanf("%d", &b); add(DL[a], DR[a], b % m, 1, n, 1); } else { temp = query(DL[a], DR[a], 1, n, 1); printf("%d\n", (int)((temp & pr).count())); } } }}
0 0
- bitset+DFS序+线段树 Codeforces633G Yash And Trees
- Manthan, Codefest 16 G. Yash And Trees(dfs序,bitset,线段树,好题)
- Manthan, Codefest 16(G. Yash And Trees(dfs序+线段树))
- Codeforces 633 G. Yash And Trees (dfs序+线段树+位图)
- Manthan, Codefest 16(G. Yash And Trees(dfs序+线段树))★ ★ ★
- Summer Training day6 codeforces633G 线段树、bitset
- codeforces dfs序+线段树+bitset
- Codeforces 276E Little Girl and Problem on Trees【线段树+Bfs序+Dfs序】好题!
- cdoj1259 线段树+bitset
- 【CodeChef-ANUDTQ】Dynamic Trees and Queries【Splay】【DFS序】
- (线段树+dfs序)
- DFS序+线段树
- DFS-bitset-hdu5506-GT and set
- cdoj 1259 线段树+bitset
- HDU5692 线段树+dfs序
- 【线段树+dfs序】J
- 线段树2.0+dfs序
- CF764 C. Timofey and a tree(dfs序+线段树)
- 为什么要使用存储过程?
- Linux下多目录的Makefile编写
- Activity生命周期详解
- hibernate基础配置
- 排它平方数
- bitset+DFS序+线段树 Codeforces633G Yash And Trees
- Android Studio初体验之导入eclipse项目
- sudo:无法解析主机
- Study Note: Instruction Optimisation of CUDA programming
- C语言(函数与宏)
- nodejs request & response 对象
- Gradle笔记——构建基础
- Spring进阶之路(2)-ApplicationContext容器以及事件机制
- java 知识体系