根号

hdu-4027 Can you answer these queries?

↘锁芯ラ 提交于 2019-11-29 05:09:55
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4027 修改操作是把区间内的所有数开根号 另一个操作是区间求和操作 2 的 63 次开方6,7 根号也就变为了 1 。 #include <iostream> #include <cmath> #include <cstdio> #include <string> #include <cstring> #include <cstdlib> #include <algorithm> #include <stack> #include <set> #include <queue> #include <map> using namespace std; #define ll(ind) (ind<<1) #define rr(ind) (ind<<1|1) #define Mid(a,b) (a+((b-a)>>1)) typedef __int64 LL; const int N = 5020000; LL a[N]; int n, m, b, c, d; struct node { int left, right; int mid() { return Mid(left, right); } LL num; }; struct segtree { node tree[N * 4];

自己yy的一个奇怪东西

馋奶兔 提交于 2019-11-28 06:30:34
散步的时候yy区间最值的不同分块做法,发现单点修改 \(O(\sqrt{n})\) 查询 \(O(1)\) 的做法不是很会? 于是yy了一个奇怪做法,写出来看看。 考虑查询的时候两端的散点可以用前后缀最值查出来,所以只需要考虑中间的块。 中间这些块似乎比较恶心,不知道怎么做。 于是我们把每一个块的最值拎出来作为一个点,再分一次块,就成功地用 \(O(1)\) 的时间把问题变成了根号级别的子问题。 于是分块套分块套分块套……,似乎很对? 如果左右端点都在同一个块内那么不是很好玩,就对每一个块里面也分块,也是一个根号级别的子问题。 于是查询 \(T(n)=T(\sqrt{n})+O(1)=O(1)\) 。 那么修改的时候呢?要更新这一个块里面的分块、更新总体的分块、更新前后缀,好像就是 \(T(n)=2T(\sqrt{n})+\sqrt{n}\) ,也就是 \(O(\sqrt{n})\) 的。 复杂度一脸正确? 来源: https://www.cnblogs.com/p-b-p-b/p/11397441.html

LOJ6281 数列分块入门5

送分小仙女□ 提交于 2019-11-27 11:08:43
LOJ6281 数列分块入门 5 标签 分块入门 前言 无 简明题意 维护序列,需要支持两种操作 区间开根号 区间加 思路 学过线段树的同学肯定都做过用线段树实现区间开根号的题。题目貌似是花神什么什么的 分块做其实跟线段树差不多。注意到2e31的数,开5次根号就变成1了,所以我们直接开一个数组tag[]记录一下每一块还有多少个根号没有开。然后修改操作,对于不在整块的直接开根号,对于在一整块的记录一下tag++。然后查询操作,不整块的直接加,整块的看看是否tag>=5,如果是,那么整块都是1,ans直接加上len。否则对这一块一个个处理就好了。 注意事项 一是一定要注意细节。处理非整块时,记得是用tag[pos[i]],而处理整块时,i就带表块,用tag[i]。 还有一个就是,0开根号后是0,这里要特判一下。总之涉及到开根号就想一下0,要特判。 总结 无 AC代码 #include<cstdio> #include<algorithm> #include<cmath> #include<vector> using namespace std; const int maxn = 1e5 + 10; int n, a[maxn]; int pos[maxn], len, tag[maxn], is_zero[maxn], num[maxn]; void change(int l, int