Codeforces 1109E Sasha and a Very Easy Test 线段树
时间:2019-10-15
本文章向大家介绍Codeforces 1109E Sasha and a Very Easy Test 线段树,主要包括Codeforces 1109E Sasha and a Very Easy Test 线段树使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
因为mod不是质数, 所以要处理一下除的操作, 考虑吧mod分解质因数, 然后把所有数都按mod
分解出来的质因数进行拆分, 然后就能维护了。
#include<bits/stdc++.h> #define LL long long using namespace std; const int N = (int)1e5 + 7; int mod; struct Bit { int a[N]; inline void modify(int x, int v) { for(int i = x; i < N; i += i & -i) { a[i] += v; } } int sum(int x) { int ans = 0; for(int i = x; i; i -= i & -i) { ans += a[i]; } return ans; } }; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 struct SegmentTree { int sum[N << 2]; int lazy[N << 2]; inline void pull(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; if(sum[rt] >= mod) sum[rt] -= mod; } inline void push(int rt) { if(lazy[rt] != 1) { sum[rt << 1] = 1LL * sum[rt << 1] * lazy[rt] % mod; sum[rt << 1 | 1] = 1LL * sum[rt << 1 | 1] * lazy[rt] % mod; lazy[rt << 1] = 1LL * lazy[rt << 1] * lazy[rt] % mod; lazy[rt << 1 | 1] = 1LL * lazy[rt << 1 | 1] * lazy[rt] % mod; lazy[rt] = 1; } } void build(int l, int r, int rt) { lazy[rt] = 1; if(l == r) { sum[rt] = 1; return; } int mid = l + r >> 1; build(lson); build(rson); pull(rt); } void update(int L, int R, int val, int l, int r, int rt) { if(R < l || r < L || R < L) return; if(L <= l && r <= R) { sum[rt] = 1LL * sum[rt] * val % mod; lazy[rt] = 1LL * lazy[rt] * val % mod; return; } push(rt); int mid = l + r >> 1; update(L, R, val, lson); update(L, R, val, rson); pull(rt); } void update2(int p, int val, int l, int r, int rt) { if(l == r) { sum[rt] = val; return; } push(rt); int mid = l + r >> 1; if(p <= mid) update2(p, val, lson); else update2(p, val, rson); pull(rt); } int query(int L, int R, int l, int r, int rt) { if(R < l || r < L || R < L) return 0; if(L <= l && r <= R) return sum[rt]; push(rt); int mid = l + r >> 1; return (query(L, R, lson) + query(L, R, rson)) % mod; } }; int n, q, a[N]; SegmentTree real_val, inv_val; Bit bit[10]; int mul_val[N]; vector<int> F, C; vector<int> V[N]; int power(int a, int b) { int ans = 1; while(b) { if(b & 1) ans = 1LL * ans * a % mod; a = 1LL * a * a % mod; b >>= 1; } return ans; } void mul_modify(int L, int R, int val) { if(val == 1) return; inv_val.update(L, R, mul_val[val], 1, n, 1); real_val.update(L, R, val, 1, n, 1); for(int i = 0; i < V[val].size(); i++) { if(!V[val][i]) continue; bit[i].modify(L, V[val][i]); bit[i].modify(R + 1, -V[val][i]); } } int ex_gcd(int a, int b, int &x, int &y) { if(b == 0) { x = 1; y = 0; return a; } int r = ex_gcd(b, a % b, x, y); int t = x; x = y; y = t - a / b * y; return r; } int inv(int a, int mod) { int d, x, y; d = ex_gcd(a, mod, x, y); if(d == 1) return (x % mod + mod) % mod; else assert(0); } void div_modify(int p, int val) { if(val == 1) return; for(int i = 0; i < V[val].size(); i++) { if(!V[val][i]) continue; bit[i].modify(p, -V[val][i]); bit[i].modify(p + 1, V[val][i]); } int gg = 1; for(int i = 0; i < F.size(); i++) { gg = 1LL * gg * power(F[i], bit[i].sum(p)) % mod; } int nex_inv = 1LL * inv_val.query(p, p, 1, n, 1) * inv(mul_val[val], mod) % mod; inv_val.update2(p, nex_inv, 1, n, 1); if(gg) real_val.update2(p, 1LL * nex_inv * gg % mod, 1, n, 1); } int query(int L, int R) { return real_val.query(L, R, 1, n, 1); } void show() { puts(""); for(int i = 1; i <= n; i++) { printf("%d ", real_val.query(i, i, 1, n, 1)); } puts(""); } int main() { scanf("%d%d", &n, &mod); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); real_val.build(1, n, 1); inv_val.build(1, n, 1); int tmp = mod; for(int i = 2; i * i <= tmp; i++) { if(tmp % i) continue; F.push_back(i); int cnt = 0; while(tmp % i == 0) { cnt++; tmp /= i; } C.push_back(cnt); } if(tmp > 1) F.push_back(tmp), C.push_back(1); for(int i = 2; i <= 100000; i++) { mul_val[i] = i; for(auto &t : F) { while(mul_val[i] % t == 0) { mul_val[i] /= t; } } } for(int i = 2; i <= 100000; i++) { for(int j = 0; j < F.size(); j++) { int cnt = 0, now = i; while(now % F[j] == 0) { cnt++; now /= F[j]; } V[i].push_back(cnt); } } for(int i = 1; i <= n; i++) { mul_modify(i, i, a[i]); } scanf("%d", &q); while(q--) { int op; scanf("%d", &op); if(op == 1) { int l, r, x; scanf("%d%d%d", &l, &r, &x); mul_modify(l, r, x); } else if(op == 2) { int p, x; scanf("%d%d", &p, &x); div_modify(p, x); } else { int l, r; scanf("%d%d", &l, &r); printf("%d\n", query(l, r)); } } return 0; } /* */
原文地址:https://www.cnblogs.com/CJLHY/p/11681600.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法