poj 2886 (线段树 统计左右各有多少个节点.)

来源:互联网 发布:办公室必备软件 编辑:程序博客网 时间:2024/05/23 15:53
   什么是反素数..
#include<iostream>#define N 5000006#include<cstdio>using namespace std;int  div_num[N];int max_id[N];char name[N][12];int n_person; int s_id;int card[N];struct Node{    int l,r;    int mid;    int cnt;};Node node[5*N];int flag;void init_tree(int id,int l,int r);void query(int id,int num);void init()     ;int main(){    freopen("in.txt","r",stdin);    init();     while(scanf("%d%d",&n_person,&s_id)!=EOF)     {         for(int i=0;i<n_person;i++)         {             scanf("%s%d",name[i],&card[i]);         }         init_tree(1,0,n_person);          int x=max_id[n_person];          int t=s_id;          int num=n_person;          int tmp=0;          int id;          while(x--)          {              if(tmp<0) {                  tmp%=num;              tmp=num+tmp+1;              }            t=(t+tmp-1)%num;       //     cout<<t<<endl;             query(1,t+1);             tmp=card[flag];             num--;          }          printf("%s %d",name[flag],div_num[max_id[n_person]]+2);     }}void init_tree(int id,int l,int r){     node[id].l=l; node[id].r=r;      node[id].cnt=r-l; node[id].mid=(l+r)/2;     if(l+1==r) return;     init_tree(2*id,l,node[id].mid);     init_tree(2*id+1,node[id].mid,r);}void query(int id,int num){    node[id].cnt--;     if(node[id].l+1==node[id].r)        {            flag=node[id].l; return ;        }    if(node[2*id].cnt>=num)    query(2*id,num);    else query(2*id+1,num-node[2*id].cnt);}void init()             //约数的个数{    int i=2;    div_num[1]=-1;    while(i<N)    {        if(div_num[i]>div_num[max_id[i-1]]) max_id[i]=i;        else  max_id[i]=max_id[i-1];        for(int j=i+i;j<N;j+=i)          div_num[j]++;        i++;    }}

原创粉丝点击