poj 2886 线段树的更新+反素数
Who Gets the Most Candies?
Time Limit: 5000 MS Memory Limit: 0 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
Description
N children are sitting in a circle to play a game.
The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (−A)-th child to the right.
The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p. Who gets the most candies?
Input
Output
Output one line for each test case containing the name of the luckiest child and the number of candies he/she gets. If ties occur, always choose the child who jumps out of the circle first.
Sample Input
4 2
Tom 2
Jack 4
Mary -1
Sam 1
Sample Output
Sam 3if(val[pos]>=0)//顺时针
k = (k-1+val[pos]-1)%n+1; else//逆时针 k = ((k-1+val[pos])%n+n)%n+1; #include <stdio.h>
#include <string.h>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
const int M = ;
int n,id;
struct tree
{
int l;
int r;
int sum; //sum 表 该区间剩余人数 } node[M*]; struct data
{
int val;
char name[];
} pp[M]; int ans[M]; //ans[i]保存第i个人跳出能得到的糖果数量 void Build (int l,int r,int root)
{
node[root].l = l;
node[root].r = r;
node[root].sum = r - l + ;
if (l == r)
return ;
int mid = (l + r)>>;
Build(l,mid,root*);
Build(mid+,r,root*+);
}
int update (int key,int root)
{
node[root].sum --;
if (node[root].l == node[root].r)
return node[root].l;
if (node[root*].sum >= key)
return update(key,root*);
else
return update (key - node[root*].sum,root*+);
}
void count_ans() ///n人中 第几个跳出来的人获得最多 ///反素数
{
memset (ans,,sizeof(ans)); //计算ans
for (int i = ; i <= n; i ++)
{
ans[i] ++; ///均==1了
for (int j = *i; j <= n; j += i)
ans[j] ++; ///ans[2]=2 ans[3]=2 ans[4]=2 ans[4]=3 ......
}
int max = ans[];
id = ;
for (int i = ; i <= n; i ++) //找出第几个人跳出获得的糖最多
if (ans[i] > max)
{
max = ans[i];
id = i;
}
}
int main ()
{
int i,k,mod;
while (~scanf ("%d %d",&n,&k))
{
count_ans();
for (i = ; i <= n; i ++)
scanf ("%s %d",pp[i].name,&pp[i].val);
Build (,n,);
mod = node[].sum;
int pos = ;
pp[].val = ;
n = id;
while (n --)
{
if (pp[pos].val > ) //k表剩余的人中从左起第k中出队(PS:k的求法是看别人的)
k = ((k + pp[pos].val - )%mod + mod)%mod + ;
else
k = ((k + pp[pos].val - )%mod + mod)%mod + ;
pos = update(k,); mod = node[].sum; ///不断更新后的结果
}
printf ("%s %d\n",pp[pos].name,ans[id]);
}
return ;
} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <iostream>
#include <stdio.h>
#include <string.h> using namespace std;
#define MAX 500000 const int antiprime[] = {,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,};
const int factor[] = {,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}; struct node
{
int l;
int r;
int cnt;
} tr[*MAX]; struct p
{
char name[];
int v;
} pp[MAX]; int build(int l,int r,int root)
{
tr[root].l=l;
tr[root].r=r;
int mid=(l+r)/;
tr[root].cnt=tr[root].r-tr[root].l+;
if(l!=r)
{
build(l,mid,root*);
build(mid+,r,root*+);
}
} int update(int root,int k)
{
tr[root].cnt--;
if(tr[root].l==tr[root].r)
return tr[root].l;
if(tr[root*].cnt >= k)
return update(root*, k);
else
return update(root*+, k - tr[root*].cnt);
} int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=; i<=n; i++)
scanf("%s%d",&pp[i].name,&pp[i].v);
build(,n,); ///建树
int cnt=;
while(antiprime[cnt]<=n) cnt++;
cnt--;
int pos=;
pp[pos].v=;
for(int i=; i<antiprime[cnt]; i++)
{
if(pp[pos].v > ) ///顺时针
{
k = ((k + pp[pos].v - ) % tr[].cnt + tr[].cnt) % tr[].cnt + ;
}
else ///逆时针
{
k = ((k + pp[pos].v - ) % tr[].cnt + tr[].cnt) % tr[].cnt + ;
}
pos = update(, k); ///更新一下
}
printf("%s %d\n", pp[pos].name, factor[cnt]);
}
return ;
}
*******
定义 反素数:
问题描述:
对于任何正整数x,起约数的个数记做g(x).例如g(1)=1,g(6)=4.
如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.
现在给一个N,求出不超过N的最大的反素数.
比如:输入1000 输出 840
思维过程:
求[1..N]中约数在大的反素数-->求约数最多的数
如果求约数的个数 756=2^2*3^3*7^1
(2+1)*(3+1)*(1+1)=24
基于上述结论,给出算法:按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子
为了剪枝:
性质一:一个反素数的质因子必然是从2开始连续的质数.
因为最多只需要10个素数构造:2,3,5,7,11,13,17,19,23,29
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....
(以上摘自百度百科)
以hdu4228 和zoj2562为例
hdu4228
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef __int64 lld;
lld p[1010];
lld prime[30]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
void getartprime(lld cur,int cnt,int limit,int k)
{
//cur:当前枚举到的数;
//cnt:该数的因数个数;
//limit:因数个数的上限;2^t1*3^t2*5^t3……t1>=t2>=t3……
//第k大的素数
if(cur>((lld)1<<60) ||
cnt>150) return ;
if(p[cnt]!=0
&&
p[cnt]>cur)//当前的因数个数已经记录过且当时记录的数比当前枚举到的数要大,则替换此因数个数下的枚举到的数
p[cnt]=cur;
if(p[cnt]==0)//此因数个数的数还没有出现过,则记录
p[cnt]=cur;
lld
temp=cur;
for(int
i=1;i<=limit;i++)//枚举数
{
temp=temp*prime[k];
if(temp>((lld)1<<60))
return;
getartprime(temp,cnt*(i+1),i,k+1);
}
}
int main()
{
int n;
getartprime(1,1,75,0);
for(int
i=1;i<=75;i++)
{
if(p[i*2-1]!=0 && p[i*2]!=0)
p[i]=min(p[i*2-1],p[i*2]);
else if(p[i*2]!=0)
p[i]=p[i*2];
else
p[i]=p[i*2-1];
}
while(scanf("%d",&n),n)
{
printf("%I64d\n",p[n]);
}
return
0;
}
zoj 2562
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long lld;
lld
prime[20]={2,3,5,7,11,13,17,19,23,29,31,37,39,41,43,47,53};
lld n;
lld bestcurr,largecnt;//bestcurr
相同最大因数个数中值最小的数,largecnt:n范围内最大的因数个数
void getarcprime(lld curr,int cnt,int limit,int k)
{
if(curr>n)
return ;
if(largecnt<cnt)//此时枚举到的因数个数比之前记录的最大的因数个数要大,就替换最大因数个数
{
largecnt=cnt;
bestcurr=curr;
}
if(largecnt==cnt &&
bestcurr>curr)//替换最优值
bestcurr=curr;
lld
temp=curr;
for(int
i=1;i<=limit;i++)
{
temp=temp*prime[k];
if(temp>n)
return;
getarcprime(temp,cnt*(i+1),i,k+1);
}
}
int main()
{
while(scanf("%lld",&n)!=EOF)
{
bestcurr=0;
largecnt=0;
getarcprime(1,1,50,0);
printf("%lld\n",bestcurr);
}
return
0;
}
poj 2886 线段树的更新+反素数的更多相关文章
- POJ 2886 线段树单点更新
转载自:http://blog.csdn.net/sdj222555/article/details/6878651 反素数拓展参照:http://blog.csdn.net/ACdreamers/a ...
- poj 2886 线段树+反素数
Who Gets the Most Candies? Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 12744 Acc ...
- poj 2886 (线段树+反素数打表) Who Gets the Most Candies?
http://poj.org/problem?id=2886 一群孩子从编号1到n按顺时针的方向围成一个圆,每个孩子手中卡片上有一个数字,首先是编号为k的孩子出去,如果他手上的数字m是正数,那么从他左 ...
- poj 3468 线段树区间更新/查询
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- hdu 1698+poj 3468 (线段树 区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注 ...
- poj 2828(线段树单点更新)
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 18561 Accepted: 9209 Desc ...
- POJ 3225 线段树区间更新(两种更新方式)
http://blog.csdn.net/niuox/article/details/9664487 这道题明显是线段树,根据题意可以知道: (用0和1表示是否包含区间,-1表示该区间内既有包含又有不 ...
- POJ 2828 (线段树 单点更新) Buy Tickets
倒着插,倒着插,这道题是倒着插! 想一下如果 Posi 里面有若干个0,那么排在最前面的一定是最后一个0. 从后往前看,对于第i个数,就应该插在第Posi + 1个空位上,所以用线段树来维护区间空位的 ...
- POJ 3225 (线段树 区间更新) Help with Intervals
这道题搞了好久,其实坑点挺多.. 网上找了许多题解,发现思路其实都差不多,所以就不在重复了. 推荐一篇比较好的题解,请戳这. 另外,如果因为可能要更新多次,但最终查询只需要一次,所以没有写pushup ...
随机推荐
- iOS 3D Touch功能
新的触摸体验——iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了 ...
- 网页启用Gzip压缩 提高浏览速度
启用Gzip压缩的好处 它的好处显而易见,提高网页浏览速度,无论是之前说的精简代码.压缩图片都不如启用Gzip来的实在.下图为启用Gzip后的效果. Gzip压缩效率非常高,通常可以达到70%的压缩率 ...
- c++11 stl 学习之 shared_ptr
shared_ptr智能指针 shared_ptr 的声明初始化方式由于指针指针使用explicit参数 必须显示声明初始化shared_ptr<string> pNico = new s ...
- HBuilder中ios打包
参考:http://ask.dcloud.net.cn/article/152 在ios端钥匙串双击(教程上是双击)导入证书时候,可能会报错,直接把证书文件拖入到keychain的登录里就解决了. 1 ...
- dblink(转)
oracle在进行跨库访问时,可以通过创建dblink实现,今天就简单的介绍下如果创建dblink,以及通过dblink完成插入.修改.删除等操作 首先了解下环境:在tnsnames.ora中配置两个 ...
- 异常处理(异常解析器) 和 对于Properties类型的属性的配置
在程序运行中,有可能因为用户的不当操作,发生异常.. 在springmvc中可以根据不同的异常配置不同的处理方式 1.例如出现 这个类型异常 org.springframework.web.multi ...
- mybatis 接口绑定 和 动态SQL
一.MyBatis 接口绑定方案及多参数传递 1.作用:实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取mapper.xml中编写的sql 2.后面 ...
- Linux+Apache+Mysql+PHP优化技巧
LAMP 平台由四个组件组成,呈分层结构.每一层都提供了整个软件栈的一个关键部分:Linux.Apache.MySQL.PHP. LAMP这个词的由来最早始于德国杂志“c't Magazine”,Mi ...
- 2018.11.06 bzoj1040: [ZJOI2008]骑士(树形dp)
传送门 由题可知给出的是基环森林. 因此对于每个基环森林找到环断开dpdpdp两次就行了. 代码: #include<bits/stdc++.h> using namespace std; ...
- EF对应null的处理
原来的代码是 if (string.IsNullOrWhiteSpace(seal)) seal = null; ctx.Terminal.FirstOrDefault(ent=>ent.Sea ...