[ An Ac a Day ^_^ ] CodeForces 691F Couple Cover 花式暴力

Time Limit: 3000MS   Memory Limit: 524288KB   64bit IO Format: %I64d & %I64u

Description

方宝宝有n个篮球,每个篮球上写有一个值ai。他第一次从n个篮球中取出1个,不放回。第二次再在剩余的篮球中取出一个。
(每个球被取概率相同)。如果这两个球上的值的乘积大于等于p,他会变得高兴,然后请大家吃饭。否则方宝宝会不高兴,
然后暴食暴饮变得更胖。
当然为了方宝宝的健康(被请吃饭),我想取一个合适的p值,使方宝宝高兴。
那么问题来了,现在有m个数:p1,p2……pm.对于每个p值有多少种选法使方宝宝高兴。
于是善(毒)良(瘤)的出题人把这个问题交给了你们。

Input

第一个行的数是n,第二行是个篮球上面的值ai,第三行是m,第四行p1, p2, p3……pm.
1<=n<=10^6,1<=m<=10^6,1<=pi<=3*10^6,1<=ai<=10^6

Output

第i行输出对于当前pi值,方宝宝能赢的方案数。

Sample Input

输入:
5
4 2 6 1 3
4
1 3 5 8
输出:
20
18
14
10
 
输入:
2
5 6
2
30 31
输出:
2
0

Source

 
好不容易看到一道CF的中文题(原题是英文的) 果断就做了……
 
题意:
有n个篮球 不放回取出两个球a b
对于m组提问 问对每个pi a*b>=pi的取法有多少种
 
思路:
根据样例可以分析出来(a=5,b=6)和(a=6,b=5)是两种方法
所以算出来的正常值应该乘2
而且时间限制3000ms 内存限制也很大 就想到暴力了
开两个3e6的数组 计算之前先预处理一下
最后输出n*(n-1)-sum[n-1]  这个式子就已经是乘2的了
 
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<math.h>
 5 #include<string.h>
 6 #include<string>
 7 #include<map>
 8 #include<set>
 9 #include<vector>
10 #include<queue>
11 #define M(a,b) memset(a,b,sizeof(a))
12 using namespace std;
13 typedef long long ll;
14 const int maxn=3e6+5;
15 ll cnt[maxn];
16 ll sum[maxn];
17 ll n,m,a,max_=-1;
18 int main(){
19     scanf("%I64d",&n);
20     for(int i=0;i<n;i++){
21         scanf("%d",&m);
22         cnt[m]++;
23         if(m>max_) max_=m;
24     }
25     for(int i=0;i<=max_;i++){
26         for(int j=0;j<=max_;j++){
27             if(i*j>maxn) break;
28             sum[i*j]+=cnt[i]*cnt[j];
29             if(i==j) sum[i*j]-=cnt[j];
30         }
31     }
32     for(int i=1;i<=maxn;i++)
33         sum[i]+=sum[i-1];
34     scanf("%I64d",&m);
35     for(int i=0;i<m;i++){
36         scanf("%d",&a);
37         printf("%I64d\n",n*(n-1)-sum[a-1]);
38     }
39     return 0;
40 }
41 /*
42 
43 5
44 4 2 6 1 3
45 4
46 1 3 5 8
47 
48 2
49 5 6
50 2
51 
52 */

 

posted @ 2016-08-13 10:13  良将ℓ  阅读(182)  评论(0编辑  收藏  举报