template<class T1, class T2> inline void sort(T1 &a, T2 comp) { sort(ALL(a), comp); }
inline void sort(T1& a, T2 comp) { sort(ALL(a), comp); }
template<class T> inline void sort(T &a) { std::sort(ALL(a)); }
void dfs(int i, vi G) { if(!V[i]){ V[i] = 1; for_each(ALL(G[i]), dfs); } }
inline void sort(T& a) { std::sort(ALL(a)); }
Answer Solver::Solve(Problem &prob) { auto statuses = tbb::concurrent_vector<Answer>(); auto nextStatuses = tbb::concurrent_vector<Answer>(); auto hashTable = tbb::concurrent_unordered_set<Answer, std::hash<Answer>>(); int maxZk = 0; int minUsed = 256; statuses.push_back(std::move(Answer(prob))); while (_bestFirst || statuses.front()._stoneCount != statuses.front()._places.size()) { if (_bestFirst) { // 最良優先ビームサーチ // ハッシュテーブルが大きすぎる場合の処理 if (hashTable.size() > _maxQueueSize) { tbb::concurrent_vector<Answer> tmp; tbb::concurrent_unordered_set<Answer, std::hash<Answer>> newHashTable; for (const auto & status : hashTable) tmp.push_back(status); tbb::parallel_sort(ALL(tmp), std::greater<Answer>()); for (int i = 0; i < _maxQueueSize; i++) newHashTable.insert(tmp[i]); hashTable = std::move(newHashTable); } } else { // 幅優先ビームサーチ hashTable = tbb::concurrent_unordered_set<Answer, std::hash<Answer>>(); } if (_beam < statuses.size()) { tbb::parallel_sort(ALL(statuses), std::greater<Answer>()); tbb::concurrent_vector<Answer> tmp; tmp.resize(_beam); for (int i = 0; i < _beam; i++) tmp[i] = statuses[i]; statuses = std::move(tmp); } // 並列処理! tbb::parallel_for_each(ALL(statuses), [&](Answer ¤t) { auto next = current; if (statuses.front()._stoneCount != statuses.front()._places.size()) { if (current.first()) { for (int i = 0; i <= 1; i++) // up { for (int j = 0; j < 4; j++) // dir { for (int y = -7; y < 32; y++) { for (int x = -7; x < 32; x++) { if (next.applyPlacement(x, y, (bool)i, (Direction)j)) { auto it = hashTable.find(next); if (it == hashTable.end()) { hashTable.insert(next); } else { if (*it < next) { *it = next; } } next = current; } } } } } } else { auto &stone = current._stones[current._places.size()]; for (int i = 0; i <= 1; i++) // up { for (int j = 0; j < 4; j++) // dir { bool alreadyPlaced[39][39]; memset(alreadyPlaced, 0, sizeof(alreadyPlaced)); for (auto stonePos : stone.stonePos((bool)i, (Direction)j)) for (auto neighborPos : current._neighbors) alreadyPlaced[neighborPos._y - stonePos._y + 1 + 7][neighborPos._x - stonePos._x + 1 + 7] = true; for (int y = 0; y < 39; y++) { for (int x = 0; x < 39; x++) { if (alreadyPlaced[y][x]) { if (next.applyPlacement(x - 7, y - 7, (bool)i, (Direction)j)) { auto it = hashTable.find(next); if (it == hashTable.end()) { hashTable.insert(next); } else { if (*it < next) *it = next; } next = current; } } } } } } } current.skipStone(); nextStatuses.push_back(current); } }); statuses = std::move(nextStatuses); for (auto status : hashTable) { if (_bestFirst) { if (status._stoneCount == status._places.size()) { if (maxZk < status.zk()) { maxZk = status.zk(); minUsed = status.used(); // int value = (1024 - status.zk()) * 257 + status.used(); // std::cout << value << std::endl; // std::cout << status.getAnswer(); } else if (maxZk == status.zk() && minUsed > status.used()) { minUsed = status.used(); // int value = (1024 - status.zk()) * 257 + status.used(); // std::cout << value << std::endl; // std::cout << status.getAnswer(); } } } statuses.push_back(std::move(status)); } } Answer result; if (!_bestFirst) { int maxZk = 0; int minUsed = 256; for (const auto & status : statuses) { if (maxZk < status.zk()) { maxZk = status.zk(); minUsed = status.used(); result = status; } else if (maxZk == status.zk() && minUsed > status.used()) { minUsed = status.used(); result = status; } } // int value = (1024 - result.zk()) * 257 + result.used(); // std::cout << value << std::endl; // std::cout << result.getAnswer(); } return result; }
ASTNode::Link XMLParser::parseXMLNode(rapidxml::xml_node<>* node) { auto safeAttr = [node](std::string what, std::string defaultValue = "") -> std::string { auto attr = node->first_attribute(what.c_str()); if (attr != nullptr) return attr->value(); else return defaultValue; }; auto requiredAttr = [node](std::string what) -> std::string { auto attr = node->first_attribute(what.c_str()); if (attr != nullptr) return attr->value(); else throw XMLParseError("Can't find required attribute", { METADATA_PAIRS, {"missing attribute", what} }); }; auto funArgs = [node, &safeAttr]() -> FunctionSignature::Arguments { FunctionSignature::Arguments args {}; std::vector<std::string> stringArgs = split(safeAttr("args"), ','); for (auto& arg : stringArgs) { std::vector<std::string> namePlusTypes = split(arg, ':'); std::vector<std::string> types = split(namePlusTypes[1], ' '); args.push_back(std::make_pair(namePlusTypes[0], TypeList(ALL(types)))); } return args; }; auto funRet = [node, &safeAttr]() -> TypeInfo { std::vector<std::string> returnTypes = split(safeAttr("return"), ' '); return returnTypes.size() == 0 ? nullptr : TypeInfo(TypeList(ALL(returnTypes))); }; auto funBlock = [=](Node<FunctionNode>::Link f) { if (!f->isForeign()) { auto codeBlock = node->first_node("block"); if (codeBlock == nullptr) throw XMLParseError("Method missing code block", {METADATA_PAIRS}); f->setCode(Node<BlockNode>::staticPtrCast(parseXMLNode(codeBlock))); } }; auto getVisibility = [node, &safeAttr]() -> Visibility { return fromString(safeAttr("visibility", "private")); }; auto boolAttr = [node, &safeAttr](std::string what) -> bool { return safeAttr(what, "false") == "true"; }; if (node == nullptr) throw XMLParseError("Null node", {METADATA_PAIRS}); std::string name = node->name(); if (name == "block") { std::string type = safeAttr("type", "code"); BlockType bt = type == "root" ? ROOT_BLOCK : type == "if" ? IF_BLOCK : type == "function" ? FUNCTION_BLOCK : CODE_BLOCK; auto block = Node<BlockNode>::make(bt); parseChildren(node, block); return block; } else if (name == "return") { auto retNode = Node<ReturnNode>::make(); auto val = node->first_node("expr"); if (val != nullptr) retNode->setValue(Node<ExpressionNode>::dynPtrCast(parseXMLNode(val))); return retNode; } else if (name == "expr") { TokenType tokenType = TT::findByPrettyName(requiredAttr("type")); std::string data = requiredAttr("value"); std::unique_ptr<Token> content; if (tokenType == TT::OPERATOR) { content = std::make_unique<Token>(tokenType, Operator::find(data), defaultTrace); } else { content = std::make_unique<Token>(tokenType, data, defaultTrace); } auto expr = Node<ExpressionNode>::make(*content); parseChildren(node, expr); return expr; } else if (name == "decl") { Node<DeclarationNode>::Link decl; std::string ident = requiredAttr("ident"); bool isDynamic = boolAttr("dynamic"); if (isDynamic) { decl = Node<DeclarationNode>::make(ident, TypeList {}); } else { std::string tlValue = requiredAttr("types"); auto vec = split(tlValue, ' '); decl = Node<DeclarationNode>::make(ident, TypeList(ALL(vec))); } auto expr = node->first_node("expr"); if (expr != nullptr) { decl->setInit(Node<ExpressionNode>::dynPtrCast(parseXMLNode(expr))); } return decl; } else if (name == "branch") { auto branch = Node<BranchNode>::make(); auto cond = node->first_node(); if (cond == nullptr) throw XMLParseError("Missing condition in branch", {METADATA_PAIRS}); branch->setCondition(Node<ExpressionNode>::dynPtrCast(parseXMLNode(cond))); auto success = cond->next_sibling(); if (success == nullptr) throw XMLParseError("Missing success node in branch", {METADATA_PAIRS}); branch->setSuccessBlock(Node<BlockNode>::dynPtrCast(parseXMLNode(success))); auto blockFailiure = success->next_sibling("block"); if (blockFailiure != nullptr) { branch->setFailiureBlock(Node<BlockNode>::dynPtrCast(parseXMLNode(blockFailiure))); } auto branchFailiure = success->next_sibling("branch"); if (branchFailiure != nullptr) { branch->setFailiureBlock(Node<BranchNode>::dynPtrCast(parseXMLNode(branchFailiure))); } return branch; } else if (name == "loop") { auto loop = Node<LoopNode>::make(); auto init = node->first_node("loop_init"); if (init != nullptr) { loop->setInit(Node<DeclarationNode>::dynPtrCast(parseXMLNode(init))); } auto cond = node->first_node("loop_condition"); if (cond != nullptr) { loop->setCondition(Node<ExpressionNode>::dynPtrCast(parseXMLNode(cond))); } auto update = node->first_node("loop_update"); if (update != nullptr) { loop->setUpdate(Node<ExpressionNode>::dynPtrCast(parseXMLNode(update))); } auto code = node->first_node("block"); if (code != nullptr) { loop->setCode(Node<BlockNode>::dynPtrCast(parseXMLNode(code))); } return loop; } else if (name == "loop_init" || name == "loop_condition" || name == "loop_update") { return parseXMLNode(node->first_node()); } else if (name == "break") { return Node<BreakLoopNode>::make(); } else if (name == "function") { std::string ident = safeAttr("ident"); bool isForeign = boolAttr("foreign"); auto n = Node<FunctionNode>::make(ident, FunctionSignature(funRet(), funArgs()), isForeign); funBlock(n); if (isForeign && ident.empty()) throw XMLParseError("Can't have anonymous foreign function", {METADATA_PAIRS}); return n; } else if (name == "type") { std::string typeName = requiredAttr("name"); std::vector<std::string> inheritTypes = split(safeAttr("inherits"), ' '); auto typeNode = Node<TypeNode>::make(typeName, TypeList(ALL(inheritTypes))); parseChildren(node, typeNode); return typeNode; } else if (name == "member") { std::string ident = requiredAttr("ident"); std::vector<std::string> types = split(safeAttr("types"), ' '); auto member = Node<MemberNode>::make(ident, TypeList(ALL(types)), boolAttr("static"), getVisibility()); auto init = node->first_node("expr"); if (init != nullptr) { member->setInit(Node<ExpressionNode>::staticPtrCast(parseXMLNode(init))); } return member; } else if (name == "method") { std::string ident = safeAttr("ident"); bool isForeign = boolAttr("foreign"); auto method = Node<MethodNode>::make(ident, FunctionSignature(funRet(), funArgs()), getVisibility(), boolAttr("static"), isForeign); funBlock(method); if (isForeign && ident.empty()) throw XMLParseError("Can't have anonymous foreign method", {METADATA_PAIRS}); return method; } else if (name == "constructor") { auto constructor = Node<ConstructorNode>::make(funArgs(), getVisibility()); funBlock(constructor); return constructor; } throw XMLParseError("Unknown type of node", {METADATA_PAIRS, {"node name", name}}); }
void terrainInit(const char *texture_path) { terrain_current = loadTextureFromFile(texture_path); if(!terrain_current) terrain_current = &terrain; //Use default, included texture else puts("External texture loaded!"); int fields_x = 16; int fields_y = 16; int field_width = terrain_current->width / fields_x; int field_height = terrain_current->height / fields_y; //Give grass and leaves color const RGB green = { 0.5f, 0.8f, 0.3f }; makeColor(green, *terrain_current, 0, 0, field_width, field_height); makeColor(green, *terrain_current, 5 * field_width, 3 * field_height, field_width, field_height); makeColor(green, *terrain_current, 4 * field_width, 3 * field_height, field_width, field_height); //Also redstone drawTexture(*terrain_current, *terrain_current, 4 * field_width, 10 * field_height, field_width, field_height, 4 * field_width, 11 * field_height, field_width, field_height); const RGB red = { 0.9f, 0.1f, 0.1f }; makeColor(red, *terrain_current, 4 * field_width, 11 * field_height, field_width, field_height); //And redstone switches drawTexture(*terrain_current, *terrain_current, 0 * field_width, 6 * field_height, field_width, field_height, 0 * field_width, 7 * field_height, field_width, field_height); const RGB red_tint = { 1.0f, 0.8f, 0.8f }; makeColor(red_tint, *terrain_current, 0 * field_width, 7 * field_height, field_width, field_height); if(terrain_current->width == 256 && terrain_current->height == 256) terrain_resized = terrain_current; else terrain_resized = resizeTexture(*terrain_current, 256, 256); for(int y = 0; y < fields_y; y++) for(int x = 0; x < fields_x; x++) { //+1 and -2 to work around GLFix inaccuracies resulting in rounding errors TerrainAtlasEntry tea = terrain_atlas[x][y] = {textureArea(x * field_width + 1, y * field_height + 1, field_width - 2, field_height - 2), textureArea(x * 16, y * 16, 16, 16) }; BLOCK_TEXTURE bt = texture_atlas[y][x]; if(bt.sides == 0) continue; if(bt.sides & BLOCK_BOTTOM_BIT) block_textures[bt.block][BLOCK_BOTTOM] = tea; if(bt.sides & BLOCK_TOP_BIT) block_textures[bt.block][BLOCK_TOP] = tea; if(bt.sides & BLOCK_LEFT_BIT) block_textures[bt.block][BLOCK_LEFT] = tea; if(bt.sides & BLOCK_RIGHT_BIT) block_textures[bt.block][BLOCK_RIGHT] = tea; if(bt.sides & BLOCK_FRONT_BIT) block_textures[bt.block][BLOCK_FRONT] = tea; if(bt.sides & BLOCK_BACK_BIT) block_textures[bt.block][BLOCK_BACK] = tea; } //Slight hack, you can't assign a texture to multiple blocks block_textures[BLOCK_GRASS][BLOCK_BOTTOM] = block_textures[BLOCK_DIRT][BLOCK_BOTTOM]; //Prerender four times the same texture to speed up drawing, see terrain.h const BLOCK_TEXTURE quad_textures[] = { ALL(BLOCK_DIRT), SID(BLOCK_GRASS), TOP(BLOCK_GRASS), ALL(BLOCK_STONE), ALL(BLOCK_SAND), SID(BLOCK_WOOD), ALL(BLOCK_PLANKS_NORMAL), ALL(BLOCK_LEAVES) }; terrain_quad = newTexture(field_width * 2 * (sizeof(quad_textures)/sizeof(*quad_textures)), field_height * 2); for(BLOCK b = 0; b <= BLOCK_NORMAL_LAST; b++) for(uint8_t s = 0; s <= BLOCK_SIDE_LAST; s++) quad_block_textures[b][s].has_quad = false; unsigned int x = 0; for(BLOCK_TEXTURE bt : quad_textures) { TextureAtlasEntry *tae = nullptr; if(bt.sides & BLOCK_BOTTOM_BIT) tae = &block_textures[bt.block][BLOCK_BOTTOM].current; if(bt.sides & BLOCK_TOP_BIT) tae = &block_textures[bt.block][BLOCK_TOP].current; if(bt.sides & BLOCK_LEFT_BIT) tae = &block_textures[bt.block][BLOCK_LEFT].current; if(bt.sides & BLOCK_RIGHT_BIT) tae = &block_textures[bt.block][BLOCK_RIGHT].current; if(bt.sides & BLOCK_FRONT_BIT) tae = &block_textures[bt.block][BLOCK_FRONT].current; if(bt.sides & BLOCK_BACK_BIT) tae = &block_textures[bt.block][BLOCK_BACK].current; if(!tae) { printf("Block %d has no texture!\n", bt.block); continue; } //- 1 to reverse the workaround above. Yes, I hate myself for this. drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x, 0, field_width, field_height); drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x + field_width, 0, field_width, field_height); drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x+ field_width, field_height, field_width, field_height); drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x, field_height, field_width, field_height); //Get an average color of the block RGB sum; for(unsigned int tex_x = tae->left - 1; tex_x <= tae->right; ++tex_x) for(unsigned int tex_y = tae->top - 1; tex_y <= tae->bottom; ++tex_y) { RGB rgb = rgbColor(terrain_current->bitmap[tex_x + tex_y*terrain_current->width]); sum.r += rgb.r; sum.g += rgb.g; sum.b += rgb.b; } int pixels = field_width * field_height; sum.r /= pixels; sum.g /= pixels; sum.b /= pixels; const COLOR darker = colorRGB(sum.r / GLFix(1.5f), sum.g / GLFix(1.5f), sum.b / GLFix(1.5f)); //And add the workaround here again.. TerrainQuadEntry tqe = { true, textureArea(x + 1, 1, field_width * 2 - 2, field_height * 2 - 2), colorRGB(sum), darker }; if(bt.sides & BLOCK_BOTTOM_BIT) quad_block_textures[bt.block][BLOCK_BOTTOM] = tqe; if(bt.sides & BLOCK_TOP_BIT) quad_block_textures[bt.block][BLOCK_TOP] = tqe; if(bt.sides & BLOCK_LEFT_BIT) quad_block_textures[bt.block][BLOCK_LEFT] = tqe; if(bt.sides & BLOCK_RIGHT_BIT) quad_block_textures[bt.block][BLOCK_RIGHT] = tqe; if(bt.sides & BLOCK_FRONT_BIT) quad_block_textures[bt.block][BLOCK_FRONT] = tqe; if(bt.sides & BLOCK_BACK_BIT) quad_block_textures[bt.block][BLOCK_BACK] = tqe; x += field_width * 2; } //Part 2 of the hack above quad_block_textures[BLOCK_GRASS][BLOCK_BOTTOM] = quad_block_textures[BLOCK_DIRT][BLOCK_BOTTOM]; if(lcd_type() == SCR_320x240_4) { greyscaleTexture(*terrain_current); greyscaleTexture(*terrain_resized); greyscaleTexture(*terrain_quad); } //Resize the glass texture to 32x32 const TextureAtlasEntry &glass_tex = block_textures[BLOCK_GLASS][BLOCK_FRONT].current; glass_big = newTexture(32, 32); drawTexture(*terrain_current, *glass_big, glass_tex.left - 1, glass_tex.top - 1, field_width, field_height, 0, 0, 32, 32); }
int main() { scanf("%d", &n); for (int i = 0; i < n; ++ i) { scanf("%d", a + i); } scanf("%d", &m); for (int i = 0; i < m; ++ i) { scanf("%d", b + i); } std::sort(b, b + m); std::vector<std::pair<int, int>> low(n + 1, std::make_pair(INT_MAX, -1)); low[0] = std::make_pair(INT_MIN, -1); for (int i = 0; i < n; ++ i) { if (~a[i]) { int l = std::lower_bound(ALL(low), std::make_pair(a[i], INT_MIN)) - low.begin(); pre[i] = low[l - 1].second; low[l] = std::min(low[l], std::make_pair(a[i], i)); } else { for (int j = m - 1, k = n; j >= 0; -- j) { while (low[k].first >= b[j]) { k --; } low[k + 1] = std::min(low[k + 1], std::make_pair(b[j], low[k].second)); } } } int ml = n; while (low[ml].first == INT_MAX) { ml --; } std::vector<int> seq; for (int i = low[ml].second; ~i; i = pre[i]) { seq.push_back(i); } std::sort(ALL(seq)); std::vector<int> val; for (int i = 0; i < m; ++ i) { if (!i || b[val.back()] < b[i]) { val.push_back(i); } } memset(used, 0, sizeof(used)); for (int i = 0, j = 0, k = 0; i < n; ++ i) { if (a[i] == -1) { bool valid = j < (int)val.size(); if (k < (int)seq.size()) { valid &= b[val[j]] < a[seq[k]]; } if (valid) { used[val[j]] = true; a[i] = b[val[j ++]]; } } if (k < seq.size() && i == seq[k]) { while (j < (int)val.size() && b[val[j]] <= a[i]) { j ++; } k ++; } } for (int i = 0, j = 0; i < n; ++ i) { if (a[i] == -1) { while (used[j]) { j ++; } a[i] = b[j ++]; } printf("%d%c", a[i], " \n"[i == n - 1]); } return 0; }
#define ALL(block) {block, BLOCK_TOP_BIT | BLOCK_BOTTOM_BIT | BLOCK_LEFT_BIT | BLOCK_RIGHT_BIT | BLOCK_FRONT_BIT | BLOCK_BACK_BIT} #define TOP(block) {block, BLOCK_TOP_BIT} #define BOT(block) {block, BLOCK_BOTTOM_BIT} #define LEF(block) {block, BLOCK_LEFT_BIT} #define RIG(block) {block, BLOCK_RIGHT_BIT} #define FRO(block) {block, BLOCK_FRONT_BIT} #define BAC(block) {block, BLOCK_BACK_BIT} #define TAB(block) {block, BLOCK_TOP_BIT | BLOCK_BOTTOM_BIT} #define SID(block) {block, BLOCK_FRONT_BIT | BLOCK_BACK_BIT | BLOCK_LEFT_BIT | BLOCK_RIGHT_BIT} #define SWF(block) {block, BLOCK_BACK_BIT | BLOCK_LEFT_BIT | BLOCK_RIGHT_BIT} #define AWF(block) {block, BLOCK_TOP_BIT | BLOCK_BOTTOM_BIT | BLOCK_LEFT_BIT | BLOCK_RIGHT_BIT | BLOCK_BACK_BIT} //Maps location in texture atlas to block ID BLOCK_TEXTURE texture_atlas[][16] = { { TOP(BLOCK_GRASS), ALL(BLOCK_STONE), ALL(BLOCK_DIRT), SID(BLOCK_GRASS), ALL(BLOCK_PLANKS_NORMAL), NON, NON, ALL(BLOCK_WALL), ALL(BLOCK_TNT), TOP(BLOCK_TNT), BOT(BLOCK_TNT), NON, NON, NON, NON, NON }, { NON, ALL(BLOCK_BEDROCK), ALL(BLOCK_SAND), ALL(BLOCK_COBBLESTONE), SID(BLOCK_WOOD), TAB(BLOCK_WOOD), ALL(BLOCK_IRON), ALL(BLOCK_GOLD), ALL(BLOCK_DIAMOND), NON, NON, NON, NON, NON, NON, NON }, { ALL(BLOCK_GOLD_ORE), ALL(BLOCK_IRON_ORE), ALL(BLOCK_COAL_ORE), FRO(BLOCK_BOOKSHELF), NON, NON, NON, NON, NON, NON, NON, TAB(BLOCK_CRAFTING_TABLE), FRO(BLOCK_FURNACE), SWF(BLOCK_FURNACE), NON, NON }, { ALL(BLOCK_SPONGE), ALL(BLOCK_GLASS), ALL(BLOCK_DIAMOND_ORE), ALL(BLOCK_REDSTONE_ORE), NON, ALL(BLOCK_LEAVES), NON, NON, NON, NON, NON, SID(BLOCK_CRAFTING_TABLE), FRO(BLOCK_CRAFTING_TABLE), NON, TOP(BLOCK_FURNACE), NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, TAB(BLOCK_PUMPKIN), ALL(BLOCK_NETHERRACK), NON, ALL(BLOCK_GLOWSTONE), NON, NON, NON, NON, NON, NON}, { NON, NON, NON, NON, NON, NON, SWF(BLOCK_PUMPKIN), FRO(BLOCK_PUMPKIN), NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, ALL(BLOCK_PLANKS_DARK), AWF(BLOCK_BOOKSHELF), NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, ALL(BLOCK_PLANKS_BRIGHT), NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }, { NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON }
int main(int argc, char **argv) { Vals vals; /* the application */ QApplication app(argc, argv); app.setApplicationName(APP_NAME); app.setWindowIcon(QIcon(":/icon")); Window window; /* translations */ QTranslator qtr; if (qtr.load("qt_" + QLocale::system().name(), QTR_PATH)) app.installTranslator(&qtr); QTranslator htr; if (htr.load("H4KvT_" + QLocale::system().name(), ":/")) app.installTranslator(&htr); /* display information */ QTextEdit *text = new QTextEdit; text->setReadOnly(true); text->setLineWrapMode(QTextEdit::NoWrap); text->setToolTip(Window::tr("Drop any file for hashing")); QObject::connect(&window, &Window::idle, text, &QWidget::setEnabled); /* compare hash */ QLineEdit *test = new QLineEdit; HexVal hexval; test->setValidator(&hexval); test->installEventFilter(&window); test->setToolTip(Window::tr("Compare hashes")); QObject::connect(test, &QLineEdit::textChanged, [&](const QString &newValue) { if (vals.name != "") { std::string hashVal = newValue.toStdString(); std::transform(hashVal.begin(), hashVal.end(), hashVal.begin(), ::tolower); std::stringstream html; if (hashVal != "") html << "<style>.h" << hashVal << "{color:green}</style>"; html << "<div style='margin-bottom:2; font-size:27px'><i><b>" << vals.name << "</b></i></div>"; html << "<div style='margin-bottom:7; margin-left:23; font-size:13px'>" << vals.path << "</div>"; if (!ALL(vals,"")) { html << "<div style='font-size:13px'><table>"; if (vals.md5 != "") html << "<tr><td>md5: </td><td class='h" << vals.md5 << "'>" << vals.md5 << "</td</tr>"; if (vals.sha1 != "") html << "<tr><td>sha1: </td><td class='h" << vals.sha1 << "'>" << vals.sha1 << "</td</tr>"; if (vals.sha224 != "") html << "<tr><td>sha224: </td><td class='h" << vals.sha224 << "'>" << vals.sha224 << "</td</tr>"; if (vals.sha256 != "") html << "<tr><td>sha256: </td><td class='h" << vals.sha256 << "'>" << vals.sha256 << "</td</tr>"; if (vals.sha384 != "") html << "<tr><td>sha384: </td><td class='h" << vals.sha384 << "'>" << vals.sha384 << "</td</tr>"; if (vals.sha512 != "") html << "<tr><td>sha512: </td><td class='h" << vals.sha512 << "'>" << vals.sha512 << "</td</tr>"; html << "</table></div>"; } int horizontal = text->horizontalScrollBar()->value(); int vertical = text->verticalScrollBar()->value(); text->setHtml(QString::fromStdString(html.str())); text->horizontalScrollBar()->setValue(horizontal); text->verticalScrollBar()->setValue(vertical); test->setStyleSheet(ANY(vals,hashVal) ? "color:green" : ""); }}); /* error messages */ QLabel *error = new QLabel; error->setStyleSheet("color:red"); /* test or error */ QStackedWidget *stack = new QStackedWidget; delete stack->layout(); stack->setLayout(new Stack); stack->addWidget(error); stack->addWidget(test); stack->setCurrentIndex(1); /* toggle test or error */ QPushButton *hash = new QPushButton(QIcon(":/icon"), ""); hash->setCheckable(true); hash->setChecked(true); hash->setToolTip(Window::tr("Compare hashes")); QObject::connect(hash, &QPushButton::toggled, stack, &QStackedWidget::setCurrentIndex); /* store method */ QSettings settings("H4KvT", "H4KvT"); /* more methods */ bool more; try { settings.setValue("MoreHashingMethods", more = moreOrLess()); } catch (...) { more = settings.value("MoreHashingMethods", false).toBool(); } /* hashing method */ QComboBox *meth = new QComboBox; meth->addItem("md5"); meth->addItem("sha1"); if (more) meth->addItem("sha224"); meth->addItem("sha256"); if (more) meth->addItem("sha384"); meth->addItem("sha512"); meth->setToolTip(Window::tr("Hashing method")); meth->setCurrentText(settings.value("HashingMethod", "md5").toString()); QObject::connect(&window, &Window::idle, meth, &QWidget::setEnabled); QObject::connect(meth, &QComboBox::currentTextChanged, [&](const QString &text) { settings.setValue("HashingMethod", text); }); /* toolbar */ QHBoxLayout *pane = new QHBoxLayout; pane->addWidget(hash, 0, Qt::AlignLeft); pane->addWidget(stack); pane->addWidget(meth, 0, Qt::AlignRight); /* main layout */ QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(text); layout->addLayout(pane); /* the window */ window.centralWidget()->setLayout(layout); window.show(); /* future hashing */ QFutureWatcher<Vals> zu; QObject::connect(&zu, &QFutureWatcher<Vals>::finished, [&]() { Vals valsi = zu.future().result(); window.idle(true); if (valsi.path == "") { error->setText(QString::fromStdString(valsi.name)); hash->setChecked(false); } else { error->clear(); vals += valsi; test->textChanged(test->text()); } }); QObject::connect(meth, &QComboBox::currentTextChanged, [&](const QString &text) { if (vals.name != "") { window.idle(false); zu.setFuture(QtConcurrent::run(&update, text, vals)); }}); QObject::connect(&window, &Window::fileDroped, [&](const QString &name, const QString &path) { window.idle(false); zu.setFuture(QtConcurrent::run(&update, meth->currentText(), Vals(name, path))); }); /* hashing info */ QGraphicsBlurEffect blur; blur.setBlurHints(QGraphicsBlurEffect::AnimationHint); QPropertyAnimation anim(&blur, "blurRadius"); anim.setDuration(2000); anim.setLoopCount(-1); anim.setKeyValueAt(0, 0); anim.setKeyValueAt(0.5, 3); anim.setKeyValueAt(1, 0); QLabel *hashing = new QLabel; hashing->setPixmap(QPixmap(":/icon")); hashing->setAttribute(Qt::WA_TransparentForMouseEvents); hashing->setGraphicsEffect(&blur); hashing->hide(); (new QHBoxLayout(text))->addWidget(hashing, 0, Qt::AlignCenter); QObject::connect(&blur, &QGraphicsBlurEffect::blurRadiusChanged, hashing, static_cast<void(QWidget::*)()>(&QWidget::update)); QObject::connect(&window, &Window::idle, [&](bool idle) { if (idle) { hashing->hide(); anim.stop(); } else { hashing->show(); anim.start(); } }); /* about app */ QMenu about; QAction *action = about.addAction(QIcon(":/icon"), Window::tr("About %1").arg(APP_NAME)); action->setMenuRole(QAction::AboutRole); QObject::connect(action, &QAction::triggered, &window, &Window::about); error->setContextMenuPolicy(Qt::NoContextMenu); hash->setContextMenuPolicy(Qt::NoContextMenu); meth->setContextMenuPolicy(Qt::NoContextMenu); window.setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(&window, &QWidget::customContextMenuRequested, [&about, &window](const QPoint &pos) { about.popup(window.mapToGlobal(pos)); }); text->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(text, &QWidget::customContextMenuRequested, [action, text](const QPoint &pos) { if (QMenu *m = text->createStandardContextMenu()) { m->insertAction(m->insertSeparator(m->actions()[0]), action); m->popup(text->mapToGlobal(pos)); } }); test->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(test, &QWidget::customContextMenuRequested, [action, test](const QPoint &pos) { if (QMenu *m = test->createStandardContextMenu()) { m->insertAction(m->insertSeparator(m->actions()[0]), action); m->popup(test->mapToGlobal(pos)); } }); return app.exec(); }
int main() { timestamp = 0; memset(visited, -1, sizeof(visited)); int n, m, q; scanf("%d%d%d", &n, &m, &q); for (int i = 0; i < n; ++ i) { scanf("%d", weight + i); } for (int i = 0; i < m; ++ i) { int a, b; scanf("%d%d", &a, &b); a --; b --; graph[a].push_back(b); rgraph[b].push_back(a); } memset(match_x, -1, sizeof(match_x)); memset(match_y, -1, sizeof(match_y)); int sum = 0; { std::vector<int> order(n); std::iota(ALL(order), 0); std::sort(ALL(order), by_weight); memset(match_x, -1, sizeof(match_x)); memset(match_y, -1, sizeof(match_y)); timestamp ++; for (int v : order) { if (weight[v] < 0) { break; } if (find(v)) { sum += weight[v]; timestamp ++; } } } while (q --) { int u, w; scanf("%d%d", &u, &w); u --; timestamp ++; do { if (match_x[u] == -1) { weight[u] = w; if (w < 0) { continue; } if (find(u)) { sum += weight[u]; } else { timestamp ++; dfs(u); int best = u; for (int v = 0; v < n; ++ v) { if (visited[v] == timestamp && weight[v] < weight[best]) { best = v; } } if (best != u) { match_x[best] = -1; } for (int p = best; p != u; p = parent[p]) { match_y[via[p]] = parent[p]; match_x[parent[p]] = via[p]; } sum += weight[u] - weight[best]; } } else { sum += w - weight[u]; weight[u] = w; rdfs(u); int best = u; for (int v = 0; v < n; ++ v) { if (visited[v] == timestamp && match_x[v] == -1 && weight[v] > weight[best]) { best = v; } } if (weight[best] <= 0) { sum -= weight[u]; match_y[match_x[u]] = -1; match_x[u] = -1; } else { for (int p = best; p != u; p = parent[p]) { match_x[p] = via[p]; match_y[via[p]] = p; } if (best != u) { match_x[u] = -1; } sum += weight[best] - weight[u]; } } } while (false); printf("%d\n", sum); } return 0; }
subs TrManager::StrToSub(const QString& str) { return static_cast<subs>( std::find(ALL(rawSubs), Uncapitalized(str)) - rawSubs); }
kinds TrManager::StrToKind(const QString& str) { return static_cast<kinds>( std::find(ALL(rawKinds), Capitalized(str)) - rawKinds ); }