博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2886 【线段树模拟约瑟夫环】.cpp
阅读量:4653 次
发布时间:2019-06-09

本文共 2521 字,大约阅读时间需要 8 分钟。

题意:

  一群小孩顺时针坐然后在玩约瑟夫环的游戏..

  从第k个小孩开始..每个被选中的孩子扔出手中的纸牌..

  然后按着纸牌上面的数找下一个被选中的小孩..

  如果牌中的数是正数就顺时针数..

  如果是负数就逆时针数..

  

  其中第 i 个被选中的小孩会得到f( i )颗糖..

  f( i )表示 i 的正因子个数..

 

  要求是找出得到糖最多的孩子个数..

  

输入:  

  n k 表示有n个小孩..从第k个开始

  接下来 n 行有n个小孩的名字和他手上的牌的编号..

 

思路:

  一开始想的是暴力找出这个小孩..

  但是会很麻烦..

  然后这里就用到了反素数了..

  反素数:<>

  找出f[ j ] > f[ i ] : f[ j ]为 j 的正因子个数..

  然后就可以找出n之前正因子最多的那个数 即 得糖最多的那个小孩编号 ans..

  再找出这个小孩是谁..

 

  用线段树模拟找的过程..感觉跟二分有点像~感觉..

 

Tips:

  ※ 改的是 rt 是 sum 的..但是输入的per的数据是 l 和 r

  ※ 还有一个让我很纠结的就是根据数的正负向左数还是向右数..

 

Code:

View Code
1 #include 
2 #include
3 4 const int MAXN = 500010; 5 6 struct P 7 { 8 char name[20]; 9 int sum;10 }per[MAXN];11 int sum[MAXN<<2];12 13 int antiprime[]={
1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,14 7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,15 166320,221760,277200,332640,498960,554400,665280};16 int factorNum[]={
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,17 100,108,120,128,144,160,168,180,192,200,216,224};18 19 void pushup(int rt)20 {21 sum[rt] = sum[rt<<1] + sum[rt<<1|1];22 }23 24 void creat(int l, int r, int rt)25 {26 if(l == r) {27 scanf("%s %d", per[l].name, &per[l].sum);28 sum[rt] = 1;29 return;30 }31 int mid = (l+r)>>1;32 creat(l, mid, rt<<1);33 creat(mid+1, r, rt<<1|1);34 pushup(rt);35 36 }37 38 int modify(int k, int l, int r, int rt)39 {40 if(l == r) {41 sum[rt]--;42 return l;43 }44 int mid = (l+r)>>1;45 int loc;46 if(k <= sum[rt<<1]) loc = modify(k, l, mid, rt<<1);47 else loc = modify(k-sum[rt<<1], mid+1, r, rt<<1|1);48 pushup(rt);49 return loc;50 }51 52 int main()53 {54 int i, j;55 int n, k;56 int loc, tmp;57 int ans;58 while(scanf("%d %d", &n, &k) != EOF)59 {60 creat(1, n, 1);61 62 for(i = 0; i < 36; ++i) if(antiprime[i] <= n) ans = i;63 64 k = ((k-1)%n+n)%n+1;65 loc = modify(k, 1, n, 1);66 67 for(i = 1; i < antiprime[ans]; ++i) {68 if(per[loc].sum > 0) k = ((k+per[loc].sum - 2)%sum[1] + sum[1])%sum[1] + 1;69 else k = ((k+per[loc].sum-1)%sum[1] + sum[1])%sum[1] + 1;70 loc = modify(k, 1, n, 1);71 }72 73 printf("%s %d\n", per[loc].name, factorNum[ans]);74 }75 return 0;76 }

 

题目链接:

转载于:https://www.cnblogs.com/Griselda/archive/2012/10/16/2725791.html

你可能感兴趣的文章
[CQOI2013]新Nim游戏 线性基
查看>>
我的成就故事
查看>>
electron-vue 更新 使用electron-update的版本
查看>>
设计模式_责任链模式
查看>>
HTTP请求中三种参数类型
查看>>
CF990G
查看>>
Noip2013货车运输
查看>>
iOS 生命周期 -init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear 区别和用途...
查看>>
Web存储使用详解(本地存储、会话存储)
查看>>
JS库
查看>>
c/c++优化结构控制
查看>>
最新Webstrom, Idea 2019.1.3 的激活
查看>>
C# chart,有关如何在鼠标移动到Series上时显示节点及数据 (有待继续更新)
查看>>
HDU 6201【最长路+SPFA转化为流问题求解***】
查看>>
Jmeter一、开源软件的崛起
查看>>
python sys.argv[] 用法示例
查看>>
Vcl.FileCtrl.SelectDirectory
查看>>
Java实现导入Excel文件
查看>>
动态执行超过4000个字符的SQL
查看>>
redhat 6.0更换 yum
查看>>