zoukankan      html  css  js  c++  java
  • HDU-6053 TrickGCD

    题目连接:

    https://vjudge.net/problem/HDU-6053

    Description

    You are given an array A , and Zhu wants to know there are how many different array B satisfy the following conditions?

    • 1≤Bi≤Ai
    • For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1...br)≥2

    Input

    The first line is an integer T(1≤T≤10) describe the number of test cases.

    Each test case begins with an integer number n describe the size of array A.

    Then a line contains n numbers describe each element of A

    You can assume that 1≤n,Ai≤10^5

    Output

    For the kth test case , first output "Case #k: " , then output an integer as answer in a single line . because the answer may be large , so you are only need to output answer mod 109+7

    Sample Input

    1
    4
    4 4 4 4

    Sample Output

    Case #1: 17

    Hint

    题意

    给出序列A,求出满足条件的序列B,使得:
    $ 1 <= Bi <= Ai ( )gcd(B_1, B_2,B_3cdots,B_n) >= 2$

    题解:

    考虑用总的序列B个数减去gcd为1的序列B的个数,就是gcd大于等于2的个数。
    但是原本计算G[i]的式子由O(1)变成了O(n),也没法进行分块了,复杂度变成了O(n^2)
    可以把原本计算G[i]的式子(mu[i] * prod_{j=1}^nfrac{B_j}{i})

    简化为(mu[i] * prod_{j=1}^{frac{maxA[1-n]}{i}} j^{count(j)})

    这里的count(j)是A序列中除以i等于j的数的个数
    设sum[i]为A序列中小于等于i的数的个数则count(j) = sum[i(j+1)-1]-sum[ij-1]
    于是整体复杂度变为(sum_1^nfrac{maxA[1-n]}{i} = nlogn)

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int mx = 1e5+5;
    const int mod = 1e9+7;
    const int INF = 0x3f3f3f3f;
    typedef long long ll;
    
    bool vis[mx];
    int sum[mx], prim[mx], mu[mx], num[mx], cnt = 0;
    int a[mx];
    
    void get_mu(){
        mu[1] = 1;
        for(int i = 2; i< mx; i++){
            if(!vis[i]) {
                prim[++cnt] = i;
                mu[i] = -1;
                num[i] = 1;
            }
            for(int j = 1; j <= cnt && prim[j]*i < mx; j++) {
                vis[prim[j]*i] = 1;
                num[prim[j]*i] = num[i] + 1;
                if(i % prim[j] == 0) break;
                else mu[i*prim[j]] = -mu[i];
            }
        }
    }
    
    ll pow_mod(ll a, ll b) {
        ll ans = 1;
        while (b > 0) {
            if (b & 1) ans = ans * a % mod;
            a = a * a % mod;
            b /= 2;
        }
        return ans;
    }
    
    int main() {
        // freopen("in.txt", "r", stdin);
        // freopen("out1.txt", "w+", stdout);
        get_mu();
        int T, kase = 0;
        scanf("%d", &T);
    
        while (T--) {
            memset(a, 0, sizeof(a));
            memset(sum, 0, sizeof(sum));
            int n;
            scanf("%d", &n);
            ll tot = 1;
            int len = INF, mlen = 0;
            for (int i = 1; i <= n; i++) {
                int x;
                scanf("%d", &x);
                a[x]++;
                len = min(len, x);
                mlen = max(mlen, x);
                tot = tot * x % mod;
            }
            for (int i = 1; i < mx; i++) sum[i] = sum[i-1] + a[i];
            ll ans = 0;
            
            for (int i = 1; i <= len; i++) {
                ll tmp = mu[i];
                for (int j = 1; j <= mlen/i; j++) {//计算公约数为i的个数
                    tmp *= pow_mod(j, sum[min(i*(j+1)-1, mlen)]-sum[i*j-1]);
                    tmp %= mod;
                }
                ans += tmp;
                ans = (ans % mod + mod) % mod;
            }
            ans = ((tot-ans) % mod + mod) % mod;
            printf("Case #%d: %lld
    ", ++kase, ans);
        }
    
        return 0;
    }
    
  • 相关阅读:
    第一阶段:前端开发_使用JS完成注册页面表单校验完善
    第一阶段:前端开发_使用 JS 完成页面定时弹出广告
    第一阶段:前端开发_使用JS完成首页轮播图效果
    第一阶段:前端开发_使用JS完成注册页面表单校验
    三、Java基础工具(1)_常用类——日期类
    使MySQL支持emoji
    1. Two Sum [Array] [Easy]
    『IOS』 遇到问题记录(长期更新)
    [IOS] 详解图片局部拉伸 + 实现图片局部收缩
    【IOS】模仿"抽屉新热榜"动态启动页YFSplashScreen
  • 原文地址:https://www.cnblogs.com/bpdwn-cnblogs/p/11199282.html
Copyright © 2011-2022 走看看