Problem
Thoughts
FBI warning:Thoughts是错的,正解是下面的Solution
一开始看比较懵逼,然后就开始了大力推公式
第一次迭代
第二次迭代
第k次迭代
若为1,则 ∀pi−k≤1,(qi−k≤0||pi≤1) ∀ p i − k ≤ 1 , ( q i − k ≤ 0 | | p i ≤ 1 )
然而这并不对,因为拆开后的形式并不一定是标准分解,那么大力推公式就会有毛病
Solution
可以发现,做质因数分解之后,qi减小了1,而pi-1的指数增加了1,可以感性地理解为pi向pi-1,以及更多次迭代之后出现的所有质因数都汇聚了1的水,而自己的水量减小了1。其次,汇聚最多的应该是2,因为最后都会汇集到2,所以直接考虑2的贡献即可,在线性筛的时候处理。
如果你要理性地想。。就是由提示可以知道每次取phi,就是使得一个质因数pi变成pi-1,显然仅有phi(2)是等于1的,而每取一次phi,都只能化简一个2变为1。对于大于2的质数,都是奇数,那么p-1就是一个偶数,就必定可以得到因数2。注意当原来就没有pi=2时,由于第一次无法化简掉一个2,所以ans要+1。
Code
#include <cstdio>
#define rg register
using namespace std;
typedef long long ll;
const int maxn=100010;
int z,n,p,q,tot,pri[maxn],cnt[maxn];
ll ans;
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
void init()
{
cnt[1]=1;
for(rg int i=2;i<=100000;i++)
{
if(!cnt[i]) pri[++tot]=i,cnt[i]=cnt[i-1];
for(int j=1;j<=tot&&i*pri[j]<=100000;j++)
{
cnt[i*pri[j]]=cnt[i]+cnt[pri[j]];
if(i%pri[j]==0) break;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
init();
read(z);
while(z--)
{
read(n);ans=1;
for(rg int i=1;i<=n;i++)
{
read(p);read(q);
ans+=(ll)cnt[p]*q;
if(p==2) ans--;
}
printf("%lld\n",ans);
}
return 0;
}