zoukankan      html  css  js  c++  java
  • Geometric Progression---cf 567C(求组合方式,map离散)

    题目链接:http://codeforces.com/contest/567/problem/C

    题意就是有n个数现在要让 ai aj  ak 构成公比为K的等比数列(i < j < k);求有多少种组合方法;

    我们可以对 a[i] 找 a[i]/k 和 a[i]*k ,设a[i]前面有 x个a[i]/k ;后面有y个 a[i]*k ;那么答案就是所有的x*y的和;由于数据比较大无法引用下标, 所以用map离散一下

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <vector>
    #include <map>
    #include <string>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define met(a, b) memset(a, b, sizeof(a))
    #define N 200005
    typedef long long LL;
    
    int main()
    {
        int n;
    
        LL  k, a[N];
    
        while(scanf("%d %I64d", &n, &k)!=EOF)
        {
            map<LL, LL> mp1, mp2;
    
            for(int i=1; i<=n; i++)
            {
                scanf("%I64d", &a[i]);
    
                mp1[a[i]]++;
            }
    
            LL ans = 0;
    
            for(int i=n; i>=1; i--)///倒着来便于统计mp2[x]的个数,即倒着来的数的个数;
            {
                mp1[a[i]] --;///正着来的要减减;
    
                if(a[i]%k==0)
    
                    ans += mp1[a[i]/k] * mp2[a[i]*k];
    
                mp2[a[i]] ++;
            }
    
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    View Code

    这是一个用二分写的,不用map离散化的代码;

    LL a[maxn], b[maxn], l[maxn], r[maxn], n, m;
    LL bin_sreach (LL x)
    {
        LL high = m-1, low = 0;
        while (high >= low)
        {
            LL mid = (high + low) / 2;
            if (b[mid] == x)
                return mid;
            if (b[mid] < x)
                low = mid + 1;
            else
                high = mid -1;
        }
        return n;
    }
    int main ()
    {
        LL k;
        while (scanf ("%I64d %I64d", &n, &k) != EOF)
        {
            for (LL i=0; i<n; i++)
            {
                scanf ("%I64d", &a[i]);
                b[i] = a[i];
            }
            sort (b, b+n);
            m = unique(b, b+n) - b;
            memset (l, 0, sizeof(l));
            memset (r, 0, sizeof(r));
            for (LL i=0; i<n; i++)
            {
                LL x = bin_sreach(a[i]);
                l[x] ++;
            }
            __int64 ans = 0;
            for (LL i=n-1; i>=0; i--)
            {
                LL x, y, z;
                x = y = n;
                z = bin_sreach(a[i]);
                l[z] --;
                if (a[i] % k == 0)
                    x = bin_sreach(a[i]/k);
                y = bin_sreach(a[i]*k);
                ans += l[x] * r[y];
                r[z] ++;
            }
            printf ("%I64d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【转载】Android IntentService使用全面介绍及源码解析
    【转载】作为Android开发者,你真的熟悉Activity吗?
    【转载】从使用到原理学习Java线程池
    Linux 基础知识+常见命令
    Python中的字典合并
    Python的__hash__函数和__eq__函数
    C#中实现Hash应用
    深入理解python元类
    Docker搭建Gitlab服务器
    python的加密方式
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5167533.html
Copyright © 2011-2022 走看看