POJ - 2886 Who Gets the Most Candies? 區間更新 單點查詢
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
The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F
Input
There are several test cases in the input. Each test case starts with two integers N(0 < N ≤ 500,000) and K (1 ≤ K ≤ N) on the first line. The next N
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 3
題解:先把因子最多的那個數找出來,然後模擬進行即可,人數每次減1,線段樹單點查詢
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define lowbit(x) (x&(-x))
const int N=500100;
typedef long long ll;
struct node{
int l,r;
int val;
}tree[N<<2];
struct node1{
char name[15];
int id;
}a[N];
int n,k,num[N];
void init()
{
for(int i=1;i<N;i++)
{
num[i]++;
for(int j=i+i;j<N;j+=i)
num[j]++;
}
}
int solve()
{
int ans=0,p;
for(int i=1;i<=n;i++)
{
if(num[i]>ans)
ans=num[i],p=i;
}
return p;
}
void build(int l,int r,int cur)
{
tree[cur].l=l;
tree[cur].r=r;
tree[cur].val=r-l+1;
if(l==r) return;
int mid=(r+l)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
int update(int pos,int cur)
{
tree[cur].val--;
if(tree[cur].l==tree[cur].r)
{
return tree[cur].l;
}
if(pos<=tree[cur<<1].val) return update(pos,cur<<1);
else return update(pos-tree[cur<<1].val,cur<<1|1);
}
int main()
{
init();
while(~scanf("%d%d",&n,&k))
{
for(int i=1;i<=n;i++)scanf("%s%d",a[i].name,&a[i].id);
build(1,n,1);
int ans=solve(),pos,cnt=k;
k=update(k,1);
n--;
for(int i=2;i<=ans;i++)
{
if(a[k].id>0)
{
pos=((a[k].id+cnt-1)%n+n)%n;
if(pos==0) pos=n;
}
if(a[k].id<0)
{
pos=((cnt+a[k].id)%n+n)%n;
if(pos==0) pos=n;
}
k=update(pos,1);
cnt=pos;
n--;
}
printf("%s %d\n",a[k].name,num[ans]);
}
return 0;
}