• Gym 101981J


    题目链接:http://codeforces.com/gym/101981/attachments

    题解:

    考虑每个质因子对于整体答案的贡献。

    拿第二组样例算一算就不难发现:第 p 个位置上的数,其包含的任意一个素因子,它原本应当产生的贡献有 (np+1)p(n−p+1)⋅p,

    但是考虑到若其前面出现过一样的素数,那么应当减去一些重复计算的区间。假设它前面的和它一样的素数,最后一次出现在 q 位置,那么就应当减去 (n−p+1)⋅q,即 a[p]a[p] 包含的任意一个质因子其产生的贡献为 (np+1)p(np+1)q=(np+1)(pq)。

    不妨用 pos[i][k]pos[i][k] 来存储每个素因子的 “pp”,pos[i][k1]pos[i][k−1] 存储每个素因子的 “qq”。换句话说,pos[i][k]pos[i][k] 代表某个素因子 ii 在 a[1n]a[1∼n] 中第 kk 次“出现”的位置是 pos[i][k]pos[i][k];特别地,令 pos[i][0]=0pos[i][0]=0。那么对于任意素因子 ii,它对答案的贡献是 (npos[i][k]+1)(pos[i][k]pos[i][k1])(n−pos[i][k]+1)⋅(pos[i][k]−pos[i][k−1])。

    我们可以对 a[1n]a[1∼n] 分解质因数,然后更新相应的 pos[i][k]pos[i][k]。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+5;
    int n,t,a[maxn];
    vector<int> pos[maxn];
    int prime[maxn],check[maxn];
    void LinePrime() {
        t = 0;
        for(int i=2; i<maxn; i++) {
            if(check[i]==0) prime[t++] = i;
            for(int j=0; j<t; j++) {
                if(i*prime[j]>maxn) break;
                check[i*prime[j]] = 1;
                if(i%prime[j]==0) break;
            }
        }
    }
    void dec(int p) {
        int num = a[p];
        for(int i=0; i<t&&prime[i]*prime[i]<=num; i++) {
            if(num%prime[i]==0)  pos[prime[i]].push_back(p);
            while(num%prime[i]==0) num /= prime[i];
        }
        if(num>1) pos[num].push_back(p);
    }
    void init(){
        LinePrime();
        for(int i=0; i<t; i++){
            pos[prime[i]].push_back(0);
        } 
          
    }
    int  main() {
        ll ans = 0;
        init();
        cin>>n;
        for(int i=1; i<=n; i++) {
            cin>>a[i];
            dec(i);
        }
        for(int i=0;i<t;i++){
            for(int j=1;j<pos[prime[i]].size();j++){
                ans+=(ll)(n-pos[prime[i]][j]+1)*(pos[prime[i]][j]-pos[prime[i]][j-1]);
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    然而,我的逻辑是 考虑若其后面出现一样的素数,就减去重复计算的区间。假设它后面的和它一样的素数,最近一次出现在 q 位置,那么就应当减去 (n−q+1)⋅p

    即 a[p]a[p] 包含的任意一个质因子其产生的贡献为 (np+1)p(n−q+1)⋅p=p(q-p),但是答案总是小于正确答案。。。

    错误代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+5;
    int n,t,a[maxn];
    vector<int> pos[maxn];
    int prime[maxn],check[maxn];
    void LinePrime() {
        t = 0;
        for(int i=2; i<maxn; i++) {
            if(check[i]==0) prime[t++] = i;
            for(int j=0; j<t; j++) {
                if(i*prime[j]>maxn) break;
                check[i*prime[j]] = 1;
                if(i%prime[j]==0) break;
            }
        }
    }
    void dec(int p) {
        int num = a[p];
        for(int i=0; i<t&&prime[i]*prime[i]<=num; i++) {
            if(num%prime[i]==0)  pos[prime[i]].push_back(p);
            while(num%prime[i]==0) num /= prime[i];
        }
        if(num>1) pos[num].push_back(p);
    }
    void init() {
        LinePrime();
        for(int i=0; i<t; i++) {
            pos[prime[i]].push_back(0);
        }
    
    }
    int  main() {
        ll ans = 0;
        init();
        cin>>n;
        for(int i=1; i<=n; i++) {
            cin>>a[i];
            dec(i);
        }
    
        for(int i=0; i<20; i++) {
            if(pos[prime[i]].size()==2){
                ans += (ll)(n-pos[prime[i]][1]+1)*pos[prime[i]][1]; 
            } 
            for(int j=1; j<pos[prime[i]].size()-1; j++) {
                cout<<"Prime="<<prime[i]<<endl;
                cout<<"q="<<pos[prime[i]][j]<<endl;
                cout<<"p="<<pos[prime[i]][j+1]<<endl;
                cout<<"P-q="<<pos[prime[i]][j+1]-pos[prime[i]][j]<<endl;
                ans+=(ll)pos[prime[i]][j]*(pos[prime[i]][j+1]-pos[prime[i]][j]);
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    easyui 之ComboTree 用法Demo
    sql like in 语句获取以逗号分割的字段内的数据
    基于Lumisoft.NET组件的POP3邮件接收和删除操作
    如何在滚动报表时保持标题可见 (Reporting Services)
    5个最顶级jQuery图表类库插件-Charting plugin
    无限极分类查询
    JS编码,解码. asp.net(C#)对应解码,编码
    JQuery.Ajax之错误调试帮助信息
    项目经理需要具备的11项人际关系软技能
    jquery easyui DataGrid 动态的改变列显示的顺序
  • 原文地址:https://www.cnblogs.com/Lemon1234/p/11625015.html
Copyright © 2020-2023  润新知