hdu4655Cut Pieces

http://acm.hdu.edu.cn/showproblem.php?pid=4655

先以最大的来算为 N*所有的排列数  再减掉重复的 重复的计算方法:取相邻的两个数的最小值再与它前面的组合数和后面的组合数相乘

注意负值

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 using namespace std;

 7 #define LL long long

 8 #define N 1000100

 9 #define mod 1000000007

10 LL s1[N],s2[N],a[N],b[N];

11 int main()

12 {

13     int i,j,n,t;

14     cin>>t;

15     while(t--)

16     {

17         cin>>n;

18         LL s = 1;

19         for(i = 1; i <= n ; i++)

20         {

21             scanf("%lld",&a[i]);

22             b[i] = a[i];

23             s  = (s*a[i])%mod;

24         }

25         sort(b+1,b+n+1);

26         j=0;

27         for(i = 1 ; i <= n ; i++)

28         if(i%2!=0)

29         a[i] = b[++j];

30         for(i = n ; i >= 1 ; i--)

31         if(i%2==0)

32         a[i] = b[++j];

33         s1[0] = 1;

34         for(i = 1; i <= n ; i++)

35         s1[i] = (s1[i-1]*a[i])%mod;

36         s2[n+1] = 1;

37         for(i = n ; i>= 1; i--)

38         s2[i] = (s2[i+1]*a[i])%mod;

39         LL minz;

40         LL ans = 0;

41         for(i = 1; i < n ; i++)

42         {

43             minz = min(a[i],a[i+1]);

44             ans=(ans+((s1[i-1]*minz)%mod*s2[i+2])%mod)%mod;

45         }

46         ans = ((s*n)%mod-ans)%mod;

47         if(ans<0)

48         ans+=mod;

49         cout<<ans<<endl;

50     }

51     return 0;

52 }
View Code

 

你可能感兴趣的:(HDU)