• poj2886Who Gets the Most Candies? (约瑟夫环)


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

    单点更新 初始位置都是1 如果这个人出去 位置变为0 利用线段树求区间k值 k值的计算如下

    如果这个数值是负的 那么下一个人的就是((k-1+p[id].d)%n+n)%n+1; 如果是正的 下一个人就是(k-1+p[id].d-1)%n+1; 

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include<stdlib.h>
     5 #include<iostream>
     6 #include<cmath>
     7 using namespace std;
     8 #define N 500010
     9 struct node
    10 {
    11     char s[12];
    12     int d;
    13 }p[N];
    14 int s[N<<2],n,k,num,o[N],maxz,kk,key;
    15 int a[37]={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,
    16            55440,83160,110880,166320,221760,277200,332640,498960,500001};
    17 int b[37]={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,1314521};
    18 void build(int l,int r,int w)
    19 {
    20     if(l==r)
    21     {
    22         s[w] = 1;
    23         return ;
    24     }
    25     int m = (l+r)>>1;
    26     build(l,m,w<<1);
    27     build(m+1,r,w<<1|1);
    28     s[w] = s[w<<1]+s[w<<1|1];
    29 }
    30 void update(int p,int l,int r,int w)
    31 {
    32     if(l==r)
    33     {
    34         s[w] = 0;
    35         key = l;
    36         return ;
    37     }
    38     int m = (l+r)>>1;
    39     if(p<=s[w<<1])
    40     update(p,l,m,w<<1);
    41     else
    42     update(p-s[w<<1],m+1,r,w<<1|1);
    43     s[w] = s[w<<1] + s[w<<1|1];
    44 }
    45 int main()
    46 {
    47     int i,j,sum;
    48     while(scanf("%d%d",&n,&k)!=EOF)
    49     {
    50         kk=0;i=0;maxz=0;
    51         while(a[i]<=n) i++;
    52         kk = a[i-1];
    53         maxz = b[i-1];
    54         int nn = n;
    55         build(1,n,1);
    56         for(i = 1 ;i <= n ; i++)
    57         scanf("%s%d",p[i].s,&p[i].d);
    58         int id;
    59         for(i = 0 ; i < kk ; i++)
    60         {
    61             n--;
    62             update(k,1,nn,1);
    63             id = key;
    64             if(n==0) break;
    65             if(p[id].d>0)
    66             k = (k-1+p[id].d-1)%n+1;
    67             else
    68             k = ((k-1+p[id].d)%n+n)%n+1;
    69         }
    70         printf("%s %d
    ",p[id].s,maxz);
    71     }
    72 }
    View Code
  • 相关阅读:
    const修饰指针
    C++调用C中编译过的函数要加extern "C"
    linux常用指令(1)
    链式队列实现
    存储类别和类型限定词
    数组,指针和引用
    字符函数和字符串函数
    C/C++编译的程序占用的内存
    结构体1(嵌套使用)
    输入输出函数小结
  • 原文地址:https://www.cnblogs.com/shangyu/p/3184714.html
Copyright © 2020-2023  润新知