• codeforces 691F F. Couple Cover(组合计数)


    题目链接:

    F. Couple Cover

    time limit per test
    3 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    Couple Cover, a wildly popular luck-based game, is about to begin! Two players must work together to construct a rectangle. A bag withn balls, each with an integer written on it, is placed on the table. The first player reaches in and grabs a ball randomly (all balls have equal probability of being chosen) — the number written on this ball is the rectangle's width in meters. This ball is not returned to the bag, and the second player reaches into the bag and grabs another ball — the number written on this ball is the rectangle's height in meters. If the area of the rectangle is greater than or equal some threshold p square meters, the players win. Otherwise, they lose.

    The organizers of the game are trying to select an appropriate value for p so that the probability of a couple winning is not too high and not too low, but they are slow at counting, so they have hired you to answer some questions for them. You are given a list of the numbers written on the balls, the organizers would like to know how many winning pairs of balls exist for different values of p. Note that two pairs are different if either the first or the second ball is different between the two in pair, and two different balls with the same number are considered different.

    Input

    The input begins with a single positive integer n in its own line (1 ≤ n ≤ 10^6).

    The second line contains n positive integers — the i-th number in this line is equal to ai (1 ≤ ai ≤ 3·106), the number written on the i-th ball.

    The next line contains an integer m (1 ≤ m ≤ 106), the number of questions you are being asked.

    Then, the following line contains m positive integers — the j-th number in this line is equal to the value of p (1 ≤ p ≤ 3·10^6) in the j-th question you are being asked.

    Output

    For each question, print the number of winning pairs of balls that exist for the given value of p in the separate line.

    Examples
    input
    5
    4 2 6 1 3
    4
    1 3 5 8
    output
    20
    18
    14
    10
    input
    2
    5 6
    2
    30 31
    output
    2
    0

    题意:

    给一个数列,问这里面有多少对的积大于等于p;


    思路:

    由于询问太多,所以要降低复杂度,可以反方向考虑,可以用总的方案数减去小于p的方案数,小于p的方案数;
    可以先把相同的数压缩,最的的复杂度是O(nlogn+m)


    AC代码:

    #include <bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    
    typedef  long long LL;
    
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e18;
    const int N=3e6+10;
    const int maxn=3e6;
    const double eps=1e-10;
    
    int m,a[N],b[N];
    LL num[N],sum[N],n;
    void Init()
    {
        sort(a+1,a+n+1);
        int cnt=0;
        For(i,1,n)
        {
            if(a[i]==a[i-1])num[cnt]++;
            else 
            {
                ++cnt;
                b[cnt]=a[i];
                num[cnt]=1;
            }
        }
        For(i,1,cnt)
        {
            For(j,1,i)
            {
                if((LL)b[i]*b[j]>=maxn)break;
                if(i==j)sum[b[i]*b[j]]+=num[i]*(num[i]-1);
                else sum[b[i]*b[j]]+=2*num[i]*num[j];
            }
        }
        //for(int i=1;i<30;i++)print(sum[i]);
        For(i,1,maxn)sum[i]+=sum[i-1];
    }
    int main()
    {
        read(n);
        For(i,1,n)read(a[i]);
        Init();
        read(m);
        int p;
        For(i,1,m)
        {
            read(p);
            print((LL)n*(n-1)-sum[p-1]);
        }
            return 0;
    }
    

      

  • 相关阅读:
    java语言程序设计与数据结构(基础版)第三章**3.4
    贪心练习:阿里巴巴与十四大盗————背包问题
    贪心练习最优装载问题
    贪心训练均分纸牌Noip2002
    排队打水问题(信息学奥赛一本通贪心算法)
    PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
    PAT甲题题解-1039. Course List for Student (25)-建立映射+vector
    PAT甲题题解-1038. Recover the Smallest Number (30)-排序/贪心,自定义cmp函数的强大啊!!!
    PAT甲题题解-1037. Magic Coupon (25)-贪心,水
    PAT甲题题解-1036. Boys vs Girls (25)-找最大最小,大水题
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5673476.html
Copyright © 2020-2023  润新知