t1 循环
#include<cstdio> using namespace std; int x,a=1;bool v[105]; int main(){ freopen("number.in","r",stdin); freopen("number.out","w",stdout); scanf("%d",&x); a=x%=100; for(int i=1;!v[a];++i){ printf("%d ",a); v[a]=1; a*=x;a%=100; } printf("%d",a); return 0; }
t2漫步P3111
#include<cstdio> using namespace std; int n,v[100005],ans=1,x; int main(){ // freopen("jog.in","r",stdin); // freopen("jog.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%*d%d",&v[i]); x=v[n]; for(int i=n-1;i;--i) if(v[i]<=x) ++ans,x=v[i]; printf("%d",ans); return 0; }
t4 结队 merge 洛谷 P1621
N^2的暴力,A到B的任意两个数如果有公共质因子就合并它们所在的集合。很明显是用并查集来维护合并集合这个工作。时间复杂度O((B-A)^2)
优化:题目让我们找两个公共质因数 ≥P≥P 的,不在一个集合里的数,并合并它们。我们不这样找
枚举每一个质数primes[i]
,计算出第一个
大于A
的primes[i]的倍数
(题目要求的)记为tt,然后从t+primes[i]t+primes[i]一直枚举到BB(每次增长一个primes[i]primes[i],毕竟要求必须有primes[i]primes[i]这个数作为质因数),每次用并查集合并tt和当前枚举到的这个数
3 5 7 9 11 13 ...
12 15
15和12合并 20和15合并
18和12合并
#include<cstdio> using namespace std; bool np[25005]={1,1}; void shai(int x){//埃氏筛 for(int i=2;i*i<=x;++i) if(!np[i]) for(int j=i*i;j<=x;j+=i) np[j]=1; } int a,b,p,ans; int f[50005]; int find(int x){ return f[x]==x?x:f[x]=find(f[x]); } int main(){ // freopen("merge.in","r",stdin); // freopen("merge.out","w",stdout); scanf("%d%d%d",&a,&b,&p); shai(b/2); for(int i=a;i<=b;++i) f[i]=i; ans=b-a+1; for(int i=p;i<=b/2;++i) if(!np[i]){ int j=(a/i+(bool)(a%i))*i;//第一个大于a的质数的数3的倍数12>10,10/3 + (if 10%3 > 0 -> 1)*3->4*3 int u=find(j); for(;j<=b;j+=i){ int v=find(j); if(u!=v) f[v]=u,--ans; } } printf("%d",ans); return 0; }