JZOJ.5288【NOIP2017模拟8.17】球场大佬

Description

每天下午,古猴都会去打羽毛球。但是古猴实在是太强了,他必须要到一些比较强的场去打。但是每个羽毛球场都有许多的人排着队,每次都只能上四个人,每个人都有自己的能力值,然而这四个人的总能力的高低与否才是古猴是否决定参加这个场的关键。
      每四个人的总能力值的定义是:任意选两个与另两个PK,能力值的贡献是较高的一组减去较低的一组。比如能力值为5和7的去PK 6和10的差值,那么用较高的减去较低的就是6+10-5-7=4。然后四个人的总能力值要任意两两之间与其他两个的总贡献。如(a,b,c,d)四个人,那么他们的总能力值就是(a,b)一组与(c,d)一组PK,(a,c)一组与(b,d)一组PK,(a,d)一组与(b,c)一组PK,(b,c)一组与(a,d)一组PK,(b,d)一组与(a,c)一组PK,(c,d)一组与(a,b)一组PK这六项PK差值就是四个人的总能力值。
     现在,古猴想知道这个场任意四个人的总能力值的和是多少,但是急着要拿拍,你需要马上告诉他这个场的情况?

Input

第一行一个T,接下来T组数据,每组数据第一行一个n,第二行n个整数a[i]表示每个人的能力值,a[i]∈[0,10^9]。

Output

输出一个整数表示任意四个人的总能力值。最后答案对10^9+7取模。

Sample Input

3
4
1 2 3 3
5
1 2 3 4 5
6
9 18 28 23 12 9

Sample Output

10
76
1176

Data Constraint

对于30%的数据n≤50,T≤5
对于另外20%的数据n≤200,T≤10
对于另外50%的数据n≤2000,T≤100
保证所有的n加起来不超过2000

题目就是求

朴素的O(n4)显然过不了,我们得考虑一下优化下。

观察公式我们发现它是两两配对进行相减,我们可以尝试将a[i]+a[j]两两配对储存在数组b里,然后计算每对对答案的贡献。

绝对值不好处理, 我们可以尝试去掉绝对值,那么我们就得确定该结果的正负。我们将b数组从大到小排序,发现对于一个bi,它会被减去(i-1)次,加上(nn-i)次(其中nn为b数组里数的个数)

但是我们会发现有个问题,就是有可能会选到具有同一个数的bi,bj,比如bi=ax+ay,但bj=ax+az,这是不合法的情况,因为三个人不符题目要求,我们就要将这一些去掉。

对于一个bi,它是由ax+ay得到的,其中ax>ay,我们考虑bj=ax+az,其中假设bi>bj,那么ay>az,对于这些的az+ax=bj都是不合法的,那么一共就有rank[ay]-1个。(rank[i]表示i的排名)

再对于bk=as+ay,假设bi>bk,那么ax>as,对于这些就有rank[ax]-2个(除去它本身和ay)

bi<bj   bi<bk同样的道理也可以得到(n-rank[ay]-1)个和(n-rank[ax])个

这样我们就可以把重复的去掉就可以了。

复杂度O(n2+nlogn2)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define N 2002000
 6 #define mo 1000000007
 7 using namespace std;
 8 int a[2002],t;
 9 long long ans,n,len;
10 struct data{
11     long long x,y,v;
12 }b[N];
13 bool comp(const struct data a,const struct data b){
14     return a.v>b.v;
15 }
16 int main(){
17     scanf("%d",&t);
18     while (t--){
19         scanf("%lld",&n);
20         ans=0;
21         for (int i=1;i<=n;i++)
22          scanf("%d",&a[i]);
23         sort(a+1,a+1+n);
24         len=0;
25         for (int i=1;i<=n;i++)
26          for (int j=i+1;j<=n;j++)
27           b[++len].v=a[j]+a[i],b[len].x=i,b[len].y=j;
28         sort(b+1,b+1+len,comp);
29         for (long long i=1;i<=len;i++)
30          ans=(b[i].v%mo*(len-i-(b[i].x-1+b[i].y-2))%mo-b[i].v%mo*(i-1-(n-b[i].x-1+n-b[i].y))%mo+ans+mo)%mo;
31         printf("%lld\n",ans*2%mo);
32     }
33 }

神奇的代码

这道题就是通过拆散式子把相等的式子一起加起来从而降低了复杂度。

时间: 2024-08-02 18:23:55

JZOJ.5288【NOIP2017模拟8.17】球场大佬的相关文章

Cisco PT模拟实验(17) 路由器IP访问控制列表配置

Cisco PT模拟实验(17) 路由器IP访问控制列表配置 实验目的: 理解两种IP访问控制列表的原理及功能 掌握常见IP访问控制列表的配置方法 实验背景: 公司的经理部.财务部们和销售部门分属于不同的3个网段,三部门之间用路由器进行信息传递,为了安全起见,公司领导要求销售部门不能对财务部进行访问,但经理部可以对财务部进行访问. 技术原理: 路由器能提供防火墙的功能,根据一些预设置的ACL过滤规则对任何经过接口的流量进行过滤,说明哪些具体的通信(来自设备.协议或端口等)是被允许或拒绝,该功能是

JZOJ.5281【NOIP2017模拟8.15】钦点

Description Input Output Sample Input 4 4 2 a a b b a a b b c c d d c c d d 1 1 3 3 2 2 3 1 1 3 2 2 Sample Output d d c c  d d c c  b b a a  b b a a  Data Constraint 本题时限4s. 很明显这是一道模拟题,朴素算法O(nmq)看似过得去,实际上字符串的操作是很慢的,同样对字符串赋值10w次比对数组元素赋值10w次要慢3倍以上. 实际上

JZOJ.5331【NOIP2017模拟8.23】壕游戏

Description Input Output Sample Input 6 8 2 2 4 5  1 2 4 0 2 1 3 5 0 2 3 4 1 5 1 2 5 1 0 1 4 6 4 2 2 5 6 0 4 2 1 5 5 9 2 2 6 4 5 2 Sample Output 16 Data Constraint Hint 类似于一种可撤销的贪心,不难想到这是费用流的模型. 考虑到我们实际会用到的边比实际的边少很多,我们可以动态建边,以减少空间的使用,即当流过了一条边之后再建立第二次

JZOJ.5274【NOIP2017模拟8.14】数组

Description Input Output Sample Input 输入样例1: 3 2 7 5 4 2 输入样例2: 5 3 1 5 4 3 5 5 Sample Output 输出样例1: 999999732 输出样例2: 0 Data Constraint 这个题要求乘积最小,显然我们希望乘积是负数是最好的,然后就是让这个负数的绝对值尽可能的大. 对于一堆数相乘,绝对值最小的对这个结果影响是最大的,所以我们就每次让绝对值最小的,如果是正数就加上x,负数就减去x,用个优先队列维护绝对

JZOJ.5287【NOIP2017模拟8.16】最短路

Description Input Output Sample Input 9 10 2 1 2 1 1 4 1 3 4 1 2 3 1 3 7 1 7 8 2 7 9 2 1 5 3 1 6 4 5 6 1 1 9 5 7  Sample Output 5 6 Data Constraint 容易发现这是一张仙人掌图(每条边最多属于一个环的无向连通图) 仙人掌图求最短路的常用处理方法是将它变成一棵树,原图里为环的点更改为该环上的点都指向该环的某个点A,然后边长就是该点到点A的最短路径. 再预处

JZOJ.5329【NOIP2017模拟8.22】时间机器

Description Input Output Sample Input 3 2 2 1 4 2 3 5 1 1 4 2 2 5 1 3 2 1 3 1 2 4 1 3 5 1 1 3 2 2 5 1 2 2 1 2 2 1 2 1 1 2 1 1 2 2   Sample Output Yes No Yes Data Constraint Hint 很明显这是要让我们匹配,很容易想到可以二分图匹配,但是又有数量,于是我们可以网络流,但是n还是巨大,使得我们不得不想想其他办法. 我们的期望搭配

JZOJ.5305【NOIP2017模拟8.18】C

Description Input Output Sample Input 10 11 1 2 2 3 3 4 1 4 3 5 5 6 8 6 8 7 7 6 7 9 9 10  6 1 2 3 5 6 9 9 2 9 3 9 10  Sample Output 2 2 2 4 4 1  Data Constraint Hint 题意有点问题,实际上简单路径这里指的是不经过重复边的路径. 这题Tarjan缩点,然后LCA统计两点间环的个数k,答案就是2k个路径. 1 #include<iostr

JZOJ.5286【NOIP2017模拟8.16】花花的森林

Description Input Output Sample Input 3 1 2 3 1 2 1 3 2 1 Sample Output 6 9 6 Data Constraint Hint 题目大意就是要求删边和计算直径. 很明显每次删边后两边BFS计算直径必会超时,但我们可以通过lca和预处理节点到根节点的距离来快速计算,但删边后lca很可能有所变化,重新预处理lca的信息又太慢了. 我们可以试着逆向. 即正着删边看成反着添边. 这样子我们可以发现是等效的. 一开始每棵树的直径就是该点

JZOJ.5307【NOIP2017模拟8.18】偷窃

Description Input Output Sample Input 5 5 1 4 0 5 2 2 1 2 0 1 0 2 3 4 4 0 3 0 3 1 1 2 2 1 1 Sample Output 9 Data Constraint Hint 本题直接做比较麻烦,加上金砖可移动. 这题就是要求我们找出一种摆放方式,三视图与之前一样且用得金块数最少. 我们可以重新构造. 对于俯视图,它提供的信息就是我们要在哪里放金砖,哪里不能放金砖. 对于正视图和侧视图,它提供的信息就是某一行或某一