题意:给2组数据a和b数组,每次有2种操作:(+,l,r,x)把a数组第l个到第r个元素全置为x,(?,l,r)查询[l,r]之间哪些位置满足a[i]>=b[i](i>=l && i<=r)并把这些位置的数量统计

一直想很久,没想到什么有效的方案,直到看到题解才明白过来,原来线段树套平衡树还有这种情况:里面其实不是平衡树,只是有序表。

然后这题就转换为区间查找数对应排名

由于此题不用对2个数组都修改,其中1个b树可作为固定的线段树套有序表以节省时间,另外1个表a树则单纯使用线段树的方法先修改,再更新对应b树结点的排名

这里查找排名如果全部logn查找会因为常数太大直接卡,注意每个结点都含有序表并且上下有包含关系

那咱们可以在b树自底向上更新父结点排名对应左右子树里的排名,用归并排序的方法,占用空间才o(nlogn),时间也是o(nlogn)

顺带把会改变的a树1个个结点查询b树查出排名,修改时先查出根结点对应位置,再根据位置子树表一边向下更新一边转移到子树对应位置

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
typedef __int64 ll;
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int cnt;
const int N=,M=,E=;
int n,m,i,a[N],b[N],x,l,r;
int st[M],en[M],v[M],tag[M],pl[E],pr[E],pool[E],cur;
ll ans,sum; void build(int x,int l,int r)
{
tag[x]=-;
if(l==r)
{
st[x]=cur+;
pool[++cur]=b[l];
en[x]=cur;
v[x]=(a[l]>=b[l]);
return;
}
int mid=((l+r)>>);
build(x<<,l,mid);
build((x<<)|,mid+,r);
v[x]=v[x<<]+v[(x<<)|];
int al=st[x<<],ar=en[x<<],bl=st[(x<<)|],br=en[(x<<)|];
st[x]=cur+;
while(al<=ar&&bl<=br)pool[++cur]=pool[al]<pool[bl]?pool[al++]:pool[bl++];
while(al<=ar)pool[++cur]=pool[al++];
while(bl<=br)pool[++cur]=pool[bl++];
en[x]=cur;
al=st[x<<],bl=st[x<<|];
for(int i=st[x];i<=cur;i++)
{
while(al<=ar&&pool[al]<=pool[i])al++;
while(bl<=br&&pool[bl]<=pool[i])bl++;
pl[i]=al-,pr[i]=bl-;
if(pl[i]<st[x<<])pl[i]=;
if(pr[i]<st[(x<<)|])pr[i]=;
}
} inline void rankpt(int x,int p)
{
v[x]=(p?p-st[x]+:);
tag[x]=p;
}
inline void pushdown(int x)
{
if(tag[x]<)return;
int p=tag[x];
rankpt(x<<,pl[p]);
rankpt((x<<)|,pr[p]);
tag[x]=-;
} void update(int x,int a,int b,int p)
{
if(l<=a && b<=r){rankpt(x,p);return;}
pushdown(x);
int mid=(a+b)>>;
if(l<=mid)update(x<<,a,mid,pl[p]);
if(r>mid)update((x<<)|,mid+,b,pr[p]);
v[x]=v[x<<]+v[(x<<)|];
} void query(int x,int a,int b)
{
if(l<=a && b<=r)
{
ans+=v[x];
return;
}
pushdown(x);
int mid=((a+b)>>);
if(l<=mid)query(x<<,a,mid);
if(r>mid)query((x<<)|,mid+,b);
v[x]=v[x<<]+v[(x<<)|];
} inline int lower(int x){
//lower_bound(pool+st[1],pool+ed[1]+1,x);
int l=st[],r=en[],mid,t=;
while(l<=r)
if(pool[mid=(l+r)>>]<=x)l=(t=mid)+;
else r=mid-;
return t;
} int seeda, seedb, C = ~(<<), MM = (<<)-;
int rnd(int last) {
seeda = ( + (last >> )) * (seeda & MM) + (seeda >> );
seedb = ( + (last >> )) * (seedb & MM) + (seedb >> );
return (C & ((seeda << ) + seedb)) % ;
} int main()
{
int t,ku;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&n,&m,&seeda,&seedb);
for(i=;i<=n;i++)scanf("%d",a+i);
for(i=;i<=n;i++)scanf("%d",b+i);
ans=sum=cur=;
build(,,n);
for(i=;i<=m;i++)
{
l=rnd(ans)%n+,r=rnd(ans)%n+,ku=rnd(ans)+;
int kkk=lower(ku);
if(l>r)l^=r^=l^=r;
if((l+r+ku)&)update(,,n,lower(ku));
else
{
ans=;
query(,,n);
sum=(sum+(ll)i*ans)%;
}
}
printf("%I64d\n",sum);
}
return ;
}

hdu5737(2016多校联赛第2场D)的更多相关文章

  1. 2016 多校联赛7 Elegant Construction

    Being an ACMer requires knowledge in many fields, because problems in this contest may use physics, ...

  2. 2016 多校联赛7 Joint Stacks (优先队列)

    A stack is a data structure in which all insertions and deletions of entries are made at one end, ca ...

  3. 2016 多校联赛7 Balls and Boxes(概率期望)

    Mr. Chopsticks is interested in random phenomena, and he conducts an experiment to study randomness. ...

  4. HDU 4627 The Unsolvable Problem 杭电多校联赛第三场1009 数学题

    题意描述:给出一个n,要求在所有满足n = a+b的a和b里面求a和b的最小公倍数最大的两个数的最小公倍数. 解题报告:比赛的时候看到这个题的第一反应就是寻找这两个数一定是在a和b比较接近的地方找,这 ...

  5. HDU 4639 hehe 杭电2013多校联赛第四场1008题

    解题报告:题目的意思是输入一个字符串,并规定,里面的“hehe”可以用"wqnmlgb"来代替,也可以不代替,问输入的这个字符串在经过相关的代替之后可以有多少种不同的形态.先打一个 ...

  6. 2018HDU多校联赛第六场 6373 Pinball——水题&&物理题

    题意 给定一个斜面,从某处让一个小球作自由落体运动,求小球与斜面的碰撞次数(假设都为弹性碰撞). 分析 题图如下,x轴.y轴是虚拟的. 根据高中物理的套路,沿斜面方向分解重力加速度即可. #inclu ...

  7. 2015 HDU 多校联赛 5363 Key Set

    2015 HDU 多校联赛 5363 Key Set 题目: http://acm.hdu.edu.cn/showproblem.php? pid=5363 依据前面给出的样例,得出求解公式 fn = ...

  8. 2015 HDU 多校联赛 5317 RGCDQ 筛法求解

    2015 HDU 多校联赛 5317 RGCDQ 筛法求解 题目  http://acm.hdu.edu.cn/showproblem.php? pid=5317 本题的数据量非常大,測试样例多.数据 ...

  9. 【杂题总汇】HDU多校赛第十场 Videos

    [HDU2018多校赛第十场]Videos 最后一场比赛也结束了…… +HDU传送门+ ◇ 题目 <简要翻译> 有n个人以及m部电影,每个人都有一个快乐值.每场电影都有它的开始.结束时间和 ...

随机推荐

  1. Delphi以及三方控件的源代码规模

    这些项目大多数使用C++或者C编写,使用SourceCounter-3.5.33.73工具来统计源代码数量,本来是这里下载的: https://code.google.com/p/boomworks/ ...

  2. java中使用 redis (转载)

    jedis是一个著名的key-value存储系统,而作为其官方推荐的java版客户端jedis也非常强大和稳定,支持事务.管道及有jedis自身实现的分布式. 在这里对jedis关于事务.管道和分布式 ...

  3. isKindOfClass和isMemberOfClass的区别

    isKindOfClass和isMemberOfClass的区别 isKindOfClass和isMemberOfClass 都是NSObject的比较Class的方法 但两个有很大区别: isKin ...

  4. Zookeeper:通过yarn实现大型分布式管理系统

    http://www.cnblogs.com/leesf456/p/6063694.html

  5. Leetcode: Convex Polygon

    Given a list of points that form a polygon when joined sequentially, find if this polygon is convex ...

  6. 实验三——for语句及分支结构else-if

    1.本节课学习到的知识点: (1)for语句是循环语句,它可以实现c语句的重复执行 (2)for语句中的3个表达式的执行顺序和书写顺序不同 (3)遇到复合语句时要用大括号将几句话括起来,复合语句在语法 ...

  7. 。。。欢乐捕鱼App WeX5 连接打包代理服务失败,请检查代理服务地址是否正确。。。

    今天学习了WeX5,第一次使用,使用它打包一个Web App 欢乐捕鱼的时候,在最终打包生成Native App的时候突然报错了,说:"连接打包代理服务失败,请检查代理服务地址是否正确&qu ...

  8. Buge's Fibonacci Number Problem

    Buge's Fibonacci Number Problem Description snowingsea is having Buge’s discrete mathematics lesson, ...

  9. Qt timer学习

    QTimer(重复和单发计时器) 应用QTimer时,先创建一个QTimer类,利用connect将timeout()与对应槽函数连接,在调用start()函数设置定时器时间间隔,每经过设置时间后,定 ...

  10. oracle中scn(系统改变号)

    系统scn:                 select checkpoint_change# from v$database; 文件scn:                 select name ...