ZOJ 3929 Deque and Balls

There are n balls, where the i-th ball is labeled as pi. You are going to put n balls into a deque. In the i-th turn, you need to put the i-th ball to the deque. Each ball will be put to both ends of the deque with equal probability.

Let the sequence (x1x2, ..., xn) be the labels of the balls in the deque from left to right. The beauty of the deque B(x1x2, ..., xn) is defined as the number of descents in the sequence. For the sequence (x1x2, ..., xn), a descent is a position i (1 ≤ i < n) with xi > xi+1.

You need to find the expected value of B(x1x2, ..., xn).

Deque is a double-ended queue for which elements can be added to or removed from either the front (head) or the back (tail).

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 (2 ≤ n ≤ 100000) -- the number of balls. The second line contains n integers: p1p2, ..., pn (1 ≤ pi ≤ n).

Output

For each test case, if the expected value is E, you should output E⋅2n mod (109 + 7).

Sample Input

2
2
1 2
3
2 2 2

Sample Output

2
0
 
 
给出n个数字放入队列中,可以放在队列的前面也可以放在队列的后面,问得到xi>xi+1的概率
(就是数出有多少xi>xi+1然后除以总共可能的情况),由于最后要求将所得的数字乘以2^n,
所以也就是将得到的个数乘以二就是最后答案;
这里举个例子
3
1 2 3
 				1
		12				21
	123		231		321		213
      (没有)	      (31一个)       (32.21两个)    (21一个)
总共4个,乘以2后答案是8
 
 
 
 
AC代码:
#include<bits/stdc++.h>  
using namespace std;  
#define mod 1000000007  
long long ans[100005];//存的是从0-当前位置,递减数对的个数,可递推  
  
//就是当前的可配对数,就是先前已经匹配好的*2+当前增加的  
  
long long r[100005];//记录相同数对当前数的影响  
long long power[100005];//2的幂  
int n,t,a;  
int main()  
{  
    power[1]=1;  
    for(int i=2; i<=100000; i++)//预处理部分  
        power[i]=(power[i-1]*2)%mod;  
    cin>>t;  
    while(t--)  
    {  
        memset(ans,0,sizeof(ans));  
        memset(r,0,sizeof(r));  
        cin>>n;  
        for(int i=1; i<=n; i++)  
        {  
            cin>>a;  
            ans[i]=(ans[i-1]*2+power[i-1]-r[a]+mod)%mod;  
            //翻译上面一行:  
            //这个状态的可能值=上个状态可行的对数*2(因为我这个数放下去不影响之前就匹配好的数,但是放下去有两种可能性。  
            //                                       例如:21,然后后边不管多少个数,这个21数对总是需要被计算进去)  
            //  
            //                +放下这个数后所有的可能性(每放下一个数,这个串就像二叉树一样在生长)  
            //                -相同数造成的影响(如果这个数是第一次出现,那么总是可以放在比他大的数的右边,同理也可以放在比他小的左边)  
            //                  那么这个数的对这个状态先前的所有数都有影响。然后再后来出现这个数的时候要减去先前已经造成的影响。  
            //                  最后+mod是因为power被mod过,可能比r[a]大,(但是mod前实际是不会的)  
            //                 然后最后取模  
            //关于这个power[i-1],我再解释下,比如21 12 ,你将要放下3,你一定可以放在一个地方使得
            //总共的xi>xi+1多一个,比如这个你可以放在21的左边.还有12的左边,分别会多出一个32和31.
            //这个就是power[i-1]=power[2]=2;
            //还有那个r[a]也是类似的方式去理解;
            if(i==1)  
                r[a]=(r[a]+1)%mod;  
            else  
                r[a]=(r[a]+power[i-1])%mod;  
            //cout<<ans[i]<<endl;  
        }  
        cout<<(2*ans[n])%mod<<endl;  
    }  
    return 0;  
} 
 
 
比赛的时候队友题目翻译错了,我也没有去认真读题,于是也没有做出来,赛后问了下学长,才稍微懂了点。
 
 
转自http://blog.csdn.net/tinyguyyy/article/details/51133548(稍微加了点自己的的理解)

猜你喜欢

转载自blog.csdn.net/qq_34621169/article/details/51145904
ZOJ
今日推荐