poj2886

来源:互联网 发布:淘宝助理和千牛 编辑:程序博客网 时间:2024/06/06 06:48

此题需要了解反素数的知识,之前不了解反素数还想把1e5以内的数的因子个数全部打表。。。。

此题还有一点,就是线段树的更新操作,删除某节点,这可能是大家之前没有接触到得

#include <iostream>#include<stdio.h>#include<algorithm>#include<cstring>using namespace std;const int MAX=5*1e5+20;typedef struct{    char name[15];    int v;}P;P p[MAX];int sum[4*MAX];int N,K;int RPrime[]={//反素数    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 fact[]={//反素数约数个数    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};void build(int L,int R,int id){    sum[id]=R-L+1;    if(L==R)        return;    int mid=(L+R)>>1;    build(L,mid,id*2);    build(mid+1,R,id*2+1);}int update(int p,int L,int R,int id){    sum[id]--;    if(L==R)        return L;    int mid=(L+R)>>1;    if(p<=sum[id*2])        return update(p,L,mid,id*2);    else        return update(p-sum[id*2],mid+1,R,id*2+1);}int main(){    int i,j,cnt;    while(~scanf("%d%d",&N,&K))    {        memset(sum,0,sizeof(sum));        cnt=0;        for(i=1;i<=N;i++)            scanf("%s%d",p[i].name,&p[i].v);        build(1,N,1);        for(int i=0;i<=35;i++)        {            if(RPrime[i]<=N)                cnt++;        }        cnt--;        int na,h=N;        for(i=1;i<=RPrime[cnt];i++)        {            na=update(K,1,N,1);            if(--h>0)            {            int v=p[na].v;            if(v>=0)            {                K=(K+v-1)%h;                if(K==0)                    K+=h;            }            else            {                K=(K+v)%h;                if(K<=0)                    K+=h;            }            }        }        cout<<p[na].name<<" "<<fact[cnt]<<endl;    }    return 0;}

0 0
原创粉丝点击