https://ac.nowcoder.com/acm/contest/923/B
我真是个辣鸡,现在才知道线性筛,
思路:对于每个数字的阶乘,开一个一维数组记录每个数字出现的个数,先利用一维差分将每个数字的阶乘中出现都得数字累加个数,然后再利用线性筛中,已知每个数字的最小质因数是什么,在比较过程中,我们可以从大到小比较,如果发现对于同一个数字它的出现次数不同,我们可以把这个数字划分为两个数字的乘积形式(已知每个数字的最小质因数都是固定的),如果数字相同就不用管了,最后在遍历一遍看看是否每个位置的数字个数都相同就可以了。
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int v[maxn],prime[maxn]; int a[maxn],b[maxn]; int da[maxn],db[maxn]; void primes(int n) { memset(v,0,sizeof(v)); int m=0; for(int i=2; i<=n; i++) { if(v[i]==0) { v[i]=i; prime[++m]=i; } for(int j=1; j<=m; j++) { if(prime[j]>v[i]||prime[j]>n/i) break; v[i*prime[j]]=prime[j]; } } } int main() { primes(100000); int t; scanf("%d",&t); for(int it=1; it<=t; it++) { int n,m; scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(da,0,sizeof(da)); memset(db,0,sizeof(db)); for(int i=1; i<=n; i++) { int t; scanf("%d",&t); if(t>1) { da[2]++; da[t+1]--; } } for(int i=1; i<=m; i++) { int t; scanf("%d",&t); if(t>1) { db[2]++; db[t+1]--; } } for(int i=2; i<=1e5; i++) { da[i]+=da[i-1]; db[i]+=db[i-1]; a[i]+=da[i]; b[i]+=db[i]; } for(int i=1e5; i>=2; i--) { if(a[i]!=b[i]) { int zy1=i/v[i]; int zy2=i/zy1; int ta=a[i]; int tb=b[i]; a[i]=b[i]=0; a[zy1]+=ta; a[zy2]+=ta; b[zy1]+=tb; b[zy2]+=tb; } } int flag=1; for(int i=2; i<=1e5; i++) { if(a[i]!=b[i]) { // printf("%d %d\n",a[i],b[i]); flag=0; break; } } if(flag) printf("equal\n"); else printf("unequal\n"); } }
原文地址:https://www.cnblogs.com/dongdong25800/p/11067710.html
时间: 2024-11-01 22:40:48