区间计数
 
基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80
 

两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下:

Ans:=Σni=1Σnj=i[max{Ai,Ai+1,...,Aj}=max{Bi,Bi+1,...,Bj}]

注:[ ]内表达式为真,则为1,否则为0.

 
 
1≤N≤3.5×1051≤Ai,Bi≤N 
 
样例解释:
7个区间分别为:(1,4),(1,5),(2,4),(2,5),(3,3),(3,5),(4,5)
Input
  1. 第一行一个整数N
  2. 第二行N个整数Ai
  3. 第三行N个整数Bi
Output
  1. 一行,一个整数Ans
Input示例
  1. 5
  2. 1 4 2 3 4
  3. 3 2 2 4 1
Output示例
 
7
 
题解:
  第一种做法是 两个单调栈 + 二分
  两个数都同时维护一个单调递减的 栈
  当元素出栈是我们可以确定以其为最大值所能掌管的一段区间,那么 在对应另一个栈内通过二分找到此值也能掌管一段区间
  求出区间交就可以了
  第二种做法比较类似
  枚举固定最大值为x 的区间有哪些
  在A数组中 假设x 所在位置为  i   ,利用单调栈可以求出 其掌管范围 [L1,R1], 对应的
  在B数组中 假设x 所在位置为  i   ,利用单调栈可以求出 其掌管范围 [L2,R2],
  那么抽出 [L1,i] [i,R1],  [L2,i] [i,R2], 在二维坐标系上就是两个矩阵,求出矩阵面积交就可以了
  1. #include <bits/stdc++.h>
  2. inline long long read(){long long x=,f=;char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return x*f;}
  3. using namespace std;
  4. #define ls i<<1
  5. #define rs ls | 1
  6. #define mid ((ll+rr)>>1)
  7. #define MP make_pair
  8. typedef long long LL;
  9. typedef unsigned long long ULL;
  10. const long long INF = 1e18+1LL;
  11. const double pi = acos(-1.0);
  12. const int N = 4e5 + , M = 1e3, inf = 2e9;
  13.  
  14. int n,a[N],b[N];
  15. int l[],r[],q[][N],pos[][N];
  16. LL cal(int x,int p,int i) {
  17. int ll = l[p], rr = r[p],ok = ll;
  18. while(ll <= rr) {
  19. if(q[p][mid] > x) {
  20. ll = mid + ;
  21. } else ok = mid,rr = mid - ;
  22. }
  23. // cout<<i<<" "<<p<<" "<<ok<<" "<<q[p][ok]<<" "<<x<<endl;
  24. int mmp1,mmp2;
  25. mmp1 = max(pos[p][ok-]+,pos[p^][r[p^]-]+);
  26. mmp2 = i-;
  27.  
  28. if(q[p][ok] == x)
  29. return 1LL * max(min(pos[p^][r[p^]],pos[p][ok]) - mmp1+,)
  30. * max(mmp2 - max(pos[p^][r[p^]],pos[p][ok]) + ,);
  31. else return ;
  32. }
  33. int main() {
  34. cin >> n;
  35. for(int i = ; i <= n; ++i) scanf("%d",&a[i]);
  36. for(int i = ; i <= n; ++i) scanf("%d",&b[i]);
  37. l[] = l[] = ;
  38. r[] = r[] = ;
  39. pos[][] = pos[][] = ;
  40. LL ans = ;
  41. for(int i = ; i <= n; ++i) {
  42. LL ret = ;
  43. while(l[] <= r[] && a[i] >= q[][r[]]) {
  44. ret += cal(q[][r[]],,i);
  45. r[]--;
  46. }
  47. q[][++r[]] = a[i];pos[][r[]] = i;
  48. while(l[] <= r[] && b[i] >= q[][r[]]) {
  49. ret += cal(q[][r[]],,i);
  50. r[]--;
  51. }
  52. q[][++r[]] = b[i];pos[][r[]] = i;
  53. //cout<<"fuck "<<i<<" " << ret<<endl;
  54. ans += ret;
  55. }
  56. while(l[] <= r[]) {
  57. ans += cal(q[][r[]],,n+);
  58. r[]--;
  59. }
  60. cout<<ans<<endl;
  61. return ;
  62. }
  1.  

51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线的更多相关文章

  1. 51nod 1962区间计数(单调栈加二分)

    题目要求是求出两个序列中处于相同位置区间并且最大值相同的区间个数,我们最直观的感受就是求出每个区间的最大值,这个可以O(N)的求,利用单调栈求出每个数作为最大值能够覆盖的区间. 然后我们可以在进行单调 ...

  2. 51nod 1206 Picture 矩形周长求并 | 线段树 扫描线

    51nod 1206 Picture 矩形周长求并 | 线段树 扫描线 #include <cstdio> #include <cmath> #include <cstr ...

  3. 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)

    线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...

  4. 【10.7校内测试】【队列滑窗】【2-sat】【贪心+栈二分+线段树(noip模拟好题)】【生日祭!】

    比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; ...

  5. 51Nod—1174 区间中最大的数 线段树模版

    在大佬们题解的帮助下算是看懂了线段树吧...在这mark下防一手转头就忘. #include<iostream> #include<stdio.h> using namespa ...

  6. 51nod 1962 区间计数(单调栈+二分)

    维护两个单调递减的栈,当i加进栈,位置x的数弹出的时候,在另一个栈中找到和这个数一样大的数,计算贡献(x-靠右左端点)*(i-x). #include<iostream> #include ...

  7. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  8. BZOJ1012最大数 [JSOI2008] 单调栈+二分

    正解:单调栈+二分查找(or,线段树? 解题报告: 拿的洛谷的链接quq 今天尝试学习了下单调栈,然后就看到有个博客安利了这个经典例题?于是就去做了,感觉还是帮助了理解趴quqqqqq 这题,首先,一 ...

  9. 【bzoj4237】稻草人 分治+单调栈+二分

    题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...

随机推荐

  1. hdu 2262 高斯消元求期望

    Where is the canteen Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...

  2. 基于promise和script标签的jsonp

    function Jsonp(url){ var url=url.indexOf('?')>-1?url+"&callback=callback":url+" ...

  3. windows8.1如何分盘

    磁盘分区首先要弄明白磁盘物理顺序与逻辑顺序的区别,在[磁盘管理]界面,所显示的前后顺序为物理顺序,这是磁盘上实实在在的物理位置,如下图2的电脑磁盘物理顺序为CFDE.在[资源管理器]界面,所显示的顺序 ...

  4. 标准C程序设计七---77

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  5. linux 调试常用命令

    top 参数 1 ,查看多核cpu  也可用 mpstat -P ALL pstate PID 查看进程堆栈 pmap -x PID 查看进程 内存段 ldd  XXX.so 查看 .so 的link ...

  6. linux下 open fopen区别

    open是linux下的底层系统调用函数,fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲.linxu下的fopen是open的封装函数,fopen最终还是要调用底层的系统 ...

  7. Oracle For 循环添加数据

    自己亲自使用的,绝对OK --添加数据declare i number; --用for实现 begin for i in 0 .. 500 loop insert into cust(custsn,t ...

  8. python笔记3:注释命名风格

    6.注释: 行注释采用  # 开头,多行注释使用三个单引号 (''') 或三个双引号 ("' '"),注释不需要对齐 三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保 ...

  9. HDU 1018.Big Number-Stirling(斯特林)公式 取N阶乘近似值

    最近一堆题目要补,一直咸鱼,补了一堆水题都没必要写题解.备忘一下这个公式. Stirling公式的意义在于:当n足够大时,n!计算起来十分困难,虽然有很多关于n!的等式,但并不能很好地对阶乘结果进行估 ...

  10. vs2017秘钥

    VS2017专业版和企业版激活密钥 需要的请自取- Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional: KBJFW-NXHK6-W4WJM- ...