2017.9.6 外星人 思考记录

来源:互联网 发布:合理利用网络教学反思 编辑:程序博客网 时间:2024/04/29 18:42

这题做了好久、、

首先我非常zz的无视了提示、、

打表找规律半天才发现还有提示、

然后就是说每次操作都会把一个2给去掉,素数拆成它-1;

所以当然就是要看给出的数有多少2就可以了、

这个直接递推是O(n)的、、  素数sqrt(n)个  * 分解sqrt(n) 、类似递推    不过好像只有我这么写、其他题解都是线筛一块求了、我果然是zz

然后用看一开始有没有给出2,有的话答案++;

**题目,不给m或n的范围

然后就可以了


码:

#include<iostream>#include<cstdio>using namespace std;#define N 100005#define ll long longll n,tot,su[N],i,j,phi[N],cnt,ans,m,x,y,f[N],T;bool he[N];void eular(int n){int i;for(i=2;i<=n;i++){if(!he[i]){su[++tot]=i;}for(j=1;su[j]*i<=n&&j<=tot;j++){ll k=su[j]*i;he[k]=1;if(i%su[j]==0)break;}}}int main(){     eular(100005);     f[2]=1;for(i=2;i<=tot;i++){ x=su[i]-1; cnt=0;while(!(x%2)){x/=2;cnt++;}for(j=3;j*j<=x;j++){while(!(x%j)){cnt+=f[j];x/=j;}}cnt+=f[x];f[su[i]]=cnt;}scanf("%lld",&T);while(T--){ans=1;scanf("%lld",&m);for(i=1;i<=m;i++){scanf("%lld",&x);scanf("%lld",&y);    if(x==2)ans--;ans+=f[x]*y;}printf("%lld\n",ans);    }}