• 2019CCPC-江西省赛C题 HDU6569 GCD预处理+二分


    Trap

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 100    Accepted Submission(s): 39


    Problem Description
    Avin is studying isosceles trapezoids. An isosceles trapezoid is a convex quadrilateral with two opposite parallel bases, two equal-length legs and positive area. In this problem, we further require that the two legs are not parallel. Given n segments, you are asked to find the number of isosceles trapezoids whose 4 edges are from these segments and the greatest common divisor of their lengths is 1. Two congruent isosceles trapezoids are counted only once.
     
    Input
    The first line contains a number n (4 ≤ n ≤ 2, 000). The second line contains n numbers, each of which represents the length of a segment (the length is within [2, 10000]).
     
    Output
    Print the number of non-congruent isosceles trapezoids.
     
    Sample Input
    5
    4 4 2 8 9
    6
    4 4 4 2 8 9
     
    Sample Output
    2
    3
     
    题意 n条线段,每条线段的长度为ai,问能够组成等腰梯形的方案数,要求四条边的gcd为1,且不是矩形,即上底下底不能相等。(4<=n<=2000,2<=ai<=10000)
    解析 n只有1000 我们可以先排序去重,然后$n^2$枚举 上底 i ,下底 j,我们要找有多少个数x 满足 x的数量>=2 且 长度能与上底下底组成四边形 且 x与上底下底的gcd的gcd等于1,
    所以我们预处理出来一些东西 二分去查找, 上底下底的gcd=1的时候要处理一下。
    代码
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    vector<int> a,b,g[maxn];
    int num[maxn];
    int main()
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++){
            int x;
            cin>>x;
            num[x]++;
            a.push_back(x);
        }
        sort(a.begin(),a.end());
        a.erase(unique(a.begin(),a.end()),a.end());
        for(int i=0;i<=10000;i++){
            if(num[i]>=2)
                b.push_back(i);
        }
        for(int i=1;i<=10000;i++){
            for(int j=0;j<(int)b.size();j++){
                if(__gcd(i,b[j])==1)
                    g[i].push_back(b[j]);
            }
        }
        ll ans=0;
        for(int i=0;i<(int)a.size();i++){
            for(int j=i+1;j<(int)a.size();j++){
                int limit = (a[j]-a[i])%2==0?(a[j]-a[i])/2+1:(a[j]-a[i]+1)/2;
                int d = __gcd(a[i],a[j]);
                int index = lower_bound(g[d].begin(),g[d].end(),limit)-g[d].begin();
                ans=ans+(int)g[d].size()-index;
                if(d==1){
                    if(num[a[i]]==2&&a[i]>=limit)ans--;
                    if(num[a[j]]==2&&a[j]>=limit)ans--;
                }
            }
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    VC++MFC对话框程序中给对话添加背景图片
    C++中的引用
    64位Ubuntu 13.04 安装Bochs 2.3.5
    笔记
    ORG 07C00H的意思
    编译三思
    《黑客与画家》笔记
    linux 2.6up的设备和设备驱动模型
    linux嵌入式系统驱动程序的阻塞与异步
    【转】PWM占空比和分辨率
  • 原文地址:https://www.cnblogs.com/stranger-/p/11225760.html
Copyright © 2020-2023  润新知