ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【2019 CCPC 江西省赛】Trap 枚举+二进制枚举

2020-10-17 20:03:22  阅读:195  来源: 互联网

标签:arr const int CCPC long 枚举 2019 vec include


C - Trap

题意

给出 \(n\) 条边,问能组成几种等腰梯形。要满足一下要求:

  1. 不能是矩形
  2. 所有边长的 gcd 是1
  3. 全等的梯形只算一次

思路

枚举梯形的腰 \(x\) 和顶 \(y\),可以求出底的范围为:\([y+1,2*x+y-1]\)

因为还有一个条件为 \(gcd\) 为 1,那么我们可以预处理出一个数组 \(vec[N][N]\),\(vec[i]\) 存放和 \(i\) 互质的所有边长。

对于腰 \(x\) 和顶 \(y\)我们在 vec[\(gcd(x,y)\)] 中找在区间 \([y+1,2*x+y-1]\) 的个数,这时候特判一下 \(x\) 和 \(y\) 的个数避免多算。

比赛的时候因为我读错题意,以为矩形也可以,疯狂WA。。。赛后对拍发现不对劲,修改一下底的范围就过了。

代码

/*
 * @Autor: valk
 * @Date: 2020-08-21 11:06:28
 * @LastEditTime: 2020-10-16 20:47:12
 * @Description: 如果邪恶  是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
 */
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;

int arr[N], num[N];
vector<int> vec[N];
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &arr[i]);
        num[arr[i]]++;
    }
    sort(arr + 1, arr + 1 + n);
    n = unique(arr + 1, arr + 1 + n) - arr - 1;
    for (int i = 1; i <= 10000; i++) {
        for (int j = 1; j <= n; j++) {
            if (__gcd(i, arr[j]) == 1) {
                vec[i].pb(arr[j]);
            }
        }
    }
    ll ans = 0;
    for (int i = 1; i <= n; i++) { //腰
        if (num[arr[i]] < 2)
            continue;
        for (int j = 1; j <= n; j++) { //顶
            if (i == j && num[arr[i]] < 3)
                continue;
            int l = arr[j] + 1, r = arr[j] + 2 * arr[i] - 1;
            int gcd = __gcd(arr[i], arr[j]);
            int R = upper_bound(vec[gcd].begin(), vec[gcd].end(), r) - vec[gcd].begin();
            int L = upper_bound(vec[gcd].begin(), vec[gcd].end(), l - 1) - vec[gcd].begin();
            int temp = R - L;
            if (num[arr[j]] == 1 && __gcd(arr[j], gcd) == 1 && arr[j] >= l && arr[j] <= r) {
                temp--;
            }//如果边长为arr[j]的边只有一条,并且还被计算到了底中,那么要减去这个
            if (num[arr[i]] == 2 && __gcd(gcd, arr[i]) == 1 && arr[i] >= l && arr[i] <= r) {
                temp--;
            }//腰同理
            ans += temp;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
/*
6
1 1 10 8 8 5 
*/

标签:arr,const,int,CCPC,long,枚举,2019,vec,include
来源: https://www.cnblogs.com/valk3/p/13832331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有