HDU5239(线段树,找规律,快速乘法)
来源:互联网 发布:javascript基础入门 编辑:程序博客网 时间:2024/05/17 23:24
题意是给n个数,m个询问,每次输出之前的值加上此时询问区间的值,然后区间的数字都平方。
然后发现所有的数字平方到一定次数以后如果继续平方取模就不会变化了,用这个规律可以在线段树节点维护平方次数,大于某一值时可以以后的更新可以直接忽略。
坑点是模数很大,需要把平方转化成类似快速幂的加法。
#include <bits/stdc++.h>using namespace std;#define maxn 111111#define pl c<<1#define pr (c<<1)|1#define lson tree[c].l,tree[c].mid,c<<1#define rson tree[c].mid+1,tree[c].r,(c<<1)|1const unsigned long long mod = 9223372034707292160;int n, q;struct node { int l, r, mid, tt; unsigned long long sum; bool ok;}tree[maxn<<4];unsigned long long a[maxn];unsigned long long mul (unsigned long long a, unsigned long long b) { //b个a相加 if (b == 1) return a%mod; unsigned long long ans = 0; ans = (mul (a, b>>1)<<1) % mod; if (b&1) ans += a; return ans%mod;}void pushup (int c) { if (tree[c].l == tree[c].r) return ; tree[c].sum = (tree[pl].sum%mod+tree[pr].sum%mod)%mod; tree[c].ok = (tree[pl].ok&tree[pr].ok); return ;}void build_tree (int l, int r, int c) { tree[c].l = l, tree[c].r = r, tree[c].mid = (l+r)>>1, tree[c].tt = 0; tree[c].ok = 0; if (l == r) { tree[c].sum = a[l]; if (tree[c].sum == 1 || tree[c].sum == 0) tree[c].ok = 1; return ; } build_tree (lson); build_tree (rson); pushup (c);}void update (int l, int r, int c) { if (tree[c].ok) return ; if (l == r) { tree[c].sum = mul (tree[c].sum, tree[c].sum) % mod; tree[c].tt++; if (tree[c].tt >= 30) tree[c].ok = 1; return ; } update (lson); update (rson); pushup (c);}unsigned long long query (int l, int r, int c, int x, int y) { //cout << "[[" << endl; unsigned long long ans = 0; if (l == x && y == r) { ans = tree[c].sum%mod; update (l, r, c); } else if (tree[c].mid >= y) { ans = query (lson, x, y)%mod; } else if (tree[c].mid < x) { ans = query (rson, x, y)%mod; } else { ans = query (lson, x, tree[c].mid)%mod + query (rson, tree[c].mid+1, y)%mod; } ans %= mod; pushup (c); return ans;}int main () { //freopen ("in", "r", stdin); int t, kase = 0; scanf ("%d", &t); while (t--) { scanf ("%d%d", &n, &q); printf ("Case #%d:\n", ++kase); for (int i = 1; i <= n; i++) { scanf ("%lld", &a[i]); } build_tree (1, n, 1); int x, y; unsigned long long ans = 0; while (q--) { scanf ("%d%d", &x, &y); ans += query (1, n, 1, x, y); ans %= mod; printf ("%lld\n", ans); } } return 0;}
0 0
- HDU5239(线段树,找规律,快速乘法)
- hdu5239Doom 线段树+找规律
- HDU5239.Doom——线段树
- HDU 5239 Doom 线段树+找规律
- hdu1517 找规律/乘法博弈
- hdu5239 Doom(线段树单点更新区间查询+数论)
- HDU5239 Doom(线段树,区间更新,区间平方)
- [Codeforces773E] [线段树] [找规律] Blog Post Rating
- hdu 5084 HeHe (矩阵乘法 找规律)
- 【NOIP2006普及】数列 快速幂+找规律
- hdu 4506(快速幂+找规律)
- hdu 6172 矩阵快速幂 找规律
- hdu6198(矩阵快速幂+找规律)
- 【找规律 && 快速幂 && 概率论】LightOJ
- POJ——2506(找规律加大数乘法 )
- hdu 6198 dfs枚举找规律+矩阵乘法
- ZOJ 3886 Nico Number(线段树单点更新+找规律)
- Codeforces Round #316 (Div. 2) C. Replacement 找规律 或 线段树
- Cocos2D v2.0至v3.x简洁转换指南(一)
- js中的ioc体现
- 单例模式——C++实现线程安全的单例
- 10.13NOIP模拟赛
- 安装包立减1M--微信Android资源混淆打包工具
- HDU5239(线段树,找规律,快速乘法)
- 移动硬盘挂载后访问权限修改
- 在PCL中使用直通滤波器对点云进行滤波处理
- poj 1017 Packets
- 图文解释XCode常用快捷键的使用
- 编程资料
- poj 1163__The Triangle(dp)
- ARM64的启动过程之(二):创建启动阶段的页表
- 增加字段改为主键后:1062-Duplicate entry '' for key 'PRIMARY'