【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5737

【题目大意】

  给出两个序列a和b,要求实现两个操作:

  1. 将a序列的一个区间中的所有数改成同一个数

  2. 查询一个区间内a数组中大于相同下标b数组中的数的数。

【题解】

  考虑到b数组是不变的,可以在归并树上预处理出b数组中每个元素在树的左右儿子中的排名,在归并树建立时,可以求出每个区间ai>bi的个数,在发生区间修改的时候,在根节点的有序的b数组中二分查找修改值的排名,将信息下传就可以统计每个区间ai>bi的数目,由于操作具有区间性质,因此可以打延迟标记。查询时下传标记统计答案即可。

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100010,M=300000,U=2000000,mod=1e9+7;
int T,n,m,ans,a[N],b[N],A,B,C=~(1<<31),L,R,x,Ans;
int st[M],en[M],v[M],tag[M],l[U],r[U],seq[U],cnt;
void addtag(int x,int p){v[x]=p?p-st[x]+1:0;tag[x]=p;}
void pb(int x){
if(tag[x]<0)return;
addtag(x<<1,l[tag[x]]);addtag(x<<1|1,r[tag[x]]);
tag[x]=-1;
}
void build(int x,int a,int b){
tag[x]=-1;
if(a==b){st[x]=++cnt;seq[cnt]=::b[a];en[x]=cnt;v[x]=::a[a]>=::b[a];return;}
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
v[x]=v[x<<1]+v[x<<1|1];
int al=st[x<<1],ar=en[x<<1],bl=st[x<<1|1],br=en[x<<1|1];
st[x]=cnt+1;
while(al<=ar&&bl<=br)seq[++cnt]=seq[al]<seq[bl]?seq[al++]:seq[bl++];
while(al<=ar)seq[++cnt]=seq[al++];
while(bl<=br)seq[++cnt]=seq[bl++];
en[x]=cnt;
al=st[x<<1],bl=st[x<<1|1];
for(int i=st[x];i<=cnt;i++){
while(al<=ar&&seq[al]<=seq[i])al++;
while(bl<=br&&seq[bl]<=seq[i])bl++;
l[i]=al-1;r[i]=bl-1;
if(l[i]<st[x<<1])l[i]=0;
if(r[i]<st[x<<1|1])r[i]=0;
}
}
void change(int x,int a,int b,int p){
if(L<=a&&b<=R){addtag(x,p);return;}pb(x);
int mid=(a+b)>>1;
if(L<=mid)change(x<<1,a,mid,l[p]);
if(R>mid)change(x<<1|1,mid+1,b,r[p]);
v[x]=v[x<<1]+v[x<<1|1];
}
void ask(int x,int a,int b){
if(L<=a&&b<=R){ans+=v[x];return;}pb(x);
int mid=(a+b)>>1;
if(L<=mid)ask(x<<1,a,mid);
if(R>mid)ask(x<<1|1,mid+1,b);
v[x]=v[x<<1]+v[x<<1|1];
}
int lower(int x){
int l=st[1],r=en[1],pos=0;
while(l<=r){
int mid=(l+r)>>1;
if(seq[mid]<=x)pos=mid,l=mid+1;
else r=mid-1;
}return pos;
}
int rnd(){
A=(36969+(ans>>3))*(A&65535)+(A>>16);
B=(18000+(ans>>3))*(B&65535)+(B>>16);
return(C&((A<<16)+B))%1000000000;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&n,&m,&A,&B);
for(int i=1;i<=n;i++)scanf("%d",a+i);
for(int i=1;i<=n;i++)scanf("%d",b+i);
cnt=Ans=ans=0; build(1,1,n);
for(int i=1;i<=m;i++){
L=rnd()%n+1,R=rnd()%n+1,x=rnd()+1;
if(L>R)swap(L,R);
if((L+R+x)&1)change(1,1,n,lower(x));
else{
ans=0; ask(1,1,n);
Ans=(1LL*ans*i+Ans)%mod;
}
}printf("%d\n",Ans);
}return 0;
}

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

  1. Differencia (归并树)

    归并树,与我们原学过的归并排序是一样的原理,但是在那个的基础上进行扩展应用.首先每个节点储存了它每个节点所代表的点的有序序列,还有就是每个点里面包含的所有的b[i]在左右子树的排名辅助更新数据,还有一 ...

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

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

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

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

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

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

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

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

  6. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  7. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

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

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

随机推荐

  1. Git 系列(一):什么是 Git

    欢迎阅读本系列关于如何使用 Git 版本控制系统的教程!通过本文的介绍,你将会了解到 Git 的用途及谁该使用 Git. 如果你刚步入开源的世界,你很有可能会遇到一些在 Git 上托管代码或者发布使用 ...

  2. javascript自定义日期函数

    1.格式化日期(YYYY-MM-DD) 代码: var DateFormat = function (date) { if (!(date instanceof Date)) { date = dat ...

  3. 自学HTML5第四节(canvas画布详解)

    canvas画布好像可是说是HTML5的精华了,一定要学好,嗯嗯,绚丽的东西就要从基础的开始.... 先看看啥玩意叫做canvas 什么是 Canvas? HTML5 的 canvas 元素使用 Ja ...

  4. PHP MySql数据库访问

    PHP MySql数据库访问 计应134   凌豪 1.MySql数据库的连接 要操作MySql数据库,首先必须与MySQl数据库建立连接,连接MySQL服务器的语句如下: <?php$link ...

  5. Zend Studio 12 大集合

    前言 本文记录了我个人使用Zend Studio 12的点点滴滴,不定时更新. 内容来源于网络,如有侵权,告知后可删除. 下载 官方链接点击链接,填入相关信息即可下载. 破解 声明:请购买正版,非万不 ...

  6. [原创]obj-c编程17:键值观察(KVO)

    原文链接:[原创]obj-c编程17:键值观察(KVO) 系列专栏链接:objective-c 编程系列 说完了前面一篇KVC,不能不说说它的应用KVO(Key-Value Observing)喽.K ...

  7. str系列---字符串函数

    1. strcat extern char *strcat(char *dest,char *src); 把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'. 返回指 ...

  8. OSG中的几何体

    osg::Shape类 继承自osg::Object类: osg::Shape类是各种内嵌几何体的基类,不但可以用于剔除和碰撞检测,还可用于生成预定义的几何体对象: 常见的内嵌几何体包括: osg:: ...

  9. Vmware 克隆CentOS 网络IP配置

    在VMware里克隆出来的CentOS Linux.. ifconfig...没有看到eth0..然后重启网卡又报下面错误. 故障现象: service network restart Shuttin ...

  10. Python核心编程笔记----注释

    python 中注释有两种 第一种,文档注释 第二种,一般的注释 下面是例子: class MyClass: '这个是文档注释' def __repr__(self): return "re ...