版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Joky_2002/article/details/81411591
题目链接
。。。。。模型转化错了被自己蠢到哭
就首先这题如果说质因数只有
的时候,操作次数肯定是
的个数
如果质因数不只有
的时候
考虑
的式子,做一次操作就相当于把每种质因数取一个出来,都减去
,然后再质因数分解回去
由于质数除了
都是奇数,所以减
再质因数分解肯定会多很多
出来
形式化点,如果存在除了
以外的质因数,我们做一次操作 多出的
的个数
而我们每次最多只能删掉
个
,稍加分析就可以得出
答案就是 能分出的
的个数
是否为奇数
因为奇数的时候只有第一次操作没有
可以消,其余操作每次都有
而“能分出的 的个数这个东西”是能线性筛出来的
然后这样就做完了
代码:
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF = 2147483647;
const int maxn = 100010;
LL ans,f[maxn],pri[maxn],tot;
bool mark[maxn];
inline LL getint()
{
LL ret = 0,f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar();
return ret * f;
}
int main()
{
#ifdef AMC
freopen("AMC1.txt","r",stdin);
#endif
f[2] = 1;
for (int i = 2; i <= 100000; i++)
{
if (!mark[i])
pri[++tot] = i , f[i] = i == 2 ? 1 : f[i - 1];
for (int j = 1; j <= tot; j++)
{
if (i * pri[j] > 100000) break;
mark[i * pri[j]] = 1;
f[i * pri[j]] = f[i] + f[pri[j]];
if (i % pri[j] == 0) break;
}
}
int t = getint();
while (t--)
{
ans = 0;
int n = getint(),flag = 0;
for (int i = 1; i <= n; i++)
{
LL p = getint(),q = getint();
ans += f[p] * q;
flag += !(p & 1);
}
if (!flag) ans++;
printf("%lld\n",ans);
}
return 0;
}