Untitled
unknown
plain_text
2 years ago
15 kB
10
Indexable
//main #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #include <stdio.h> #define CMD_INIT (100) #define CMD_WRITE_MESSAGE (200) #define CMD_COMMENT_TO (300) #define CMD_ERASE (400) #define CMD_GET_BEST_MESSAGES (500) #define CMD_GET_BEST_USERS (600) #define MAXL (10) extern void init(); extern int writeMessage(char mUser[], int mID, int mPoint); extern int commentTo(char mUser[], int mID, int mTargetID, int mPoint); extern int erase(int mID); extern void getBestMessages(int mBestMessageList[]); extern void getBestUsers(char mBestUserList[][MAXL + 1]); static int mstrcmp(char a[], char b[]) { int idx = 0; while (a[idx] != '\0' && a[idx] == b[idx]) ++idx; return a[idx] - b[idx]; } static bool run() { int Q; int mID, mTargetID, mPoint; char mUser[MAXL + 1]; char mBestUserList[5][MAXL + 1]; int mBestMessageList[5]; int ret = -1, ans; scanf("%d", &Q); bool okay = false; for (int q = 0; q < Q; ++q) { int cmd; scanf("%d", &cmd); switch(cmd) { case CMD_INIT: init(); okay = true; break; case CMD_WRITE_MESSAGE: scanf("%s %d %d", mUser, &mID, &mPoint); ret = writeMessage(mUser, mID, mPoint); scanf("%d", &ans); if (ret != ans) okay = false; break; case CMD_COMMENT_TO: scanf("%s %d %d %d", mUser, &mID, &mTargetID, &mPoint); ret = commentTo(mUser, mID, mTargetID, mPoint); scanf("%d", &ans); if (ret != ans) okay = false; break; case CMD_ERASE: scanf("%d", &mID); ret = erase(mID); scanf("%d", &ans); if (ret != ans) okay = false; break; case CMD_GET_BEST_MESSAGES: getBestMessages(mBestMessageList); for (int i = 0; i < 5; ++i) { scanf("%d", &ans); if (mBestMessageList[i] != ans) okay = false; } break; case CMD_GET_BEST_USERS: getBestUsers(mBestUserList); for (int i = 0; i < 5; ++i) { scanf("%s", mUser); if (mstrcmp(mBestUserList[i], mUser) != 0) okay = false; } break; default: okay = false; break; } } return okay; } int main() { setbuf(stdout, NULL); freopen("Text.txt", "r", stdin); int TC, MARK; scanf("%d %d", &TC, &MARK); for (int tc = 1; tc <= TC; ++tc) { int score = run() ? MARK : 0; printf("#%d %d\n", tc, score); } return 0; } //user #define opt __attribute((optimize("Ofast"))) #define MAXL (10) #define HASH_SIZE 3179 #define HASH_SIZE1 31159 #define MAX_USER 10000 #define MAX_ID 50000 + 1 #define ull unsigned long long opt inline void mStrcpy(char *src, char *des) { int i = 0; while ((des[i] = src[i]) != 0) ++i; return; } // define Struct and variable struct Node { int data; Node *nextNode; } *firstNode[MAX_ID]; struct User { ull name; int next, ID; char userName[11]; } user[MAX_USER]; struct ID { // key = 1: Post, 2 = Comment, 3 = Reply int mID, idMap, key, point; int userID; int next; bool isDelete; } id[MAX_ID]; struct Score { int score, indexHeap; } scoreUser[MAX_USER], scorePost[MAX_ID]; int parent[MAX_ID]; // Define List, Heap and Map class LinkedList { public: opt inline void add(int index, int value) { Node *newNode = new Node(); newNode->data = value; newNode->nextNode = firstNode[index]; firstNode[index] = newNode; } opt inline void del(int index) { Node *cur = firstNode[index], *prev; while (cur != nullptr) { prev = cur; cur = cur->nextNode; delete prev; } firstNode[index] = nullptr; } opt inline void reset() { for (int i = 0; i < MAX_ID; ++i) del(i); } } linkedList; class Map { private: int userMap[HASH_SIZE]; int cntUser; int cntID, idMap[HASH_SIZE1]; opt inline ull hash(char str[]) { ull key = 0; int i; for (i = 0; str[i]; ++i) key = (key << 5) + str[i] - 'a' + 1; while (i <= 10) { key = (key << 5); ++i; } return key; } public: opt inline void reset() { for (int i = 0; i < HASH_SIZE; ++i) userMap[i] = -1; for (int i = 0; i < HASH_SIZE1; ++i) idMap[i] = -1; cntID = cntUser = 0; } opt inline int addUser(char str[]) { ull key = hash(str); ++cntUser; user[cntUser].name = key; user[cntUser].ID = cntUser; user[cntUser].next = userMap[key % HASH_SIZE]; userMap[key % HASH_SIZE] = cntUser; // Add LinkedList mStrcpy(str, user[cntUser].userName); return cntUser; } opt inline int addID(int mID, int key, int nUser, int p) { ++cntID; id[cntID].mID = mID; id[cntID].key = key; id[cntID].idMap = cntID; id[cntID].userID = nUser; id[cntID].point = p; id[cntID].isDelete = false; id[cntID].next = idMap[mID % HASH_SIZE1]; // Add LinkedList idMap[mID % HASH_SIZE1] = cntID; return cntID; } opt inline int findUser(char str[]) { ull key = hash(str); int p = userMap[key % HASH_SIZE]; while (p != -1 && user[p].name != key) p = user[p].next; if (p != -1) return user[p].ID; return -1; } opt inline int findID(int mID) { int p = idMap[mID % HASH_SIZE1]; while (p != -1 && id[p].mID != mID) p = id[p].next; if (p != -1) return id[p].idMap; return -1; } opt inline int sizeUser() { return cntUser; } opt inline int sizeID() { return cntID; } } map; struct MAX_HEAP_USER { private: int dataUser[MAX_USER]; int nUser; opt inline bool compare(int i, int j) // i > j { if (scoreUser[dataUser[i]].score > scoreUser[dataUser[j]].score) return true; if (scoreUser[dataUser[i]].score == scoreUser[dataUser[j]].score) return (user[dataUser[i]].name < user[dataUser[j]].name); return false; } opt inline void swap(int i, int j) { int id1 = dataUser[i], id2 = dataUser[j]; dataUser[i] = dataUser[j]; dataUser[j] = id1; scoreUser[id1].indexHeap = j; scoreUser[id2].indexHeap = i; } public: opt inline void upHeap(int k) { int child = k, parent = k / 2; while (parent != 0) { if (compare(child, parent)) { swap(child, parent); child = parent; parent = child / 2; } else break; } } opt inline void downHeap(int k) { int parent = k, child = 2 * k; while (child <= nUser) { if (child + 1 <= nUser && compare(child + 1, child)) child = child + 1; if (compare(child, parent)) { swap(child, parent); parent = child; child = 2 * parent; } else break; } } opt inline void push(int index) { nUser++; dataUser[nUser] = index; scoreUser[index].indexHeap = nUser; upHeap(nUser); } opt inline int pop() { int id = dataUser[1]; swap(1, nUser); nUser--; downHeap(1); scoreUser[id].indexHeap = 0; return id; } opt inline void reset() { nUser = 0; } opt inline int size() { return nUser; } } heapUser; struct MAX_HEAP_POST { private: int dataPost[MAX_ID]; int nPost; opt inline bool compare(int i, int j) { if (scorePost[dataPost[i]].score > scorePost[dataPost[j]].score) return true; if (scorePost[dataPost[i]].score == scorePost[dataPost[j]].score) return (id[dataPost[i]].mID < id[dataPost[j]].mID); return false; } opt inline void swap(int i, int j) { int id1 = dataPost[i], id2 = dataPost[j]; dataPost[i] = dataPost[j]; dataPost[j] = id1; scorePost[id1].indexHeap = j; scorePost[id2].indexHeap = i; } public: opt inline void upHeap(int k) { int child = k, parent = k / 2; while (parent != 0) { if (compare(child, parent)) { swap(child, parent); child = parent; parent = child / 2; } else break; } } opt inline void downHeap(int k) { int parent = k, child = 2 * k; while (child <= nPost) { if (child + 1 <= nPost && compare(child + 1, child)) child = child + 1; if (compare(child, parent)) { swap(child, parent); parent = child; child = 2 * parent; } else break; } } opt inline void push(int index) { nPost++; dataPost[nPost] = index; scorePost[index].indexHeap = nPost; upHeap(nPost); } opt inline int pop() { int id = dataPost[1]; swap(1, nPost); nPost--; downHeap(1); scorePost[id].indexHeap = 0; return id; } opt inline void reset() { nPost = 0; } opt inline int size() { return nPost; } } heapPost; opt void init() { heapUser.reset(); heapPost.reset(); linkedList.reset(); map.reset(); return; } opt int writeMessage(char mUser[], int mID, int mPoint) { int idUser = map.findUser(mUser); if (idUser == -1) { idUser = map.addUser(mUser); scoreUser[idUser].score = mPoint; heapUser.push(idUser); } else { scoreUser[idUser].score += mPoint; heapUser.upHeap(scoreUser[idUser].indexHeap); } int id = map.addID(mID, 1, idUser, mPoint); scorePost[id].score = mPoint; heapPost.push(id); parent[id] = id; return scoreUser[idUser].score; } opt int commentTo(char mUser[], int mID, int mTargetID, int mPoint) { int idUser = map.findUser(mUser); if (idUser == -1) { idUser = map.addUser(mUser); scoreUser[idUser].score = mPoint; heapUser.push(idUser); } else { scoreUser[idUser].score += mPoint; heapUser.upHeap(scoreUser[idUser].indexHeap); } int targetID = map.findID(mTargetID); int idx = map.addID(mID, id[targetID].key + 1, idUser, mPoint); parent[idx] = targetID; int idPost = parent[targetID]; scorePost[idPost].score += mPoint; heapPost.upHeap(scorePost[idPost].indexHeap); linkedList.add(idPost, idx); if (id[targetID].key == 2) // comment linkedList.add(targetID, idx); return scorePost[idPost].score; } opt int erase(int mID) { int id1 = map.findID(mID); if (id[id1].key == 3) // Reply { int u = id[id1].userID; scoreUser[u].score -= id[id1].point; heapUser.downHeap(scoreUser[u].indexHeap); int idPost = parent[parent[id1]]; scorePost[idPost].score -= id[id1].point; heapPost.downHeap(scorePost[idPost].indexHeap); id[id1].isDelete = true; return scorePost[idPost].score; } else if (id[id1].key == 2) { int idPost = parent[id1]; Node *curNode = firstNode[id1]; while (curNode != nullptr) { int idx = curNode->data; curNode = curNode->nextNode; if (id[idx].isDelete == true) continue; int u = id[idx].userID; scoreUser[u].score -= id[idx].point; heapUser.downHeap(scoreUser[u].indexHeap); scorePost[idPost].score -= id[idx].point; id[idx].isDelete = true; } int u = id[id1].userID; scoreUser[u].score -= id[id1].point; heapUser.downHeap(scoreUser[u].indexHeap); scorePost[idPost].score -= id[id1].point; id[id1].isDelete = true; heapPost.downHeap(scorePost[idPost].indexHeap); return scorePost[idPost].score; } else // id1 is Post (id[id1].key == 1)) { Node *curNode = firstNode[id1]; while (curNode != nullptr) { int idx = curNode->data; curNode = curNode->nextNode; if (id[idx].isDelete == true) continue; int u = id[idx].userID; scoreUser[u].score -= id[idx].point; heapUser.downHeap(scoreUser[u].indexHeap); } id[id1].isDelete = true; scorePost[id1].score = 0; heapPost.downHeap(scorePost[id1].indexHeap); int userID = id[id1].userID; scoreUser[userID].score -= id[id1].point; heapUser.downHeap(scoreUser[userID].indexHeap); return scoreUser[userID].score; } } opt void getBestMessages(int mBestMessageList[]) { int target[5], i; for (i = 0; i < 5; ++i) target[i] = heapPost.pop(); for (i = 0; i < 5; ++i) heapPost.push(target[i]); for (i = 0; i < 5; ++i) mBestMessageList[i] = id[target[i]].mID; return; } opt void getBestUsers(char mBestUserList[][MAXL + 1]) { int target[5], i; for (i = 0; i < 5; ++i) target[i] = heapUser.pop(); for (i = 0; i < 5; ++i) heapUser.push(target[i]); for (i = 0; i < 5; ++i) mStrcpy(user[target[i]].userName, mBestUserList[i]); return; } //input 25 100 20 100 200 aaa 1 10 10 200 bbb 2 5 5 300 ccc 3 1 5 15 300 ddd 4 1 3 18 300 eee 5 3 4 22 600 aaa bbb ccc eee ddd 200 ccc 6 20 25 200 bbb 7 13 18 200 aaa 8 20 30 500 1 6 8 7 2 200 fff 9 1 1 300 ddd 10 6 10 30 400 3 13 600 aaa ccc bbb ddd fff 400 6 0 300 ccc 20 2 35 40 300 fff 30 9 14 15 500 2 8 9 1 7 600 ccc aaa bbb fff ddd 27 100 200 t 424 9 9 200 mpky 7 7 7 300 l 492 7 1 8 300 p 860451 424 6 15 300 hv 2158753 860451 2 17 300 t 8225355 492 1 9 300 hv 9 860451 2 19 200 kzwgyt 56 9 9 200 mpky 90388 6 13 400 492 7 600 mpky kzwgyt t p hv 200 geur 905 1 1 200 geur 558 1 2 500 424 56 7 90388 558 300 mpky 532037 90388 6 12 300 geur 4380 532037 8 20 300 kzwgyt 580534984 905 5 6 200 l 12838 4 4 300 p 95050 90388 6 26 200 kzwgyt 81 1 15 300 zfu 2 424 8 27 400 12838 0 200 mpky 110748 1 20 200 xp 88696 3 3 500 424 90388 56 7 905 600 mpky kzwgyt p geur t
Editor is loading...