ZOJ 3886 Nico Number(素数筛选 + 线段树)
来源:互联网 发布:淘宝开店简介怎么写 编辑:程序博客网 时间:2024/05/02 02:39
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5556
题意:定义一种Nico数,给出三种操作:
1.询问[L, R]内有多少个Nico数
2.[L, R]内的数全部对v取余
3.将第K个数换成X
思路:打表可知满足Nico数定义的有:素数,2的幂,6,可以先预处理出这些数,对于1,3操作线段树都好处理,对于2操作,可以维护区间最大值,因为对于每一个数x取模的次数都不会超过log(x)次,如果当前区间最大值 < 取模值v,那就不必更新了
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <utility>#include <cmath>#include <queue>#include <set>#include <map>#include <climits>#include <functional>#include <deque>#include <ctime>#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int MAXN = 100010;const int INF = 0x3f3f3f3f;typedef long long ll;int pri[10000005];bool vis[10000005];void init(){ memset(vis, 0, sizeof(vis)); memset(pri, 0, sizeof(pri)); for (int i = 2; i <= 10000000; i++) { if (!pri[i]) pri[++pri[0]] = i; for (int j = 1; j <= pri[0] && pri[j] <= 10000000 / i; j++) { pri[pri[j] * i] = 1; if (i % pri[j] == 0) break; } } for (int j = 1; j <= pri[0]; j++) vis[pri[j]] = 1; vis[0] = vis[1] = vis[6] = 1; for (int i = 2; i <= 10000000; i *= 2) vis[i] = 1;}int ma[MAXN << 2], num[MAXN << 2];void pushup(int rt){ ma[rt] = max(ma[rt << 1], ma[rt << 1 | 1]); num[rt] = num[rt << 1] + num[rt << 1 | 1];}void build(int l, int r, int rt){ if (l == r) { scanf("%d", &ma[rt]); if (vis[ma[rt]]) num[rt] = 1; else num[rt] = 0; return ; } int mid = (l + r) >> 1; build(lson); build(rson); pushup(rt);}void update1(int ql, int qr, int c, int l, int r, int rt){ if (ql > r || qr < l) return ; if (ma[rt] < c) return ; if (l == r) { ma[rt] %= c; if (vis[ma[rt]]) num[rt] = 1; else num[rt] = 0; return ; } int mid = (l + r) >> 1; update1(ql, qr, c, lson); update1(ql, qr, c, rson); pushup(rt);}void update2(int p, int c, int l, int r, int rt){ if (l == p && r == p) { ma[rt] = c; if (vis[c]) num[rt] = 1; else num[rt] = 0; return ; } int mid = (l + r) >> 1; if (p <= mid) update2(p, c, lson); else update2(p, c, rson); pushup(rt);}int query(int ql, int qr, int l, int r, int rt){ if (ql > r || qr < l) return 0; if (ql <= l && qr >= r) return num[rt]; int res = 0, mid = (l + r) >> 1; res += query(ql, qr, lson); res += query(ql, qr, rson); return res;}int main(){ init(); int n; while (~scanf("%d", &n)) { build(1, n, 1); // for (int i = 1; i <= n; i++) // printf("%d ", num[i]); int m; scanf("%d", &m); while (m--) { int ch; scanf("%d", &ch); if (ch == 1) { int l, r; scanf("%d%d", &l, &r); printf("%d\n", query(l, r, 1, n, 1)); } else if (ch == 2) { int l, r, c; scanf("%d%d%d", &l, &r, &c); update1(l, r, c, 1, n, 1); } else { int p, c; scanf("%d%d", &p, &c); update2(p, c, 1, n, 1); } } } return 0;}
0 0
- ZOJ 3886 Nico Number(素数筛选 + 线段树)
- ZOJ 3886 Nico number(线段树)
- ZOJ 3886 Nico Number (线段树)
- 【ZOJ】3886 Nico Number【线段树】
- zoj3886--Nico Number(素数筛+线段树)
- ZOJ 3886 Nico Number(筛素数+Love(线)Live(段)树)
- zoj 3886 Nico Number(线段树,区间取模操作)
- ZOJ 3886 Nico Number(线段树单点更新+找规律)
- ZOJ 3886 Nico Number
- ZOJ3886 2015July月赛 F-Nico Number(线段树)
- Number Transformation (bfs) (素数筛选)
- ZOJ 1484 Minimum Inversion Number(线段树,数论)
- zoj 1951 Goldbach's Conjecture(素数筛选继续水)
- zoj3886.Nico Number
- zoj2886 Nico Number
- ZOJ3886-Nico Number
- ZOJ 2723 Semi-Prime (素数筛选大法)
- Number Transformation-bfs+素数筛选法
- 正则表达式 - 自动生成器
- 黑马程序员--java基础--IO流概述
- Android 跳转基础应用(联系人,日历)
- C语言笔记
- 黑马程序员--java基础--反射
- ZOJ 3886 Nico Number(素数筛选 + 线段树)
- HDU 2063.过山车【二分图、二分匹配初接触】【8月3】
- 剑指Offer面试题22(Java版):栈的压入、弹出序列
- 【HDOJ 1532】 Drainage Ditches(最大流模板)
- Yii2的安装及简单配置
- 黑马程序员--java基础--面向对象概述
- IOS使用纯C语言创建静态库
- String类与StringBuffer类的研究
- Watch OS 2 Complication开发教程(一)基础(持续连载中)