zoukankan      html  css  js  c++  java
  • 2005: [Noi2010]能量采集

    2005: [Noi2010]能量采集

    链接

    分析

    答案要求 $ans=2sumlimits_{x=1}^n sumlimits_{y=1}^mgcd(x,y)-n imes m$

    主要求出中间的那一块就好了。

    思路一:

      容斥:f[i]表示gcd(x,y)=i的对数。(n/i)*(m/i)是gcd(x,y)=i的倍数 的对数。那么f[i] -= f[2*i] - f[3*i] ...就好了。

    思路二:

      莫比乌斯反演

    $ sumlimits_{x=1}^n sumlimits_{y=1}^mgcd(x,y)$
    $=sumlimits_p^{min(n,m)} p sumlimits_{x=1}^n sumlimits_{y=1}^m[gcd(x,y)=p]$
    $=sumlimits_p^{min(n,m)} p sumlimits_d^{min(frac{n}{p},frac{m}{p})}μ(d)frac{n}{pd} imes frac{m}{pd}$
    $ sumlimits_T^{min(n,m)} frac{n}{T} imes frac{m}{T} sumlimits_{p|T}p imes μ(frac{T}{p})$
    $=sumlimits_T^{min(n,m)} frac{n}{T} imes frac{m}{T} φ(T)$

    容斥:

     1 #include<cstdio>
     2 #include<iostream>
     3  
     4 using namespace std;
     5  
     6 typedef long long LL;
     7 const int N = 100100;
     8 LL f[N];
     9  
    10 int main() {
    11     LL n,m,ans = 0;
    12     cin >> n >> m;
    13     int mi = min(n,m);
    14     for (int i=mi; i>=1; --i) {
    15         f[i] = (n / i) * (m / i);
    16         for (int j=i+i; j<=mi; j+=i) {
    17             f[i] -= f[j];
    18         }
    19         ans += f[i] * i;
    20     }
    21     cout << 2 * ans - n * m;
    22     return 0;
    23 }
    24 
    View Code

    莫比乌斯+欧拉函数:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 inline int read() {
     6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     7     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     8 }
     9 
    10 const int N = 100010;
    11 int prime[N],phi[N],tot;
    12 bool noprime[N];
    13 
    14 void getphi(int n) {
    15     phi[1] = 1;
    16     for (int i=2; i<=n; ++i) {
    17         if (!noprime[i]) prime[++tot] = i,phi[i] = i-1;
    18         for (int j=1; j<=tot&&prime[j]*i<=n; ++j) {
    19             noprime[i * prime[j]] = true;
    20             if (i % prime[j] == 0) {
    21                 phi[i * prime[j]] = phi[i] * prime[j];
    22                 break; 
    23             }
    24             phi[i * prime[j]] = phi[i] * (prime[j]-1); 
    25         }
    26     }
    27     for (int i=1; i<=n; ++i) phi[i] += phi[i-1];
    28 }
    29 int main() {
    30     
    31     LL n,m;
    32     cin >> n >> m;
    33     LL mi = min(n,m);
    34     getphi((int)mi);
    35     LL ans = 0,pos = 0;
    36     for (int T=1; T<=mi; T=pos+1) {
    37         pos = min(n/(n/T),m/(m/T));
    38         ans += (n/T) * (m/T) * (phi[pos] - phi[T-1]);
    39     }
    40     cout << ans * 2 - n * m;    
    41     return 0;
    42 }
    View Code
  • 相关阅读:
    P2024 [NOI2001]食物链[扩展域并查集]
    poj1733 Parity game[带权并查集or扩展域]
    BZOJ1079 [SCOI2008]着色方案[组合计数DP]
    P1801 黑匣子[对顶堆]
    poj3784 Running Median[对顶堆]
    P1196 [NOI2002]银河英雄传说[带权并查集]
    poj1456 Supermarket[另类的并查集做法]
    P1955 [NOI2015]程序自动分析[离散化+并查集]
    BZOJ1306 [CQOI2009]match循环赛/BZOJ3139 [Hnoi2013]比赛[dfs剪枝+细节题]
    android的模拟器-Genymotion
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9225476.html
Copyright © 2011-2022 走看看