[51nod1678] lyk with gcd (+ enum Mobius inversion factor)

Click here to see the problem surface

Generally meaning of the questions: a length \ (n-\) array, to achieve two operations: modifying single point, given \ (I \) seeking \ (\ sum_ {j = 1 } ^ na_j [gcd (i, j) = 1] \) .

Mobius inversion

Consider asking push a push operation of the equation:

\[\sum_{j=1}^na_j[gcd(i,j)=1]\]

According Mobius inversion general routine, we know \ (\ sum_ {P | X} \ MU (P) = [X =. 1] \) , we enumerate a \ (P \) :

\[\sum_{j=1}^na_j\sum_{p|i,p|j}\mu(p)\]

Adjustment enumeration order to obtain:

\[\sum_{p|i}\mu(p)\sum_{j=1}^na_j[p|j]\]

Taking into account the number of divisor of a number of small, so we can directly enumerate \ (the p-\) , then as long as the maintenance satisfy \ (p | j \) is \ (a_j \) the sum of, you can find the answer.

Then we can see about the same number as the number of a number of small, single-point modification, we can modify the position of the enumerator about the number and modify answers about the number of each, so that we can achieve maintained.

Code

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define IT vector<int>::iterator
#define pb push_back
using namespace std;
int n,a[N+5],s[N+5];vector<int> v[N+5];
class FastIO
{
    private:
        #define FS 100000
        #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
        #define pc(c) (C==E&&(clear(),0),*C++=c)
        #define tn (x<<3)+(x<<1)
        #define D isdigit(c=tc())
        int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
    public:
        I FastIO() {A=B=FI,C=FO,E=FO+FS;}
        Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
        Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
        Tp I void writeln(Con Ty& x) {write(x),pc('\n');}
        I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;} 
}F;
class LinearSieve//线性筛预处理莫比乌斯函数
{
    private:
        int Pt,P[N+5],mu[N+5];
    public:
        I int operator [] (CI x) Con {return mu[x];}
        I LinearSieve()
        {
            mu[1]=1;for(RI i=2,j;i<=N;++i)
                for(!P[i]&&(mu[P[++Pt]=i]=-1),j=1;j<=Pt&&1LL*i*P[j]<=N;++j)
                    if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=-mu[i];else break;
        }
}L;
int main()
{
    RI Qt,i,j,op,x,y,t;IT it;for(F.read(n),F.read(Qt),i=1;i<=n;++i)
    {
        for(F.read(a[i]),j=1;1LL*j*j<=i;++j) !(i%j)&&(v[i].pb(j),i^(j*j)&&(v[i].pb(i/j),0));//预处理约数
        for(it=v[i].begin();it!=v[i].end();++it) s[*it]+=a[i];//预处理答案
    }
    W(Qt--) switch(F.read(op),F.read(x),op)
    {
        case 1:for(F.read(y),it=v[x].begin();it!=v[x].end();++it) s[*it]+=y-a[x];a[x]=y;break;//单点修改,枚举约数进行修改
        case 2:for(t=0,it=v[x].begin();it!=v[x].end();++it) t+=L[*it]*s[*it];F.writeln(t);break;//询问,枚举约数统计答案
    }return F.clear(),0;
}

Guess you like

Origin www.cnblogs.com/chenxiaoran666/p/51nod1678.html