[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\n",ans+del); } } } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); using namespace OI; slove(); return 0; }