【bzoj2749】[HAOI2012]外星人
阿新 • • 發佈:2018-11-19
題目連結
。。。。。模型轉化錯了被自己蠢到哭
就首先這題如果說質因數只有
的時候,操作次數肯定是
的個數
如果質因數不只有
的時候
考慮
的式子,做一次操作就相當於把每種質因數取一個出來,都減去
,然後再質因數分解回去
由於質數除了
都是奇數,所以減
再質因數分解肯定會多很多
出來
形式化點,如果存在除了
以外的質因數,我們做一次操作 多出的
的個數
而我們每次最多隻能刪掉
個
,稍加分析就可以得出
答案就是 能分出的
的個數
是否為奇數
因為奇數的時候只有第一次操作沒有
可以消,其餘操作每次都有
而“能分出的 的個數這個東西”是能線性篩出來的
然後這樣就做完了
程式碼:
#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;
}