[bzoj2749][數論]外星人
阿新 • • 發佈:2018-12-10
Description
Input
Output
輸出test行,每行一個整數,表示答案。
Sample Input
1
2
2 2
3 1
Sample Output
3
HINT
Test<=50 Pi<=105,1<=Q1<=109
題解
其實HINT裡面那張圖告訴了我們做法… 如果是大於2的質數,那麼每次操作會多出至少一個2 如果有2,那麼每次操作會消去一個2 預處理f[i]表示第i個數能搞出多少個2 答案就是2的個數 注意如果一開始沒有2,那麼先要一次操作弄出來至少一個2
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #define LL long long using namespace std; inline int read() { int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int f[110000],pri[110000],pr; bool v[110000]; void get_pri() { f[1]=1;memset(v,true,sizeof(v)); for(int i=2;i<=100000;i++) { if(v[i])f[i]=f[i-1],pri[++pr]=i; for(int j=1;j<=pr&&i*pri[j]<=100000;j++) { v[i*pri[j]]=false;f[i*pri[j]]=f[i]+f[pri[j]]; if(i%pri[j]==0)break; } } } int main() { get_pri(); int T=read(); LL ans; while(T--) { ans=0; int n=read(); for(int i=1;i<=n;i++) { int x=read(),m=read(); if(i==1&&x!=2)ans++; ans+=(LL)f[x]*m; } printf("%lld\n",ans); } return 0; }