zoukankan      html  css  js  c++  java
  • 【莫比乌斯反演+树状数组+分块求和】GCD Array

    https://www.bnuoj.com/v3/contest_show.php?cid=9149#problem/I

    【题意】

    给定长度为l的一个数组,初始值为0;规定了两种操作:

    【思路】

    找到了一个讲解很清楚的博客http://www.cnblogs.com/flipped/p/HDU4947.html

    【Accepted】

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <stack>
      7 #include <queue>
      8 #include <string>
      9 #include <vector>
     10 #include <set>
     11 #include <map>
     12 #include <cassert>
     13 using namespace std;
     14 
     15 #define CLR(a,b) memset(a,b,sizeof(a))
     16 typedef long long LL;
     17 const int N = 200000+20;
     18 bool check[N];
     19 int mu[N],prime[N];
     20 
     21 vector<int> fac[N];
     22 LL f[N];
     23 int l,q;
     24 
     25 void Mobius()
     26 {
     27     CLR(check, 0);
     28     mu[1] = 1;
     29     int tot = 0;
     30     for(int i = 2; i < N ; i++){
     31         if(!check[i]){
     32             prime[tot ++] = i;
     33             mu[i] = -1;
     34         }
     35         for(int j = 0 ;j < tot; j ++){
     36             if(i * prime[j] >= N)break;
     37             check[i * prime[j]] = true;
     38             if(i % prime[j] == 0){
     39                 mu[i * prime[j]] = 0;
     40                 break;
     41             }else{
     42                 mu[i * prime[j]] = -mu[i];
     43             }
     44         }
     45     }
     46     for(int i = 1 ;i < N ; i++){
     47         for(int j = i ; j < N ; j += i){
     48             fac[j].push_back(i);
     49         }
     50     }
     51 }
     52 
     53 inline LL sum(int p){
     54     LL s = 0;
     55     while(p > 0){
     56         s += f[p];
     57         p -= p & (-p);
     58     }
     59     return s;
     60 }
     61 
     62 inline void add(int p,int v){
     63     while(p <= l){
     64         f[p] += v;
     65         p += (p) & (-p);
     66     }
     67 }
     68 
     69 void update(int n,int d,int v){
     70     if(n % d != 0)return;
     71     
     72     n = n/d;
     73     for(int i = 0 ;i < fac[n].size() ; i++){
     74         int q = fac[n][i];
     75         add(q * d, v * mu[q]);
     76     }
     77 }
     78 
     79 LL query(int p)
     80 {
     81     LL ans = 0;
     82     for(int i = 1,last = i ; i <= p ; i = last + 1){
     83         last = p/(p/i);
     84         ans += (LL)(p/i) * (sum(last) - sum(i-1)) ;
     85     }
     86     return ans;
     87 }
     88 
     89 int main()
     90 {
     91     Mobius();
     92     int cas = 0;
     93     while(~scanf("%d%d",&l,&q)){
     94         if(l == 0 && q == 0)break;
     95         CLR(f, 0);
     96         cas ++;
     97         printf("Case #%d:
    ",cas);
     98         while(q--){
     99             int t;
    100             scanf("%d",&t);
    101             if(t == 1){
    102                 int n,d,v;
    103                 scanf("%d%d%d",&n,&d,&v);
    104                 update(n, d, v);
    105             }else{
    106                 int x;
    107                 scanf("%d",&x);
    108                 printf("%I64d
    ",query(x));
    109             }
    110         }
    111     }
    112     return 0;
    113 }
    114 
    115 /*
    116 
    117  6 4
    118  1 4 1 2
    119  2 5
    120  1 3 3 3
    121  2 3
    122  0 0
    123 
    124 */
    View Code

     

     

  • 相关阅读:
    神秘题目4
    神秘题目3
    神秘题目2
    AC自动机
    Fence Obstacle Course 题解
    Fractal Streets
    龟速乘
    快速幂
    Stall Reservation
    Sunscreen
  • 原文地址:https://www.cnblogs.com/itcsl/p/7133565.html
Copyright © 2011-2022 走看看