zoukankan      html  css  js  c++  java
  • POJ 2886 Who Gets the Most Candies? (线段树)

    题意:模拟约瑟夫环。有N(1<=N<=500000)个孩子围成一圈,他们被顺时针编号为 1 到 N。每个小孩手中有一个卡片,上面有一个非 0 的数字,游戏从第 K 个小孩开始,他告诉其他小孩他卡片上的数字并离开这个圈,他卡片上的数字 A 表明了下一个离开的小孩,如果 A 是大于 0 的,则下个离开的是左手边第 A 个,如果是小于 0 的,则是右手边的第 A 个小孩。游戏将直到所有小孩都离开,在游戏中,第 p 个离开的小孩将得到 F(p) 个糖果,F(p) 是 p 的约数的个数,问谁将得到最多的糖果。输出最幸运的小孩的名字和他可以得到的糖果。
            F(p)的值直接暴力跑一下就可以了。

            因为A的值可能很大,所以会用到模运算,这就要求下标是从0开始,但是小孩的编号从1开始,所以在更新的时候,要考虑两者的转换,即从编号下标从1开始的,转换成编号下标从0开始的,再转换回去。

     

    // Time 1563ms; Memory 24196K
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define maxn 1<<20
    #define mm 500010
    
    using namespace std;
    
    int tmp[mm],d[mm],g[mm];
    char s[mm][12];
    int size,n,cnt,dx;
    
    struct line
    {
    	int l,r;
    	int m;
    }a[maxn];
    
    void init()
    {
    	int i;
    	for(n=1;n<size;n<<=1);
    	for(i=n;i<2*n;i++)
    	{
    		a[i].l=a[i].r=i-n+1;
    		if(i-n<size) a[i].m=1;
    		else a[i].m=0;
    	}
    	for(i=n-1;i>0;i--)
    	{
    		a[i].l=a[2*i].l;
    		a[i].r=a[2*i+1].r;
    		a[i].m=a[2*i].m+a[2*i+1].m;
    	}
    }
    void insert(int i,int x)
    {
    	if(a[i].l==a[i].r)
    	{
    		tmp[a[i].l-1]=++cnt;
    		a[i].m=0;
    		dx=a[i].l;
    		return;
    	}
    	if(a[2*i].m>=x) insert(2*i,x);
    	else insert(2*i+1,x-a[2*i].m);
    	a[i].m--;
    }
    
    void calu() //建表,得到约数个数
    {
    	int i,j,limit;
    	limit=(int)sqrt(mm*1.0);
    	for(i=1;i<=limit;i++)
    	{
    		for(j=i+1;j*i<=mm;j++)
    			g[i*j]+=2;
    		g[i*i]++;
    	}
    }
    int main()
    {
    	int i,k,y,p,mx;
    	calu();
    	while(scanf("%d%d",&size,&k)!=EOF)
    	{
    		init();
    		cnt=0;
    		memset(tmp,0,sizeof(tmp));
    		for(i=0;i<size;i++)
    			scanf("%s%d",s[i],&d[i]);
    		p=size;
    		for(;p;) 
    		{
    			insert(1,k);
    			p--;
    			if(p==0) break;
    			if(d[dx-1]>0) k=((k-2+d[dx-1]%p)%p+p)%p+1; //得到要插入(删除)的是第几个
    			else k=((k-1+d[dx-1]%p)%p+p)%p+1;
    		}
    		mx=0;
    		for(i=0;i<size;i++) 
    		{
    			if(g[tmp[mx]]<g[tmp[i]]) mx=i;
    			else if(g[tmp[mx]]==g[tmp[i]] && tmp[mx]>tmp[i]) mx=i;
    		}
    		printf("%s %d
    ",s[mx],g[tmp[mx]]);
    	}
    	return 0;
    }
    


  • 相关阅读:
    map集合的见解、排序
    java mysql 数据类型对照
    spring 通过@Value 获取properties文件中设置了属性 ,与@Value # 和$的区别
    nginx中的超时设置,请求超时、响应等待超时等
    Linux配置多个Tomcat同时运行
    Socket TCP Server一个端口可以有多少个长连接?受到什么影响?linux最大文件句柄数量总结
    tomcat关闭后线程依然运行解决办法
    守护线程与非守护线程的区别
    SSM整合——spring4.*配置案例
    SSM事务——事务回滚如何拿到返回值
  • 原文地址:https://www.cnblogs.com/aukle/p/3233884.html
Copyright © 2011-2022 走看看