hihoCoder 1596 Beautiful Sequence 搜索

Beautiful Sequence

Description

对于一个正整数列a[1], ... , a[n] (n ≥ 3),如果对于所有2 ≤ i ≤ n - 1,都有a[i-1] + a[i+1] ≥ 2 × a[i],则称这个数列是美丽的。

现在有一个正整数列b[1], ..., b[n],请计算:将b数列均匀随机打乱之后,得到的数列是美丽的概率P。

你只需要输出(P × (n!))mod 1000000007即可。(显然P × (n!)一定是个整数)

Input

第一行一个整数n。 (3 ≤ n ≤ 60)
接下来n行,每行一个整数b[i]。 (1 ≤ b[i] ≤ 1000000000)

Output

输出(P × (n!))mod 1000000007。

Sample Input

4
1
2
1
3

Sample Output

8

题意

首先定义一个序列为Beautiful为:对 2<=i<=n-1  : a[i-1]+a[i+1] >= 2*a[i]

给定n个数,问这些数的所有排列为Beautiful的有多少个

题解

由 a[i-1]+a[i+1] >= 2*a[i]  可以推导出  a[i+1]-a[i] >= a[i]-a[i-1]

也就是说构造出来的序列,两项之差逐渐递增

由于差可能为正数,也可能为负数

那么顺序肯定时由负数到正数

所以构造出来的序列要么是递减的,要么是递增的,要么是先递减随后递增的

事实上三种情况都可以规约为  先递减随后递增 的情况,类似一个抛物线

假设现在得到了a[i],同时已知a[i-1],那么显然 a[i+1]>= a[i]*2-a[i-1],即补充在后的数的下界是已知的

通过搜索解决这个问题

那么,先把所有数排个序,最小的那个数肯定就是抛物线的底部,记它有k个,总共可能构成k!个排列

然后维护四元组:<补充在左边的数的下界,当前最左边的数,补充在右边的数的下界,当前最右边的数>

递推:考虑补充在右边:若当前数a[now],比所求补充在右边的数下界要大,那么更新四元组中的后两项分别为 2*a[now]-pre,a[now];左边同理

然后爆完了

为了防T我还特意加了个计数项,把相同的项四元组合并了

唔折腾一晚上RE后来发现=-=请务必认真写好排序函数  不然会哭qwq

(好久没更博客了qwq发现我好懒

(有时候hihoCoder的题挺有意思的=-=虽然题面总给人一种硬翻国外题目的赶脚

代码

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 //#define FUCKOJ
  4 typedef long long ll;
  5 struct Node
  6 {
  7     ll fi,se;
  8     ll pre1,pre2;
  9     ll cnt;
 10 };
 11 bool operator != (Node x,Node y)
 12 {
 13     return !((x.fi==y.fi)&&(x.se==y.se)&&(x.pre1==y.pre1)&&(x.pre2==y.pre2));
 14 }
 15 bool operator < (Node x,Node y)
 16 {
 17     if(x.fi!=y.fi)  return x.fi<y.fi;
 18     if(x.se!=y.se)  return x.se<y.se;
 19     if(x.pre1!=y.pre1)  return x.pre1<y.pre1;
 20     if(x.pre2!=y.pre2)  return x.pre2<y.pre2;
 21     return x.cnt<y.cnt;
 22 }
 23 typedef vector<Node> VEC;
 24 #define pb push_back
 25 VEC V;
 26 const ll MOD = 1e9+7;
 27 const int MAXN = 60+3;
 28 ll a[MAXN];
 29
 30 void Run(int now)
 31 {
 32     //VEC tV(V.begin(),V.end());
 33     VEC tV;
 34     tV.clear();
 35     //V.clear();
 36     Node node1,node2;
 37     for(int i=0;i<V.size();++i)
 38     {
 39         node1=node2=V[i];
 40
 41         if(a[now]>=node1.fi)
 42         {
 43             if(node1.pre1==0)    node1.fi=a[now];
 44             else node1.fi=a[now]+(a[now]-node1.pre1);
 45
 46             node1.pre1=a[now];
 47             tV.pb(node1);
 48             /*if(V[i].pre1!=0)    tV.pb(node1);
 49             else if(V[i].pre2==0)
 50             {
 51                 node1.pre2=node1.se=a[now];
 52                 tV.pb(node1);
 53             }*/
 54         }
 55
 56         if(a[now]>=node2.se)
 57         {
 58             if(node2.pre2==0)    node2.se=a[now];
 59             else node2.se=a[now]+(a[now]-node2.pre2);
 60
 61             node2.pre2=a[now];
 62             tV.pb(node2);
 63             //if(V[i].pre2!=0)    tV.pb(node2);
 64         }
 65     }
 66     sort(tV.begin(),tV.end());
 67     V.clear();
 68     for(int i=0;i<tV.size();++i)
 69     {
 70         if(V.size()==0||(V[V.size()-1]!=tV[i]))    V.pb(tV[i]);
 71         else V[V.size()-1].cnt=(V[V.size()-1].cnt+tV[i].cnt)%(MOD);
 72     }
 73 #ifdef FUCKOJ
 74     cout<<"====="<<a[now]<<"====="<<endl;
 75     for(auto v:V)
 76     {
 77         cout<<v.fi<<" "<<v.pre1<<" "<<v.se<<" "<<v.pre2<<" "<<v.cnt<<endl;
 78     }
 79 #endif
 80
 81 }
 82
 83 int main()
 84 {
 85     int n;
 86     scanf("%d",&n);
 87     Node x;
 88     //x.pre1=x.pre2=x.fi=0,x.cnt=1;
 89     //x.se=0;
 90     //V.pb(x);
 91     for(int i=0;i<n;++i)
 92         scanf("%lld",a+i);
 93     sort(a,a+n);
 94     x.pre1=x.pre2=x.fi=x.se=a[0];
 95     x.cnt=1;
 96     int k=0;
 97     while(k<n&&a[k]==a[0])    k++;
 98     for(int i=1;i<=k;++i)    x.cnt=(x.cnt*i)%MOD;
 99     V.pb(x);
100     for(int i=k;i<n;++i)    Run(i);
101     ll ans=0;
102     for(auto v:V)    ans=(ans+v.cnt)%(MOD);
103     printf("%lld",(ans)%MOD);
104     return 0;
105 }


题解链接:http://www.cnblogs.com/scidylanpno/p/7618274.html

版权所有:scidylanpno

时间: 2024-11-05 11:47:21

hihoCoder 1596 Beautiful Sequence 搜索的相关文章

poj 1699 Best Sequence (搜索技巧 剪枝 dfs)

题目链接 题意:给出几个基因片段,要求你将它们排列成一个最短的序列,序列中使用了所有的基因片段,而且不能翻转基因. 分析:先计算出add数组,再dfs枚举. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstdio> 6 #include <vector> 7 #include <al

Beautiful Sequence

Beautiful Sequence 给定一些数(可能相同),将它们随机打乱后构成凹函数,求概率 .N<=60 . 首先,这种题求概率事实上就是求方案.所以现在要求的是用这些数构成凹函数的方案数. 依稀记得上次的一道考试题,只是把凹函数变成了一个具有特殊性质的单调序列而已.这道题也是一样,由于它不关心数的位置,所以把数排序以后,可以统计把当前数插入凹函数的方案. exp1:与数的位置无关的计数题可以考虑排序. 用\(f[i][j][k][l]\)表示凹函数最左边的两个点,最右边的两个点.那么新来

Codeforces Round #604 (Div. 2) D. Beautiful Sequence(构造)

链接: https://codeforces.com/contest/1265/problem/D 题意: An integer sequence is called beautiful if the difference between any two consecutive numbers is equal to 1. More formally, a sequence s1,s2,-,sn is beautiful if |si?si+1|=1 for all 1≤i≤n?1. Trans

hihocoder 1061.Beautiful String

题目链接:http://hihocoder.com/problemset/problem/1061 题目意思:给出一个不超过10MB长度的字符串,判断是否里面含有一个beautiful strings的子串:连续递增且数量相等的字母. 照着题目分析翻译的代码... 分析得很到位呢,大赞 ^_^ http://hihocoder.com/discuss/question/2083 hiho的题目其实挺好的,有专题,有分析,有代码 & 思路参考... 想想出来工作那么久,浮躁的心啊,一个多快两个月没

hihocoder 九十八周 搜索一 24点

题目1 : 搜索一·24点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 周末,小Hi和小Ho都在家待着. 在收拾完房间时,小Ho偶然发现了一副扑克,于是两人考虑用这副扑克来打发时间. 小Ho:玩点什么好呢? 小Hi:两个人啊,不如来玩24点怎么样,不靠运气就靠实力的游戏. 小Ho:好啊,好啊. <经过若干局游戏之后> 小Ho:小Hi,你说如果要写个程序来玩24点会不会很复杂啊? 小Hi:让我想想. <过了几分钟> 小Hi:我知道了!其实很简单嘛.

[SOJ475]【SPC #2】美丽的序列 ~ Beautiful Sequence【莫队】【哈希】

题意简述:给一个长度为\(n\)的序列,每次给出\(x, y\),求有多少区间\([l, r]\)满足\(x\leq l\leq r\leq y\),且\([l, r]\)中每个元素都出现了偶数次.\(1\leq n, q \leq 10^5, 1\leq a_i\leq 10^6\). 设\(s_{i, j}\in[0, 1]\)表示前\(i\)个位置中,元素\(j\)出现的总次数\(\bmod 2\)的结果.显然\([l, r]\)中每个元素都出现了偶数次等价于\(\forall i\in

CodeForces 1265 D. Beautiful Sequence

贪心 #include <iostream> #include<algorithm> #include<string.h> #include<set> using namespace std; const int maxn=100010; int ans[maxn]; int a[4]; void solve() { int a,b,c,d; cin>>a>>b>>c>>d; if(a>b) { if(a

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI