归并树,与我们原学过的归并排序是一样的原理,但是在那个的基础上进行扩展应用。首先每个节点储存了它每个节点所代表的点的有序序列,还有就是每个点里面包含的所有的b[i]在左右子树的排名辅助更新数据,还有一个用来记录当前节点a[] >b[] 的数量的num。这时候查询的话就是线段树查询了,然后更新,首先求出要更新进去的点在原本数组的排名,然后就可以将该数据更新进去范围里面的lazy数组了,那么这时候lazy数组怎么使用?其实你这个lazy数组就是你更新进来的数据在确定范围内的一个排名,那么你这个排名就是a[] > b[] 的数量了。当然不可能更新所有的节点,所以需要使用lazydown的方法优化时间。

#include<bits/stdc++.h>
#define debug 0
#define Lson (rt << 1)
#define Rson ((rt << 1) | 1)
#define M ((l + r) / 2) using namespace std; const long long mod = 1e9 + ;
const int maxn = ; int T, n, m, ans, last, cnt, L, R, X;
int a[maxn], b[maxn], st[maxn * ], en[maxn * ], lazy[maxn * ], num[maxn * ];
int pl[maxn * ], pr[maxn * ], pool[maxn * ]; void Build(int l, int r, int rt){
lazy[rt] = -;
if(l == r){
st[rt] = ++cnt;en[rt] = cnt;
pool[cnt] = b[l];
num[rt] = (a[l] >= b[l]);
return ;
}
Build(l, M, Lson);Build(M + , r, Rson);
num[rt] = num[Lson] + num[Rson];
int leftL = st[Lson], leftR = en[Lson];
int rightL = st[Rson], rightR = en[Rson]; st[rt] = cnt + ;
while(leftL <= leftR && rightL <= rightR)pool[++cnt] = ((pool[leftL] <= pool[rightL]) ? pool[leftL ++] : pool[rightL ++]);
while(leftL <= leftR)pool[++cnt] = pool[leftL ++];
while(rightL <= rightR)pool[++cnt] = pool[rightL ++];
en[rt] = cnt; leftL = st[Lson], rightL = st[Rson];
for(int i = st[rt]; i <= en[rt]; i ++){
while(leftL <= leftR && pool[leftL] <= pool[i]) leftL ++;
while(rightL <= rightR && pool[rightL] <= pool[i]) rightL ++;
pl[i] = leftL - ; pr[i] = rightL - ;
if(pl[i] < st[Lson]) pl[i] = ;
if(pr[i] < st[Rson]) pr[i] = ;
}
} void Lazy(int rt, int pos){
num[rt] = pos ? pos - st[rt] + : ;
lazy[rt] = pos;
} void Pushdown(int rt){
if(lazy[rt] == -) return ;
int pos = lazy[rt];
Lazy(Lson, pl[pos]);
Lazy(Rson, pr[pos]);
lazy[rt] = -;
} int erfen(int x){
int l = st[], r = en[], ans = ;
while(l <= r){
if(pool[M] <= x){ ans = M; l = M + ;}
else r = M - ;
}
return ans;
} void query(int l, int r, int rt){
if(L <= l && r <= R){
last += num[rt];
return ;
}
Pushdown(rt);
if(L <= M) query(l, M, Lson);
if(R > M) query(M + , r, Rson);
num[rt] = num[Lson] + num[Rson];
} void Update(int l, int r, int pos, int rt){
if(L <= l && r <= R){
Lazy(rt, pos);return ;
}
Pushdown(rt);
if(L <= M) Update(l, M, pl[pos], Lson);
if(R > M) Update(M + z1, r, pr[pos], Rson);
num[rt] = num[Lson] + num[Rson];
} int AA,BB,CC = ~(<<),MM = (<<) - ;
int rnd(){
AA = ( + (last >> )) * (AA&MM) + (AA >> );
BB = ( + (last >> )) * (BB&MM) + (BB >> );
return (CC & ((AA << ) + BB)) % ;
} int main(){
int n,m;
scanf("%d", &T);while(T --){
ans = last = cnt = ;
scanf("%d%d%d%d", &n, &m, &AA, &BB);
for(int i = ; i <= n; i ++) scanf("%d",&a[i]);
for(int i = ; i <= n; i ++) scanf("%d",&b[i]);
Build(, n, ); for(int i = ; i <= m; i ++){
L = rnd()%n + ; R = rnd()%n + ; X = rnd() + ;
if(L > R)swap(L, R);
if((L + R + X) & )
Update(, n, erfen(X), );
else{
last = ;
query(, n, );
ans = (1LL * i * last % mod + ans) % mod;
}
}
printf("%d\n",ans);
}
return ;
}

Differencia (归并树)的更多相关文章

  1. HDU 5737 Differencia(归并树)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5737 [题目大意] 给出两个序列a和b,要求实现两个操作: 1. 将a序列的一个区间中的所有数改成 ...

  2. POJ2104 K-th Number(归并树)

    平方分割一直TLE,最后用归并树处理过了,使用STL会比较慢. #include<cstdio> #include<iostream> #include<cstdlib& ...

  3. K-th Number 线段树(归并树)+二分查找

    K-th Number 题意:给定一个包含n个不同数的数列a1, a2, ..., an 和m个三元组表示的查询.对于每个查询(i, j, k), 输出ai, ai+1, ... ,aj的升序排列中第 ...

  4. 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

    如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...

  5. POJ 2014.K-th Number 区间第k小 (归并树)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 57543   Accepted: 19893 Ca ...

  6. hdu 4417,poj 2104 划分树(模版)归并树(模版)

    这次是彻底把划分树搞明确了,与此同一时候发现了模版的重要性.敲代码一个字符都不能错啊~~~ 划分树具体解释:点击打开链接 题意:求一组数列中随意区间不大于h的个数. 这个题的做法是用二分查询  求给定 ...

  7. SPOJ:K-Query Online(归并树)

    Given a sequence of n numbers a1, a2, ..., an and a number of k-queries. A k-query is a triple (i, j ...

  8. 静态区间第k大(归并树)

    POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...

  9. POJ 2104 K-th Number(区间第k大数)(平方切割,归并树,划分树)

    题目链接: http://poj.org/problem? id=2104 解题思路: 由于查询的个数m非常大.朴素的求法无法在规定时间内求解. 因此应该选用合理的方式维护数据来做到高效地查询. 假设 ...

随机推荐

  1. falsk 与 django 过滤器的使用与区别

    1,flask中内置的过滤器模板中常用方法: {#过滤器调用方式{{变量|过滤器名称}} #} <!-- safe过滤器,可以禁用转义 --> {{'<strong>hello ...

  2. 1、python同级目录及子目录模块引入

    2个模块在同一个包内时(即引入和被引入的2个py文件在同一个目录下),直接引入模块名 1.引入与被引入模块或包在同一目录下时,直接引入模块名或者包名import modulename.py或者impo ...

  3. canvas将图片转成base64格式 以及 验证图片是否透明

    logoImgUpload:function(file) { let self = this; self.formatUpload(file); let reader = new FileReader ...

  4. 【Python基础】安装python第三方库

    pip命令行安装(推荐) 打开cmd命令行 安装需要的第三方库如:pip install numpy 在安装python的相关模块和库时,我们一般使用“pip install  模块名”或者“pyth ...

  5. project proposal写作框架

    主要有八个因素: 背景(Your Background):对于proposal有意义的要点,如国家职业证书.技能.经验.能力和实习经历等. 大纲(Outline Proposal):描述你明确的感兴趣 ...

  6. 第 9 章 DOM 的增删改查

    DOM 的增删改查 本文不会详细讲解,只是简单提及知识要点,详细可以参考<dom高级编程>. 1. document.write document.write('<h1>创建节 ...

  7. webpack浅析~

    1.webpack打包原理: 把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载. 2.webpack的优势: ①.webpack 是以 commonJS 的形式来书写脚 ...

  8. jQuery 学习笔记(2)(jQuery静态方法)

    jQuery静态方法 1.$.each() 和 $.map()  既可以遍历数组也可以遍历伪数组 $.each(arr, function(value, index) { ... } ) $.map( ...

  9. kvo观察实例变量

    // 手动设定KVO - (void)setAge:(NSString *)age { [self willChangeValueForKey:@"age"]; _age = ag ...

  10. 同一局域网运行两套LVS

    两套LVS的ID必须不一致 ,原文:  http://blog.chinaunix.net/uid-29578485-id-5671910.html 在LVS服务器中修改配置文件 vi /etc/ke ...