PKU2886(Who Gets the Most Candies?)线段树+反素数
来源:互联网 发布:网络教育平台 编辑:程序博客网 时间:2024/05/21 14:44
/*******************************************题目大意:有n个小孩在玩游戏,每个小孩手上都有一个数字;第k个小孩先出去,然后给出手上的数值x;大于0的话就是从他左边开始数的第x个小孩;否则就是从右边数的第-x个小孩接着出列;直到所有小孩出列;第p个出列的小孩,将拿到f(p)个糖果;f(p)表示p的正因子个数;现在要求得到最多糖果的小孩;算法分析:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4;如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数;所以反素数满足f[x]>f[i](1<i<x);所以得到的最多糖果数其实就是小于n的最大反素数k;反素数可以直接预处理也可以求;之后用线段树模拟二分搜索找到第k个小孩出列为止;算法过程:建立线段树,线段树区间表示区间内人的个数;搜索第i个人时所经过的路径区间人数的减一;然后根据提示求得的下一个跳出的人是谁;并记录第i个跳出的人是谁;********************************************/#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<climits>#include<algorithm>using namespace std;#define L l,m,u<<1#define R m+1,r,u<<1|1 //u*2+1const int N=500005;struct node{ int l,r; int sum;}a[N*3];struct game{ char name[12]; int x;}s[N];int c[N];//第i个人跳出所得糖果int num;//得糖果最多的人的输入序号int n,k;int v,z;//z表示当前已跳出的人数int e;//e表示第几个跳出的人得到的糖果最多void build(int l,int r,int u)//u为根结点{ a[u].l=l; a[u].r=r; a[u].sum=(r-l+1); if(a[u].l==a[u].r) return; int m=(r+l)>>1; build(L); build(R);}void updata(int u,int t)//t表示目前队列此区间第几个人跳出{ a[u].sum--;//所到区间人数减一,自上而下沿途更新 if(a[u].l==a[u].r)//最后结点 { if(e==z)//z是当前已跳出的人数 { num=a[u].l;//如果是第e个人跳出 记录答案 } if(n-z==0)//全跳出 return ; if(s[a[u].l].x>0)//求从线段树左起下一次第几个人跳出 v--; v=((v+s[a[u].l].x)%(n-z)+(n-z))%(n-z);//坑爹有没有~ if(v==0)//一圈转完了 v=n-z;//计算下一个要删除的人是从左算起的第几个人 } else { if(a[u*2].sum>=t)//左边人数足够则向左搜 { updata(u*2,t); } else { t-=a[u*2].sum;//否则减去左边人数向右搜 updata(u*2+1,t); } }}void candy()//求第i人跳出能得到的糖果数量{ memset(c,0,sizeof(c)); for(int i=1; i<N; i++) { c[i]++; for(int j=i*2; j<N; j+=i) { c[j]++; } }}int main(){ //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); candy(); while(~scanf("%d %d",&n,&k)) { e=1; for(int i=1; i<=n; i++) { getchar(); scanf("%s %d",s[i].name,&s[i].x); if(c[i]>c[e]) e=i; } build(1,n,1); v=k;//第k个孩子先跳出 for(z=1; z<=n; ++z)//z表示当前已跳出的人数 { updata(1,v); } printf("%s %d\n",s[num].name,c[e]); } return 0;}
- PKU2886(Who Gets the Most Candies?)线段树+反素数
- Who Gets the Most Candies?+POJ+线段树+反素数
- poj2886--Who Gets the Most Candies?(线段树+反素数)
- 【POJ2886】Who Gets the Most Candies?-线段树+反素数
- poj2886 Who Gets the Most Candies?反素数+线段树
- pku2886 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 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?(线段树、反素数)
- POJ2886 Who Gets the Most Candies? 【线段树】+【单点更新】+【模拟】+【反素数】
- POJ - 2886 Who Gets the Most Candies? (反素数+线段树)
- poj 2886 Who Gets the Most Candies?(数据结构:线段树+DFS反素数打表)
- 银行储蓄利息计算
- PHP面试题(一)
- 几个Linux终端下超赞的小命令
- flex中的分割组件(DividedBox)
- WCF简要介绍
- PKU2886(Who Gets the Most Candies?)线段树+反素数
- 网站常见问题及解决方法(div/css)
- svn 冲突的产生与解决
- 服务器端判断是否相等
- Autoscroll
- WCF简要介绍
- win7 x64 链接 hp p2055d 出现 0x0000007e 错误
- JavaScript 错误 - Throw、Try 和 Catch
- 微软老将Philip Su的离职信:回首12年职场生涯的心得和随笔