poj 2886 反素数+约瑟夫环线段树单点更新
来源:互联网 发布:淘宝产品市场分析报告 编辑:程序博客网 时间:2024/04/19 23:10
题意:
有n(5*10^5)只小朋友做游戏,每个人手上有一张卡片,上面记录着一个非零的数val。
现在他们按照1~n坐成一个环。
然后游戏从第k只小朋友开始,他先跳出这个圈,然后如果他手上的val为正,则下一个小朋友的位置就是他当前位置+val;
相反的,如果他手上的val为负,则下一个小朋友的位置就是他当前位置-val。
现在,第p次的小朋友跳出圈圈的时候他会获得f(p)个糖果,f(p)的定义是p的因子数。
然后问,哪个小朋友出圈时能够得到最多的糖果,输出他的名字,并且输出糖果数。
解析:
无从下手啊。。。
所以从f(p)处下手,f(p)咋一看是确定的值,也就是说,可以确定是第几个小朋友出圈获得最多的糖果。
这个f(p)就是反素数,而他获得的糖果数就是当前这个反素数对应的因子个数。
关于反素数看上一篇。
这样就好办了,因为确定了p,所以只要模拟整个过程,然后确定第p次出来的小朋友是在原来的哪个位置就好了。
用线段树来维护这个游戏,线段树里保存的是当前的小朋友的个数,每当跳出一个小朋友,就更新当前的树,并返回当前小朋友原来的位置lo,就行了。
蛋疼的地方是做还模的时候会模出0,所以模拟的时候。。。。
附带讨论区里的测试数据。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 500000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int antiprime[]= {0,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,665280};int factorNum[]= {0,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,224};struct People{ char name[20]; int val;} people[maxn];int sum[maxn << 2];void pushup(int rt){ sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void build(int lo, int hi, int rt){ if (lo == hi) { sum[rt] = 1; return ; } int mi = (lo + hi) >> 1; build(lson); build(rson); pushup(rt);}int update(int k, int lo, int hi, int rt){ sum[rt]--; if (lo == hi) return lo; int mi = (lo + hi) >> 1; if (k <= sum[rt << 1]) return update(k, lson); else return update(k - sum[rt << 1], rson);}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL int n, k; while (~scanf("%d%d", &n, &k)) { for (int i = 1; i <= n; i++) { scanf("%s%d", people[i].name, &people[i].val); } /// int t = 1; while (antiprime[t] <= n) t++; t--; int p = antiprime[t];//第p个小朋友所得到的factorNum是最大的。 /// build(1, n, 1); int pos = 0; //模拟p次就好了 while (p--) { if (0 < people[pos].val) k = (k - 1 + people[pos].val - 1) % sum[1] + 1; else if (people[pos].val < 0) k = ((k - 1 + people[pos].val) % sum[1] + sum[1]) % sum[1] + 1; pos = update(k, 1, n, 1); } printf("%s %d\n", people[pos].name, factorNum[t]); } return 0;}///input/*2 15705 -2446416827 232812 1292 -15318716 -174212 117035 2629923811 -287034 132662 2764412859 2003727529 97413035 -123162 115890 -2380515350 243706 34966 -1184026308 -1393124626 -3243921538 553722929 -208231115 48332 126924 287455829 -62706 123655 2476712052 -403116941 -11503430 -1396618007 3019112287 154572 127506 -2494629168 -164132 127595 -648324350 36022 18281 -244841999 -532 117807 -224836617 143105 122798 3155611008 622414989 -3260920485 -319530523 143434 115281 -1479828009 2079823622 204726038 -122922 12634 1620220328 -200552 131998 -2188110021 -186513 126869 -2100313401 1468816423 152552 14169 -3093217189 -257216 130145 95123753 -2171816279 1242312529 -1668719866 1743723195 1932 131316 -1170112263 57862 128321 2775627982 -236465 312044 1046626439 2629226154 2002420649 -47454474 -83133 14414 2647729334 -2582420159 -243722 117192 26688480 31025 113061 2997227432 3100322725 27593142 849213064 -312862 125760 197117285 -46672 126302 -226584678 224663 11926 3106032170 -475730227 95766 12625 1447431928 56296902 2852024596 -12310195 132618260 12642 129790 2152021763 -30188*////output/*16827 218716 223811 212859 315350 221538 45829 23430 429168 224350 21999 26617 214989 36038 320328 210021 216423 217189 219866 412263 227982 24474 329334 28480 2142 37285 24678 230227 224596 421763 2*/
0 0
- poj 2886 反素数+约瑟夫环线段树单点更新
- poj 2886(约瑟夫+单点修改+反素数)
- 线段树单点更新+反素数 poj-2886-Who Gets the Most Candies
- POJ 2886 Who Gets the Most Candies?(线段树单点更新+反素数)
- poj 2886 Who Gets the Most Candies?(线段树单点更新+反素数)真难。。。
- poj 2886 Who Gets the Most Candies? 【线段树单点更新 + 反素数】
- POJ 2886 Who Gets the Most Candies?【线段树单点更新+反素数打表】【好题】
- poj 2886 who get the most candies? 约瑟夫+反素数
- POJ 2886 Who Gets the Most Candies? (约瑟夫环+反素数+线段树)
- [poj 2886] Who Gets the Most Candies[线段树][约瑟夫环][反素数]
- POJ 2886 Who Gets the Most Candies?(线段树 + 约瑟夫环 + 反素数)
- ACM练级日志:POJ 2886 约瑟夫环,线段树和反素数
- poj 2886 Who Gets the Most Candies?(线段树+约瑟夫环+反素数)
- POJ 2886 Who Gets the Most Candies? 数据结构+线段树+约瑟夫环+反素数
- poj 2886 Who Gets the Most Candies?(线段树单点更新模拟约瑟夫环)
- POJ 2352 Stars 线段树 单点更新 成段求和
- poj 2886(线段树+反素数)
- poj 2886 线段树+反素数
- 飞翔
- 搭系统--第1天
- Web.xml配置详解
- GDOI模拟8.7总结
- 使用栈计算后缀表达式
- poj 2886 反素数+约瑟夫环线段树单点更新
- 杭电 HDU ACM Coder (STL)
- CodeForces 567E President and Roads(最短路 + tarjan求桥)
- Unity3D技术之优化图形性能绘制调用批处理浅析
- CF 91E
- oop_day01_类和对象_20150807
- 求最大子序列和--体会算法的魅力
- 14、C语言和设计模式(装饰模式)
- C语言中的逻辑运算符