zoukankan      html  css  js  c++  java
  • poj 2886 Who Gets the Most Candies?(线段树单点更新)

    题目:http://poj.org/problem?id=2886

    题意:有一群小朋友围成一个环,编号1,2,3…N。每个人手上握着一个非0的数字,首先第K个人出列,然后看他手上的数字,假设为m,则从下一个开始第m个人出列,一直如此。

    第i个出列的人会得到  i的约数个数  个糖果,求得到最多糖果的人的名字和糖果数。

    思路:先预处理每个数的约数个数,然后找出得到最多的糖果的是第几个出队的人,假设为res;

       建立一个线段树,表示这一段还有几个人,

         在更新时计算出出队的这个人的前面和后面的人的个数(L和R),用他手上的数字计算出是剩下人中的第几个人,然后进入线段树搜索出这个人的原始序号。。重复这个过程直到找到第res个出队的人,跳出循环

    代码:

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn=500100;
      7 struct node
      8 {
      9     char name[15];
     10     int num;
     11 }st[maxn];
     12 int tree[maxn*4];
     13 int mark[maxn*4];
     14 int L,R;
     15 int prim[maxn];
     16 void init()
     17 {
     18     int i,j;
     19     memset(prim,0,sizeof(prim));
     20     for(i=1;i<=500000;i++)
     21     {
     22         for(j=i;j<=500000;j+=i)
     23         {
     24             prim[j]++;
     25         }
     26     }
     27 }
     28 void push(int w)
     29 {
     30     tree[w]=tree[w<<1]+tree[w<<1|1];
     31 }
     32 void build(int l,int r,int w)
     33 {
     34     if(l==r)
     35     {
     36         tree[w]=1;
     37         mark[w]=1;
     38         return ;
     39     }
     40     int m=(l+r)>>1;
     41     build(l,m,w<<1);
     42     build(m+1,r,w<<1|1);
     43     push(w);
     44 }
     45 void update(int now,int l,int r,int w)
     46 {
     47     tree[w]--;
     48     if(l==r&&l==now)
     49     {
     50         return ;
     51     }
     52     int m=(l+r)/2;
     53     if(now<=m)
     54     {
     55         R+=tree[w<<1|1];
     56         update(now,l,m,w<<1);
     57     }
     58     else
     59     {
     60         L+=tree[w<<1];
     61         update(now,m+1,r,w<<1|1);
     62     }
     63 }
     64 int find(int x,int l,int r,int w)
     65 {
     66     while(l<=r)
     67     {
     68         if(mark[w]==1)
     69         return l;
     70         int m=(l+r)/2;
     71         //printf("%d %d
    ",x,tree[w<<1]);
     72         if(x<=tree[w<<1])
     73         {
     74             r=m;
     75             w=w<<1;
     76         }
     77         else
     78         {
     79             l=m+1;
     80             x-=tree[w<<1];
     81             w=w<<1|1;
     82             //printf("w=%d
    ",w);
     83 
     84         }
     85 
     86         //printf("
    l=%d r=%d
    ",l,r);
     87     }
     88 }
     89 int main()
     90 {
     91     int n,k;
     92     init();
     93     while(scanf("%d%d",&n,&k)!=EOF)
     94     {
     95         int i;
     96         for(i=1;i<=n;i++)
     97         {
     98             getchar();
     99             scanf("%s%d",st[i].name,&st[i].num);
    100         }
    101         int max=0;
    102         int res=0;
    103         for(i=1;i<=n;i++)
    104         {
    105             if(prim[i]>max)
    106             {
    107                 max=prim[i];
    108                 res=i;
    109             }
    110 
    111         }
    112         //printf("res=%d  ",res);
    113         memset(mark,0,sizeof(mark));
    114         build(1,n,1);
    115         int now=k;
    116         for(i=1;i<=n;i++)
    117         {
    118             if(i==res)
    119             break;
    120             L=R=0;
    121             update(now,1,n,1);
    122             int u=st[now].num;
    123             //printf("u=%d  ",u);
    124             //printf("L=%d R=%d  ",L,R);
    125             if(u<0)
    126             {
    127                 u=-u;
    128                 u%=(L+R);
    129                 u=(L+R)-u+1;
    130             }
    131             if(u<R)
    132             u=L+u;
    133             else
    134             u-=R,u%=(L+R);
    135             if(u==0)
    136             u=(L+R);
    137             //printf("uu=%d  ",u);
    138             now=find(u,1,n,1);
    139             //printf("now=%d
    ",now);
    140         }
    141         printf("%s %d
    ",st[now].name,prim[res]);
    142     }
    143     return 0;
    144 }
    View Code

      

  • 相关阅读:
    How to determine proper SQL Server configuration settings [ZT from MS]
    How to Create a Performance Monitor Log for NT Troubleshooting [ZTfrom MS]
    HOW TO: Troubleshoot Application Performance with SQL Server[ZTfrom MS]
    INF: How to Monitor SQL Server 7.0 Blocking [ZT from MS]
    ADO.Net基础复习(一)
    JS实现跟随鼠标的魔法文字
    ADO.NET基础复习(二)
    SQL 基础复习
    关于Visual Studio无法连接到Visual Studio 的Localhost Web服务器问题
    计算机十二种常用密码破解法
  • 原文地址:https://www.cnblogs.com/wanglin2011/p/3143280.html
Copyright © 2011-2022 走看看