Description

Chiaki has a sequence A={a1,a2,…,an}. Let RMQ(A,l,r) be the minimum i (l≤i≤r) such that ai is the maximum value in al,al+1,…,ar.

Two sequences A and B are called \textit{RMQ Similar}, if they have the same length n and for every 1≤l≤r≤n, RMQ(A,l,r)=RMQ(B,l,r).

For a given the sequence A={a1,a2,…,an}, define the weight of a sequence B={b1,b2,…,bn} be ∑i=1nbi (i.e. the sum of all elements in B) if sequence B and sequence A are RMQ Similar, or 0 otherwise. If each element of B is a real number chosen independently and uniformly at random between 0 and 1, find the expected weight of B.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤106) – the length of the sequence.
The second line contains n integers a1,a2,…,an (1≤ai≤n) denoting the sequence.
It is guaranteed that the sum of all n does not exceed 3×106.

Output

For each test case, output the answer as a value of a rational number modulo 109+7.
Formally, it is guaranteed that under given constraints the probability is always a rational number pqpq\frac{p}{q}(p and q are integer and coprime, q is positive), such that q is not divisible by 1e9+7. Output such integer a between 0 and 1e9+6 that p−aq is divisible by 1e9+7.

Sample Input

3
3
1 2 3
3
1 2 1
5
1 2 3 2 1

Sample Output

250000002
500000004
125000001

Source

2018 Multi-University Training Contest 1


这题现场被卡常了,3e6的nlogn竟然会T,吐槽HDU的评测机
我们发现对于相同的数,RMQ的位置算最左边的那个,相当于对于相同的数,越靠左越大,这样我们可以对A数组进行重新标号,这样可以得到一个和他similar的一个n的排列A
考虑到在0到1之间随机n个数,有数字相等的概率是0,所以可以认为把随机出来的数离散化以后一定是一个n的排列,所以随机到每种排列的概率应该都是1n!1n!\frac{1}{n!}
所以我们现在要求和A similar的排列有多少种
我们尝试给出一种similar的递归定义:
对于数列A和B,他们similar当且仅当
1. 记A的最大值位置为p,B的最大值位置为q,则有p=q
2. A的p左边的部分和B的q左边的部分(如果存在)similar
3. A的p右边的部分和B的q右边的部分(如果存在)similar
我们尝试证明这个定义和原定义是等价的:首先如果最大值的位置不一样,那么任何包含最大值的区间RMQ的位置都不一样,肯定不similar;第二,当左边和右边都similar以后,左边的那些区间和右边的那些区间肯定符合原定义,考虑跨过p的那些RMQ,答案肯定是p,所以所有的区间都和原定义相符
这样我们考虑我们生成的排列A,尝试构造一个排列B和他similar,按照A中n的位置把B中n的位置放好,然后我们从B的n-1个数划分成左右两个集合都是合法的,因为不论怎样划分,考虑所有数的相对关系,两边等价于一个排列,这个部分就是一个组合数
如果我们从大到小插入这些数的话,每次我们要找比当前数位置右的最左位置和比当前位置左的最右位置来确定当前的区间,乘上组合数,这样需要一个set,多出一个log会T
考虑从小到大确定每个数对应的区间,我们建一个向前并查集和一个向后并查集,假设当前考虑到i,查找pos(i)+1和pos(i)-1的祖先以确定当前数对应的区间,然后因为之后要处理的数都比当前数打,所以当前数不可能成为后面的数的区间的边界,在两个并查集中分别将pos(i)和pos(i)+1和pos(i)-1连起来就好了,复杂度O(n)O(n)O(n)
这样我们已经算出了获得一个合法排列的概率,要算期望权值,考虑到期望的线性性和每个点的期望权值是1212\frac{1}{2},所以整个序列的期望权值就是概率乘上n2n2\frac{n}{2}

#include <bits/stdc++.h>
using namespace std;#define LL long long
#define LB long double
#define ull unsigned long long
#define x first
#define y second
#define pb push_back
#define pf push_front
#define mp make_pair
#define Pair pair<int,int>
#define pLL pair<LL,LL>
#define pii pair<double,double>
#define LOWBIT(x) x & (-x)const int INF=2e9;
const LL LINF=2e16;
const int magic=348;
const int MOD=1e9+7;
const double eps=1e-10;
const double pi=acos(-1);inline int getint()
{bool f;char ch;int res;while (!isdigit(ch=getchar()) && ch!='-') {}if (ch=='-') f=false,res=0; else f=true,res=ch-'0';while (isdigit(ch=getchar())) res=res*10+ch-'0';return f?res:-res;
}const int MAXN=1e6;int n;
int a[MAXN+48];
vector<int> v[MAXN+48];
int pos[MAXN+48];int inv[MAXN+48],finv[MAXN+48],fac[MAXN+48];
inline void init_inv()
{fac[0]=fac[1]=inv[0]=inv[1]=finv[0]=finv[1]=1;for (register int i=2;i<=MAXN;i++){inv[i]=MOD-((long long)(MOD/i)*inv[MOD%i])%MOD;fac[i]=(1ll*fac[i-1]*i)%MOD;finv[i]=(1ll*finv[i-1]*inv[i])%MOD;}
}inline int C(int x,int y)
{int res=fac[x];res=(1ll*res*finv[y])%MOD;res=(1ll*res*finv[x-y])%MOD;return res;
}struct DSU
{int pre[MAXN+48];inline void init() {for (register int i=0;i<=n+1;i++) pre[i]=i;}inline int find_anc(int x) {if (pre[x]!=x) pre[x]=find_anc(pre[x]);return pre[x];}inline void update(int x,int y) {x=find_anc(x);y=find_anc(y);pre[x]=y;}
}dsu;int L[MAXN+48],R[MAXN+48];int main ()
{//freopen ("a.in","r",stdin);//freopen ("a.out","w",stdout);int ca;ca=getint();int i,j,pt;init_inv();while (ca--){n=getint();for (i=1;i<=n;i++) a[i]=getint();for (i=1;i<=n;i++) v[i].clear();for (i=n;i>=1;i--) v[a[i]].pb(i);pt=0;for (i=1;i<=n;i++)for (j=0;j<int(v[i].size());j++)a[v[i][j]]=++pt,pos[pt]=v[i][j];a[0]=a[n+1]=n+1;dsu.init();for (i=1;i<=n;i++){L[i]=dsu.find_anc(pos[i]-1)+1;dsu.update(pos[i],pos[i]-1);}dsu.init();for (i=1;i<=n;i++){R[i]=dsu.find_anc(pos[i]+1)-1;dsu.update(pos[i],pos[i]+1);}int ans=1;for (i=1;i<=n;i++) ans=(1ll*ans*C(R[i]-L[i],R[i]-pos[i]))%MOD;ans=(((1ll*ans*finv[n])%MOD*inv[2])%MOD*n)%MOD;printf("%d\n",ans);}return 0;
}

HDU6305: RMQ Similar Sequence 题解相关推荐

  1. HDU 6305 RMQ Similar Sequence(笛卡尔树)

    题目链接:RMQ Similar Sequence 题意 首先给定一个长度为 nnn 的整数序列 A={a1,a2,⋯,an}" role="presentation" ...

  2. HDU - 6305 RMQ Similar Sequence(笛卡尔树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6305 题目 对于A,B两个序列,任意的l,r,如果RMQ(A,l,r)=RMQ(B,l,r),B序列里的数为[0 ...

  3. [HDU 6305]RMQ Similar Sequence

    HDU 6305 题解: 首先B数列一定是一个下标满足二叉搜索树,值满足大根堆的东西. 先考虑B数列满足这个条件的概率. 首先根的元素一定是A数列中最大的(第二关键字是下标最小),考虑B数列中对应的元 ...

  4. CF1726C Jatayu‘s Balanced Bracket Sequence 题解

    题面 题目大意 对于一个长度为 2n2n2n 的合法的括号串 sss,按照如下方法构造一张无向图: 括号序列的所有位置都是无向图中的一个点. 对于该序列的任意位置 lll,它能向另一个位置 rrr 连 ...

  5. hdu6305(笛卡尔树/分治)

    这道需要注意到一点..就是如果询问的区间如果覆盖了最大数,那么rmq一定是确定的..故以这个最大数为分界,左右2个区间是完全独立的..因此就可以采用分治的做法去做..聪明的汪聚聚已经实现.. 然后dl ...

  6. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

  7. leetcode 264. Ugly Number II

    传送门 264. Ugly Number II QuestionEditorial Solution My Submissions Total Accepted: 36259 Total Submis ...

  8. 2021UPC个人训练赛第47场

    个人训练赛第47场 A: 加工零件(最短路) 问题 A: 加工零件时间限制: 1 Sec 内存限制: 128 MB 题目描述 凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神 ...

  9. poj 3378 Crazy Thairs

    题意/Description:     These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ≤ N ≤ 5 ...

最新文章

  1. 织梦php 中英文加手机,织梦dedecms系统中英文网站之中英文搜索结果
  2. centos6.x 搭建K8S环境准备
  3. 金蝶K3cloud问题单排查
  4. Lambda表达式和闭包Closure
  5. 相亲对象能有多油腻......
  6. 贪心算法设计作业调度c语言,贪心算法 - 数据结构与算法教程 - C语言网
  7. 3 运行时间太长_10大污水处理预处理系统动态图及运行管理、故障处理
  8. 在Windows 2003 IIS 6.0中配置PHP的运行环境(图)
  9. 机器学习入门系列:关于机器学习算法你需要了解的东西、如何开发机器学习模型?...
  10. 【sampleDateFormat】对日期进行解析
  11. 5月博客恢复更新的通知
  12. nodepad代码格式复制到word发布到博客
  13. 【优化模型】逐步回归算法
  14. Windows环境下用nmake编译libevent
  15. Java8 日期时间类
  16. 瞻博QFX5100系列交换机光模块解决方案
  17. javascript库概念与连缀
  18. 智能养老手环能够防止老年人出现安全意外
  19. php中的时间戳_php时间戳是什么
  20. Android 各种时间格式转换

热门文章

  1. Wireshark数据流追踪和信息说明
  2. 【Java】 SpringBoot - 零基础搭建并使用
  3. 在rviz中画轨迹,使用rosbag抓取,并回放
  4. 15基于峰谷分时电价引导下的电动汽车充电负荷优化(matlab程序)
  5. 聊一聊IBM对于全球半导体产业的贡献
  6. xshell连接成功
  7. (秦路)七周成为数据分析师(第二周)—— 业务能力
  8. Linux下系统如何监控服务器硬件、操作系统、应用服务和业务
  9. Landsat8、GF-1、GF-2等遥感影像真彩色假彩色影像特征
  10. 高分一号(GF-1)卫星影像数据介绍