关于反素数的问题就不在说名,可以自己找题目去做
这里讲一下自己对约瑟夫环问题的理解,如果有错希望有人指明,,因为看了很多博客都没怎么看懂,
自己想了一下:这个问题线段树能处理的剩余空余的位置中的第几个位置,比如第一个2走了之后剩余3个人线段树可以找出剩余3人中的第几个,现在的问题就是怎么将剩余的几个人的第几个找出来,
打表代码
#include <iostream>
using namespace std;
int tt;
int ans,anum;
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
int a[111];
int b[111];
int cont=0;
void dfs(int d,int t,int num)
{
if(d>7) return;
if(anum<num)
{
anum=num;
ans=t;
}
else if(anum==num)
{
if(t<ans)
ans=t;
}
for(int i=1;i<=64;i++)
{
if(t*p[d]>tt) break;
t*=p[d];
dfs(d+1,t,num*(i+1));
}
}
int main()
{
tt=1;
a[cont]=1;
b[cont++]=1;
for(int i=2;i<555555;i++)
{
tt=i;
ans=555555;
anum=0;
dfs(0,1,1);
if(anum>b[cont-1])
{
a[cont]=ans;
b[cont++]=anum;
}
else if(anum==b[cont-1])
{
if(a[cont-1]<ans)
a[cont-1]=ans;
}
}
cout<<cont<<endl;
for(int i=0;i<cont;i++)
printf("%d,",a[i]);
printf("\n");
for(int i=0;i<cont;i++)
printf("%d,",b[i]);
return 0;
}
36
1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,221760,277200,332640,498960,554400,
1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200,216,
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define MAXN 555555
int stree[MAXN<<2];
int a[]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,
45360,50400,55440,83160,110880,166320,221760,277200,332640,498960,554400};
int b[]={1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200,216};
struct node
{
char name[111];
int num;
}stu[MAXN];
void pushup(int rt)
{
stree[rt]=stree[rt<<1]+stree[rt<<1|1];
}
void build(int l,int r,int rt)
{
if(l==r)
{
stree[rt]=1;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int tt;
void update(int k,int l,int r,int rt)
{
if(l==r)
{
stree[rt]=0;
tt=l;
return;
}
int mid=(l+r)>>1;
if(k<=stree[rt<<1]) update(k,lson);
else update(k-stree[rt<<1],rson);
pushup(rt);
}
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)==2)
{
build(1,n,1);
for(int i=1;i<=n;i++)
scanf("%s%d",stu[i].name,&stu[i].num);
int cont=0;
while(a[cont]<=n)
cont++;
cont--;
int cont1=0;
while(1)
{
update(k,1,n,1);
cont1++;
if(cont1==a[cont]) break;
if(stu[tt].num>0)
k=(k-1+stu[tt].num-1)%stree[1]+1;
else
k=((k+stu[tt].num-1)%stree[1]+stree[1])%stree[1]+1;
}
printf("%s %d\n",stu[tt].name,b[cont]);
}
return 0;
}