1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std;
int nPrime[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; int nAns; int nCN; const int MAX_N = 500010;
void InitBest(int nCur, int nI, int nMax, int nN, int nNum) { if (nCur > nN) return; if (nNum > nCN){nAns = nCur;nCN = nNum;} if (nNum == nCN){nAns = min(nAns, nCur);} for (int i = 1; i <= nMax; ++i) { nCur *= nPrime[nI]; if (nCur > nN)return; if (nI < 15) InitBest(nCur, nI + 1, i, nN, nNum * (i + 1)); } }
char szNames[MAX_N][10]; int nValue[MAX_N]; int nTree[MAX_N << 2]; void PushUp(int nRt) { nTree[nRt] = nTree[nRt << 1] + nTree[nRt << 1 | 1]; }
void BuildTree(int nL, int nR, int nRt, int nV) { if (nL == nR) { nTree[nRt] = nV; return; } int nMid = (nL + nR) >> 1; BuildTree(nL, nMid, nRt << 1, nV); BuildTree(nMid + 1, nR, nRt << 1 | 1, nV); PushUp(nRt); }
void Add(int nL, int nR, int nRt, int nP, int nV) { if (nL == nR) { nTree[nRt] += nV; } else { int nMid = (nL + nR) >> 1; if (nP <= nMid)Add(nL, nMid, nRt << 1, nP, nV); else Add(nMid + 1, nR, nRt << 1 | 1, nP, nV); PushUp(nRt); } }
int Query(int nL, int nR, int nRt, int nSum) { if (nL == nR) { return nL; } int nMid = (nL + nR) >> 1; int nLs = nRt << 1; int nRs = nLs | 1; if (nTree[nLs] >= nSum) return Query(nL, nMid, nLs, nSum); else return Query(nMid + 1, nR, nRs, nSum - nTree[nLs]); }
int main() { int nN, nK;
while (scanf("%d%d", &nN, &nK) == 2) { nK--; nAns = 2; nCN = 0; InitBest(1, 0, 20, nN, 1); for (int i = 0; i < nN; ++i) { scanf("%s%d", szNames[i], nValue[i]); }
BuildTree(0, nN - 1, 1, 1); int nTotal = nN; int nPos; for (int i = 0; i < nAns; ++i) { nPos = Query(0, nN - 1, 1, nK + 1); nTotal--; Add(0, nN - 1, 1, nPos, -1); if (!nTotal)break; if (nValue[nPos] >= 0) { nK = (nK - 1 + nValue[nPos] + nTotal) % nTotal; } else { nK = ((nK + nValue[nPos]) % nTotal + nTotal) % nTotal; } } printf("%s %d\n", szNames[nPos], nCN); }
return 0; }
|