poj 2886(线段树)

#pragma warning(disable:4996)
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<set>
#include<map>
#include<string>
#include<stack>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int MAX_N = 680;
#define INF 0x3f3f3f3f
#define LL long long
typedef pair<int, int> PII;
#define MP make_pair
#define pb push_back
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOR0(i,n) for(int i=0;i<n;i++)
#define FORL0(i,n) for(int i=n;i>=0;i--)
#define clr(x,a) memset(x,a,sizeof(x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
void RD(int &x){ scanf("%d", &x); }
void RD(int &x, int &y){ scanf("%d%d", &x, &y); }
void RD(double &x){ scanf("%lf", &x); };
void RD(char &x){ scanf("%c", &x); }
void PR(int x){ printf("%d\n", x); }
void PR(LL x){ printf("%lld\n", x); }
void PRK(int x) { printf("%d ", x); }
void PL(){ puts(""); }
const int maxn = 555555;
int sum[maxn << 2];
int ne[maxn];
char name[maxn][11];
int n, m, k, t, ans, cas, x, y, s;
int table[50000] = { 0, 1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680, 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 45360, 50400, 55440, 83160, 110880, 166320, 221760, 277200, 332640, 498960, 555555 };
void PushUp(int rt){
	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int l, int r, int rt){
	if (l == r){
		sum[rt] = 1;
		return;
	}
	int m = (l+r)>>1;
	build(lson);
	build(rson);
	PushUp(rt);
}
int su[] = {2,3,5,7,11,13,17,19};
int yue(int x){
	int ans = 1;
	for (int i = 0; i < 8; i++){
		if (x%su[i] == 0){
			int temp = 1;
			while (x%su[i] == 0){
				temp++;
				x /= su[i];
			}
			ans *= temp;
		}
	}
	return ans;
}
int update(int p, int l, int r, int rt){
	if (l == r){
		sum[rt]--;
		return l;
	}
	int m = (l+r)>>1;
	int ans;
	if (p <= sum[rt << 1]) ans = update(p, lson);
	else ans = update(p - sum[rt << 1], rson);
	PushUp(rt);
	return ans;
}
int main()
{
    //freopen("aaa.txt", "r", stdin);
	//cout << -14 % 5 << endl;
	//while (1);
	while (~scanf("%d%d", &n, &k)){
		for (int i = 0; i < n; i++)
			scanf("%s%d", name[i], &ne[i]);
		int p = 1;
		while (table[p] <= n) p++;
		p--;
		p = table[p];
		build(1, n, 1);
		int pos;
		for (int i = 1; i < p; i++){
			pos = update(k, 1, n, 1);
			if (ne[pos-1] >= 0)
				k = (k - 2 + ne[pos - 1]) % sum[1]+1;
			else
				k = ((k - 1 + ne[pos - 1]) % sum[1] + sum[1]) % sum[1] + 1;
			

		}
		pos = update(k, 1, n, 1);
		printf("%s %d\n", name[pos - 1], yue(p));
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值