线段树-HDU5737-这题有点神

HDU5737

题意

[1][1][1]有长度为nnn的序列A,BA,BA,B
[2]Q[2]Q[2]Q此操作两种类型

  • (1,l,r,x)(1,l,r,x)(1,l,r,x)将区间[l,r][l,r][l,r]aia_iai覆盖为xxx
  • (2,l,r)(2,l,r)(2,l,r)询问区间[l,r][l,r][l,r]中有多少ai≥bia_i \ge b_iaibi

题解

考虑用线段树维护.

重点考虑覆盖操作,当覆盖一个线段时,我们打上延迟修改标记(就是lazylazylazy标记).

但是当前线段的答案要立刻被计算出来,那么这里如何求呢?

其实就相当于找区间[l,r][l,r][l,r]中小于等于xxx的有多少个.

因此想到我们可以在线段树的每一个节点维护一个平衡树.

这样的话,空间复杂度是O(nlogn)O(nlogn)O(nlogn)

仅平衡树合并的时间复杂度就是O(nlogn2)O(nlogn^2)O(nlogn2),这个时间复杂度我们接受不了,因此我们要换一种能查询rankrankrank的数据结构,但是合并要快.

因此我们就想到了有序表,合并时候用归并排序即可,查找的时候使用lower_boundlower\_boundlower_bound即可.

空间复杂度是O(nlogn)O(nlogn)O(nlogn).

有序表合并的时间复杂度是O(nlogn)O(nlogn)O(nlogn),可以接受.

查询rankrankrank的时间复杂度为O(logn)O(logn)O(logn),而考虑如果修改时区间大小为n−1n-1n1时,涉及到打lognlognlogn个覆盖标记,每打一个覆盖标记时候都要lognlognlogn时间复杂度来查rankrankrank,总的时间复杂度就是O(logn2)O(logn^2)O(logn2),那么询问的时间复杂度就是O(m∗logn∗logn)O(m*logn*logn)O(mlognlogn),这是无法接受的.

因此我们考虑怎么优化这步操作.

如果我们能记录下来对于线段中的每个数xxx,在左线段中小于等于xxx的最大的位置和在右线段中小于等于xxx的最大位置,那么我们在changechangechange函数中,可以直接O(1)O(1)O(1)传递给儿子这个关键的位置.

这样总的时间复杂度就优化到了O(nlogn+mlogn)O(nlogn + mlogn)O(nlogn+mlogn)

代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
#define clr(x) memset(x,0,sizeof(x))
#define setinf(x) memset(x,0x3f,sizeof(x))const int N = 100007;
const int P = 1e9+7;struct node{int ans,tag,len;node(int ans = 0,int tag = -1,int len = 1):ans(ans),tag(tag),len(len){}
}ns[N<<2],NIL;std::vector<int> vec[N<<2],lft[N<<2],rgt[N<<2];int a[N],b[N];inline node maintain(node& lch,node &rch) {node res = node(lch.ans + rch.ans,-1,lch.len + rch.len);return res;
}inline void tag(int o,int val){ns[o].ans = val;ns[o].tag = val;
}inline void pushdown(int o) {if(ns[o].tag != -1) {if(ns[o].tag == 0){tag(o<<1,0);tag(o<<1|1,0);}else {tag(o<<1,lft[o][ns[o].tag-1]);tag(o<<1|1,rgt[o][ns[o].tag-1]);}ns[o].tag = -1;}
}inline void merge(int o){int posl = 0,posr = 0;while(posl < vec[o<<1].size() || posr < vec[o<<1|1].size()) {if(posl == vec[o<<1].size()) vec[o].push_back(vec[o<<1|1][posr++]);else if(posr == vec[o<<1|1].size()) vec[o].push_back(vec[o<<1][posl++]);else {if(vec[o<<1][posl] < vec[o<<1|1][posr])vec[o].push_back(vec[o<<1][posl++]);else vec[o].push_back(vec[o<<1|1][posr++]);}}posl = posr = 0;rep(i,0,vec[o].size()-1) {while(posl < vec[o<<1].size() && vec[o<<1][posl] <= vec[o][i])posl++;while(posr < vec[o<<1|1].size() && vec[o<<1|1][posr] <= vec[o][i])posr++;lft[o].push_back(posl);rgt[o].push_back(posr);}
}inline void build(int o,int l,int r) {if(l == r) {vec[o].push_back(b[l]);ns[o] = node(a[l] >= b[l],-1,1);return ;}int mid = (l + r) >> 1;build(o<<1,l,mid);build(o<<1|1,mid+1,r);ns[o] = maintain(ns[o<<1],ns[o<<1|1]);merge(o);
}inline void change(int o,int l,int r,int cl,int cr,int val) {if(cl <= l && r <= cr) {//val = std::upper_bound(vec[o].begin(),vec[o].end(),val) - vec[o].begin();tag(o,val);return ;}if(r < cl || cr < l) return ;int mid = (l + r) >> 1;pushdown(o);change(o<<1,l,mid,cl,cr,val?lft[o][val-1]:0);change(o<<1|1,mid+1,r,cl,cr,val?rgt[o][val-1]:0);ns[o] = maintain(ns[o<<1],ns[o<<1|1]);
}inline node query(int o,int l,int r,int ql,int qr) {if(ql <= l && r <= qr) return ns[o];if(r < ql || qr < l)return NIL;int mid = (l + r) >> 1;pushdown(o);node lch = query(o<<1,l,mid,ql,qr);node rch = query(o<<1|1,mid+1,r,ql,qr);return maintain(lch,rch);
}
int T,n,m,A,B;int aa,bb,C,M,last;
inline int rnd(int last) {aa = (36969 + (last >> 3)) * (aa & M) + (aa >> 16);bb = (18000 + (last >> 3)) * (bb & M) + (bb >> 16);return (C & ((aa << 16) + bb)) % 1000000000;
}inline void clear(int o,int l,int r){if(l == r) {vec[o].clear();	lft[o].clear();	rgt[o].clear();	return ;}clear(o<<1,l,(l+r)>>1);clear(o<<1|1,((l+r)>>1)+1,r);vec[o].clear();lft[o].clear();rgt[o].clear();
}
int main() {std::ios::sync_with_stdio(false);std::cin >> T;while(T--) {std::cin >> n >> m >> A >> B;long long ans = 0;aa = A,bb = B,C = ~(1<<31), M = (1<<16)-1, last = 0;rep(i,1,n) std::cin >> a[i];rep(i,1,n)std::cin >> b[i];build(1,1,n);rep(i,1,m) {int l = (rnd(last) % n) + 1,r = (rnd(last) % n) + 1,x = rnd(last) + 1;if(l > r) std::swap(l,r);int tp = (l+r+x)%2 == 0 ? 2:1;if(tp == 1){x = upper_bound(vec[1].begin(),vec[1].end(),x) - vec[1].begin();change(1,1,n,l,r,x);}else if(tp == 2){node res = query(1,1,n,l,r);ans = ans + 1LL * i * res.ans;last = res.ans;}}std::cout << ans % P << std::endl;clear(1,1,n);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【高精】Oliver的成绩(jzoj 2008)

Oliver的成绩 题目大意&#xff1a; Oliver考了一次试&#xff0c;现在知道他的语数英的成绩&#xff0c;还有年级其他n个人的成绩&#xff0c;现在问Oliver三科各和年级第一差多少分&#xff0c;如果Oliver在这一科上是第一&#xff0c;则输出‘0’ 样例输入 10 10 10 …

P4070-[SDOI2016]生成魔咒【SA,平衡树】

正题 题目链接:https://www.luogu.com.cn/problem/P4070 题目大意 长度为nnn的字符串&#xff0c;对于每个iii求字符串1∼i1\sim i1∼i部分有多少个不同的子串。 解题思路 对于整个串ans∑i1nn−i1−heightians\sum_{i1}^nn-i1-height_ians∑i1n​n−i1−heighti​&#xff…

ASP.NET Core 2.1 使用Docker运行

1.新建一个 ASP.NET Core 2.1 项目然后运行一下项目&#xff0c;确保我们刚刚建立的项目可以正常运行。2.编写 Dockerfile新建一个文本文件&#xff0c;命名为 DockerfileFROM microsoft/dotnet:2.1-aspnetcore-runtimeWORKDIR /appCOPY . .EXPOSE 80ENTRYPOINT ["dotnet&…

【DP】和谐的奶牛(jzoj 1750)

和谐的奶牛 题目大意&#xff1a; 有一些括号&#xff08;保证是合法的&#xff0c;合法&#xff1a;每一个左括号都有自己配对的有括号&#xff09;&#xff0c;现在要将这些括号分为两组&#xff08;其中一组可以为空&#xff09;&#xff0c;分完组后括号的顺序要和原来的…

费用流-Wannafly Day2 TwoGraph-神题

TwoGraph 题意 题解 这真是一道神题,这题有两点比较难想,其中第一点是最难想的. 我们先考虑只有一张图的情况. 性质: [1]如果给每个点匹配一条边,形成一个(点,边)(点,边)(点,边)对,其中点不能重复出现,边也不能重复出现.那么这些对形成的图的联通块要么是树,要么是环套树. 证…

ASP.NET Core Web API 与 SSL

SSL一直没有真正研究过SSL&#xff0c;不知道下面的理解是否正确。SSL是Secure Sockets Layer的缩写&#xff0c;它用来保护服务器和客户端之前的通信。它是基于信任加密的概念。在介绍SSL的原理之前&#xff0c;首先介绍一下加密&#xff08;Encryption&#xff09;的概念。刷…

P5662-纪念品【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P5662 题目大意 有TTT天&#xff0c;nnn个纪念品&#xff0c;每个纪念品每天的价格不同&#xff0c;数量不限。开始小明有mmm块钱&#xff0c;求最后一天的最多钱。 解题思路 因为一个纪念品可以一天卖出并且一天买入&#…

【模拟】聊天服务器的外部流量

聊天服务器的外部流量 题目大意&#xff1a; 有一个通讯系统&#xff0c;可以将某人邀请进来&#xff08;name&#xff09;&#xff0c;也可以将某人T出去&#xff08;-name&#xff09;&#xff0c;也可以向群中的所有人发一条信息&#xff08;name&#xff1a;…&#xff0…

线段树-Pudding Monster CF526F-单调栈

Pudding Monster 题目连接:https://www.luogu.org/problem/show?pidCF526F 问题提出 给长度为nnn的排列AAA.问有多少(l,r)(l,r)(l,r),使得将Al,Al1,...,ArA_l,A_{l1},...,A_rAl​,Al1​,...,Ar​排序之后是连续的一段数.n≤105n \le 10^5n≤105 问题解决 判断一段区间是否…

P5664-Emiya家今天的饭【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P5664 题目大意 对于nnn个方法&#xff0c;mmm个材料&#xff0c;一个方法配对一个材料可以做an,ma_{n,m}an,m​道菜。选择kkk个配对要求 配对至少为k>1k>1k>1每个配对的方法不同每个材料最多用⌊k2⌋\lfloor\frac…

GitHub宣布GitHub Education 新计划,学校可免费用企业版

今天 GitHub 宣布面向所有学校和教育机构开放 GitHub Education&#xff0c;方便学生和老师免费使用 GitHub 企业版功能&#xff0c;以及学生开发者工具包、GitHub 教室、培训等资源。2014 年&#xff0c;GitHub 推出了学生开发者工具包&#xff0c;其中包括 Azure 等云服务、G…

【dfs】聚会

聚会 题目大意&#xff1a; 有一些树&#xff0c;求深的树的深度 原题 解题思路&#xff1a; 从一个根出发&#xff0c;dfs往下搜 代码&#xff1a; #include<cstdio> #include<iostream> #include<cstring> using namespace std; int n,t,g,w,ans,c[2…

P3960-列队【权值线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P3960 题目大意 n∗mn*mn∗m的队列&#xff0c;起初站在第(i,j)(i,j)(i,j)位置的人编号是(i−1)∗nj(i-1)*nj(i−1)∗nj。然后每次选择一个人出队后所有人向左补齐后所有人向前补齐&#xff0c;然后刚刚出列的那个人入队。 求…

2018 大湾区(深圳) .NET技术分享交流会 第一期

.NET Core 2.1 已于2018年5月30日正式发布&#xff0c;邀请粤港澳大湾区.NET技术专家和从业人员&#xff0c;一起分享与交流.NET技术的发展方向&#xff0c;提高粤港澳大湾区.NET技术交流氛围&#xff0c;挖掘.NET高级人才&#xff0c;为改善.NET生态系统贡献力量&#xff0c;使…

线段树-Mex-洛谷P4137

Mex 问题提出 有一个长度为nnn的数组{a1,a2,…,an}\{a_1,a_2,…,a_n\}{a1​,a2​,…,an​}。mmm次询问&#xff0c;每次询问一个区间内最小没有出现过的自然数。 题目解答 对1−n1-n1−n这里能够的每个数xxx,都统计出来在数组中出现的位置,并在前补上000,在后补上n1n1n1. …

卡车

卡车 题目大意&#xff1a; 有一个卡车向里面放东西&#xff08;重量要么是一要么是二&#xff09;&#xff0c;价值不同&#xff0c;放的东西的价值之和最大是多少 原题&#xff1a; 解题思路&#xff1a; 看看数据就知道DP会MLE&#xff0c;所以要用排序来做&#xff0c;…

P2831-愤怒的小鸟【状压dp】

正题 题目链接:https://www.luogu.com.cn/problem/P2831 题目大意 nnn个点&#xff0c;每次可以射掉在函数yax2bxyax^2bxyax2bx上的点&#xff08;a,ba,ba,b自定但是要求a<0a<0a<0&#xff09;。求最少射击次数。 解题思路 考虑状压&#xff0c;我们发现如果一次射掉…

初一级模拟赛总结(3.15)

成绩&#xff1a; rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4111lyflyflyf220220220100100100100100100000202020222fyfyfy150150150000100100100000505050333lthlthlth120120120100100100202020000000444hkyhkyhky100100100000100100100000000444tjhtj…

从明面上学习ASP.NET Core

一、前言这篇文章就是从能看到地方去学习Core&#xff0c;没有很深奥&#xff0c;也没有很难懂&#xff0c;现在我们开始吧。二、构建项目&#xff0c;引发思考创建项目的步骤真的很简单&#xff0c;你要是不会&#xff0c;我真也没法了&#xff0c;我这是创建的MVC的项目。接下…

线段树-区间的交

区间的交 题目来源 孙耀峰Segment_Tree.pdf 原创 题目描述 给定nnn个区间,[li,ri][l_i,r_i][li​,ri​],可以选出其中一些区间,设选出tottottot个,令xxx表示这tottottot个区间交的长度.求min{x,tot}min\{x,tot\}min{x,tot}n≤105,1≤xi≤yi≤nn \le 10^5,1 \le x_i \le y_i…