• HDU


    Given you a sequence of number a 1, a 2, ..., a n, which is a permutation of 1...n.
    You need to answer some queries, each with the following format:
    Give you two numbers L, R, you should calculate sum of gcd(a[i], a[j]) for every L <= i < j <= R.

    InputFirst line contains a number T(T <= 10),denote the number of test cases.
    Then follow T test cases.
    For each test cases,the first line contains a number n(1<=n<= 20000).
    The second line contains n number a 1,a 2,...,a n.
    The third line contains a number Q(1<=Q<=20000) denoting the number of queries.
    Then Q lines follows,each lines contains two integer L,R(1<=L<=R<=n),denote a query.OutputFor each case, first you should print "Case #x:", where x indicates the case number between 1 and T.
    Then for each query print the answer in one line.Sample Input

    1
    5
    3 2 5 4 1
    3
    1 5
    2 4
    3 3

    Sample Output

    Case #1:
    11
    4
    0

    题意:给定N个数,已经Q次询问,每次询问这个区间的两两GCD之和。

    思路:之前做过一个类似的题,问区间两两有多少对互质,维护每个数的因子个数,即把下面的公式换成莫比乌斯系数瞎搞即可。

    51nod1439:https://www.cnblogs.com/hua-dong/p/9141249.html

    这里直接推。不过上次自己推的,这里我没有想出来,百度了一下。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=20010;
    struct in{int l,r,id;}s[maxn];
    bool cmp(in w,in v){
        if(w.l/100==v.l/100) return w.r<v.r;
        return w.l/100<v.l/100;
    }
    int a[maxn],ans[maxn],vis[maxn],phi[maxn];
    int num[maxn],p[maxn],cnt,res;
    vector<int>G[maxn];
    void solve()
    {
        phi[1]=1;
        for(int i=2;i<maxn;i++){
            if(!vis[i]) p[++cnt]=i,phi[i]=i-1;
            for(int j=1;j<=cnt&&i*p[j]<maxn;j++){
                phi[i*p[j]]=phi[i]*phi[p[j]]; vis[i*p[j]]=1;
                if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j]; break;}
            }
        }
        for(int i=1;i<maxn;i++){
            for(int j=i;j<maxn;j+=i) G[j].push_back(i);
        }
    }
    void add(int x)
    {
        for(int i=0;i<G[x].size();i++){
            res+=phi[G[x][i]]*num[G[x][i]];
        }
        for(int i=0;i<G[x].size();i++) num[G[x][i]]++;
    }
    void del(int x)
    {
        for(int i=0;i<G[x].size();i++) num[G[x][i]]--;
        for(int i=0;i<G[x].size();i++){
            res-=phi[G[x][i]]*num[G[x][i]];
        }
    }
    int main()
    {
        solve();
        int T,N,Q,L,R,C=0;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&N);
            rep(i,1,N) scanf("%d",&a[i]);
            scanf("%d",&Q);
            rep(i,1,Q) scanf("%d%d",&s[i].l,&s[i].r),s[i].id=i;
            sort(s+1,s+Q+1,cmp);
            L=0; R=0; res=0; memset(num,0,sizeof(num));
            rep(i,1,Q){
                while(L<s[i].l) del(a[L++]);
                while(R>s[i].r) del(a[R--]);
                while(L>s[i].l) add(a[--L]);
                while(R<s[i].r) add(a[++R]);
                ans[s[i].id]=res;
            }
            printf("Case #%d:
    ",++C);
            rep(i,1,Q) printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    C# 定时任务
    Web电子签集成开发笔记
    海康威视二次开发笔记
    SQL Server 2008R2创建自动备份计划
    图片上传及显示(包含多文件)
    程序员的孤独
    Iframe用法
    Bootstrap模态框(MVC)
    工作时发现的问题【组织管理】【客户对接】【项目流程】
    为啥有人觉得你写程序写得好,有人觉得你不称职
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9905846.html
Copyright © 2020-2023  润新知