刚学会的常规版的线段树,单点更新。不知道为什么预处理因子和就超时,在线算就A,求大牛指点。
#include <iostream>
#include <cstring>
#include <cstdio>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1^1
using namespace std;
const int N = 500005;
struct People{
char name[20];
int v;
}p[N];
struct Seg{
int left,right;
int remain;
}seg[3*N];
void segtree_build(int l,int r,int rt){
seg[rt].left=l;
seg[rt].right=r;
seg[rt].remain=r-l+1;
if(l==r) return ;
int mid=(l+r)>>1;
segtree_build(lson);
segtree_build(rson);
}
int segtree_query(int num,int rt){
seg[rt].remain--;
if(seg[rt].left==seg[rt].right)
return seg[rt].left;
if(seg[rt<<1].remain>=num)
return segtree_query(num,rt<<1);
else
return segtree_query(num-seg[rt<<1].remain,rt<<1^1);
}
int candies[N];
int fun(int n){
int ans=1,cal;
for(int i=2;i*i<=n;i++)
if(n%i==0){
for(cal=0;n%i==0;cal++,n/=i);
ans*=cal+1;
}
if(n>1) ans*=2;
return ans;
}
void candies_init(){
for(int i=1;i<=N;i++)
candies[i]=fun(i);
}
int main(){
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
int n,k,remain,ans,tmp;
char name[20];
//candies_init();
while(~scanf("%d%d",&n,&k)){
segtree_build(1,n,1);
for(int i=1;i<=n;i++)
scanf("%s%d",p[i].name,&p[i].v);
ans=0;
for(int i=1;n;i++){
tmp=segtree_query(k,1);
//if(candies[i]>ans){
if(fun(i)>ans){
strcpy(name,p[tmp].name);
//ans=candies[i];
ans=fun(i);
}
n--;
if(n){
if(p[tmp].v>=0)
k=k+p[tmp].v%n-1;
else
k=k-(0-p[tmp].v)%n;
if(k>n) k-=n;
else if(k<1) k+=n;
}
}
printf("%s %d\n",name,ans);
}
return 0;
}