题目链接 简易CDQ分治教程 //每个操作分解为一个有序数对(t,p),即(时间,操作位置),时间默认有序,用CDQ分治处理第二维 //对于位置相同的操作 修改优先于查询 //时间是默认有序的 所以可以忽略掉对操作的影响:有影响的只是位置.(再理解) #include <cstdio> #include <cctype> #define gc() getchar() //typedef long long LL; const int N=5e5+5; int n,m,Ans[N];…
题面传送门 首先学过树状数组的应该都知道,将树状数组方向写反等价于前缀和 \(\to\) 后缀和,因此题目中伪代码的区间求和实质上是 \(sum[l-1...n]-sum[r...n]=sum[l-1...r-1]\),我们要求 \(sum[l...r]=sum[l-1...r-1]\) 的概率,等价于求 \(a_{l-1}=a_r\) 的概率. 因此我们可将题目转化为,每次从 \([l,r]\) 中随机选择一个数将其状态翻转,并询问 \(a_x=a_y\) 的概率. 这个可以通过二维线段树解决…
BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为询问与格子(x,y)的曼哈顿距离不超过z的格子值的和. (1 ≤ n ≤10 000, 1 ≤ m ≤ 80 000)  题解 这道题如果数据不大,那就可以直接用二维的树状数组来做. 方法1:二维树状数组 因为数据比较大,所以要离线处理并且离散化一下修改的值,再用二维树状数组: 查询的是菱形,我们把…
题链: https://www.luogu.org/problemnew/show/P3688题解: 二维线段树. 先不看询问时l=1的特殊情况. 对于一个询问(l,r),如果要让错误的程序得到正确答案, 显然应该满足l-1位置的值=r位置的值(或者说两个位置的异或值为0). 那么定义二元组函数f(x,y)表示x位置与y位置的异或值为0的概率. 如果可以维护出所有这样的二元组的函数值, 对于一个询问的话,就可以很方便的回答了. 现在看看,怎样维护这样的二元组的函数值. 假设现在给出了一个操作1:…
传送门 拿个二维偏序练练cdq板子,其实就和归并排序差不多,复杂度不太会,似乎nlogn?. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; ; ; typedef long long LL; inline LL rd(){ LL x=,f=;char ch=getchar(); :;ch=getchar();} )+(x…
闲来无事(其实是打了两三道树状数组题),写了个树状数组模板…… /* Author: hotwords */ template<typename tp> class BinTree { private: int n;tp *a; public: inline int lowbit(int x)const{return x&-x;} int size()const{return n;} void empty() { if(a) delete []a; n=;a=; } void clea…
HDU1166 上好的线段树模板&&树状数组模板 自己写的第一棵线段树&第一棵树状数组 莫名的兴奋 线段树: #include <cstdio> using namespace std; int cases,n,tree[200500],ql,qr; char s[50]; void build(int l,int r,int num){ if(l==r){scanf("%d",&tree[num]);return;} int mid=(l+…
题目:已知一个数列,你需要进行下面两种操作:1.将某一个数加上x:2.求出某区间每一个数的和. 解法:树状数组求前缀和. #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; ; int n; int c[N]; int lowbit(int x) {return x&-x;} void ins(int x,int d)…
题目:已知一个数列,你需要进行下面两种操作:1.将某区间每一个数数加上x:2.求出某一个数的和. 解法:树状数组+前缀和优化.数组中每位存和前一位的数的差,这样区间修改只用改两位,单点询问就是求前缀和. #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; ; int n; int c[N]; int lowbit(int x)…
题目:http://poj.org/problem?id=2299 只能相邻两个交换,所以交换一次只会减少一个逆序对.所以交换次数就是逆序对数. ps:原来树状数组还可以记录后边lowbit位的部分和.见代码. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 500005 using namespace std; int n,f[ma…
BZOJ 2738 "矩阵乘法"(子矩阵第k大) 题意 给出一个矩阵,多次询问子矩阵中第k大的数是多少. 题解 我做这道题之前先照着这道题出了一道题,是这道题的一维版本,在这里:https://vijos.org/d/contest/p/5a26541bd3d8a11cef1706aa. 思路是这样的:二分答案mid,将所有小于mid的位置都在树状数组上 +1,对于每个询问,如果子矩阵所有"+1"之和 >= 这个询问的k,则把询问划分到"左边那一组&…
Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The squares form an S * S matrix with the rows and columns numbered from 0 to S-1. Each square contains a base sta…
洛谷题面传送门 咦?鸽子 tzc 竟然来补题解了?incredible( 首先看到这样类似于路径统计的问题我们可以非常自然地想到点分治.每次我们找出每个连通块的重心 \(x\) 然后以 \(x\) 为根 DFS 一遍整个子树,我们假设 \(y\) 到 \(x\) 的距离为 \(dep_y\),\(x\to y\) 这一段上颜色的权值之和为 \(sum_y\),那么考虑怎样合并两条路径.显然对于两个在 \(x\) 不同子树内的点 \(y,z\),\(y\to z\) 路径上边的个数就是 \(dep…
题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=bv[in[l]]%mod; 忘了要用反映射搞一下...... 树链剖分,从每个节点的儿子中,找出子树最大的一个作为重儿子. 然后以此将树链分成轻链和重链. 之后dfs一遍求出树链剖分序. 树链剖分序不仅保证子树内节点的编号在序列上连续,还保证一条重链上的节点的编号连续. 用一个线段树维护一下. 更改…
链接 luogu 思路 可耐我连cdq都不会,Orz 陈丹琦 代码 #include <bits/stdc++.h> using namespace std; const int N = 5e5 + 7; int read() { int x = 0, f = 1; char s = getchar(); for (;s > '9' || s < '0'; s = getchar()) if (s == '-') f = -1; for (;s >= '0' &&am…
P3374 [模板]树状数组 1 cdq分治 刚学了cdq分治(dyf神犇强力安利下),发现可以做这种题,当然是来试水了(逃 cdq好像只能离线的样子 cdq分治(转) 以下是摘录的几句: 在合并的时候,我们只处理左区间的修改,只统计右区间的查询 因为左区间的修改一定可以影响右区间的查询 这就体现出了CDQ分治的基本思想了 我们把所有操作都记录到了一个数组中,所以数组的大小至少要开到500000*3 过程: 按操作顺序读入--->按位置从小到大归并排序(这样可以保证每个询问操作进行前,都只有位置…
题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1…
题意:给2个数字序列 a 和 b ,问按从小到达排序后,a中的哪些子串与b的名次匹配. a 的长度 N≤100,000,b的长度 M≤25,000,数字的大小 K≤25. 解法:[思考]1.X 暴力.枚举 a 中的子串,选出来排序后比对名次.O(n*  m log m  *m)=O(n*m^2*log m).    2.X  暴力+树状数组优化.枚举 a 中的子串,选出来后比较前缀名次(P.S.这种转化常出现,比如:[洛谷 p3368]模板-树状数组 2(数据结构) 就是将个体转化为前缀.),看…
经典问题:二维偏序.给定平面中的n个点,求每个点左下方的点的个数. 因为 所有点已经以y为第一关键字,x为第二关键字排好序,所以我们按读入顺序处理,仅仅需要计算x坐标小于<=某个点的点有多少个就行. 这就是所说的:n维偏序,一维排序,二维树状数组,三维 分治 Or 树状数组套平衡树…… <法一>树状数组. #include<cstdio> #include<algorithm> #include<iostream> using namespace st…
P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:…
P3374 [模板]树状数组 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3个整数,表示一个操作,具体如下: 操作1: 格式:1 x k 含义:将第x个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 输出格式 输出包含若干行整数,即为所有…
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x k 含义:将第x个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 输出格式: 输出包含若干行整数,即为所有操作2的结果…
一维树状数组的作用主要是单点修改,单点查询,区间修改,区间查询. 模板1是单点修改,区间查询:模板2是单点查询,区间修改. 模板1: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 500000+10 using namespace std; inline int read() { ; ; char c=getchar(); ; )+…
题目链接 https://www.luogu.org/problemnew/show/P3374 树状数组 树状数组最基本的就是求区间和. 维护: 空间复杂度:O(n) 时间复杂度(区间和,单点修改): 修改:O(logn) 查询:O(logn) 用c[i]表示(i-lowbit[i]+1,i)区间的和. 查询时,用到前缀和的思想,(i,j)=c[j]-c[i-1]. 优点 代码简单 缺点 难理解 代码(解析) #include<iostream> #include<cstdio>…
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x k 含义:将第x个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 输出格式: 输出包含若干行整数,即为所有操作2的结果…
图片来自度娘~~ 树状数组形如上图,是一种快速查找区间和,快速修改的一种数据结构,一个查询和修改复杂度都为log(n),树状数组1和树状数组2都是板子题,在这里进行详解: 求和: 首先我们看一看这个图’ A数组对应各个元素的值,c数组用来求和和修改. 有连线代表着此节点的值为连线下全部子节点的和such as   c[4]=c[2]+c[3]+A[4]=A[1]+A[2]+A[3]+A[4]; 貌似没有什么神仙规律......小学找规律题都不会了嘤嘤嘤 那么我们看一下: C1 = A1 对应的:…
洛谷题目传送门 emm...题目名写了个平衡树,但是这道题的理论复杂度最优解应该还是树状数组套值域线段树吧. 就像dynamic ranking那样(蒟蒻的Sol,放一个link骗访问量233) 所有的值(包括初始a数组,操作1.3.4.5的k)全部先丢进去离散化 对于1操作查比它小的数,挑log棵线段树,找区间小于这个数的个数+1,这个还比较好像 操作2就是dynamic ranking,log棵线段树一起加减,像静态主席树求第k小一样跳,操作3 dynamic ranking里也有 操作4先…
P3368 [模板]树状数组 2 102通过 206提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式…
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x 含义:输出第x个数的值 输出格式: 输出包含若干行整数,即为所有操作2的结…
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3个整数,表示一个操作,具体如下: 操作1: 格式:1 x k 含义:将第x个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 输出格式: 输出包含若干行整数,即为所有操作2的结果.…