码迷,mamicode.com
首页 > 其他好文 > 详细

hihoCoder 1596 Beautiful Sequence 搜索

时间:2017-10-02 00:20:50      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:定义   ack   for   struct   inpu   排列   链接   正整数   bit   

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

hihoCoder 1596 Beautiful Sequence 搜索

标签:定义   ack   for   struct   inpu   排列   链接   正整数   bit   

原文地址:http://www.cnblogs.com/scidylanpno/p/7618274.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!