[haoi2012]外星人

艾莉欧在她的被子上发现了一个数字 ,她觉得只要找出最小的x使得,
::点击图片在新窗口中打开::
根据这个 她就能找到曾经绑架她的外星人的线索了。当然,她是不会去算,请你帮助她算出最小的x。

样例:

input:

1
2
2 2
3 1

output:

3

样例解释
::点击图片在新窗口中打开::
数据规模
30%的数据,n<=10^6 ,
60%的数据,x<=100  n 在 long long 范围内,
100%的数据, test<=50;pi<=10^5; 1<=qi<=10^9

题解:

设答案为f(N)

可以得出:

f(1<<n)=n(由题目提供的公式很容易得出)

意思就是

再分析一次转换:

每次转换时左边的(pi-1),如果pi不等于2,那么(pi-1)肯定是个偶数;

那么尝试对它右边的结构进行质因数分解,

piqi-1没法变,左边的pi-1是偶数,因此每次质因数分解,质因数2的指数会增大,而等到pi这些都分完了后,质因子只剩下2,那么就可以参照f(1<<n)的处理;

概括一下:

每次原数N phi后,都会产生2,而每次phi都会消掉一个2,因此我们只需要算出原数N的质因子一共会产生多少个2即可;

说起来很麻烦,理解至上;

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std;
#define up(i,j,n) for(int i=j;i<=n;i++)
#define LL long long
#define pii pair<int,int> 
#define FILE "dealing"
inline bool chkmin(int &x,int y){return x>y?(x=y,true):false;}
inline bool chkmax(int &x,int y){return x<y?(x=y,true):false;}
namespace IO{
    char buf[1<<15],*fs,*ft;
    int gc(){return (fs==ft&&((ft=(fs=buf)+fread(buf,1,1<<15,stdin)),fs==ft))?0:*fs++;}
    int read(){
        int x=0,ch=gc(),d=0;
        while(ch<'0'||ch>'9'){if(ch=='-')d=1;ch=gc();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
        return d?-x:x;
    }
}using namespace IO;
namespace OI{
    const int maxn(101000),inf(100000),mod(1000000007);
    int T,n,t[maxn],p[maxn],tail=0;
    LL f[maxn];
    void pre(){
        f[1]=1;
        for(int i=2;i<=inf;i++){
            if(!t[i])p[++tail]=i,f[i]=f[i-1];
            for(int j=1;j<=tail&&i*p[j]<=inf;j++){
                f[i*p[j]]=f[i]+f[p[j]];
                t[i*p[j]]=1;
                if(!(i%p[j]))break;
            }
        }
    }
    void slove(){
        T=read();
        pre();
        while(T--){
            n=read();LL del=1,p,q,ans=0;
            for(int i=1;i<=n;i++){
                p=read();q=read();
                ans+=f[p]*q;
                if(p==2)del=0;
            }
            printf("%I64d
",ans+del);
        }
    }
}
int main(){
    freopen(FILE".in","r",stdin);
    freopen(FILE".out","w",stdout);
    using namespace OI;
    slove();
    return 0;
}
原文地址:https://www.cnblogs.com/chadinblog/p/6019035.html