Because work requested, I have to study English now. So I will write the problem solutions with English.
Same with 2935
Firstly, we can create a map<{employee}, {access times array}>
to distinguish access times of each employee.
For each employee, we sort their access times array from little to big. And then iterate over this array, when there is $ access_times_{i} - access_times_{i-1} < 60 $, this employee is a High-Access Employee.
1 | class Solution { |
Follow the mean of this problem, care detail is ok.
1 | class Solution { |
01 trie + two points
Firstly, we need to find all Strong Pairs.
For a Strong Pairs: (x, y). if $ x < y $, we can transfer $ |x-y| <= min(x, y) $ to $ x \times 2 >= y $.
When we fix the little number is $ nums_{i} $, the other number must in $ [ nums_{i}, nums_{i} \times 2] $, When we sort nums
from little to big, the other numbers must consequent and start $ nums_{i} $.
Consider $ nums,length() <= 5 \times 10^4 $, two layer for must TLE.
We can use two points
, fix a number to find the period of the other number.
But answer is maximum XOR
of all Strong Pairs. We can use 01-trie
. When we fix a number, add all other numbers to 01-trie
, so that we can find maximum XOR
about the fix number quickly. We loop nums
array, fix each $ nums_{i} $. We can get the final answer.
Note: When we visit $ nums_{i} $, we need to delete $ nums_{0}, nums_{1}, … , nums{i-1} $ from 01-trie
.
首先,我们要找到所有的 Strong Pair
对于一个 Strong Pair: (x, y)。当 x < y 时,我们可以把 $ |x - y| <= min(x, y) $ 转换成 $ x*2 >= y$。
当固定小的那个数字为 $ nums_{i} $ 时,另一个数字的大小一定在 $ [ nums_{i}, nums_{i} \times 2] $。对 nums
从小到大排序后,另一个数字一定是从 $ nums_{i} $ 开始连续的数。
考虑到 $ nums.length() <= 5*10^4 $, 两层 for 一定会超时。
我们可以使用双指针
的技巧在固定一个数字时找到另一个数字的区间。而我们的结果是求 Strong Pair 的 XOR
,我们可以使用 01-trie
,固定一个数字 x 时,把另外的数字都加到 01-trie
中,来快速地找到与 x XOR
最大的结果是多少。这样遍历一遍 nums 既可,取最大的既可。
注意当遍历到 $ nums_{i} $ 时,需要吧 $ nums_{0}, nums{1}, … , nums_{i-1} $ 从 01-trie
中删掉。
1 | const int N = 5e4+7; |
2019 年开始持续一年多使用叨叨记账软件进行记账。最开始一直是花费一笔就记一笔,然后变成每天记一笔,到后来实在太懒就一个月记一次。
后面可能是加班比较多,连着好几个月都没有记账了,一条一条的记账实在太累。
于是就想找找有没有工具可以自动记账,后面发现实在是没有。哪怕是系统层面也不是很容易的能获取不同支付 APP 的消费数据。
后来找了很多的记账工具,发现钱迹这个软件批量导入比较方便,就迁移到这里来了。
但问题又来了。
目前我个人涉及支出的几个软件下载的账单多少有些问题:
支付工具 | 问题 |
---|---|
微信 | 会包含信用卡/招商银行卡的支出 分类不好,很多分类都只是 商户消费 。 |
支付宝 | 会包含信用卡/招商银行卡的支出 没有分类,导入到钱迹的只有 其它 。 |
招商银行卡 | 导出的是 PDF 只有日期,没有时间 |
招商信用卡 | 导出的是 PDF 只有日期,没有时间 |
京东金融 | 不支持导出 只有京东的支持和白条在这里 |
美图 | 美团也是直接用 信用卡/招商银行卡 进行支出的。 |
Apple Store | 有些分期也是直接用 信用卡/招商银行卡 进行支出的。 |
所以在这里记录下拉各软件账单及解决这些问题的流程(避免忘记)。
直接参考 钱迹官方文档-微信账单获取步骤 既可。
不过微信的账单比较坑,每次最多仅支持导出 3 个月的明细。
同样直接参考 钱迹官方文档-支付宝账单获取-网页端 既可。
不过现在直接登陆就到个人版页面了,不需要再手动切换。
// TODO
// TODO
PDF 可以用 PDF24 Tools 工具进行转换。这个是我试过效果最好的一个了。
因为钱迹支持微信和支付宝账单的导入,所以建议保留微信和支付宝账单的格式,去掉部分
偶尔需要处理 Excel、Word、PPT 的时候还是需要使用 Office 软件,但 MS Office 需要收费,又不想用破解版,于是选择了 WPS ,但 WPS 国内版的乱七八遭东西实在太多。最近发现 WPS 居然有国际版,国际版的就良心多了,没啥乱七八遭的东西。
下面的不用看了,现在国际版已经默认带中文了,从国际版官网下载就好了。 -> https://www.wps.com/
下面的不用看了,现在国际版已经默认带中文了,从国际版官网下载就好了。 -> https://www.wps.com/
下面的不用看了,现在国际版已经默认带中文了,从国际版官网下载就好了。 -> https://www.wps.com/
安装国际版首先得能够「出国留学」,然后执行 brew
命令就好了。
1 | 先安装国内版拿到语言包之后再安装国际版 |
因为是提供给国际友人的,国际版没有自带中文。所以需要自己手动汉化一下才行。
汉化首先得有 WPS 中文的语言包,最简单的还是从国内版 WPS 中拿到。
1 | brew install wpsoffice-cn |
APP 安装的目录在 /Applications/wpsoffice.app/
在终端执行 cp -r
复制到另一个目录就好了就好
删除国内版,安装国际版
略
找到中文语言包。
语言包在这个目录下
1 | /Applications/wpsoffice.app/Contents/Resources/office6/mui |
从国内版复制 zh_CN
目录到国际版的相同目录下
设置中文
打开 WPS 国际版,【设置】-【Switch Language】,选择文再重启 WPS 就是中文了。部分地方还没有中文翻译不过不影响使用。
GG 感觉
遍历每个句子,split一下后的数组元素个数最大的那个就是结果了。
1 | class Solution: |
对每个菜dfs下去就好了,要注意下循环的情况。
1 | class Solution { |
这题写的很混乱。甚至担心是水过去的。。
大概就是如果’(‘为1,’)‘为-1。 那么合法序列的前缀和一只是>=0的。结果一定是0的。
考虑locked[i]=1不能变,locked[i]=0能变,那就记录两种前缀和的值,一种只把locked[i]=0时当成’(‘,一种只把locked[i]=0时当成’)'。
记录前缀和的最大最小值, 过程中最大值一定是>=0的。结果一定是0在最大最小值中间的。
正反都判断一遍即可。
1 | class Solution { |
这题分成个部分,
最高的位数字
每次保留前12位数字,因为仅保留5位数字可能会少了后面的进位,影响结果。
除外最低的位数字
正常情况下只要一直对取模就好了,但是这里要的是除外的末尾个数字。
但这里可能有结尾是的情况,多保存几位,保留最后12位数字这样去掉末尾0的时候也不会影响结果。
结尾0的个数
先考虑结尾0的个数,考虑每个因子因式分解后2和5的个数,取最小值即可。
⚠️注意:计算过程中先判断非结尾0的部分是不是大于10位,是的话再处理上述的1和2就好。
1 | class Solution { |
回文串判定不在赘述,遍历下字符串数组找到第一个回文串返回即可。
1 | class Solution { |
简单模拟题,整一个空字符串,不断追加即可,
遍历原字符串,索引在spaces
中的时候就先加一个空格。
考虑spaces数组是有序的,维护一个spaces
的下标,一个个比对就好。
1 | class Solution { |
对于第i
天的股票价格,如果有连续k
天下降为,对结果的贡献就是k
。
eg: 中第天的价格是,那么多了的平滑下降阶段就有,个。
1 | class Solution { |
首先要意识到,k把原数组分成了k个不相干的子数组。
子数组要成为连续不下降序列,那就可以求他的连续不下降子序列的值,然后再改其他值就行了。
1 | class Solution { |
准备好好学习下 MySQL 了,一直以来对其了解只限于粗浅的使用,买了个《MySQL实战45讲》系统了解下MySQL。也不会特别深入,在全局视野知道MySQL都有哪些东西就好了。
这个系列课程感觉还是有很多干货的,每篇下面的思考题,以及评论区的互动都有学习价值。
没啥好说的。
MySQL 的框架有几个组件,各是什么作用?
query_cache_type
设置成DEMAND
Server层和存储引擎层各是什么作用?
server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多核心服务功能,以及所有内置函数(如日期、时间、数学和加密函数等),所有夸存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层负责数据的存储和提取。其架构模式是插件模式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB, 它从MySQL 5.5.5 版本开始成为默认的存储引擎。
you have an error in your SQL syntax
这个报错是在词法分析里还是在语法分析里?
词法分析
对于表的操作权限验证在哪里进行?
执行器
执行器的执行查询语句的流程是什么样的?
更新操作首先要把旧的数据查询出来,所以根据WHERE条件走一遍SELECT的过程,
查出来之后更新就好了。本身是一个事物操作。
但是为了保证MySQL的crash-safe,引入了redo log,redo log 和 bin log一起组成两阶段提交机制。
带着大佬总结的问题记笔记。
redo log的概念是什么?为什么会存在?
redo log 是重做日志,是属于 InnoDB 的日志。。主要用于MySQL异常重启后的一种数据恢复手段,确保了数据的一致性。归根到底是MySQL为了实现WAL机制的一种手段。因为MySQL进行更新操作,为了能够快速响应,所以采取了异步写磁盘写入内存后就返回的策略。但是会存在crash后内存数据丢失的隐患,redo log 具备了crash-safe能力。
什么事WAL(write-ahead log)机制,好处是什么?
WAL机制事写前日志,也就是MySQL更新操作后在真正把数据写入磁盘前就先记录日志。好处是不用每一次操作都实时把数据写盘,就算crash后也可以通过redo log重放恢复,达到快速响应SQL的目的。
redo log 为什么可以保证crash-safe?
redo log 是在事务提交前先写入的,redo log 的内部结构是基于页的,记录了这个页的字段值变化,只要crash后读取redo log重放就可以恢复数据。(redo log 是环形写入的,如果写满了会真正进行写盘的)
binlog的概念是什么?起到什么作用?可以做crash-safe嘛?
binlog 是归档日志,属于MySQL Server层的日志。可以起到全量备份的作用。当需要恢复数据时,可以取出某个时间段内的bin log进行重放恢复。但是bin log不可以做crash-safe,因为crash之前,可能还没有写完 binlog MySQL就宕掉了。所以需要配合redo log 才可以进行crash-safe。
bin log 和 redo log的不同点有哪些?
bin log 是服务层的,追加写不会覆盖,记录了逻辑变化,是逻辑日志。
rego log 是引擎层的,循环写满了会覆盖,记录了基于页的物理变化,是物理日志,具备crash-safe操作。
物理一致性和逻辑一致性各应该怎么理解?
TODO 不是很确定
物理一致性:在实际物理存储中没有差别。
逻辑一致性(logical consistency)与矛盾(Contradiction)相对;
也即逻辑上的一致(logically consistent)= 没有逻辑矛盾(no logical contraction)
执行器和InnoDB在执行update语句时候的流程是什么样的?
执行器在优化器选择索引后,调用InnoDb的读接口,读取要更新的行到内存中,执行SQL操作后,更新到内存中,然后写redo log,在写bin log,此时InnoDB会在合适的时候把此次操作的结果写入磁盘。
如果数据库误操作,如何执行数据恢复?
如果数据库在某一天误操作,就可以找到距离误操作最近时间点前的bin log,重放到临时数据库里,然后选择当天误操作的数据恢复到线上数据库。
*什么是两阶段提交?为什么需要两阶段提交?两阶段提交怎么保证数据库中两份日志间的逻辑一致性?
先写入redo log 处于prepare阶段,然后写入bin log,最后在redo log中提交变成commit状态。
如果不用两阶段提交会出现问题(UPDATE SET a=2 table_name WERE a=1)
redo log变成commit状态时bin log一定写完了,两边的逻辑一定是一致的。
如果不是两阶段, 先写redo log和先写bin log两种情况会遇到什么问题?
见上题
ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)
脏读、不可重复读、幻读。
具体使用哪个隔离级别可以看数据库的transaction_isolation
参数配置。
脏读:
当一个数据库中一个事物A正在修改一个数据但是还未提交或者回滚,另一个事物B来读取了修改后的数据并使用了。
此情况仅会发生在: 读未提交的的隔离级别.
不可重复读:
在一个事物A中多次操作数据,在事物操作过程中(未提交),事物B也才做了处理,并且该值发生了改变,这时候就会导致A在事物操作的时候发现数据与第一次不一样了。
此情况仅会发生在:读未提交、读提交的隔离级别
幻读:
一个事物按相同的查询条件重新读取以前检索过的数据,却发现其他事物插入了满足其查询条件的新数据。
幻读史之当事物不是独立执行时发生的一种现象,例如一个事物对一个表中的数据进行了修改,比如这种修改设计到表中的全部数据行。同时第二个事物也修改这个表中的数据,这种修改时向表中插入一行新数据。那么就会发生第一个事物的用户发现表中还存在没有修改的数据行,就好像发生了幻觉一样。
一般解决幻读的方法是增加范围锁,锁定检查范围为只读,
此情况会发生在:读未提交、读提交、可重复读的隔离级别.
事务隔离级别 脏读 不可重复读 幻读读未提交(read-uncommitted) 是 是 是读已提交(read-committed) 否 是 是可重复读(repeatable-read) 否 否 是串行化(serializable) 否 否 否
每条记录在更新的时候都会同时记录一条回滚操作,同一条记录在系统中可以存在多个版本。这就是数据库的多版本并发控制(MVCC)。
更新操作会在回滚日志记一条回滚操作,众多记录构成不同的read-view。假设一个值从1被按顺序改成了2、3、4,在回滚日志里面就会有类似下面的记录。
每个事物查询的时候都会到根据该事物启动的时刻读取当时时刻的read-view。
回滚日志总不能一直保留,在不需要的时候,也就是系统判断宕没有事物在需要用到这些回滚日志是,就会把这些回滚日志删除。
具体实现时会有事物ID。
显式启动事物语句 begin
或者start transaction
提交 commit
。回滚rollback
set autocommit=0
该命令会把这个线程的自动提交关掉,这样只要之行一个SELECT
语句,事物就会启动,并不会自动提交,知道主动commit
或者 rollback
或者断开链接。
建议显示启动事物。 如果考虑多一次commit交互问题,可以使用commit work and chain
语法,可以提交事物并自动启动下一个事物。
长事物存在时系统里面会存在很老的事物视图,在这个食物提交之前,回滚记录都要保留,这回占用大量存储空间。
长事物占用锁和链接资源,增大锁冲突的记录,使连接数占用增加,最终影响服务器性能。
从应用开发段看:
set autocommit=0
。这个确认工作可以在测试环境中开展,把 MySQL 的 general_log 开起来,然后随便跑一个业务逻辑,通过 general_log 的日志来确认。一般框架如果会设置这个值,也就会提供参数来控制行为,你的目标就是把它改成 1。从数据库端看:
information_schema.innodb_trx
表,设置长事物阈值,超过就报警或者kill。innodb_undo_tablespaces
设置成2(或者更大的值)。如果真的出现大事物导致的回滚段过大,这样设置后清理起来更方便。提高数据查询的效率
哈希表
key-value形式,把值放到数组里面,用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置。
哈希冲突的解决方式:开链法,
只适用等值查询的场景。
有序数组
按顺序存储。查询使用二分法,时间复杂度是O(log(N))
.
更新效率低,线性的。
适用于静态数据存储(不需要更新)场景。
搜索树
二叉搜索树
每个节点的左儿子小于父节点,父节点又小于右儿子。
查询时间复杂度O(log(N)),更新时间复杂度O(log(N))。
InnoDB中的索引模型:B+Tree
B+Tree 是一个N叉树,N差不多是1200,树高小,读盘次数小。
主键索引存储的是整行的数据(聚簇索引),非主键索引存储的主键的值(二级索引)。
主键索引只要所搜主键所在的这个B+Tree即可拿到数据。普通索引先搜索索引拿到主键值,在到主键索引搜索一次(回表)。
当一个数据页满了是,按照B+Tree算法,会申请一个新的数据页,挪动部分数据过去,这个过程叫做页分裂。这种情况下性能会下降,空间利用路降低大概50%。当相邻的数据页利用率很低的时候会做数据页合并,合并过程是分裂过程的逆过程。
从性能和存储空间方面考量,自增主键往往是更合理的选择。 自增主键每新加一行,都会在尾部追加。
如果查询条件使用的是普通索引(或者联合索引的最左原则字段),查询结果是联合索引的字段或者主键,就不需要回表操作,可以直接返回结果,减少磁盘IO。
联合索引的最左N个字段,也可以是字符串索引的最左M个字符。
根据创建联合索引的顺序,以最左原则进行where检索,比如(age,name)以age=1
或age=1 and name='张三'
可以使用索引,单以name='张三'
不可以使用索引。考虑到存储空间的问题,需要根据业务诉求,将查找频繁的数据进行靠左创建索引。
类似like 'hello%' and age > 10
的检索,MySQL 5.6 版本之前会对匹配的数据进行回表查询。 5.6版本之后会先过滤掉age<10
的数据,在进行回表查询,减少回表率,提升检索速度。
MySQL中的锁大致分成全局锁、表级锁和行锁三类
全局锁就是对整个数据库实例加锁。当需要让整个库处于只读状态的时候,可以使用Flush tables with read lock (FTWRL)
命令。执行这个命令后 数据更新语句(数据的增删改,DML)、数据定义语句(包括建表、修改表结构等,DDL)和更新类事物的提交语句都会被阻塞。
典型的使用场景是做全库逻辑备份。也就是把整库每个表都select出来存成文本。
如果不加全局锁,备份系统备份的时候得到的库不是一个逻辑时间点,这个视图的逻辑不一致。
如果在主库备份,在备份期间不能更新,业务停摆。
如果在从库备份,备份期间不能执行主库同步的binlog,导致主从延迟。
MySQL官方自带的逻辑备份工具mysqldump,当mysqldump使用参数–single-transaction的时候,会启动一个事物,确保拿到一执行视图。由于MVCC的支持,这个过程中的数据是可以正常更新的。
一致性读是好,但前提是引擎要支持这个隔离级别。
set global realonly=true
?表锁
表锁的语法是lock tables ... read/write
。与FTWR
L类似,可以用unlock tables
主动释放锁,也可以在客户端断开的时候自动释放。需要注意,lock tables
语法除了会限制别的线程的读写外,也限定了本线程接下来的操作。
元数据锁(meta data lock,MDL)
MDL不需要显示使用,在访问一个表的时候会被自动加上。
MDL的作用是保证读写的正确性。
当对一个表进行增删改查操作的时候,加MDL读锁;当对表做结构变更的时候,加MDL写锁。
给小表加字段是对表结构变更,会加MDL写锁。
如果之前有事物A搞了MDL读锁,事物没有提交。然后就进行修改表结构,因为加了写锁,所以会被阻塞。如果后面事物A又进行增删改查操作需要申请读锁,就会被锁住,这个表就完全不可读写了。
客户端又重试机制,超时后会仔起session进行请求,这个库的线程很快就爆满了。
那么如何安全地给小表加字段呢?
比较理想的机制是,在 alter table 语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。之后开发人员或者 DBA 再通过重试命令重复这个过程。
MySQL 的行锁是在引擎层实现的。并不是所有引擎都支持行锁,比如MyISAM就不支持行锁。
不支持行锁的引擎处理并发只能使用表锁,并发度差。
InnoDB实现了行锁,这也是InnoDB代替MyISAM成为MySQL的默认引擎的原因之一。
两阶段锁:在InnoDB事务中,行锁是在需要时才加上的,但并不是需要了就立刻释放,而是要等食物结束才释放。
帮助:如果事务中需要锁多个行,把最可能造成锁冲突、最可能影响并发的锁尽量往后放。
当并发系统中不同线程出现循环资源依赖,涉及的线程都在等别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,成为死锁。
举例:事物A更新行1不提交,行1被事物A锁住,事物B更新行2不提交,行2被事物B锁住。这时事物A再更新行2,因为行2被事物B锁着,事物A被阻塞。同时事物B更新行1,又因为行1倍事物A锁着,事物B又被阻塞了。事物A需要事物B提交才能继续执行,事物B需要事物A提交才能继续执行。就是进入死锁状态了。
等待超时机制:
通过设置innodb_lock_wait_timeout
设置锁等待时间,超过这个时间就可以断开连接。该连接的锁会释放掉。
局限:
等待时间不好拿捏。时间过长服务不能接受;时间过短会出现误伤,把正常锁等待的事物所在的连接都给断开了。
死锁检测处理机制:
通过设置innodb_deadlock_detect
设置为on
,开启死锁检测逻辑。当检测到死锁时,会主动回滚死锁事物中一个某一个事物打破死锁,让其他事物可以继续执行。
局限:
死锁检测逻辑太耗CPU了,每个新来的线程,都会检测自己会不会导致死锁,需要遍历所有更新这一行的其他线程,总的复杂度是的,如果有1000个线程同时更新同一行,需要进行100万次死锁检测操作。
innoDB行锁是通过锁索引记录实现的,如果更新的列没建索引是会锁住整个表的。
所以对于update语句一般在后面加上limit 1.
这样在处理的时候查到一条数据就会停止遍历,只会对遍历过的行加锁,
create view ...
,而他的查询方法与表一样。事物启动时会拍一个快照,这个快照时基于整个库的。
快照不是物理快照,瞬间复制几百G的库时不现实的。
基于整个库的意思就是说一个事物内整个库的修改对于该事物都是不可见的(对于快照读的情况)
如果在事物内进行SELECT t表,另外执行的事物执行了DDL t表,根据发生时间,要么锁住,要么报错。
每一个事物都有一个事物ID,叫做transaction id。其值是按申请顺序严格递增的。
每行数据在每次事物更新的时候都会生成一个新的数据版本,并把transaction id赋值给这个数据版本的事物ID,记为row trx_id。同时旧的版本保留。每次更新页会在undo log(回滚日志)中记录一条,通过row trx_id和undo log 就可以计算出所有的版本了。
实现上,InnoDB为每个事物构造了一个数组,存储这个事物启动瞬间,正在“活跃”的所有transaction id。“活跃”是指,启动了但还没提交的。
数组里事物ID的最小值记为低水位,当前系统已经创建过的事物ID的最大值+1记为高水位。
这个视图数组和高水位,就组成了当前事物的一致性视图(read-view)
对于一个数据版本的row trx_id
绿色部分是已提交的事物或者是当前事物生成的,这个是可见的。
红色部分是将来启动的事物生成的,不可见。
黄色部分
如果row trx_id 在数组中表示是还没提交的事物生成的,不可见。
如果row trx_id 不在数组中表示是已提交的事物生成的,可见。
TODO:这里有点乱。。。
当前事物生成的为啥不是在黄色?
当前读是否破坏了可重复读/一致性读?
可重复度和一致性读是一样的嘛?
排序之后 遍历一遍每个大小为k的区间, 然后计算下就好
1 | class Solution { |
还是排序, 注意字符串比较和整数不同,需要补上前导0
. 最后别忘了把前导0
去掉。
1 | class Solution { |
经典状压dp
dp[i] 表示 在i的二进制下 干了对应的任务所花的最少工作时间段。
1 | class Solution { |
类似940. 不同的子序列 II, 针对0特殊处理下就好了。
1 | class Solution { |
md 开始读错题了。。
其实就是把words的前缀拼一起 看有没有等于s的就好
1 | class Solution { |
这题很简单, 维护一个队头最大的优先队列。
每次取最大的元素,也就是队头,减去就好了。
1 | class Solution { |
维护下 括号是否匹配, 如果不匹配就把最后一个 '['
换过来就好。
1 | class Solution { |
md, lis 写不明白了。。。
这题就是求每个元素在最长不下降子序列中的序号
。
1 | func longestObstacleCourseAtEachPosition(obstacles []int) []int { |
遍历下1->n, 统计下约数个数,最后看是否等于3就好了
1 | class Solution { |
取最大值, 看最大值能否被其他穿插开就好。 穿插不开就要舍弃不能连续的部分(值变成sum-mx+1)。
1 | class Solution { |
经典的二分, 对花园的半径(<0,0> 到一边的长度)二分。 最后计算答案就好
1 | class Solution { |
dp问题;
设 表示到第个位置的以结尾的序列个数。
对于非当前位置a
对于当前位置为a
1 | class Solution { |
这场是虚拟的,还是在床上躺着优哉游哉的打的,,成绩居然还可以?
这是巧合还是,,,
找到最后一个是奇数的位置作为结尾即可
1 | func largestOddNumber(num string) string { |
简单算下就好,
都转成分钟,startTime向上取整,finishTime向下取整。 然后算差即可
注意两个点:
1 | class Solution { |
搜索一下grid2即可,中间记录下结果
1 | class Solution { |
因为值域只有100,所以统计100个前缀和方便快速计算出在任意一个区间这个是否有过即可。
总复杂度是 也就是 ,不过常熟比较大。
1 | class Solution { |
彻底翻车,,,,,
数学能力没有了。。。。
因为都是正整数,乘积最大和最小的一定是最大的两个数字的乘积和最小两个数的乘积。
1 | class Solution { |
模拟一下获得每个圈的数字然后旋转k次就好。
我这里用搜索搞的, 应该是麻烦了。
1 | class Solution { |
我这里直接无脑统计了, 因为只需要考虑奇偶,用二进制数表示每个字母的出现次数的奇偶性,并记录下前缀异或和即可。
然后暴力FWT计算一下。
赛后看了大佬的做法, 又一个小点, 当前n位置的前缀异或和为x的时候,只有与x异或的二进制位上1的个数小于等于1的情况才需要统计。代码就简洁多了。
1 | class Solution { |
简洁做法
1 | class Solution { |
开始还在搞拓扑图,但实际上这玩意就是一个以0为根的树。。。。
蚂蚁能够构建的顺序需要保证父节点在前。
设以节点为根的子树中,他的孩子节点为,所有子节点个数为;
以节点x为根的子树中,所有可行的排序为;
1 | class Solution { |
GG
暴力一下,
枚举每个元素删除后的数据是不是严格递增的, 数据范围是. 平凡才没问题的。
1 | class Solution { |
开始还想要不要有啥骚操作, 后面觉得暴力没啥问题,然后暴力就过了,,
1 | class Solution { |
简单dp?吧,
dp[0] 表示以长度为偶数的子序列的最大值。
dp[1] 表示以长度为奇数的子序列的最大值。
遍历每个数字,计算当前这个数字为奇数或者偶数的最大值, 奇数就是dp[0]减去它,偶数就是d[1]加上它。
1 | class Solution { |
模拟题
我是用了一个 map[(shop, movie)] = price,其中price的政府表示借出还是没借出。借出为负,没借出为正。
用一个priority_queue<tuple<price,shop,movie >> 的小顶堆维护借出的。
用n个priority_queue<tuple<price,shop>>的小顶堆维护没借出这个电影的商店。
1 | class MovieRentingSystem { |
基于 Redis 6.2.1
]]>再再再再再再再再次翻车了
第三个没仔细想+超时挂了3次
第四个最大值没搞好+瞎提交WA了3次。。。
思维又慢,码得又慢,没救了。
模拟一下, 旋转可以多次,但状态最多就4种:
不旋转,旋转90度,旋转180度,旋转270度。
这里循环一下, 每次旋转90度,在比较是否相等就好了。
1 | class Solution { |
如果存在两个数,a<b , 则b一定会变到a的转态。所以统计会变成当前数字的数字个数就好。
处理的话,因为有重复值,所以放到一个桶里面。从小到大遍历上去统计就好。
1 | class Solution { |
这里写的有点丑,代码没法看,,
分情况讨论:
0101010
这种,要么变成101010
这种,第一个操作对他无影响。10101
是可以变成10110
的。所以这种情况下,可以分成两段,前一段1开头,后一段0开头。或者前一段0开头,后一段1开头。注意奇数的情况下处理时可以线性。
1 | class Solution { |
考虑数据范围,只可以遍历所有商家的所有盒子。
针对不同商家统计每个盒子的空余空间就好。一个盒子,利用两个前缀和统计需要使用它的货物个数,以及需要使用它货物占用大小总数,最后减一下就好了。
1 | class Solution { |
再次翻车了
第四个卡精度搞了好久好久,,还是看了讨论区才处理精度问题的。。
第三个纯属自己代码写的太丑了,脑子不够清晰吧。赛后1分钟ac。。。
简单模拟, 不过我这里写的太麻烦了。
1 | class Solution { |
正负情况讨论一下就好了,
正数:
想要值最大就把这个数字放到第一个比他小的数字前面
负数
想要值最大就把这个数字放到第一个比他大的数字前面
1 | class Solution { |
这里维护两个优先队列就好了,
一个维护tuple<int, int>
表示 权重,下标。这个就是空闲的服务器队列
另一个维护tuple<int, int, int>
表示 任务处理的时间,权重,下标。这个就是正在处理任务的服务器队列
过程中维护一个时间就行了, 如果空闲队列为空,就从非空闲的队列中吧做完任务的拿出来,如果没有做完的就调大下时间。
这里好像有卡长,我最开始写的比较丑,是
++time
这样玩儿的,因为值域是 所以这里++time
的次数应该也是线性的才对,理论上不会增大复杂度的。
1 | class Solution { |
又是一个DP,,
不过这个DP很简单
设dp[i][j]
表示前i个道路 跳过j个所花的时间
转移就是
因为浮点数精度问题, 所以我这里改了下
设dp[i][j]
表示前i个道路 跳过j个 “行进” 距离,
转移就是
1 | class Solution { |
GG
简单模拟。
1 | class Solution { |
排序之后最大的和最小的配对,次大的和次小的配对,以此类推。
1 | class Solution { |
模拟题
单开个数组记录下grid[i][j]
开始右下长度为的和 与 grid[i][j]
开始左下长度为的和就好了。
结果就枚举在每个[i][j]
位置美剧边长为的菱形的和。
最后去重后取最大的个就好了。复杂度
1 | class Solution { |
这题看了数据范围,就开始想有啥暴力的解没有。。。
最后是转化了下求了个二分图最大权匹配。。。
a+b = a ^ b + ((a&b)<<1) => a^b = a+b -((a&b)<<1)
a+b 的值 恒定,所以只要找边权为与值的 nums1 和 nums2 二分图最大权匹配就好。 搞个板子就怼上去了。
不过这题还是可以把利用上的。赛后看了大佬的做法,可以dp
i表示 nums2数组被使用的情况,
dp[i] 表示 nums2中对应的那些元素排序后与nums1中前几个元素异或值的和的最小值
转移为
dp[i | (1<<j)] = min(dp[i|(1<<j)], dp[i] + (nums1[i的二进制中1的个数] ^ nums2[j]));
二分图做法
1 | template <typename T> |
dp做法
1 | class Solution { |
基于 Redis 6.2.1
Redis 服务器将所有数据库保存到server.h/redisServer结构的db数组中,db数组的每一项都是server.h/redisDb结构,每个redisDb代表一个数据库:
1 | struct redisServer { |
说起来,四五百行的结构体,真是活久见啊。。。。
在初始化服务器时,程序会根据服务器状态的dbnum属性来决定创建多少个数据库:
1 | struct redisServer { |
dbnum的属性值由服务器配置的database选项决定,缺省为16,所以Redis服务器默认会创建16个数据库。
1 | // redisServer |
Redis客户端都有自己的目标数据库。在一个客户端没有主动切换数据库的时候,该客户端只会操作这个数据库的内容,同时这个数据库与其他数据库的内容是相互隔离的。
默认情况下Redis客户端的目标数据库为0号数据库,客户端可以使用SELECT
命令主动切换目标数据库。Redis服务端会记录每个链接的目标数据库,也就是说,Redis可以同时连接处理多个不同目标数据库的客户端。
server.h/client
1 | typedef struct client { |
db.c
1 | int selectDb(client *c, int id) { |
⚠️注意:默认情况下,客户端默认连接的是0号数据库,一般情况下只要用一个0号数据库就够了。但是如果是有使用多个数据库的诉求,还是要先显示的执行一个SELECT
命令再执行别的命令。
这是自己简单学习的使用Redis,生产环境使用的还是公司自己搞的兼容Redis协议的自研数据库,记得没有
SELECT
命令,用的就是默认的一个数据库。。
Redis本身是一个键值对(key-value pair)数据库服务,服务中每一个数据库中采用了dict字典保存了数据库中的所有键值对,我们将这个字典称为键空间:
1 | typedef struct redisDb{ |
键空间和用户所见的数据库是直接对应的:
如下图所示:
而Redis中添加心焦也一样是在操作redisDb
中的dict
成员,支持基本dict操作,同时可以对其中每个键值的增删改查。
除基本的增删改查操作外,还有很多针对数据库本身的命令,也是通过对键空间的处理完成的。
比如说:
这些命令都是通过对键空间进行操作来实现的。
当使用Redis命令对数据库进行读写时,服务器不仅会对键空间执行指定的读写操作,还会执行一些额外的维护操作,其中包括:
通过EXPIRE
命令或者PEXPIRE
命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间(Time To Live,TTL),在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为0的键:
1 | redis> SET key value |
⚠️注意:
SETEX
命令可以在设置一个字符串键的同时为键设置过期时间,因为这个命令是一个类型限定的命令(只能用于字符串键),所以本章不会对这个命令进行介绍,但SETEX
命令设置过期时间的原理和本章介绍的EXPIRE
命令设置过期时间的原理是完全一样的。
与EXPIRE
命令和PEXPIRE
命令类似,客户端可以通过EXPIREAT
命令或PEXPIREAT
命令,以秒或者毫秒精度给数据库中的某个键设置过期时间(expire time)。
过期时间是一个UNIX时间戳,当键的过期时间来临时,服务器就会自动从数据库中删除这个键:
1 | redis> SET key value |
TTL
命令和PTTL
命令接受一个带有生存时间或者过期时间的键,返回这个键的剩余生存时间,也就是,返回距离这个键被服务器自动删除还有多长时间:
1 | redis> SET key value |
Reids有四个不同的命令可以用于设置键的生命时间(键可以存在多久)或过期时间(键什么时候会被删除)。
EXPIRE<key><ttl>
命令用于将键的生存时间设置为ttl秒。PEXPIRE<key><ttl>
命令用于将键的生存时间设置为ttl毫秒。EXPIREAT<key><timestamp>
命令用于将键的过期时间设置为所指定的秒数时间戳。PEXPIREAT<key><timestamp>
命令用于将键的过期时间设置为所指定的毫秒数时间戳。虽然有多种不同单位和不同形式的设置命令,但实际上EXPIRE、PEXPIRE、EXPIREAT三个命令都是使用PEXPIREAT命令来实现的:无论客户端执行的是以上四个命令中的哪一个,经过转换之后,最终的执行效果都是一样的。
这四个命令的具体实现在expire.c
,都仅调用了expireGenericCommand
,在expireGenericCommand
中通过入参传入basetime
时间参数(本身是毫秒级时间戳),unit
时间戳类型(妙计或毫秒级时间戳)来转化为实际操作的时间。最终具体逻辑是以毫秒级的时间戳设置过期时间。
1 | /* EXPIRE key seconds */ |
expireGenericCommand
实现如下:
1 | /* This is the generic command implementation for EXPIRE, PEXPIRE, EXPIREAT |
redisDb结构的expires字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典:
过期字典的键是一个指针,这个指针指向键空间中的某个键对象(也即是某个数据库键)。
过期字典的值是一个long long类型的整数,这个整数保存了键所指向的数据库键的过期时间——一个毫秒精度的UNIX时间戳。
1 | typedef struct redisDb{ |
expires
字典可以方便对每个键计算并返回剩余生存时间。TTL
命令以秒为单位返回键的剩余生存时间,而PTTL
命令则以毫秒为单位返回键的剩余生存时间。
expires
中没有找到,则说明这个键没有过期时间。是永久存储的。⚠️注意:
实现过期键判定的另一种方法是使用
TTL
命令或者PTTL
命令,比如说,如果对某个键执行TTL
命令,并且命令返回的值大于等于,那么说明该键未过期。在实际中,Redis
检查键是否过期的方法就是访问字典获取过期的时间戳,因为直接访问字典比执行一个命令稍微快一些
过期键的删除策略:
定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
定时删除策略是对内存友好的,能够及时的将已过去数据的内存释放。
但定时删除的缺点是对CPU不友好,当一些键的过期时间比较集中的时候,删除这些过期键会占用相对较长的CPU时间,在内存不紧张但CPU紧张的场景,会提升机器的负载,影响到服务的性能(耗时和吞吐量)。
惰性删除是对CPU友好的,程序只会在取出键时才检查键的过期时间。这个策略不会在删除其他无关的键上花费任何CPU时间。
与定时删除相反,惰性删除对内存并不友好。当一个键已经过期,但是没有被访问到的时候,他的内存不会被释放,会一直保存。
在采取惰性删除策略时,如果数据库中存在很多很多过期键,又都没有被访问,那么就会一直保存在服务器中,这部分内存就被浪费了。服务器不会主动去释放他们,这种情况对于以来内存作为存储的Redis服务器来说,是不利的,随着时间的推移,这样的过期键越来越多,最终数据库的空间就不够用了,在未来某一个时就会过载。
定时删除和惰性删除是对服务器两种资源(内存,CPU)偏重其中一个下所诞生的。
定期删除策略是前两种策略的一种整合和折中:
定期删除策略的难点时确定删除操作执行的时长和频率:
因此,如果采用定期删除策略,服务器必须根据情况,合理地设置删除操作的执行时长和执行频率。
Redis服务器实际泗洪的是惰性删除和定期删除两种策略:通过配合这两种策略,服务器可以更好的平衡CPU和内存的消耗。
过期键的惰性删除策略由db.c/expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前都会调用expireIfNeeded函数对输入键进行检查:
expireIfNeeded函数就像一个过滤器,它可以在命令真正执行之前,过滤掉过期的输入键,从而避免命令接触到过期键。
另外,因为每个被访问的键都可能因为过期而被expireIfNeeded函数删除,所以每个命令的实现函数都必须能同时处理键存在以及键不存在这两种情况:
过期键的定期删除策略由expire.c/activeExpireCycle
函数实现,每当Redis的服务器周期性操作server.c/serverCron
函数执行时,activeExpireCycle
函数就会被serverCron
中的databsaesCron
调用。它在规定的时间内,多次便利服务器中的各个数据库,从数据库中的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。
activeExpireCycle
函数的工作模式可以总结如下:
current_db
会记录当前activeExpireCycle
函数检查的进度,并在下一次activeExpireCycle
函数调用时,接着上一次的进度进行处理。比如说,当前activeExpireCycle
函数在便利号数据库时返回了,那么下次activeExpireCycle
函数执行时,将从号数据库开始查找并删除过期键。activeExpireCycle
函数的不断执行,服务器中所有的数据库键都会被检查一遍,这是函数将current_db
变量重置为,然后再次开始新一轮的检查。当服务器以AOF持久化模式运行时,如果某个键已经过期,但它还没有被惰性删除或者定期删除,那么AOF文件不会因为这个过期键产生任何影响。
当过期键被惰性删除或者定期删除之后,程序会向AOF文件追加(append)一条DEL命令,来显式地记录该键已经被删除。
和生成RDB文件时类似,在执行AOF重写的过程中,程序会对数据库中的键进行检查,已经过期的键不会被保存到重写后的AOF文件中。
在执行save命令或者BGSAVE命令创建一个新的RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB文件中。
在启动Redis服务器时,如果服务器开启了RDB功能,那么服务器将对RDB文件进行载入:
如果服务器以主服务器模式运行,那么在载入RDB文件时,程序会对文件中保存的键进行检查,未过期的键将被载入到数据库中,而过期的键则会被忽略,所以过期的键对载入RDB文件的主服务器不会造成影响。
如果服务器以从服务器模式运行,那么在载入RDB文件时,文件中保存的所有键,无论是否过期,都会被载入到数据库中。
不过,因为主从服务器在进行数据同步时,从服务器的数据库就会被清空,所以一般来讲,过期键对载入RDB文件的从服务器也不会产生影响。
当服务器运行在复制模式下,从服务器的过期键删除动作由主服务器控制:
通过主服务器来控制从服务器统一地删除过期键,可以保证主从服务器数据的一致性,也正是因为这个原因,当一个过期键仍然存在于主服务器的数据库时,这个过期键在从服务器的拷贝也会继续存在。
数据库通知时Redis 2.8版本新增加的功能,这个功能可以让客户端通过订阅给定的频道或者模式,来获知数据库中键的变化,以及数据库中命令的执行情况。
通知分为两种类型:
键空间通知(key-space notification):关注具体某个键执行了什么命令。
1 | 127.0.0.1:6379> SUBSCRIBE _ _keyspace@0_ _:message |
键事件通知(key-event notification):关注某一个命令被那些键执行了。
1 | 127.0.0.1:6379> SUBSCRIBE _ _keyevent@0_ _:del |
服务器配置的notify-keyspace-events选项决定了服务器所发送通知的类型:
关于数据库通知功能的详细用法,以及notify-keyspace-events选项的更多设置,Redis的官方文档已经做了很详细的介绍,这里不再赘述。
发送数据库通知的功能是由notify.c/notifyKeyspaceEvent函数实现的:
1 | void notifyKeyspaceEvent(int type,char *event,robj *key,int dbid); |
函数的type参数是当前想要发送的通知的类型,程序会根据这个值来判断通知是否就是服务器配置notify-keyspace-events选项所选定的通知类型,从而决定是否发送通知。
event、keys和dbid分别是事件的名称、产生事件的键,以及产生事件的数据库号码,函数会根据type参数以及这三个参数来构建事件通知的内容,以及接收通知的频道名。
每当一个Redis命令需要发送数据库通知的时候,该命令的实现函数就会调用notify-KeyspaceEvent函数,并向函数传递传递该命令所引发的事件的相关信息。
1 |
|
基于 Redis 6.2.1
前文也有提到,Redis
中并没有直接使用底层的基本数据结构,比如简单动态字符串(SDS
)、双端链表、字典、压缩列表、整数集合等。Redis
是基于这些基本的数据结构创建了一个对象系统,这个系统包含字符串对象(string
)、列表对象(list
)、哈希对象(hash
)、集合对象(set
)和有序集合对象(sorted sort
)等。每种对象都用到了至少一种前面所介绍的数据结构。
通过这五种不同类型的对象,Redis
可以在执行命令前,根据对象的类型判断一个对象是否可以执行给定的命令。使用对象的另一个好处是,可以针对不同的使用场景,采用不同的底层基本数据结构实现对象,从而优化性能。
另外,Redis
的对象系统还实现了基于引用计数的内存回收机制,当程序不再使用某个对象的时候,会自动释放这个对象所占用的内存;Redis
还通过引用计数实现了对象共享机制,在适当的条件下,多个数据库键可以共享同一个对象类节约内存。
最后,Redis
的对象记录了访问时间信息,可以用来计算数据库键的空转时长,在服务器开启了 maxmemory
功能时,空转较大的键可能会优先被服务器删除。
Redis
使用对象来表示数据库中的键和值,每当我们创建一个新的键值对时,至少会创建两个对象,一个对象用作键值对的键(键对象),另一个用作键值对的值(值对象)。
举个例子,一下 SET
命令在数据库中创建了一个新的键值对,其中键值对的键是一个包含了字符串值 “msg”
的对象,而键值对的值则是一个包含了字符串值 “hello world”
的对象。
1 | redis > SET msg "hello world" |
Redis
中对象的结构如下:
1 | typedef struct redisObject { |
type
:对象类型。encoding
:对象编码。lru
:对象最后一次被访问的时间。refcount
:引用计数。*ptr
:指向底层数据结构的指针。Redis
的对象类型共有七个。由对象的 type
属性记录。
OBJ_STRING
0 字符串(String)对象OBJ_LIST
1 列表(List)对象OBJ_SET
2 集合(Set)对象OBJ_ZSET
3 有序集合(Sorted set)对象OBJ_HASH
4 哈(Hash)希对象OBJ_MODULE
5 模(Module)块对象OBJ_STREAM
6 流(Stream)对象对于
Redis
数据库保存的键值对来说,键总是一个字符串对象,而值则可以是字符串对象、列表对象、哈希对象、集合对象或者有序集合对象的其中一种,因此:
- 当我们称呼一个数据库键为“字符串键”时,我们指的是“这个数据库键所对应的值为字符串对象”;
- 当我们称呼一个键为“列表键”时,我们指的是“这个数据库键所对应的值为列表对象”。
TYPE
命令的实现方式也与此类似,当我们对一个数据库键执行TYPE
命令时,命令返回的结果为数据库键对应的值对象的类型,而不是键对象的类型:
1
2
3
4
5
6
7
8
9 redis> SET msg "hello world"
OK
redis> TYPE msg
"string"
redis> RPUSH numbers 1 3 5
(integer) 6
redis> TYPE numbers
"list"
// 其他对象同理,不赘述了。
对象的 ptr
指针指向对象的底层实现数据结构,而这些数据结构由对象的 encoding
属性决定。
Redis
的编码类型共有十一个。由对象的 encoding
属性记录。
下面的枚举就有些有点词不达意,,,
OBJ_ENCODING_RAW
0 SDS
表示。OBJ_ENCODING_INT
1 编码为整数(long
类型)OBJ_ENCODING_HT
2 编码为字典OBJ_ENCODING_ZIPMAP
3 编码为 zipmap
。⚠️ 这个在代码中从来没有用过。OBJ_ENCODING_LINKEDLIST
4 不再使用:旧列表编码。OBJ_ENCODING_ZIPLIST
5 编码为 ziplist
OBJ_ENCODING_INTSET
6 编码为 intset
OBJ_ENCODING_SKIPLIST
7 编码为 skiplist
(其实是跳表和字典)OBJ_ENCODING_EMBSTR
8 embstr 编码 SDS
OBJ_ENCODING_QUICKLIST
9 编码为 ziplist
的链接列表OBJ_ENCODING_STREAM
10 编码为列表包的基数树不同类型采取了多种编码方式,下表列出了每种类型的对象可以使用的编码。
可通过
object.c
中的size_t objectComputeSize(robj **o*, size_t *sample_size*)
查看objectComputeSize 源码 展开/收起
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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 size_t objectComputeSize(robj *o, size_t sample_size) {
sds ele, ele2;
dict *d;
dictIterator *di;
struct dictEntry *de;
size_t asize = 0, elesize = 0, samples = 0;
if (o->type == OBJ_STRING) {
if(o->encoding == OBJ_ENCODING_INT) {
asize = sizeof(*o);
} else if(o->encoding == OBJ_ENCODING_RAW) {
asize = sdsZmallocSize(o->ptr)+sizeof(*o);
} else if(o->encoding == OBJ_ENCODING_EMBSTR) {
asize = sdslen(o->ptr)+2+sizeof(*o);
} else {
serverPanic("Unknown string encoding");
}
} else if (o->type == OBJ_LIST) {
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
quicklist *ql = o->ptr;
quicklistNode *node = ql->head;
asize = sizeof(*o)+sizeof(quicklist);
do {
elesize += sizeof(quicklistNode)+ziplistBlobLen(node->zl);
samples++;
} while ((node = node->next) && samples < sample_size);
asize += (double)elesize/samples*ql->len;
} else if (o->encoding == OBJ_ENCODING_ZIPLIST) {
asize = sizeof(*o)+ziplistBlobLen(o->ptr);
} else {
serverPanic("Unknown list encoding");
}
} else if (o->type == OBJ_SET) {
if (o->encoding == OBJ_ENCODING_HT) {
d = o->ptr;
di = dictGetIterator(d);
asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
while((de = dictNext(di)) != NULL && samples < sample_size) {
ele = dictGetKey(de);
elesize += sizeof(struct dictEntry) + sdsZmallocSize(ele);
samples++;
}
dictReleaseIterator(di);
if (samples) asize += (double)elesize/samples*dictSize(d);
} else if (o->encoding == OBJ_ENCODING_INTSET) {
intset *is = o->ptr;
asize = sizeof(*o)+sizeof(*is)+is->encoding*is->length;
} else {
serverPanic("Unknown set encoding");
}
} else if (o->type == OBJ_ZSET) {
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
asize = sizeof(*o)+(ziplistBlobLen(o->ptr));
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
d = ((zset*)o->ptr)->dict;
zskiplist *zsl = ((zset*)o->ptr)->zsl;
zskiplistNode *znode = zsl->header->level[0].forward;
asize = sizeof(*o)+sizeof(zset)+sizeof(zskiplist)+sizeof(dict)+
(sizeof(struct dictEntry*)*dictSlots(d))+
zmalloc_size(zsl->header);
while(znode != NULL && samples < sample_size) {
elesize += sdsZmallocSize(znode->ele);
elesize += sizeof(struct dictEntry) + zmalloc_size(znode);
samples++;
znode = znode->level[0].forward;
}
if (samples) asize += (double)elesize/samples*dictSize(d);
} else {
serverPanic("Unknown sorted set encoding");
}
} else if (o->type == OBJ_HASH) {
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
asize = sizeof(*o)+(ziplistBlobLen(o->ptr));
} else if (o->encoding == OBJ_ENCODING_HT) {
d = o->ptr;
di = dictGetIterator(d);
asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
while((de = dictNext(di)) != NULL && samples < sample_size) {
ele = dictGetKey(de);
ele2 = dictGetVal(de);
elesize += sdsZmallocSize(ele) + sdsZmallocSize(ele2);
elesize += sizeof(struct dictEntry);
samples++;
}
dictReleaseIterator(di);
if (samples) asize += (double)elesize/samples*dictSize(d);
} else {
serverPanic("Unknown hash encoding");
}
} else if (o->type == OBJ_STREAM) {
stream *s = o->ptr;
asize = sizeof(*o);
asize += streamRadixTreeMemoryUsage(s->rax);
/* Now we have to add the listpacks. The last listpack is often non
* complete, so we estimate the size of the first N listpacks, and
* use the average to compute the size of the first N-1 listpacks, and
* finally add the real size of the last node. */
raxIterator ri;
raxStart(&ri,s->rax);
raxSeek(&ri,"^",NULL,0);
size_t lpsize = 0, samples = 0;
while(samples < sample_size && raxNext(&ri)) {
unsigned char *lp = ri.data;
lpsize += lpBytes(lp);
samples++;
}
if (s->rax->numele <= samples) {
asize += lpsize;
} else {
if (samples) lpsize /= samples; /* Compute the average. */
asize += lpsize * (s->rax->numele-1);
/* No need to check if seek succeeded, we enter this branch only
* if there are a few elements in the radix tree. */
raxSeek(&ri,"$",NULL,0);
raxNext(&ri);
asize += lpBytes(ri.data);
}
raxStop(&ri);
/* Consumer groups also have a non trivial memory overhead if there
* are many consumers and many groups, let's count at least the
* overhead of the pending entries in the groups and consumers
* PELs. */
if (s->cgroups) {
raxStart(&ri,s->cgroups);
raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) {
streamCG *cg = ri.data;
asize += sizeof(*cg);
asize += streamRadixTreeMemoryUsage(cg->pel);
asize += sizeof(streamNACK)*raxSize(cg->pel);
/* For each consumer we also need to add the basic data
* structures and the PEL memory usage. */
raxIterator cri;
raxStart(&cri,cg->consumers);
raxSeek(&cri,"^",NULL,0);
while(raxNext(&cri)) {
streamConsumer *consumer = cri.data;
asize += sizeof(*consumer);
asize += sdslen(consumer->name);
asize += streamRadixTreeMemoryUsage(consumer->pel);
/* Don't count NACKs again, they are shared with the
* consumer group PEL. */
}
raxStop(&cri);
}
raxStop(&ri);
}
} else if (o->type == OBJ_MODULE) {
moduleValue *mv = o->ptr;
moduleType *mt = mv->type;
if (mt->mem_usage != NULL) {
asize = mt->mem_usage(mv->value);
} else {
asize = 0;
}
} else {
serverPanic("Unknown object type");
}
return asize;
}
类型 | 编码 | 对象 |
---|---|---|
OBJ_STRING | OBJ_ENCODING_INT | 使用整数值实现的字符串对象 |
OBJ_STRING | OBJ_ENCODING_RAW | 使用 SDS 实现的字符串对抗 |
OBJ_STRING | OBJ_ENCODING_EMBSTR | 使用 embstr 编码的 SDS 实现的字符串对象 |
OBJ_LIST | OBJ_ENCODING_QUICKLIST | 使用 quicklist 实现的列表对象 |
OBJ_LIST | OBJ_ENCODING_ZIPLIST | 使用 ziplist 实现的列表对象 |
OBJ_SET | OBJ_ENCODING_HT | 使用字典实现的集合对象 |
OBJ_SET | OBJ_ENCODING_INTSET | 使用整数集合实现的集合对象 |
OBJ_ZSET | OBJ_ENCODING_SKIPLIST | 使用跳表和字典实现的有序集合对象 |
OBJ_ZSET | OBJ_ENCODING_ZIPLIST | 使用 ziplist 实现的有序集合对象 |
OBJ_HASH | OBJ_ENCODING_ZIPLIST | 使用 ziplist 实现的哈希对象 |
OBJ_HASH | OBJ_ENCODING_HT | 使用字典实现的哈希对象 |
OBJ_STREAM | 无 | TODO 这里还没弄清 应该是特殊的实现 |
OBJ_MODULE | 无 | TODO 这里还没弄清 应该是特殊的实现 |
使用
OBJECT ENCODING
命令可以查看一个数据库键的值对象的编码
字符串对象的编码可以是 INT
、RAW
或者 EMBSTR
。
如果一个字符串对象保存的是整数,同时可以用 long
类型表示,那么该字符串对象的整数值会保存为 long
类型。编码设置为 int
。否则会当错字符串处理。
值的一说的是,浮点数都是被当作字符串处理的。
在执行某些操作,需要当作浮点数处理的时候。Redis 也提供的单独的命令,如
INCRBYFLOAT
等。
如果一个字符串对象保存的是字符串,并且这个字符串值的长度大于 32 字节,那么字符串对象的值将使用一个简单动态字符串(SDS
)存储。编码设置为 raw
。
如果一个字符串对象保存的是字符串,并且这个字符串值的长度小于等于 32 字节,那么字符串对象的值将使用 embstr
编码的方式存储。编码设置为 embstr
。
embstr
编码embstr
编码是专门用于保存短字符串的一个优化的编码方式,这种编码和 raw
一样,都是用 redisObject
结构和 sdshdr
结构来表示字符串,但是 raw
会调用两次内存分配函数分别穿件 redisObject
结构和 sdshdr
结构,而 embstr
编码则通过调用一次内存分配函数来分配一块连续的空间,空间中一次包含 redisObject
和 sdshdr
两个结构。
1 | ┌────────────────────────────────────────┬───────────────────────────┐ |
下面分别看下 embstr
和 raw
编码的字符串对象的创建函数:
1 | /* embstr 编码 |
embstr 编码的字符串对象在执行命令时,产生的效果和 raw 编码的字符串对象执行命令时产生的效果是相同的,但使用 embstr 编码的字符串对象来保存短字符串值有以下好处:
⚠️ 注意:这里值对象的内存是固定的,同时 Redis 本身没有编写 embstr
编码的字符串的修改程序,所以它是只读的。
Redis 的字符串对象的众多命令中,可能会出现当前编码不满足的情况。
比如 int
编码下的字符串对象被执行 INCR
命令都是正常的,但如果被执行 APPEND
命令,就会出现问题。整数从语义上也没有追加的操作。类似这种情况会将该字符串转化为 raw
编码进行处理。(⚠️ 注意:这种编码转换行为,即使处理后的编码小于等于 32 也不会采用 embstr
编码。)
1 | > set int 1 |
embstr
类型的转换也是只能转成 raw
。如上面所说,embstr
是只读的,所以对 embstr 编码的字符串对象执行任何修改命令时,程序会先将对象的编码从 embstr 转换成 raw,然后再执行修改命令。
命令 | int 编码的实现方法 | embstr 编码的实现方法 | raw 编码的实现方法 |
---|---|---|---|
SET | 使用 int 编码保存值。 | 使用 embstr 编码保存值。 | 使用 raw 编码保存值。 |
GET | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 然后向客户端返回这个字符串值。 | 直接向客户端返回字符串值。 | 直接向客户端返回字符串值。 |
APPEND | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此操作。 | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此操作。 | 调用 sdscatlen 函数, 将给定字符串追加到现有字符串的末尾。 |
INCRBYFLOAT | 取出整数值并将其转换成 longdouble 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 | 取出字符串值并尝试将其转换成 long double 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 如果字符串值不能被转换成浮点数, 那么向客户端返回一个错误。 | 取出字符串值并尝试将其转换成 longdouble 类型的浮点数, 对这个浮点数进行加法计算, 然后将得出的浮点数结果保存起来。 如果字符串值不能被转换成浮点数, 那么向客户端返回一个错误。 |
INCRBY | 对整数值进行加法计算, 得出的计算结果会作为整数被保存起来。 | embstr 编码不能执行此命令, 向客户端返回一个错误。 | raw 编码不能执行此命令, 向客户端返回一个错误。 |
DECRBY | 对整数值进行减法计算, 得出的计算结果会作为整数被保存起来。 | embstr 编码不能执行此命令, 向客户端返回一个错误。 | raw 编码不能执行此命令, 向客户端返回一个错误。 |
STRLEN | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 计算并返回这个字符串值的长度。 | 调用 sdslen 函数, 返回字符串的长度。 | 调用 sdslen 函数, 返回字符串的长度。 |
SETRANGE | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此命令。 | 将对象转换成 raw 编码, 然后按 raw 编码的方式执行此命令。 | 将字符串特定索引上的值设置为给定的字符。 |
GETRANGE | 拷贝对象所保存的整数值, 将这个拷贝转换成字符串值, 然后取出并返回字符串指定索引上的字符。 | 直接取出并返回字符串指定索引上的字符。 | 直接取出并返回字符串指定索引上的字符。 |
列表对象的编码可以是 ziplist
或者 linkedlist
。
ziplist
编码的列表对象使用压缩列表作为底层实现, 每个压缩列表节点(entry)保存了一个列表元素。
另一方面, linkedlist
编码的列表对象使用双端链表作为底层实现, 每个双端链表节点(node)都保存了一个字符串对象, 而每个字符串对象都保存了一个列表元素。
当列表对象可以同时满足以下两个条件时, 列表对象使用 ziplist
编码:
64
字节;512
个;不能满足这两个条件的列表对象需要使用 linkedlist
编码。
⚠️注意:以上两个条件的上限值是可以修改的, 具体请看配置文件中关于 list-max-ziplist-value
选项和 list-max-ziplist-entries
选项的说明。
仅列举常用命令。
命令 | ziplist 编码的实现方法 | linkedlist 编码的实现方法 |
---|---|---|
LPUSH | 调用 ziplistPush 函数, 将新元素推入到压缩列表的表头。 | 调用 listAddNodeHead 函数, 将新元素推入到双端链表的表头。 |
RPUSH | 调用 ziplistPush 函数, 将新元素推入到压缩列表的表尾。 | 调用 listAddNodeTail 函数, 将新元素推入到双端链表的表尾。 |
LPOP | 调用 ziplistIndex 函数定位压缩列表的表头节点, 在向用户返回节点所保存的元素之后, 调用ziplistDelete 函数删除表头节点。 | 调用 listFirst 函数定位双端链表的表头节点, 在向用户返回节点所保存的元素之后, 调用 listDelNode 函数删除表头节点。 |
RPOP | 调用 ziplistIndex 函数定位压缩列表的表尾节点, 在向用户返回节点所保存的元素之后, 调用ziplistDelete 函数删除表尾节点。 | 调用 listLast 函数定位双端链表的表尾节点, 在向用户返回节点所保存的元素之后, 调用 listDelNode 函数删除表尾节点。 |
LINDEX | 调用 ziplistIndex 函数定位压缩列表中的指定节点, 然后返回节点所保存的元素。 | 调用 listIndex 函数定位双端链表中的指定节点, 然后返回节点所保存的元素。 |
LLEN | 调用 ziplistLen 函数返回压缩列表的长度。 | 调用 listLength 函数返回双端链表的长度。 |
LINSERT | 插入新节点到压缩列表的表头或者表尾时, 使用ziplistPush 函数; 插入新节点到压缩列表的其他位置时, 使用 ziplistInsert 函数。 | 调用 listInsertNode 函数, 将新节点插入到双端链表的指定位置。 |
LREM | 遍历压缩列表节点, 并调用 ziplistDelete 函数删除包含了给定元素的节点。 | 遍历双端链表节点, 并调用 listDelNode 函数删除包含了给定元素的节点。 |
LTRIM | 调用 ziplistDeleteRange 函数, 删除压缩列表中所有不在指定索引范围内的节点。 | 遍历双端链表节点, 并调用 listDelNode 函数删除链表中所有不在指定索引范围内的节点。 |
LSET | 调用 ziplistDelete 函数, 先删除压缩列表指定索引上的现有节点, 然后调用 ziplistInsert 函数, 将一个包含给定元素的新节点插入到相同索引上面。 | 调用 listIndex 函数, 定位到双端链表指定索引上的节点, 然后通过赋值操作更新节点的值。 |
哈希对象的编码可以是 ziplist
或者 hashtable
。
ziplist
编码的哈希对象使用压缩列表作为底层实现, 每当有新的键值对要加入到哈希对象时, 程序会先将保存了键的压缩列表节点推入到压缩列表表尾, 然后再将保存了值的压缩列表节点推入到压缩列表表尾, 因此:
1 | // ziplist 编码 |
hashtable
编码的哈希对象使用字典作为底层实现, 哈希对象中的每个键值对都使用一个字典键值对来保存:
1 | // hashtable 编码 |
当哈希对象可以同时满足以下两个条件时, 哈希对象使用 ziplist
编码:
64
字节;512
个;不能满足这两个条件的哈希对象需要使用 hashtable
编码。
⚠️注意:这两个条件的上限值是可以修改的, 具体请看配置文件中关于 hash-max-ziplist-value
选项和 hash-max-ziplist-entries
选项的说明。
仅列举常用命令。
命令 | ziplist 编码实现方法 | hashtable 编码的实现方法 |
---|---|---|
HSET | 首先调用 ziplistPush 函数, 将键推入到压缩列表的表尾, 然后再次调用 ziplistPush 函数, 将值推入到压缩列表的表尾。 | 调用 dictAdd 函数, 将新节点添加到字典里面。 |
HGET | 首先调用 ziplistFind 函数, 在压缩列表中查找指定键所对应的节点, 然后调用 ziplistNext 函数, 将指针移动到键节点旁边的值节点, 最后返回值节点。 | 调用 dictFind 函数, 在字典中查找给定键, 然后调用dictGetVal 函数, 返回该键所对应的值。 |
HEXISTS | 调用 ziplistFind 函数, 在压缩列表中查找指定键所对应的节点, 如果找到的话说明键值对存在, 没找到的话就说明键值对不存在。 | 调用 dictFind 函数, 在字典中查找给定键, 如果找到的话说明键值对存在, 没找到的话就说明键值对不存在。 |
HDEL | 调用 ziplistFind 函数, 在压缩列表中查找指定键所对应的节点, 然后将相应的键节点、 以及键节点旁边的值节点都删除掉。 | 调用 dictDelete 函数, 将指定键所对应的键值对从字典中删除掉。 |
HLEN | 调用 ziplistLen 函数, 取得压缩列表包含节点的总数量, 将这个数量除以 2 , 得出的结果就是压缩列表保存的键值对的数量。 | 调用 dictSize 函数, 返回字典包含的键值对数量, 这个数量就是哈希对象包含的键值对数量。 |
HGETALL | 遍历整个压缩列表, 用 ziplistGet 函数返回所有键和值(都是节点)。 | 遍历整个字典, 用 dictGetKey 函数返回字典的键, 用dictGetVal 函数返回字典的值。 |
集合对象的编码可以是 intset
或者 hashtable
。
intset
编码的集合对象使用整数集合作为底层实现, 集合对象包含的所有元素都被保存在整数集合里面。
1 | // intset 编码 |
hashtable
编码的集合对象使用字典作为底层实现, 字典的每个键都是一个字符串对象, 每个字符串对象包含了一个集合元素, 而字典的值则全部被设置为 NULL
。
1 | // hashtable 编码 |
当集合对象可以同时满足以下两个条件时, 对象使用 intset
编码:
512
个;不能满足这两个条件的集合对象需要使用 hashtable
编码。
⚠️注意:第二个条件的上限值是可以修改的, 具体请看配置文件中关于 set-max-intset-entries
选项的说明。
仅列举常用命令。
命令 | intset 编码的实现方法 | hashtable 编码的实现方法 |
---|---|---|
SADD | 调用 intsetAdd 函数, 将所有新元素添加到整数集合里面。 | 调用 dictAdd , 以新元素为键, NULL 为值, 将键值对添加到字典里面。 |
SCARD | 调用 intsetLen 函数, 返回整数集合所包含的元素数量, 这个数量就是集合对象所包含的元素数量。 | 调用 dictSize 函数, 返回字典所包含的键值对数量, 这个数量就是集合对象所包含的元素数量。 |
SISMEMBER | 调用 intsetFind 函数, 在整数集合中查找给定的元素, 如果找到了说明元素存在于集合, 没找到则说明元素不存在于集合。 | 调用 dictFind 函数, 在字典的键中查找给定的元素, 如果找到了说明元素存在于集合, 没找到则说明元素不存在于集合。 |
SMEMBERS | 遍历整个整数集合, 使用 intsetGet 函数返回集合元素。 | 遍历整个字典, 使用 dictGetKey 函数返回字典的键作为集合元素。 |
SRANDMEMBER | 调用 intsetRandom 函数, 从整数集合中随机返回一个元素。 | 调用 dictGetRandomKey 函数, 从字典中随机返回一个字典键。 |
SPOP | 调用 intsetRandom 函数, 从整数集合中随机取出一个元素, 在将这个随机元素返回给客户端之后, 调用 intsetRemove 函数, 将随机元素从整数集合中删除掉。 | 调用 dictGetRandomKey 函数, 从字典中随机取出一个字典键, 在将这个随机字典键的值返回给客户端之后, 调用dictDelete 函数, 从字典中删除随机字典键所对应的键值对。 |
SREM | 调用 intsetRemove 函数, 从整数集合中删除所有给定的元素。 | 调用 dictDelete 函数, 从字典中删除所有键为给定元素的键值对。 |
有序集合的编码可以是 ziplist
或者 skiplist
。
ziplist
编码的有序集合对象使用压缩列表作为底层实现, 每个集合元素使用两个紧挨在一起的压缩列表节点来保存, 第一个节点保存元素的成员(member), 而第二个元素则保存元素的分值(score)。(这里和ziplist
表示HASH
对象有些类似)
压缩列表内的集合元素按分值从小到大进行排序, 分值较小的元素被放置在靠近表头的方向, 而分值较大的元素则被放置在靠近表尾的方向。
1 | // ziplist 编码 |
skiplist
编码的有序集合对象使用 zset
结构作为底层实现, 一个 zset
结构同时包含一个字典和一个跳跃表:
1 | typedef struct zset { |
zset
中的zsl
成员是一个跳表,按照scrore
从小到大保存了所有的集合元素,跳表节点的object
属性保存了元素的成员,score
属性保存了元素的分值。通过这个跳表,程序可以对有序集合进行范围操作,比如ZRANGE
,ZRANK
等。
zset
中的dict
成员为有序集合存储了从member
到score
的映射。通过这个字典,程序可以用的复杂度查找给定成员的分值,ZSCORE
命令就是如此实现的,同时很多其他有序集合的实现也是通过它来实现的。
值得一提的是, 虽然 zset
结构同时使用跳表和字典来保存有序集合元素, 但这两种数据结构都会通过指针来共享相同元素的成员和分值, 所以同时使用跳表和字典来保存集合元素不会产生任何重复成员或者分值, 也不会因此而浪费额外的内存。
为什么有序集合要用两种底层数据结构实现呢?
A:如果有序集合采用跳表或字典单独实现,那么性能会降低很多。
- 如果只使用跳表
- 查询特定成员的分数值需要遍历整个跳表,复杂度为。 用字典之后复杂度降为
- 如果只使用字典
- 字典中不会按score顺序存储元素的,那么对于
ZRANK
,ZRANGE
等需要根据score
来查找的命令时需要对字典排序。复杂度变成.
1 | // zset 编码 |
当有序集合对象可以同时满足以下两个条件时, 对象使用 ziplist
编码:
128
个;64
字节;不能满足以上两个条件的有序集合对象将使用 skiplist
编码。
⚠️注意:以上两个条件的上限值是可以修改的, 具体请看配置文件中关于 zset-max-ziplist-entries
选项和 zset-max-ziplist-value
选项的说明。
仅列举常用命令。
命令 | ziplist 编码的实现方法 | zset 编码的实现方法 |
---|---|---|
ZADD | 调用 ziplistInsert 函数, 将成员和分值作为两个节点分别插入到压缩列表。 | 先调用 zslInsert 函数, 将新元素添加到跳跃表, 然后调用 dictAdd 函数, 将新元素关联到字典。 |
ZCARD | 调用 ziplistLen 函数, 获得压缩列表包含节点的数量, 将这个数量除以 2 得出集合元素的数量。 | 访问跳跃表数据结构的 length 属性, 直接返回集合元素的数量。 |
ZCOUNT | 遍历压缩列表, 统计分值在给定范围内的节点的数量。 | 遍历跳跃表, 统计分值在给定范围内的节点的数量。 |
ZRANGE | 从表头向表尾遍历压缩列表, 返回给定索引范围内的所有元素。 | 从表头向表尾遍历跳跃表, 返回给定索引范围内的所有元素。 |
ZREVRANGE | 从表尾向表头遍历压缩列表, 返回给定索引范围内的所有元素。 | 从表尾向表头遍历跳跃表, 返回给定索引范围内的所有元素。 |
ZRANK | 从表头向表尾遍历压缩列表, 查找给定的成员, 沿途记录经过节点的数量, 当找到给定成员之后, 途经节点的数量就是该成员所对应元素的排名。 | 从表头向表尾遍历跳跃表, 查找给定的成员, 沿途记录经过节点的数量, 当找到给定成员之后, 途经节点的数量就是该成员所对应元素的排名。 |
ZREVRANK | 从表尾向表头遍历压缩列表, 查找给定的成员, 沿途记录经过节点的数量, 当找到给定成员之后, 途经节点的数量就是该成员所对应元素的排名。 | 从表尾向表头遍历跳跃表, 查找给定的成员, 沿途记录经过节点的数量, 当找到给定成员之后, 途经节点的数量就是该成员所对应元素的排名。 |
ZREM | 遍历压缩列表, 删除所有包含给定成员的节点, 以及被删除成员节点旁边的分值节点。 | 遍历跳跃表, 删除所有包含了给定成员的跳跃表节点。 并在字典中解除被删除元素的成员和分值的关联。 |
ZSCORE | 遍历压缩列表, 查找包含了给定成员的节点, 然后取出成员节点旁边的分值节点保存的元素分值。 | 直接从字典中取出给定成员的分值。 |
Redis
中用于操作键的命令基本上可以分为两种类型。
可以对任何类型的键执行
比如说
DEL
命令、EXPIRE
命令、RENAME
命令、TYPE
命令、OBJECT
命令, 等等。
只能对特定类型的键执行
比如说:
SET
、GET
、APPEND
、STRLEN
等命令只能对字符串键执行;HDEL
、HSET
、HGET
、HLEN
等命令只能对哈希键执行;RPUSH
、LPOP
、LINSERT
、LLEN
等命令只能对列表键执行;SADD
、SPOP
、SINTER
、SCARD
等命令只能对集合键执行;ZADD
、ZCARD
、ZRANK
、ZSCORE
等命令只能对有序集合键执行;
为了确保只有指定类型的键可以执行某些特定的命令, 在执行一个类型特定的命令之前, Redis 会先检查输入键的类型是否正确, 然后再决定是否执行给定的命令。
类型特定命令所进行的类型检查是通过 redisObject
结构的 type
属性来实现的:
举个例子, 对于 LLEN
命令来说:
LLEN
命令之前, 服务器会先检查输入数据库键的值对象是否为列表类型, 也即是, 检查值对象 redisObject
结构 type
属性的值是否为 REDIS_LIST
, 如果是的话, 服务器就对键执行 LLEN
命令;下图展示了这一类型检查过程。
其他类型特定命令的类型检查过程也和这里展示的 LLEN
命令的类型检查过程类似。
Redis 除了会根据值对象的类型来判断键是否能够执行指定命令之外, 还会根据值对象的编码方式, 选择正确的命令实现代码来执行命令。
举个例子, 在前面介绍列表对象的编码时我们说过, 列表对象有 ziplist
和 linkedlist
两种编码可用, 其中前者使用压缩列表 API 来实现列表命令, 而后者则使用双端链表 API 来实现列表命令。
现在, 考虑这样一个情况, 如果我们对一个键执行 LLEN 命令, 那么服务器除了要确保执行命令的是列表键之外, 还需要根据键的值对象所使用的编码来选择正确的 LLEN 命令实现:
ziplist
, 那么说明列表对象的实现为压缩列表, 程序将使用 ziplistLen
函数来返回列表的长度;linkedlist
, 那么说明列表对象的实现为双端链表, 程序将使用 listLength
函数来返回双端链表的长度;借用面向对象方面的术语来说, 我们可以认为 LLEN 命令是多态(polymorphism)的: 只要执行 LLEN 命令的是列表键, 那么无论值对象使用的是 ziplist
编码还是 linkedlist
编码, 命令都可以正常执行。
下图展示了 LLEN 命令从类型检查到根据编码选择实现函数的整个执行过程, 其他类型特定命令的执行过程也是类似的。
实际上, 我们可以将 DEL 、 EXPIRE 、 TYPE 等命令也称为多态命令, 因为无论输入的键是什么类型, 这些命令都可以正确地执行。
DEL 、 EXPIRE 等命令和 LLEN 等命令的区别在于, 前者是基于类型的多态 —— 一个命令可以同时用于处理多种不同类型的键, 而后者是基于编码的多态 —— 一个命令可以同时用于处理多种不同编码。
Redis的内存回收类似智能指针维护的那种,通过引用计数实现。
因为 C 语言并不具备自动的内存回收功能, 所以 Redis 在自己的对象系统中构建了一个引用计数(reference counting)技术实现的内存回收机制, 通过这一机制, 程序可以通过跟踪对象的引用计数信息, 在适当的时候自动释放对象并进行内存回收。
每个对象的引用计数信息由 redisObject
结构的 refcount
属性记录:
1 | typedef struct redisObject { |
对象的引用计数信息会随着对象的使用状态而不断变化:
1
;0
时, 对象所占用的内存会被释放。修改对象引用计数的 API
函数 | 作用 |
---|---|
incrRefCount | 将对象的引用计数值增一。 |
decrRefCount | 将对象的引用计数值减一, 当对象的引用计数值等于 0 时, 释放对象。 |
resetRefCount | 将对象的引用计数值设置为 0 , 但并不释放对象, 这个函数通常在需要重新设置对象的引用计数值时使用。 |
对象的整个生命周期可以划分为创建对象、操作对象、释放对象三个阶段。
作为例子, 以下代码展示了一个字符串对象从创建到释放的整个过程:
1 | // 创建一个字符串对象 s ,对象的引用计数为 1 |
其他不同类型的对象也会经历类似的过程。
除了用于实现引用计数内存回收机制之外, 对象的引用计数属性还带有对象共享的作用。
举个例子, 假设键 A 创建了一个包含整数值 100
的字符串对象作为值对象, 如下图所示。
1 | ┌─────────┐ ┌──────────────────┐ |
如果这时键 B 也要创建一个同样保存了整数值 100
的字符串对象作为值对象, 那么服务器有以下两种做法:
100
的字符串对象;以上两种方法很明显是第二种方法更节约内存。
在 Redis 中, 让多个键共享同一个值对象需要执行以下两个步骤:
举个例子, 下图就展示了包含整数值 100
的字符串对象同时被键 A 和键 B 共享之后的样子, 可以看到, 除了对象的引用计数从之前的 1
变成了 2
之外, 其他属性都没有变化。
1 | ┌─────────┐ ┌──────────────────┐ |
共享对象机制对于节约内存非常有帮助, 数据库中保存的相同值对象越多, 对象共享机制就能节约越多的内存。
比如说, 假设数据库中保存了整数值 100
的键不只有键 A 和键 B 两个, 而是有一百个, 那么服务器只需要用一个字符串对象的内存就可以保存原本需要使用一百个字符串对象的内存才能保存的数据。
目前来说, Redis 会在初始化服务器时, 创建一万个字符串对象, 这些对象包含了从 0
到 9999
的所有整数值, 当服务器需要用到值为 0
到 9999
的字符串对象时, 服务器就会使用这些共享对象, 而不是新创建对象。
注意
创建共享字符串对象的数量可以通过修改 server.h/OBJ_SHARED_INTEGERS
常量来修改。
举个例子, 如果我们创建一个值为 100
的键 A
, 并使用 OBJECT REFCOUNT 命令查看键 A
的值对象的引用计数, 我们会发现值对象的引用计数为 2
:
1 | redis> SET A 100 |
引用这个值对象的两个程序分别是持有这个值对象的服务器程序, 以及共享这个值对象的键 A
, 如下图所示。
1 | ┌─────────────┐ ┌──────────────────┐ |
如果这时我们再创建一个值为 100
的键 B
, 那么键 B
也会指向包含整数值 100
的共享对象, 使得共享对象的引用计数值变为 3
:
1 | redis> SET B 100 |
下图展示了共享值对象的三个程序。
1 | ┌─────────────┐ |
另外, 这些共享对象不单单只有字符串键可以使用, 那些在数据结构中嵌套了字符串对象的对象(linkedlist
编码的列表对象、 hashtable
编码的哈希对象、 hashtable
编码的集合对象、以及 zset
编码的有序集合对象)都可以使用这些共享对象。
为什么 Redis 不共享包含字符串的对象?
当服务器考虑将一个共享对象设置为键的值对象时, 程序需要先检查给定的共享对象和键想创建的目标对象是否完全相同, 只有在共享对象和目标对象完全相同的情况下, 程序才会将共享对象用作键的值对象, 而一个共享对象保存的值越复杂, 验证共享对象和目标对象是否相同所需的复杂度就会越高, 消耗的 CPU 时间也会越多:
因此, 尽管共享更复杂的对象可以节约更多的内存, 但受到 CPU 时间的限制, Redis 只对包含整数值的字符串对象进行共享。
除了前面介绍过的 type
、 encoding
、 ptr
和 refcount
四个属性之外, redisObject
结构包含的最后一个属性为 lru
属性, 该属性记录了对象最后一次被命令程序访问的时间:
1 | typedef struct redisObject { |
OBJECT IDLETIME
命令可以打印出给定键的空转时长, 这一空转时长就是通过将当前时间减去键的值对象的 lru
时间计算得出的:
1 | redis> SET msg "hello world" |
⚠️注意:
OBJECT IDLETIME
命令的实现是特殊的, 这个命令在访问键的值对象时, 不会修改值对象的 lru
属性。
除了可以被 OBJECT IDLETIME 命令打印出来之外, 键的空转时长还有另外一项作用: 如果服务器打开了 maxmemory
选项, 并且服务器用于回收内存的算法为 volatile-lru
或者 allkeys-lru
, 那么当服务器占用的内存数超过了 maxmemory
选项所设置的上限值时, 空转时长较高的那部分键会优先被服务器释放, 从而回收内存。
配置文件的 maxmemory
选项和 maxmemory-policy
选项的说明介绍了关于这方面的更多信息。
0
到 9999
的字符串对象。彻底翻车了
最后一个都没写出来。。
找个理由强行解释下,可能是没睡好hhh。
简单模拟, 不过我这里写的太麻烦了。
1 | class Solution { |
二分答案。 注意浮点数二分用次数就好了。
1 | class Solution { |
这里因为minJump
和maxJump
的取值范围很有可能使 , 所以不建议直接bfs。
这里可以参考扫描线维护区间覆盖的方式逐步遍历过去。同时判断每个位置是否被覆盖了。
1 | class Solution { |
这里最开始脑抽了,以为可以讨论出来,后面才想起来得DP,(DP水平实在太差了)
这里设 表示 第个位置已经是新的合并后的石子时先手的最大差值。
这里注意下,我一直觉得这里很绕。
当轮到后手时因为他的值在差值里时被减的,后手又想要差值尽可能小。
这个时候如果不考虑之前的状态,那么可以说明这个后手就是现在的
先手
, 所以后手的选择策略和先手时一样的。
转移方程为:
这一手货的的积分减去下一手的最大差值
这里因为题目条件有个这个
- 将一个 新的石子 放在最左边,且新石子的值为被移除石子值之和。
所以第个位置其实已经是 了。
化简一下转移方程就是:
连续和维护一个前缀和就好了。
最终转移就是
最大值可以从后遍历维护,总的复杂度是的
1 | class Solution { |
基于 Redis 6.2.1
图片截取自《Redis设计与实现》
压缩列表(ziplist)是列表键和哈希键的底层实现之一。
当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis
就会使用压缩列表来做列表键的底层实现
当一个哈希键只包含少量键值对,并且每个键值对的键和值要么就是小整数值,要么就是长度比较短的字符串,那么Redis
就会使用压缩列表来做哈希键的底层实现
压缩列表是 Redis
为了节约内存而开发的,是由一系列特殊编码的连续内存快组成的顺序行(sequential)数据结构,是一个特殊编码的双向链表。一个压缩列表可以包含任意过个节点(entry),每个节点可以保存一个字节数组或者一个整数值。
ziplist.c
文件顶部的注释内容,解释了ziplist
的结构。
ziplist
本身声明为一个unsigned char *
类型的字符串,总体布局如下:
<zlbytes> <zltail> <zllen> <entry> <entry> ... <entry> <zlend>
zlbytes
:uint32_t
类型。zlbytes
是一个无符号整型,用于保存ziplist占用的字节数,包括zlbytes
字段本身的四个字节。需要存储该值,以便能够调整整个结构的大小,而无需先遍历它。zltail
:uint32_t
类型。zltail
是列表中最后一个条目的偏移量。这允许在列表的另一端进行弹出操作,而无需完全遍历。zllen
:uint16_t
类型。zllen
是条目数。当条目数超过时,此值将设置为,我们需要遍历整个列表以了解其包含多少项。entry
:entry
是实际的存储条目。zlend
:uint8_t
类型。zlend
是代表ziplist
末尾的特殊条目。编码为等于的单个字节。没有其他普通条目以设置为的字节开始。创建一个新的空的ziplist
源码如下:
1 | /* The size of a ziplist header: two 32 bit integers for the total |
从代码块第13行可以看出,ziplist
除entry
的内容被定义为头部(ZIPLIST_HEADER_SIZE
对应<zlbytes> <zltail> <zllen>
)和尾部(ZIPLIST_END_SIZE
对应zlend
),申请这么大的内存就好了,。
具体节点的结构,源码中注释已经说的很明白了。
源码注释(翻译)
ZIPLIST条目
===============ziplist中的每个条目都以包含两个信息的元数据作为前缀。首先,存储前一个条目的长度,以便能够从后到前遍历列表。第二,提供条目编码。它表示条目类型,整数或字符串,对于字符串,还表示字符串有效负载的长度。因此,完整的条目存储如下:
<prevlen> <encoding> <entry-data>
有时,编码代表条目本身,就像后面将要看到的小整数一样。在这种情况下,
部分丢失了,我们可以这样:
<prevlen> <encoding>
上一个条目的长度
以以下方式进行编码:如果此长度小于254个字节,则它将仅消耗一个字节来表示该长度,这是一个不带符号的8位整数。当长度大于或等于254时,它将占用5个字节。第一个字节设置为254(FE),以指示随后的值更大。剩余的4个字节将前一个条目的长度作为值。 因此,实际上,条目是通过以下方式编码的:
<prevlen from 0 to 253> <encoding> <entry>
或者,如果上一个条目长度大于253个字节,则使用以下编码:
0xFE <4字节无符号小端字节序 prevlen> <encoding> <entry>
条目的编码字段(
)取决于条目的内容。当条目是字符串时,编码第一个字节的前2位将保存用于存储字符串长度的编码类型,然后是字符串的实际长度。当条目是整数时,前2位都设置为1。接下来的2位用于指定在此标头之后将存储哪种整数。不同类型和编码的概述如下。第一个字节始终足以确定条目的类型。
| 00pppppp |
- 1个字节
长度小于或等于63个字节(6位)的字符串值。 “ pppppp”表示无符号的6位长度。| 01pppppp | qqqqqqqq |
- 2个字节
长度小于或等于16383字节(14位)的字符串值。
重要说明:14位数字采用大端字节序存储。| 10______ | qqqqqqqq | rrrrrrrr | ssssssss | tttttttt |
- 5个字节
长度大于或等于16384个字节的字符串值。第一个字节之后的仅4个字节代表最大2 ^ 32-1的长度。第一个字节的低6位未使用,设置为零。
重要说明:32位数字存储在big endian中。| 11000000 |
- 3个字节
整数编码为int16_t(2个字节)。| 11010000 |
- 5个字节
整数编码为int32_t(4个字节)。| 11100000 |
- 9个字节
整数编码为int64_t(8字节)。| 11110000 |
- 4字节
整数编码为24位带符号(3个字节)。| 11111110 |
- 2个字节
整数编码为8位带符号(1个字节)。| 1111xxxx |
-(xxxx在0001和1101之间)立即4位整数。
0到12之间的无符号整数。编码值实际上是1到13,因为不能使用0000和1111,因此应从编码的4位值中减去1以获得正确的值。| 11111111 |
- ziplist的结尾标识。像ziplist标头一样,所有整数都以小端字节序表示,即使此代码在大端系统中编译也是如此。
实际ZIP列表的示例
==========================以下是一个ziplist,其中包含表示字符串“ 2”和“ 5”的两个元素。它由15个字节组成,我们在视觉上将其分为几部分:
1
2
3 [0f 00 00 00] [0c 00 00 00] [02 00] [00 f3] [02 f6] [ff]
| | | | | |
zlbytes zltail entries "2" "5" end前4个字节代表数字15,即整个ziplist组成的字节数。
接下来的4个字节是找到最后一个ziplist条目的偏移量,即12,实际上,最后一个条目“ 5”位于ziplist内的偏移量12处。
下一个16位整数表示ziplist中的元素数,由于其中只有两个元素,因此其值为2。
最后,“ 00 f3”是代表数字2的第一个条目。它由前一个条目长度(由于这是我们的第一个条目)而为零和与编码| 1111xxxx |相对应的字节F3组成。 xxxx在0001和1101之间。我们需要删除“ F”个高阶位1111,并从“ 3”中减去1,因此条目值为“ 2”。
下一个条目的前缀为02,因为第一个条目正好由两个字节组成。条目本身F6的编码方式与第一个条目完全相同,并且6-1 = 5,因此该条目的值为5。
最后,特殊条目FF向ziplist的结尾发出信号。
在上面的字符串中添加另一个值为“ Hello World”的元素,使我们可以显示ziplist如何编码小字符串。我们将仅显示条目本身的十六进制转储。想象一下上面的ziplist中存储“ 5”的条目后面的字节:
1 [02] [0b] [48 65 6c 6c 6f 20 57 6f 72 6c 64]第一个字节02是上一个条目的长度。下一个字节表示模式| 00pppppp |中的编码这表示该条目是长度为
的字符串,因此0B表示其后为11个字节的字符串。从第三个字节(48)到最后一个字节(64),只有“ Hello World”的ASCII字符。
访问ziplist
节点的辅助结构:
1 | /* We use this function to receive information about a ziplist entry. |
prevrawlensize
: 编码 prevrawlen 所需的字节大小。字符串的时候可能是1、可能是2、也可能是5。prevrawlen
:前置节点的长度lensize
:用于编码此条目类型/len的字节。例如,字符串具有1、2或5个字节头。整数始终使用单个字节。len
:用于表示实际节点的字节。对于字符串,这只是字符串长度。而对于整数,则为1、2、3、4、8或0(立即4位),具体取决于数字范围。headersize
:当前节点 header 的大小等于 prevrawlensize + lensizeencoding
:当前节点值所使用的编码类型p
:指向当前节点的指针⚠️注意:再次申明下,这个结构体知识便于处理实际节点的辅助结构。实际存储的只有<prevrawlen> <len> <data>
。
每个节点的prevlen
都记录了上一个节点的长度;
prevlen
需要1字节保存长度值。prevlen
需要5字节保存长度值。这时如果考虑一个极端情况,一个压缩列表有连续多个长度介于250字节到253字节的节点e1
到eN
。
1 | zlbytes zltail zllen e1 e2 e3 ... eN zlend |
因为e1
到e[N-1]
的节点长度都是小雨254的的,所以e2
到eN
记录前一个节点的prevlen
只需要1个字节。
这时,如果讲一个长度大于等于254字节的新节点 new
设置为压缩列表的头节点,即e1
节点的前置节点。
1 | zlbytes zltail zllen new e1 e2 e3 ... eN zlend |
因为e1
的prevlen
只有1个字节,不能保存new
的长度。所以需要重新分配空间为5个字节长。
同样的道理,e2
的pewvlen
也只有1个字节,也需要重新分配空间,
e3
、…、eN
都需要重新分配空间了。
Redis将这种现象称为“连锁更新”(cascade update)。
1 | /* When an entry is inserted, we need to set the prevlen field of the next |
除了添加节点,删除节点也可能产生连锁更新,比如在上一个例子中的压缩列表基础上删除new
。
因为连锁更新在最坏情况下需要对压缩列表执行N次空间重分配操作,而每次空间重分配的最坏复杂度为,所以连锁更新的最坏复杂度为。
要注意的是,尽管连锁更新的复杂度较高,但它真正造成性能问题的几率是很低的:
因为以上原因,ziplistPush
等命令的平均复杂度仅为,在实际中,我们可以放心地使用这些函数,而不必担心连锁更新会影响压缩列表的性能。
函数 | 作用 | 算法复杂度 |
---|---|---|
ziplistNew | 创建一个新的压缩列表 | |
ziplistPush | 创建一个包含给定值的新节点,并将这个新节点添加到压缩列表的表头或者表尾 | 平均,最坏 |
ziplistInsert | 将包含给定值的新节点插入到给定节点之后 | 平均,最坏 |
ziplistindex | 返回压缩列表给定索引上的节点 | |
ziplistfind | 在压缩列表中查找并返回包含了给定值的节点 | 因为节点的值可能是一个字节数组,所以检查节点值和给定值是否相同的复杂度为,而查找整个列表的复杂度。 |
ziplistNext | 返回给定节点的下一个节点 | |
ziplistPrev | 返回给定节点的前一个节点 | |
ziplistGet | 获取给定节点所保存的值 | |
ziplistDelete | 从压缩列表中删除给定的节点 | 平均,最坏 |
ziplistDeleteRange | 删除压缩列表在给定索引上的连续多个节点 | 平均,最坏 |
ziplistBlobLen | 返回压缩列表目前占用的内存字节数 | |
ziplistLen | 返回压缩列表目前包含的节点数量 | 返回压缩列表目前包含的节点数量,节点数量小于65535时为,大于65535时为 |
基于 [Redis 6.2.1](redis/redis at 6.2.1 (github.com))
图片截取自《Redis设计与实现》
整数集合(intset)是Set
底层实现之一,当集合只包含整数值元素,且这个集合的元素数量不多时,Redis
就会使用整数集合作为集合的底层实现。
整数集合比较简单,简单来说就是用整数数存储整数是在来维护集合。十几年了也没更新过。
整数集合的结构体定义在intset.h
1 | typedef struct intset { |
encoding
编码方式:这里有三种INTSET_ENC_INT16
、INTSET_ENC_INT32
、INTSET_ENC_INT64
,分表表示contents中存储的元素的实际类型,所以整数集合真正存储的只有int16_t
、int32_t
、int64_t
这三种类型。
length
集合的元素数量。
contents
保存元素的数组,虽然定义是int8_t
但真正的类型要看encoding
的值,这里只是方便内存申请用了int8_t
,而为了快速查找,这里进行安元素大小顺序存储,为了后面查找是可以二分查找。
1 | /* Search for the position of "value". Return 1 when the value was found and |
这里⚠️注意,整数集合只能存储同一类型的值,不会同时存int64_t
和int16_t
。比如这个例子:
1 | ┌────┬───────┬────────────────────────────┐ |
前两个数字只需要int16_t
就可以存下了, 只有第三个数字需要int64_t
,但当集合中插入第三个数字的时候就会进行升级,把所有的数字转换成int64_t
存储。
每当我们要将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先进行升级(upgrade),然后才能将新元素添加到整数集合里面。升级整数集合并添加新元素共分为三步进行:
举个例子,最开始的一个整数集合为
目前只需要 int16_t
就可以存下了。对应的表示为。
现在要将65535 加入集合,显然int64_t
不够用了,需要int32_t
来存储,这是需要申请新的内存为sizeof(int32_t) * 4
= 128位,于是重新分配的内存如下
然后开始逐渐从后至前转换每一个元素。
就这样完成了升级的过程。
⚠️注意整数集合不支持降级操作,比如上述例子,如果65535被删除了后面再添加的也是小于32768的数时编码类型仍然为INTSET_ENC_INT32
。
函数 | 作用 | 时间复杂度 |
---|---|---|
intsetNew | 创建一个新的整数集合 | |
intsetAdd | 将给定的元素添加到整数集合里面 | |
intsetRemove | 从整数集合中移除给定元素 | |
intsetFind | 检查给定值是否存在于整数集合 | 因为底层数组有序,采用了二分查找 |
intsetRandom | 从整数集合中随机返回一个元素 | |
intsetGet | 取出底层数组再给定索引上的元素 | |
intsetLen | 返回证书集合包含的元素个数 | |
intsetBlobLen | 返回证书集合占用的内存字节数 |
C++后台开发工程师
,还是应当学习专业技能。这样才好更好的干活,从而晋升加薪走向。混不下去了跳个槽也能用得上。但是我这个人真的是很奇怪。就是不能专心的学习。。。
大学最开始学了几天C语言
就开始搞上了ACM
,开始了无尽的刷题生活。这一切都还不错,电脑也就普通用一用罢了。
不过慢慢的觉得Code::Blocks
颜色太丑了,于是开始鼓捣了,开始搜Code::Blocks
的代码高亮方法。找到了几个暗色的但又不好看,鼓捣鼓捣者用起了Sublime Text
. 颜色啥的还都好看,但是编译代码不好用,又开始配置Sublime Text
. 折腾了不少,同时发现他可以安装好多插件,于是开始研究插件。就这样浪费了很多时间。
回到正轨之后呢有开始搞ACM
,正式比赛都是用的Ubuntu
,于是安装上了Ubuntu
,从此走上使用 Linux
桌面的不归路。Ubuntu
里面的各种配置、软件安装都是命令行完成的。在鼓捣了Linux
桌面美化之后开始TUI
的折腾。最开始折腾VIM
,主题折腾完折腾插件,各种琳琅满目的插件,用的不爽还想自己改,开始看vim script
的写法,然后也没做出自己的一个插件啥的,VIM
换成Neovim
后又换了新时代的插件。但在此期间习惯了命令行操作,又开始折腾起了shell
,最开始的默认shell
不好用,开始切到zsh
,装了oh-my-zsh
有开始研究安装那个插件,后来又嫌弃太慢开始折腾zinit
,oh-my-zsh
的主题总是不满意,又开始改代码,最后终于是切换到p10k
才算终了。但是Linux
的折腾刚刚开始,Ubuntu
用着太丑了换成了deepin
,最后也不知因为信仰还是啥,估计只是为了折腾又换成了Arch
系列,开始了最麻烦的装机之路,任何软件都要自己安装一遍,桌面环境从xface
到kde
一路到i3
最后到dwm
,终端模拟器从termite
到Alacritty
最后到st
。一个一个的配置,越来越麻烦,甚至最后的suckless
系列都要改代码自己编译。这些大的东西这是一部分,期间用的各种软件Tmux
,Ranger
,wtf
,conky
,Linux
下的QQ
/Wechat
等等,每个都花费了不少时间。又这样浪费了很多时间。
后面面向颜值买了一个Pixelbook
,Chrome OS
的设备,又开始了折腾,折腾这上面安装Linux
环境,能用,但最终还是不好用,终于有一天把他出手了,这才作罢。
说起来最开始的博客都是写在CSDN
上面,但这里体验感觉不好,又总想着建站。于是搭建了自己的静态博客,也就是这个博客了。于是又一次陷入了瞎折腾的情况,主题不满意,挑来挑去的,找到差不多的了,又想着继续美化,不断的鼓捣配置。主题也一路从archer
到matery
到volantis
最后到butterfly
。即使现在也想着markdown
的渲染不够丰富,本地markdown
的编写不够友好(就是真正学习看Redis
源码写总结的时候),开始研究更换markdown
引擎和编辑器,这期间也改了MarkText
的代码写文章用了一阵儿,渲染引擎换成了hexo-lute
,但还是不太好用。前阵子甚至想自己学下前端基于vditor
+lute
自己搞一个桌面版的markdown
编辑器(思源笔记不是纯markdown文本,这里用起来很别扭),同时在搞个hexo
的渲染器。期望是用Vue3
+TypeScript
基于Electron12
搞一个桌面环境。。这里又花费了点时间,但只学了最基本的HTML
、CSS
和JavaScript
。
计算机相关知识的学习总是要查些资料,看看国外友人的讨论啥的,那就要科学上网了,最开始买VPN
软件,到后来开始买机场用,这些都还好,知道买了一个可以科学上网的路由器。虽然还是挺方便的,路由器配置好SSR
就行了,但是系统又不太稳定,开始各种换固件,固件不行就换系统,系统不好用插件不够丰富就想着自己编译固件。系统是从老毛子
到了openwrt
,但编译出的固件也不如别人搞得稳定。固件这里绕了一大圈最后又换了回去。科学上网这里知识最基本的,最花时间的是从加了几个软路由交流群开始的,开始搞什么内网穿透
、DDNS
、NAS
等等。折腾来折腾去也没用上,只是折腾了而已。。。自身并没有这些需求,NAS
的话挂了个2T
的硬盘在路由器上,最开始看了两天视频,后来就没怎么用过了。折腾的时候我甚至想买三四千的群晖了。。。
后来上班了,公司给配了MacBook Pro
,这下可好,命令行操作、稳定的GUI
环境都有了,终于可以不怎么折腾Linux
了,虽说后来也找了很多MacOS
上的小工具啥的,但也确实好用,不算瞎折腾了。
期间还折腾过键盘,开始是键盘改建位。其实也没大改,就是CapsLock 改成了单机是Esc 按住与其他按键配合是Ctrl;然后Ctrl+h/j/k/l是上下左右。不同操作系统改建都不一样,MacOS
最简单用Karabiner-Elements
就好了软件的市场?上有现成的;Windows
要用AutoHotKey
写个脚本改建脚本也行,但改完总是不好用;Linux
下也差不多要改xmodmap
体验也不怎么样。这还好,短时间就搞好了。不过后面又想再Ipad
上写写代码,又开始看客制化键盘了,从可编程固件上找,加了几个群,发现很难再键盘硬件层面改CapsLock,最终做吧。
最后的折腾可能就是浏览器插件了,大体上还好,很多有用的插件完善了浏览器的体验,除了搜索引擎分栏一直没有特别好看的解决方案(油猴脚本
、Stylus
这种都有用)瞎折腾浪费了一些时间。
瞎折腾这种事情后面还是要少做。
上面写的折腾
,有些工具的折腾其实稍微弄弄就够用了,前端的学习应该真的有用(全栈开发?),至于软路由、博客主题、Linux
桌面环境、Chrome OS
等等这些折腾真的是浪费时间了。
最近想来,为啥愿意折腾,可能是折腾一会儿如果折腾出自己满意的阶段性结果会有一个打游戏通关的快感吧。
]]>想学的东西有点多…
前端最基础的就是 HTML,CSS,JavaScript 了。所以还是先从这几个学起。
B 站上找了个扫盲视频,还挺好的。
]]>有空再看下 DOM 的这个。
GG
模拟题目
二进制枚举所有集合 计算每个集合的异或和, 最后加起来就好
1 | class Solution { |
模拟就好, 我这里写的太麻烦了。
先判断下1
和0
的个数是否是差值不大于1的. 否则无解。
然后在分情况讨论下 看和1010101
或者 0101010
的差异个数, 除 2 就是了。
1 | class Solution { |
数据结构实现题,这里观察下数据范围, 应该容易想到可以遍历nums1
同时将 nums2
中的元素放入map
中。
1 | class FindSumPairs { |
这个题最开始想偏了, 当成了 LIS 的个数, 想了半天不回做, 后来改了回来。
首先打了个表, 看下结果的规律, 然后就写了, 这里和杨辉三角差不多。
1 | class Solution { |
GG
简单模拟, 用py实现的,方便点。
1 | class Solution: |
简单模拟
1 | class Solution { |
模拟题,
1 | class Solution { |
这题写的比较麻烦,开始写了个分段除法 结果这题居然卡 ,
最后改成了类似朴素晒法的过程实现的。
首先将数放入桶中记nums[i]的个数,预处理桶的前缀和, 然后按照晒法的过程途中统计下结果就好了。
这里注意复杂度
1 | class Solution { |
1 | // O(N * Sqrt(N)) 超时的代码 |
基于 Redis 6.2.1
参考资料:
https://www.jianshu.com/p/9d8296562806
画图工具是真的难用啊, 找不到好用的工具。。。
跳表(skiplist)是一种有序的数据结构,它通过在每个节点中维护多个指向其他节点的指针,从而达到快速访问的目的。
跳跃表支持平均, 最坏复杂度的节点查找,还可以通过顺序性操作来批量处理节点。
跳表既然是叫什么什么表,那么本质上还是链表。下面先看一下普通单链表的结构:
1 | digraph link { |
对于一个单链表只能依次遍历,但跳表存储的是有序的节点。
众所周知,利用有序这个单调性是可以二分的,因此可以优化查找操作。二分需要不断的折半,也就是找当前操作区间的正中间的元素,递归下去直到这个区间长度变为1。其实二叉查找树(BST,Binary Search Tree)就是这么玩儿的。像下图这样:
1 | digraph G{ |
但办法还是有的,上图是一个无重复结点的二叉查找树。稍微换个样子就可以了。如下图:
1 | digraph G{ |
跳表结构和该二叉查找树一样采用冗余节点存储二分查找中间值的时候,就能够实现的查找效率了。
现在可以看下跳表的真正模样了。
1 | digraph link { |
1 | /* Returns a random level for the new skiplist node we are going to create. |
跳表节点在 server.h
文件中:
1 | typedef struct zskiplistNode { |
ele
元素的值,采用sds
类型。(老版本这里用的robj
,后面统一改成了sds
)score
分数,浮点型*backward
后退指针,从表尾向前遍历,这里只能一个一个遍历。zskiplistLevel
跳表层级*forward
前进指针,它指向的下一个节点。span
跨度, 到它指向的下一个节点的距离。跳表结构体:
1 | typedef struct zskiplist { |
*header
跳表头节点。*tail
跳表尾节点。length
跳表的节点数量level
最大节点的层级数。]]>看到这里又个疑惑,
Redis
用跳表实现的Sorted Set
, 那么ZSCORE
命令啥的查找岂不是要了?到了后面看代码才知道,每个
Redis
的上层数据类型(String
,Hash
,Set
,List
,Sorted Set
)等的实现都是多个底层数据结构复合而成的,比如Sorted Set
在数量多了的时候就是用了skiplist
和dict
一起实现的。
1
2
3
4 typedef struct zset {
dict *dict;
zskiplist *zsl;
} zset;
GG
简单模拟题目
1 | class Solution { |
数据结构题, 维护一个set就可以了
1 | class SeatManager { |
开始想都没想就搞二分了。。。搞了半天
后面发现只要拍个序 模拟一下就好了, 如果这个一个减上一个超过1, 就变成上一个的值+1.
没看到题目说 第一个 必须为 1 wa了一发。
1 | class Solution { |
这个题本身也不难, 数据和查询两个数组按照size从大到小拍个序就好了。 搞个set维护roomId。 set自带的二分查找下就行了。 因为是绝对值就再维护个负值的set(后面看了其他大佬的代码发现迭代器减一下就行了)。
不太会用set, 不会写c++的匿名函数,, 后面判断逻辑又少了, GG。
1 | bool cmp(vector<int>& a, vector<int>& b) { |
基于 Redis 6.2.1
字典, 又称符号表(symbol table)、关联数组(associative array)或者映射(map), 是一种用于保存键值对(key-value pair)的抽象数据结构。
在字典中,一个键(key)和一个值(value)关联,关联上的键和值被称为键值对
很多语言都提供了字典的实现,如C++ STL中的map,python中的dict,Go中的map等等。C语言中并为提供字典实现,因此Redis自行实现了字典。
Redis中很多地方用到了字典,Redis的数据库,HASH类型等。
src/dict.h
中定义了字典
1 | // hashtable 哈希表结构 |
table
属性是一个数组, 数组中的每个元素都是一个指向 dict.h/dictEntry
结构的指针, 每个 dictEntry
结构保存着一个键值对。
size
属性记录了哈希表的大小, 也即是 table
数组的大小, 而 used
属性则记录了哈希表目前已有节点(键值对)的数量。
sizemask
属性的值总是等于 size - 1
, 这个属性和哈希值一起决定一个键应该被放到 table
数组的哪个索引上面。
采用的hash算法在src/siphash.c
中, 采用的hash算法 是 SipHash 1-2
本文并不展开介绍SipHash 1-2
原理。
1 | // 哈希表节点, 也就是一个键值对 |
key
属性保存着键值对中的键, 而 v
属性则保存着键值对中的值, 其中键值对的值可以是一个指针, 或者是一个 uint64_t
整数, 又或者是一个 int64_t
整数。
next
属性是指向另一个哈希表节点的指针, 这个指针可以将多个哈希值相同的键值对连接在一次, 以此来解决键冲突(collision)的问题。
举个例子, 图 4-2 就展示了如何通过 next
指针, 将两个索引值相同的键 k1
和 k0
连接在一起。
1 | // 字典 结构 |
type
属性和 privdata
属性是针对不同类型的键值对, 为创建多态字典而设置的:
type
属性是一个指向 dictType
结构的指针, 每个 dictType
结构保存了一簇用于操作特定类型键值对的函数, Redis 会为用途不同的字典设置不同的类型特定函数。
而 privdata
属性则保存了需要传给那些类型特定函数的可选参数。
1 | typedef struct dictType { |
ht
属性是一个包含两个项的数组, 数组中的每个项都是一个 dictht
哈希表, 一般情况下, 字典只使用 ht[0]
哈希表, ht[1]
哈希表只会在对 ht[0]
哈希表进行 rehash 时使用。
除了 ht[1]
之外, 另一个和 rehash 有关的属性就是 rehashidx
: 它记录了 rehash 目前的进度, 如果目前没有在进行 rehash , 那么它的值为 -1
。
下图是一个完整的字典结构(普通状态下,没有进行rehash):
TODO 感觉没啥好说的了。
TODO 这个感觉也没啥好说的,太基础了。
随着频繁的增删操作, 哈希表可能不够用了或者空间使用率变低了,这时候就需要进行扩容或缩容,也就是Redis的rehash过程。
rehash过程很好理解,当哈希表需要扩容或缩容的时候,改变哈希表的大小,对所有元素重新 hash 后放到新的位置。
以下图为例, 当字典使用率过低时,会进行缩容。按照used个数确定合适的容量生成一个新的。这时候将旧的哈希表(h[0])中的数据重新hash放到新的哈希表中(h[1])。
同理当容量不足的时候,字典会进行扩容。容量大小会翻一倍(乘2)。也是一样生成一个新的。把旧的哈希表(h[0])中的数据重新hash放到新的哈希表中(h[1])。
⚠️注意, 如上图所示,当给一个容量为4的哈希表添加键值对,然后再删一个,然后再添加一个。。。这样重复的删除再添加。 会一直rehash下去,每次都要进行大量的内存操作和数据结构的维护处理,想想Redis本身单进程的,这得慢成什么样子。 所以 Redis 在处理扩容缩容时有这样的策略:
一般情况下 当used/size >= 1
时, 进行扩容。 容量缩到大于 used 的第一个大小。
正在进行高负载命令时(行 BGSAVE 命令或BGREWRITEAOF 命令), 当used/size > 5
时才进行扩容,容量缩到大于 used 的第一个大小。
当used/size <= 1/10
时进行缩容。容量缩到大于 used 的第一个大小。
扩容策略源码:
1 | /* Expand the hash table if needed */ |
有了上面rehash的,字典可以应对容量的变化, 但如果字典已经存储了十万,百万,甚至千万量级的键值对,一次rehash的过程会持续很久,这个时候因为Redis单进程处理会阻塞很久,业务服务就会卡住。
因此Redis实现了渐进式的rehash,将rehash的操作分散到字典多次的增删改查操作中。每一次只操作少量的哈希表的槽位,将整体rehash操作均摊。
从字典的结构中可以看到它有两个哈希表。正常情况下直接使用的ht[0]
, 渐进式的rehash过程就是逐步将键值对迁移到ht[1]
中。在rehash的过程中进行操作时字典会先从ht[0]
找,如果找不到则在ht[1]
中找。 如下面dictFind
函数:
1 | dictEntry *dictFind(dict *d, const void *key) |
渐进式rehash主要时限制了两个,
最多可迁移的槽的个数n
。
最多可遍历的空槽的个数n*10
如果进行了这么多的遍历或rehash操作,函数则退出,如果rehash已经结束返回0
,没有结束返回1
。
最后看下rehash的完整函数吧:
1 | /* Performs N steps of incremental rehashing. Returns 1 if there are still |
函数 | 作用 | 时间复杂度 |
---|---|---|
dictCreate | 创建一个新的字典。 | |
dictAdd | 将给定的键值对添加到字典里面。 | |
dictReplace | 将给定的键值对添加到字典里面, 如果键已经存在于字典,那么用新值取代原有的值。 | |
dictFetchValue | 返回给定键的值。 | |
dictGetRandomKey | 从字典中随机返回一个键值对。 | |
dictDelete | 从字典中删除给定键所对应的键值对。 | |
dictRelease | 释放给定字典,以及字典中包含的所有键值对。 | , N 为字典包含的键值对数量。 |
字典中最重要的实现是 rehash 及其渐进式的方式。
]]>这篇文章基本是抄来的。 好不要脸啊我。
带有空还是要自己整理一下。
基于 [Redis 6.2.1](redis/redis at 6.2.1 (github.com))
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将 SDS 用作 Redis 的默认字符串表示。
Redis 中除了字符串字面量,当作常量使用的地方用了C语言传统字符串。 其他可以想见的涉及到字符串的东西都是用SDS实现的。
redis 3.2 版本更新了 sds 2.0, 本文简单总结下sds1.0,再总结下sds2.0.
SDS 1.0 内容copy 自 《Redis 设计与实现(第二版)》
每个 sds.h/sdshdr 结构表示一个 SDS 值:
1 | struct sdshdr { |
图 2-1 展示了一个 SDS 示例:
free
属性的值为 0
, 表示这个 SDS 没有分配任何未使用空间。len
属性的值为 5
, 表示这个 SDS 保存了一个五字节长的字符串。buf
属性是一个 char
类型的数组, 数组的前五个字节分别保存了 'R'
、 'e'
、 'd'
、 'i'
、 's'
五个字符, 而最后一个字节则保存了空字符 '\0'
。SDS 遵循 C 字符串以空字符结尾的惯例, 保存空字符的 1
字节空间不计算在 SDS 的 len
属性里面, 并且为空字符分配额外的 1
字节空间, 以及添加空字符到字符串末尾等操作都是由 SDS 函数自动完成的, 所以这个空字符对于 SDS 的使用者来说是完全透明的。
遵循空字符结尾这一惯例的好处是, SDS 可以直接重用一部分 C 字符串函数库里面的函数。
举个例子, 如果我们有一个指向图 2-1 所示 SDS 的指针 s
, 那么我们可以直接使用 stdio.h/printf
函数, 通过执行以下语句:
1 | printf("%s", s->buf); |
来打印出 SDS 保存的字符串值 "Redis"
, 而无须为 SDS 编写专门的打印函数。
图 2-2 展示了另一个 SDS 示例:
"Redis"
。buf
数组分配了五字节未使用空间, 所以它的 free
属性的值为 5
(图中使用五个空格来表示五字节的未使用空间)。根据传统, C 语言使用长度为 N+1
的字符数组来表示长度为 N
的字符串, 并且字符数组的最后一个元素总是空字符 '\0'
。
比如说, 图 2-3 就展示了一个值为 "Redis"
的 C 字符串:
C 语言使用的这种简单的字符串表示方式, 并不能满足 Redis 对字符串在安全性、效率、以及功能方面的要求, 本节接下来的内容将详细对比 C 字符串和 SDS 之间的区别, 并说明 SDS 比 C 字符串更适用于 Redis 的原因。
因为 C 字符串并不记录自身的长度信息, 所以为了获取一个 C 字符串的长度, 程序必须遍历整个字符串, 对遇到的每个字符进行计数, 直到遇到代表字符串结尾的空字符为止, 这个操作的复杂度为 。
举个例子, 图 2-4 展示了程序计算一个 C 字符串长度的过程。
和 C 字符串不同, 因为 SDS 在 len
属性中记录了 SDS 本身的长度, 所以获取一个 SDS 长度的复杂度仅为 。
举个例子, 对于图 2-5 所示的 SDS 来说, 程序只要访问 SDS 的 len
属性, 就可以立即知道 SDS 的长度为 5
字节:
又比如说, 对于图 2-6 展示的 SDS 来说, 程序只要访问 SDS 的 len
属性, 就可以立即知道 SDS 的长度为 11
字节。
设置和更新 SDS 长度的工作是由 SDS 的 API 在执行时自动完成的, 使用 SDS 无须进行任何手动修改长度的工作。
通过使用 SDS 而不是 C 字符串, Redis 将获取字符串长度所需的复杂度从 降低到了 , 这确保了获取字符串长度的工作不会成为 Redis 的性能瓶颈。
比如说, 因为字符串键在底层使用 SDS 来实现, 所以即使我们对一个非常长的字符串键反复执行 STRLEN 命令, 也不会对系统性能造成任何影响, 因为 STRLEN 命令的复杂度仅为 。
除了获取字符串长度的复杂度高之外, C 字符串不记录自身长度带来的另一个问题是容易造成缓冲区溢出(buffer overflow)。
举个例子, <string.h>/strcat
函数可以将 src
字符串中的内容拼接到 dest
字符串的末尾:
1 | char *strcat(char *dest, const char *src); |
因为 C 字符串不记录自身的长度, 所以 strcat
假定用户在执行这个函数时, 已经为 dest
分配了足够多的内存, 可以容纳 src
字符串中的所有内容, 而一旦这个假定不成立时, 就会产生缓冲区溢出。
举个例子, 假设程序里有两个在内存中紧邻着的 C 字符串 s1
和 s2
, 其中 s1
保存了字符串 "Redis"
, 而 s2
则保存了字符串 "MongoDB"
, 如图 2-7 所示。
如果一个程序员决定通过执行:
1 | strcat(s1, " Cluster"); |
将 s1
的内容修改为 "Redis Cluster"
, 但粗心的他却忘了在执行 strcat
之前为 s1
分配足够的空间, 那么在 strcat
函数执行之后, s1
的数据将溢出到 s2
所在的空间中, 导致 s2
保存的内容被意外地修改, 如图 2-8 所示。
与 C 字符串不同, SDS 的空间分配策略完全杜绝了发生缓冲区溢出的可能性: 当 SDS API 需要对 SDS 进行修改时, API 会先检查 SDS 的空间是否满足修改所需的要求, 如果不满足的话, API 会自动将 SDS 的空间扩展至执行修改所需的大小, 然后才执行实际的修改操作, 所以使用 SDS 既不需要手动修改 SDS 的空间大小, 也不会出现前面所说的缓冲区溢出问题。
举个例子, SDS 的 API 里面也有一个用于执行拼接操作的 sdscat
函数, 它可以将一个 C 字符串拼接到给定 SDS 所保存的字符串的后面, 但是在执行拼接操作之前, sdscat
会先检查给定 SDS 的空间是否足够, 如果不够的话, sdscat
就会先扩展 SDS 的空间, 然后才执行拼接操作。
比如说, 如果我们执行:
1 | sdscat(s, " Cluster"); |
其中 SDS 值 s
如图 2-9 所示, 那么 sdscat
将在执行拼接操作之前检查 s
的长度是否足够, 在发现 s
目前的空间不足以拼接 " Cluster"
之后, sdscat
就会先扩展 s
的空间, 然后才执行拼接 " Cluster"
的操作, 拼接操作完成之后的 SDS 如图 2-10 所示。
注意图 2-10 所示的 SDS : sdscat
不仅对这个 SDS 进行了拼接操作, 它还为 SDS 分配了 13
字节的未使用空间, 并且拼接之后的字符串也正好是 13
字节长, 这种现象既不是 bug 也不是巧合, 它和 SDS 的空间分配策略有关, 接下来的小节将对这一策略进行说明。
正如前两个小节所说, 因为 C 字符串并不记录自身的长度, 所以对于一个包含了 N
个字符的 C 字符串来说, 这个 C 字符串的底层实现总是一个 N+1
个字符长的数组(额外的一个字符空间用于保存空字符)。
因为 C 字符串的长度和底层数组的长度之间存在着这种关联性, 所以每次增长或者缩短一个 C 字符串, 程序都总要对保存这个 C 字符串的数组进行一次内存重分配操作:
举个例子, 如果我们持有一个值为 "Redis"
的 C 字符串 s
, 那么为了将 s
的值改为 "Redis Cluster"
, 在执行:
1 | strcat(s, " Cluster"); |
之前, 我们需要先使用内存重分配操作, 扩展 s
的空间。
之后, 如果我们又打算将 s
的值从 "Redis Cluster"
改为 "Redis Cluster Tutorial"
, 那么在执行:
1 | strcat(s, " Tutorial"); |
之前, 我们需要再次使用内存重分配扩展 s
的空间, 诸如此类。
因为内存重分配涉及复杂的算法, 并且可能需要执行系统调用, 所以它通常是一个比较耗时的操作:
为了避免 C 字符串的这种缺陷, SDS 通过未使用空间解除了字符串长度和底层数组长度之间的关联: 在 SDS 中, buf
数组的长度不一定就是字符数量加一, 数组里面可以包含未使用的字节, 而这些字节的数量就由 SDS 的 free
属性记录。
通过未使用空间, SDS 实现了空间预分配和惰性空间释放两种优化策略。
空间预分配用于优化 SDS 的字符串增长操作: 当 SDS 的 API 对一个 SDS 进行修改, 并且需要对 SDS 进行空间扩展的时候, 程序不仅会为 SDS 分配修改所必须要的空间, 还会为 SDS 分配额外的未使用空间。
其中, 额外分配的未使用空间数量由以下公式决定:
len
属性的值)将小于 1 MB
, 那么程序分配和 len
属性同样大小的未使用空间, 这时 SDS len
属性的值将和 free
属性的值相同。 举个例子, 如果进行修改之后, SDS 的 len
将变成 13
字节, 那么程序也会分配13
字节的未使用空间, SDS 的 buf
数组的实际长度将变成 13 + 13 + 1 = 27
字节(额外的一字节用于保存空字符)。1 MB
, 那么程序会分配 1 MB
的未使用空间。 举个例子, 如果进行修改之后, SDS 的 len
将变成 30 MB
, 那么程序会分配 1 MB
的未使用空间, SDS 的 buf
数组的实际长度将为 30 MB + 1 MB + 1 byte
。通过空间预分配策略, Redis 可以减少连续执行字符串增长操作所需的内存重分配次数。
举个例子, 对于图 2-11 所示的 SDS 值 s
来说, 如果我们执行:
1 | sdscat(s, " Cluster"); |
那么 sdscat
将执行一次内存重分配操作, 将 SDS 的长度修改为 13
字节, 并将 SDS 的未使用空间同样修改为 13
字节, 如图 2-12 所示。
如果这时, 我们再次对 s
执行:
1 | sdscat(s, " Tutorial"); |
那么这次 sdscat
将不需要执行内存重分配: 因为未使用空间里面的 13
字节足以保存 9
字节的 " Tutorial"
, 执行 sdscat
之后的 SDS 如图 2-13 所示。
在扩展 SDS 空间之前, SDS API 会先检查未使用空间是否足够, 如果足够的话, API 就会直接使用未使用空间, 而无须执行内存重分配。
通过这种预分配策略, SDS 将连续增长 N
次字符串所需的内存重分配次数从必定 N
次降低为最多 N
次。
惰性空间释放用于优化 SDS 的字符串缩短操作: 当 SDS 的 API 需要缩短 SDS 保存的字符串时, 程序并不立即使用内存重分配来回收缩短后多出来的字节, 而是使用 free
属性将这些字节的数量记录起来, 并等待将来使用。
举个例子, sdstrim
函数接受一个 SDS 和一个 C 字符串作为参数, 从 SDS 左右两端分别移除所有在 C 字符串中出现过的字符。
比如对于图 2-14 所示的 SDS 值 s
来说, 执行:
1 | sdstrim(s, "XY"); // 移除 SDS 字符串中的所有 'X' 和 'Y' |
会将 SDS 修改成图 2-15 所示的样子。
注意执行 sdstrim
之后的 SDS 并没有释放多出来的 8
字节空间, 而是将这 8
字节空间作为未使用空间保留在了 SDS 里面, 如果将来要对 SDS 进行增长操作的话, 这些未使用空间就可能会派上用场。
举个例子, 如果现在对 s
执行:
1 | sdscat(s, " Redis"); |
那么完成这次 sdscat
操作将不需要执行内存重分配: 因为 SDS 里面预留的 8
字节空间已经足以拼接 6
个字节长的 " Redis"
, 如图 2-16 所示。
通过惰性空间释放策略, SDS 避免了缩短字符串时所需的内存重分配操作, 并为将来可能有的增长操作提供了优化。
与此同时, SDS 也提供了相应的 API , 让我们可以在有需要时, 真正地释放 SDS 里面的未使用空间, 所以不用担心惰性空间释放策略会造成内存浪费。
C 字符串中的字符必须符合某种编码(比如 ASCII), 并且除了字符串的末尾之外, 字符串里面不能包含空字符, 否则最先被程序读入的空字符将被误认为是字符串结尾 —— 这些限制使得 C 字符串只能保存文本数据, 而不能保存像图片、音频、视频、压缩文件这样的二进制数据。
举个例子, 如果有一种使用空字符来分割多个单词的特殊数据格式, 如图 2-17 所示, 那么这种格式就不能使用 C 字符串来保存, 因为 C 字符串所用的函数只会识别出其中的 "Redis"
, 而忽略之后的 "Cluster"
。
虽然数据库一般用于保存文本数据, 但使用数据库来保存二进制数据的场景也不少见, 因此, 为了确保 Redis 可以适用于各种不同的使用场景, SDS 的 API 都是二进制安全的(binary-safe): 所有 SDS API 都会以处理二进制的方式来处理 SDS 存放在 buf
数组里的数据, 程序不会对其中的数据做任何限制、过滤、或者假设 —— 数据在写入时是什么样的, 它被读取时就是什么样。
这也是我们将 SDS 的 buf
属性称为字节数组的原因 —— Redis 不是用这个数组来保存字符, 而是用它来保存一系列二进制数据。
比如说, 使用 SDS 来保存之前提到的特殊数据格式就没有任何问题, 因为 SDS 使用 len
属性的值而不是空字符来判断字符串是否结束, 如图 2-18 所示。
通过使用二进制安全的 SDS , 而不是 C 字符串, 使得 Redis 不仅可以保存文本数据, 还可以保存任意格式的二进制数据。
虽然 SDS 的 API 都是二进制安全的, 但它们一样遵循 C 字符串以空字符结尾的惯例: 这些 API 总会将 SDS 保存的数据的末尾设置为空字符, 并且总会在为 buf
数组分配空间时多分配一个字节来容纳这个空字符, 这是为了让那些保存文本数据的 SDS 可以重用一部分 <string.h>
库定义的函数。
举个例子, 如图 2-19 所示, 如果我们有一个保存文本数据的 SDS 值 sds
, 那么我们就可以重用 <string.h>/strcasecmp
函数, 使用它来对比 SDS 保存的字符串和另一个 C 字符串:
1 | strcasecmp(sds->buf, "hello world"); |
这样 Redis 就不用自己专门去写一个函数来对比 SDS 值和 C 字符串值了。
与此类似, 我们还可以将一个保存文本数据的 SDS 作为 strcat
函数的第二个参数, 将 SDS 保存的字符串追加到一个 C 字符串的后面:
1 | strcat(c_string, sds->buf); |
这样 Redis 就不用专门编写一个将 SDS 字符串追加到 C 字符串之后的函数了。
通过遵循 C 字符串以空字符结尾的惯例, SDS 可以在有需要时重用 <string.h>
函数库, 从而避免了不必要的代码重复。
表 2-1 对 C 字符串和 SDS 之间的区别进行了总结。
表 2-1 C 字符串和 SDS 之间的区别
C 字符串 | SDS |
---|---|
获取字符串长度的复杂度为 。 | 获取字符串长度的复杂度为 。 |
API 是不安全的,可能会造成缓冲区溢出。 | API 是安全的,不会造成缓冲区溢出。 |
修改字符串长度 N 次必然需要执行 N 次内存重分配。 | 修改字符串长度 N 次最多需要执行 N 次内存重分配。(极大成都降低了频繁内存分配导致的开销) |
只能保存文本数据。 | 可以保存文本或者二进制数据。 |
可以使用所有 <string.h> 库中的函数。 | 可以使用一部分 <string.h> 库中的函数。 |
表 2-2 SDS 的主要操作 API
函数 | 作用 | 时间复杂度 |
---|---|---|
sdsnew | 创建一个包含给定 C 字符串的 SDS 。 | , N 为给定 C 字符串的长度。 |
sdsempty | 创建一个不包含任何内容的空 SDS 。 | |
sdsfree | 释放给定的 SDS 。 | |
sdslen | 返回 SDS 的已使用空间字节数。 | 这个值可以通过读取 SDS 的 len 属性来直接获得, 复杂度为 。 |
sdsavail | 返回 SDS 的未使用空间字节数。 | 这个值可以通过读取 SDS 的 free 属性来直接获得, 复杂度为 。 |
sdsdup | 创建一个给定 SDS 的副本(copy)。 | , N 为给定 SDS 的长度。 |
sdsclear | 清空 SDS 保存的字符串内容。 | 因为惰性空间释放策略,复杂度为 。 |
sdscat | 将给定 C 字符串拼接到 SDS 字符串的末尾。 | , N 为被拼接 C 字符串的长度。 |
sdscatsds | 将给定 SDS 字符串拼接到另一个 SDS 字符串的末尾。 | , N 为被拼接 SDS 字符串的长度。 |
sdscpy | 将给定的 C 字符串复制到 SDS 里面, 覆盖 SDS 原有的字符串。 | , N 为被复制 C 字符串的长度。 |
sdsgrowzero | 用空字符将 SDS 扩展至给定长度。 | , N 为扩展新增的字节数。 |
sdsrange | 保留 SDS 给定区间内的数据, 不在区间内的数据会被覆盖或清除。 | , N 为被保留数据的字节数。 |
sdstrim | 接受一个 SDS 和一个 C 字符串作为参数, 从 SDS 左右两端分别移除所有在 C 字符串中出现过的字符。 | , M 为 SDS 的长度, N 为给定 C 字符串的长度。 |
sdscmp | 对比两个 SDS 字符串是否相同。 | , N 为两个 SDS 中较短的那个 SDS 的长度。 |
2.0 原由
https://github.com/antirez/redis/issues/757
问题就在len和free的使用类型上,使用的是unsigned int
- unsigned int,也就是32位,最多只能记录4GB大小,超过4G的大小将无法使用
- 内存损耗,如果字符串都非常短,可能16位就能记录,那么32位就损耗了2位
简单的换len和free的类型是不行的,仔细观察上面两个缺点,发现他们其实是有点互斥的成分在里面。
一个嫌弃是unsigned int过小,一个是嫌弃unsigned int过大然后这个PR就提出了自适应的sdshdr
https://github.com/antirez/redis/pull/2509也就是SDS2.0的实现
1 | typedef char *sds; |
len
:字符串的长度,不包含'\0'
,'\0'
由自己维护,用户不需要关心;
alloc
:申请的内存空间大小;
flags
:类型,当前仅使用低三位,后续可能会有扩展,用于判断当前sds对应的header的类型;
buf
:变长部分,存储数据;
2.0 根据长度的不同,分成了5种, 分别是5位,8位,16位,32位,64位。
其中sdshdr5较为特殊,没有len和alloc,flags的3位表示类型,剩下的5位表示长度,最多只能表示长度的字符串。
2.0版本与1.0版本本质功能上差别不大。
最大的区别就是header
的定义,分成5类记录长度,而不是之前的int len
,是为了节省内存(抠的着实是有些细了)。
其次在非32位环境下支持超过4GB大小内存的能力。
比起 C 字符串, SDS 具有以下优点:
准备好好学习下redis了
《Redis 设计与实现(第二版)》
redis-3.0.0 带中文注释代码
redis 最新版代码
准备跟书看,同时对比下最新版代码,最后运行调试看下。
博客还不知道会不会更新。。。。
我个人习惯用vscode。
C/C++ 开发环境这里不展开了,参考这个搞下就行了
简单配置下就可以断点调试了
.vscode/launch.json
1 | { |
.vscode/tasks.json
1 | { |
[ ] 数据结构
[ ] 基础数据结sdsß
[ ] 外部数据结构(各类对象)
[ ] 特殊结构
[ ] 单机数据库的实现
[ ] 多机数据库的实现
[ ] 独立功能实现
先把这个教程看完 - Go 指南
然后就去写代码
完毕
[【Go语言】基本类型排序和 slice 排序](https://itimetraveler.github.io/2016/09/07/【Go语言】基本类型排序和 slice 排序/)
1 | package main |
1 | func max(a, b int) int { |
1 | /** |
1 | int dp[1005][1005]; |
1 | // 双层二进制枚举 |
1 | // 并查集 |
1 | // 自定义结构体+排序 |
1 | // lis |
1 | type BIT struct { |
1 | func lisanhua(nums []int) []int { |
公司给发了个 MacBook Pro 然后就基本告别 Manjaro 了,
这里介绍下使用 osx 的一些体验
mac 的软件包管理器, 一般好用吧, 用过 pacman 感觉其他的都不太行
1 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" |
1 | # 换清华源 https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/ |
很多 App 在 Mac 下长按某个键时只会触发一次。 比如在 Sublime Text 下, 用 VIM 模式来 操作时, 长按 「J」 时, 只会按下跳一行。 但是奇怪开了中文输入法后又可以一直往下跳。
其实我们是可以用下面的命令来重新默认打开这个功能。
1 defaults write -g ApplePressAndHoldEnabled -bool false注销并重新登录系统使其更改生效。
如果需要恢复长按键盘可以重音字符或非英文字符的功能,请打开终端窗口,运行以下命令:
1 defaults delete -g ApplePressAndHoldEnabled
安装
JetBrains Mono Nerd Font
字体
1
2 brew tap homebrew/cask-fonts
brew install font-jetbrains-mono-nerd-font
vscode: 开源的编辑器, 体验很棒
brew install --cask visual-studio-code
Chrome: 浏览器, 依赖于它的很多插件, 换不了, 太费内存了…
brew install google-chrome
还需要装很多插件,TODO
Typora: Markdown 编辑器, 单页 实时预览,很 nice
brew install --cask typora
onedrive: 微软家的网盘, 跨平台同步的工具,
markText: Markdown 编辑器, 挺好用的.
Fliqlo: 好看翻页时钟屏保。
brew install --cask fliqlo
滴答清单:TODO 类软件,全平台支持了,挺好用的。
brew install --cask ticktick
SourceTree: 免费好用的git客户端软件。
brew install --cask sourcetree
NetNewsWire: RSS阅读器
brew install --cask netnewswire
OBS: 免费且开源的用于视频录制以及直播串流的软件。
brew install --cask obs
mac 独有分割线
iina: 看视频的软件,大多格式的都能放
brew install --cask iina
itsycal: 在 menu bar 上的时间点一下会出现日历
brew install --cask itsycal
utools: 一款跨平台的启动器,插件免费,更加简单易用。
brew install --cask utools
还需要装很多插件,TODO
cakebrew: homebrew 的可视化版, 还挺好用, 但是有的软件找不到…
karabiner: 键盘映射工具
brew install --cask karabiner-elements
keycastr:显示键盘按键的软件
brew install --cask keycastr
GetPlainText: 复制时删除样式.
bartender 4: 整理 menu bar 的工具.
brew install bartender --cask
Lemon: 柠檬清理.
brew install tencent-lemon --cask
SwitchResX: 快速修改屏幕分辨率的 Mac 软件
brew install switchresx
Better And Better 2.0: Better And Better 2.0 将强大功能与优秀人机交互结合提升到一个崭新的高度。全面提升 Mac 触控板、鼠标、键盘使用,数百种动作手势、绘图手势与预设、脚本、快捷键完美协作,为你带来无与伦比的 Mac 操作体验。
超级右键: 超级右键以优秀设计与丰富功能为 Mac 带来绝佳的使用体验,众多功能与右键融为一体,深得人心的设计,让你即刻进入高效的 Mac 使用体验,快、高效、便捷,效果出奇的好
ishot: iShot 堪称 macOS 上功能最为全面的截图、录屏工具,截图、长截图、多窗口截图、延时截图、标注、贴图、取色、录屏…
snipaste: 开源的多平台截图软件。
brew install snipaste
自动切换输入法: 在自动切换输入法内,提前设置每个 App 对应的输入法,切换至该 App 时,将为您自动切换至为他设定好的输入法。
键指如飞/FlyKey: 键指如飞默认使用双击 Command 显示当前 App 的所有快捷键
rectangle: 桌面窗口管理。
brew install --cask rectangle
copyless 2: 剪贴板管理器. 最多可以存储 1000 个最新剪辑
Mos: 一个用于在 MacOS 上平滑你的鼠标滚动效果的小工具, 让你的滚轮爽如触控板。
brew install --cask mos
Amphetamine: 防睡眠软件。
TopNotch: 针对2021款MBP隐藏刘海的软件。> brew install --cask topnotch
Only Switch: OnlySwitch 是一个菜单栏的工具箱,提供很多快捷的功能,例如隐藏桌面图标,黑暗模式和隐藏新 MacBook Pro 的丑陋缺口。开关显示在您的状态栏上。目前支持以下功能:隐藏桌面 黑暗模式 屏幕保护程序 自动隐藏Dock AirPods 蓝牙 Xcode 缓存 自动隐藏菜单栏 显示隐藏文件 广播电台 保持清醒 清空垃圾桶 清空粘贴板 静音 隐藏留海等。
brew install only-switch
Parallels Desktop: Mac 上的虚拟机软件
brew install --cask parallels
PD Runner: 适用于Parallels Desktop的启动器, 可无视试用期限强制启动客户机
brew install pd-runner
github 已经被封了,brew 安装不了。 点击这个下载吧
来源:https://github.com/lihaoyun6/BigSur-icons/issues/6#issuecomment-1025392331
homebrew: mac 的软件包管理器, 一般好用吧, 用过 pacman 感觉其他的都不太行
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
1 | # 换清华源 https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/ |
alacritty: 跨平台、高性能的终端模拟器。vim下大文件体验很棒。
brew install --cask alacritty
iTerm2: mac 下的终端模拟软件,其实是 GUI 软件的,故意放在这里
brew install --cask iterm2
thefuck: 帮忙修正手误导致的错误命令
brew install thefuck
tmux: 终端复用工具,
brew install tmux
neovim: 从 VIM 上 fork 来的, (没怎么用过 vim, 无法做出比较,
brew install neovim
ranger: 终端下的文件管理器,配置后能预览图片,显示压缩文件信息等, 加上类 vi 的操作方式,很奈斯
brew install ranger
orpip3 install ranger-fm
docker: mac 的 docker 感觉和 Linux 的不太一样 会有个应用程序在启动器里面…
brew install docker
ripgrep: 搜索工具, 快
brew install ripgrep
lsd: ls 的替代品, rust 写的 好看又快
brew install lsd
whistle: 代理配置软件
brew install whistle
ornpm install -g whistle
mycli: 好用的 MySQL 客户端
brew install mycli
orpip3 install mycli
Quick Look 是 macOS 最方便的功能之一,因为它可以从任何 Finder 窗口立即访问。 只需点击空格键,您就会立即看到当前选择的任何文件的大预览。
brew cask install qlcolorcode qlstephen qlmarkdown quicklook-json qlimagesize webpquicklook qlvideo provisionql quicklookapk --cask
鼠须管是一款 macOS 下的开源输入法,支持拼音、注音、仓颉、五笔等输入方案,它底层是 RIME/中州韵输入法引擎,被誉为神级输入法。
经过配置之后 会很好用
brew install squirrel --cask
我用的配置
我是在1的基础上参考2禁用了英文模式.
用了自动切换输入法的功能, 英文用自带的输入既可. 鼠须管只用做中文输入.
https://blog.csdn.net/lovechris00/article/details/113280758
https://macos-defaults.com/
https://github.com/kevinSuttle/macOS-Defaults <- 这个最全。
1 | # Finder 的退出按钮 |
未完待续
`python`用了好久了, 对它的`import`规则一直都很懵,借此机会梳理下.
导入同目录下的包, 或者安装好的第三方模块, 或者python自带的模块
1 | import module_name |
导入当前目录中某一文件夹里面的python
模块
1 | from dir import module_name |
使用github pages的用户应该都有一个痛点, 就是要本地写好博文后再执行
hexo c
,hexo g
,hexo d
等命令, 特别是当博文数量多了的时候hexo g
就要等待几分钟甚至更长时间,然后在hexo d
甚是烦恼.查了资料, 有了
travis-ci
这个GitHub
的亲兄弟,就容易的多了, 只需3
步配置,就可以享受持续集成自动部署博客的.用户只需要在
markdown
原文上修改,然后push
到github
上去就可以了,
安装github app
申请Personal access tokens
转送门 -> https://github.com/settings/tokens
在这里主要是设置github-token
,让travis
有权限读写github
项目文件
去github
上申请一个就好
点生产新的token
的按钮.申请好后就会出现下面的那个.
我勾选的设置,可以参考
注意私有项目需要用https://travis-ci.com 这个是需要费用的.
用github
账号登录https://travis-ci.org, 在右上角头像出现下拉框里面选择设置,
然后找你博客源码所在项目, (我的项目放在tabris233.github.io
的blog-source
分支下,所以勾选这个项目,然后点后面的Settings
)
先在2
上添加github-token
值用刚刚申请好的哪一个, 后面在构建日志中展示值得选项可勾可不勾. 然后点add
, 然后就会出现在1
的位置.
Ps: 3
是个定时构建, 看个人心情, 随意了.
要在项目根目录建立.travis.yml
文件
其实这个配置文件写的比较烂, https://travis-ci.org对
github\ pages
有一个专门的配置yaml
,我这个算是专门配置加原始配置杂交出来的…
最后三行感觉没啥用,但是没有就是不行…
1 | language: node_js # 指定运行环境 |
修改博文markdown
然后push
上去就行了. 会看到这样的界面
包含构建日志什么的,最后会部署到github pages
的master
分支上
某天我之前的hexo
主题被自己玩坏了, 决定换一个主题,
同时突然想把之前CSDN
博文迁移进来,CSDN这个网站是越来越傻逼了.
最终选择了hexo-theme-matery主题,
但最艰难的博文迁移过程算是完成了,但仍然有很大瑕疵…
之前迁移的版本瑕疵很大,挑了个时间重新爬了一遍, 这次的思路是登录后爬取CSDN
的Markdown
原文。
有了easyHexo这个项目做起来还是很容易的,里面很详细的介绍了hexo
博客的构建部署及主题使用以及配置.
我这里就不在赘述了,只说几个坑吧.
我采用的 hexo-prism-plugin 是一个代码高亮的插件,但是对c++
代码的编写是必须为cpp
不能为 c++
.
之前的文件中存在} }
这样的字符,hexo
渲染的时候就会出现报错
1 | FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html |
以下是新的迁移方法。 这次的思路是登录后爬取
CSDN
的Markdown
原文。
其实没啥好说的, 用这个代码就可以了。
需要注意的是 我爬取的时候发现这个编辑页的链接在变, 这里可能要F12找下最新的。
**https://blog-console-api.csdn.net/v1/editor/getArticle?id={blog_id}**
以下是旧的迁移方法。
我这里有300+
篇博文在csdn
上,所以很难人工迁移,所以选择python
爬虫的方式爬取迁移,
百度一通找了好多爬虫,不是太老了,就是效果不行,
最终我找到了一个能凑合用的脚本,csdn-blog-export
它能够自动爬取博文,并输出markdown
文本或者html
的代码,
但是年代还是过于老了, CSDN
的网站html
结构已经大变,于是进行了魔改,终于可以爬取到信息了,
期间主要是有几个问题
html
机构,> 魔改后可用
hexo
需要的yaml front matter
,> 添加此函数 获得`yaml front matter`>>>> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def getHexoTitleMarkdown(self, detail):
title = '<' + \
html2text.html2text(detail.find(class_='article-title-box').span.prettify()).rstrip('\n') + \
'>' + \
html2text.html2text(detail.find(class_='title-article').prettify()).rstrip('\n')
date = html2text.html2text(detail.find(class_='time').prettify()).replace('\n', '')
date = date[:4] + '-' + date[5:7] + '-' + date[8:10] + ' ' + date[-8:]
tags = detail.find_all(class_='tag-link')
tags = map(deleteURL, map(lambda x: x.replace('\n', ''), map(html2text.html2text, map(lambda x: x.prettify(), tags))))
# print(tags)
tags = ''.join(map(lambda x: ' - ' + x + '\n', map(lambda x: x.replace('=', '').strip(), tags)))
str = u'''---
title: %s
date: %s
description:
toc: true
author: tabris
# 图片推荐使用图床(腾讯云、七牛云、又拍云等)来做图片的路径.如:http://xxx.com/xxx.jpg
img:
# 如果top值为true,则会是首页推荐文章
top: false
# 如果要对文章设置阅读验证密码的话,就可以在设置password的值,该值必须是用SHA256加密后的密码,防止被他人识破
password:
# 本文章是否开启mathjax,且需要在主题的_config.yml文件中也需要开启才行
mathjax: false
summary: 这是你自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要
categories: OJ算法题
tags:
%s
---
''' % (title.replace('\n', '').replace(':', ' '), date.replace(':', ' '), tags.replace(':', ' '))
# print(str)
# exit(0)
return str
爬取得到的markdown
文本格式不是很理想
这个问题并没有解决
最开始查看了这个脚本使用的
html
转markdown
模块(html2text)最后一次维护是2012
年,于是就换了一个新模块html2markdown,可最后发现这个模块的效果还不如html2text, 于是放弃.
最终迁移到了https://blog.tabris.top/categories/OJ算法题/,
迁移脚本在这里csdn2hexo
]]>国内换源加速.
1 | sudo pacman-mirrors -c China |
archlinuxcn源至您的 /etc/pacman.conf
1 | [archlinuxcn] |
1 | sudo cp /etc/apt/sources.list /etc/apt/sources_init.list |
将以前的源备份一下,以防以后可以用的。
1 | sudo gedit /etc/apt/sources.list |
使用gedit打开文档,将下边的阿里源复制进去,然后点击保存关闭。
1 | deb http://mirrors.aliyun.com/ubuntu/ xenial main |
1 | sudo apt-get update |
复损坏的软件包,尝试卸载出错的包,重新安装正确版本的。
1 | sudo apt-get -f install |
1 | sudo apt-get upgrade |
1 | deb http://linux.xidian.edu.cn/mirrors/ubuntu/ xenial main restricted universe multiverse |
1 | deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse |
1 | deb http://mirrors.163.com/ubuntu/ wily main restricted universe multiverse |
pip国内的一些镜像
修改源方法:
临时使用:
可以在使用pip的时候在后面加上-i参数,指定pip源
eg: pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple
永久修改:
linux:
修改 ~/.pip/pip.conf (没有就创建一个), 内容如下:
1 | [global] |
1 | gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/ |
鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决,我使用的是阿里云的镜像加速器: https://oj7znbfj.mirror.aliyuncs.com
新版的 Docker
使用 /etc/docker/daemon.json(Linux)
或者 %programdata%\docker\config\daemon.json(Windows)
来配置 Daemon
。
请在该配置文件中加入(没有该文件的话,请先建一个):
1 | { |
安装node.js后,现在的node.js已经自带了npm工具了,但是国外的源很慢,为了解决这个问题,同时使用cnpm替换npm,我们通过切换源,切换到国内淘宝的源中。下面是我的操作过程。简单记录便于以后自己查看。
查看npm版本
1 | npm -v |
升级npm版本
1 | npm update |
查看npm配置
1 | npm config list |
更换源配置
1 | npm config set registry https://registry.npm.taobao.org |
安装cnpm插件
1 | npm install -g cnpm --registry=https://registry.npm.taobao.org |
安装包测试
docker命令行管理工具使用的dockly
但仍然有缺陷,以后再找找 有没有其他更好用的命令行工具.
教程先看了一遍 B站的尚硅谷教程 有些av号的顺序不对. 看这个就行了.
tabris’s 阿里云镜像加速器: https://oj7znbfj.mirror.aliyuncs.com
命令安装docker
本体
1 | sudo pacman -S docker |
同时建议安装
dockly
作为docker的命令行管理软件.
非root用户运行docker是执行如下命令
1 | sudo usermod -aG docker $USER #your usrname |
执行如下命令启动docker服务
1 | systemctl enable docker |
鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决,我使用的是阿里云的镜像加速器: https://oj7znbfj.mirror.aliyuncs.com
新版的 Docker
使用 /etc/docker/daemon.json(Linux)
或者 %programdata%\docker\config\daemon.json(Windows)
来配置 Daemon
。
请在该配置文件中加入(没有该文件的话,请先建一个):
1 | { |
Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
所有的 Unix Like 系统都会内建 vi 文本编辑器,其他的文本编辑器则不一定会存在。
但是目前我们使用比较多的是 vim 编辑器。
vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。
vim主要有以下几个优点.
同时现今很多开源软件(ranger,lazygit)采用的快捷键都与vim类似.学习vim变得很有必要.
但我这里采用的是neovim
NeoVim 旨在成为Vim的升级版,有不少对它的介绍,我就不赘述了。NeoVim官网强调了它的四大特点:
了解的还不是很详细, 暂时以我自己的配置介绍
1 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
参考 https://www.jianshu.com/p/0c83e6aed270
每安装一个插件最好都要去github官网看下,顺便看看文档, 会让你安装的插件用起来更顺手.
现在流行的有这几种插件管理器,VBunle
,NeoBunle
,vim-plug
, 我这里采用的是vim-plug
.
neovim下安装命令
1 | curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs \ |
vim下安装命令
1 | curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ |
要安装插件,你必须如下所示首先在 Vim 配置文件中声明它们。一般 Vim 的配置文件是 ~/.vimrc
,Neovim 的配置文件是 ~/.config/nvim/init.vim
。请记住,当你在配置文件中声明插件时,列表应该以 call plug#begin(PLUGIN_DIRECTORY)
开始,并以 plug#end()
结束。
例如,我们安装 “lightline.vim” 插件。为此,请在 ~/.vimrc
的顶部添加以下行。
1 | call plug#begin('~/.vim/plugged') |
在 vim 配置文件中添加上面的行后,通过输入以下命令重新加载::source ~/.vimrc
或者,只需重新加载 Vim 编辑器。
现在,打开 vim 编辑器:$ vim
使用以下命令检查状态::PlugStatus
然后输入下面的命令,然后按回车键安装之前在配置文件中声明的插件。:PlugInstall
要更新插件,请运行:
1 | :PlugUpdate |
更新插件后,按下 d
查看更改。或者,你可以之后输入 :PlugDiff
。
有时,更新的插件可能有新的 bug 或无法正常工作。要解决这个问题,你可以简单地回滚有问题的插件。输入 :PlugDiff
命令,然后按回车键查看上次 :PlugUpdate
的更改,并在每个段落上按 X
将每个插件回滚到更新前的前一个状态。
删除一个插件删除或注释掉你以前在你的 vim 配置文件中添加的 plug
命令。然后,运行 :source ~/.vimrc
或重启 Vim 编辑器。最后,运行以下命令卸载插件::PlugClean
该命令将删除 vim 配置文件中所有未声明的插件。
要升级vim-plug本身,请输入::PlugUpgrade
如你所见,使用 Vim-plug 管理插件并不难。它简化了插件管理。现在去找出你最喜欢的插件并使用 Vim-plug 来安装它们。
插件这个东西,少即是多,运行速度会更快
Plug 'yianwillis/vimcdoc'
vim要有python支持,如果没有需要输入pip install neovim
命令安装neovim的python支持模块.
Plug 'Valloric/YouCompleteMe'
上面的插件对C++的支持是很强大的但是在麻烦.后来改用deoplete
了
1 | Plug 'shougo/unite.vim' " deoplete依赖 |
1 | Plug 'tpope/vim-fugitive' " git plugin |
1 Plug 'shougo/vimfiler.vim' " file explorer 这个项目已经不维护了
现在采用shougo/defx.nvim
这个插件
1 | if has('nvim') |
defx 没有提供默认的键盘映射,所以需要自己进行设置
1 | " 这是我的配置. 参考文档种的配置做的修改. 还需完善 |
1 | Plug 'majutsushi/tagbar' "浏览tag |
1 | Plug 'mhinz/vim-startify' "start page |
Plug 'icymind/NeoSolarized' "主题
状态栏能显示当前的状态,还是有不少用处的,好看的状态栏就是为了美观,毕竟谁也不喜欢对着个难看的东西吧。
这里使用的是 airline :
1 | Plug 'vim-airline/vim-airline' "状态栏工具 |
1 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
这是我自己的neovim配置
https://github.com/tabris233/config/blob/master/neovim/init.vim
]]>学习下设计模式
参考菜鸟教程
但其实菜鸟教程介绍的比较简略,还是要参考下其他
1、开闭原则(Open Close Principle)
开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3、依赖倒转原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。
5、迪米特法则,又称最少知道原则(Demeter Principle)
最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
下面例子中鼠标,键盘,耳麦为产品,惠普,戴尔为工厂。
简单工厂模式不是 23 种里的一种,简而言之,就是有一个专门生产某个产品的类。
比如下图中的鼠标工厂,专业生产鼠标,给参数 0,生产戴尔鼠标,给参数 1,生产惠普鼠标。
工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。
戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。
生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。
后续直接调用鼠标工厂.生产鼠标()即可
抽象工厂模式也就是不仅生产鼠标,同时生产键盘。
也就是 PC 厂商是个父类,有生产鼠标,生产键盘两个接口。
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
创建工厂时,由戴尔工厂创建。
后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。
在抽象工厂模式中,假设我们需要增加一个工厂
假设我们增加华硕工厂,则我们需要增加华硕工厂,和戴尔工厂一样,继承 PC 厂商。
之后创建华硕鼠标,继承鼠标类。创建华硕键盘,继承键盘类即可。
在抽象工厂模式中,假设我们需要增加一个产品
假设我们增加耳麦这个产品,则首先我们需要增加耳麦这个父类,再加上戴尔耳麦,惠普耳麦这两个子类。
之后在PC厂商这个父类中,增加生产耳麦的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳麦,惠普耳麦的功能。 以上。
]]>manjaro 真好用 arch 再见!
推荐manjaro-deepin 对中文的支持比较好
桌面环境真的是个大坑啊
现在觉得折腾确实挺有趣的, 但以后有机会还是配一个mbp吧, linux的桌面环境是真的烦人…aur和稳定的桌面环境感觉还是后者比较重要.
争取能做出来一个安装+部署配置的脚本
记录一下从0开始玩linux的经历
其实之前已经有了一点ubuntu的使用经验 但是很浅
Arch 作为’最难’安装的linux系统 通过它可以更好的了解linux
这里是VMware安装的Arch虚拟机
配置和美化Arch Linux
这里参考
注意引导方式建议使用rEFInd 代替教程里采用的grub
如果进入不了[root@archiso ]
是物理机安装时 u盘的卷标不是`ARCH_20XXYY
1 | # useradd -m -G wheel <username> (请自行替换username为你的用户名) |
1 | systemctl enable dhcpcd |
1 | pacman -Syy net-tools |
装完archlinux,因为时区的问题,时间总是比实际快了8个小时,找了各种办法,最终使用了openNTPD的方法
设置时区:sudo ln sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
安装openNTPD:sudo pacman -S openntpd
重启openNTPD:systemctl restart openntpd
设置开机启动:systemctl enable openntpd
安装ssh
1 | # pacman -Syy openssh |
启动服务
1 | # systemctl start sshd |
开机启动
1 | # systemctl enable sshd.service |
1 | sudo pacman-mirrors -c China |
archlinuxcn源至您的 /etc/pacman.conf
1 | [archlinuxcn] |
yay 是下一个最好的 AUR 助手。它使用 Go 语言写成,宗旨是提供最少化用户输入的 pacman
界面、yaourt 式的搜索,而几乎没有任何依赖软件。
yay 的特性:
yay
提供 AUR 表格补全,并且从 ABS 或 AUR 下载 PKGBUILDyay
的二进制文件除了 pacman
以外别无依赖/etc/pacman.conf
文件配置中启用了色彩时支持色彩输出yay
可被配置成只支持 AUR 或者 repo 里的软件包安装 yay:
现在yay已经添加到官方源中
sudo pacman -S yay
electron-ssr : GUI的界面的ssr.很好用
[参考ArchWiki](https://wiki.archlinux.org/index.php/Font_Configuration/Chinese_(简体中文)
1 | yay -S ttf-ms-fonts ttf-roboto noto-fonts noto-fonts-cjk adobe-source-han-sans-cn-fonts adobe-source-han-serif-cn-fonts ttf-dejavu |
添加配置文件,~/.config/fontconfig/fonts.conf
or /etc/fonts/local.conf
linux 强大的命令行操作,使效率倍增,所以配置好命令行,并安装实用命令行软件是必要的
1 | sudo pacman -S zsh zsh-completions |
curl 和 git 应该已被安装(若没有Arch 用sudo pacman -S curl git 安装,其他发行版类似。)
Oh-my-zsh是一个傻瓜化的zsh配置管理框架,提供了大量实用的功能,主题等。做到开箱即用,现在基本成为了Zsh的标配。
安装
1 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" |
配置文件位置: ~/.zshrc
主题oh-my-zsh
自带大量Themes,默认为robbyrussell
。你也可以选择random
,即每次打开终端随机选一个主题。
ZSH_THEME=”你喜欢的主题名”
常用插件
git: 提供大量git的Aliases,详情
archlinux: 提供一些pacman包管理器的Aliases,详情
z:经常使用cd 切换路径,积累一定数据后可用z快速跳转到指定位置
sudo:按两次[Esc]自动在前面加sudo
pip: 补全pip 命令
zsh-autosuggestions: 根据历史记录进行智能提示(按 ctrl+E 是正确姿势)。非oh-my-zsh自带,用git下载安装
1 | git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions |
zsh-syntax-highlighting:命令高亮,正确显示绿色,错误为红色。非oh-my-zsh自带,用git下载安装
1 | git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting |
plugins=( 你想启用的插件,空格分隔 )
重新加载配置文件,立刻生效。
source ~/.zshrc
其他插件请参见官方wiki
少即是多,启用大量插件会严重拖慢zsh启动速度
我这里采用的是agnoster
主题
为在使用tmux时不重复显示whoami@whereami
做两处修改
/etc/profile
中添加环境变量1 | DEFAULT_USER=$USER |
agnoster
主题文件91行中做如下修改1 | - if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT"]]; then |
安装tmux
1 | sudo pacman -S tmux |
在这里配置tmux
https://github.com/gpakosz/.tmux 这个简单好看,且对true color支持很好, .tmux.conf.local
配置文件很方便
为 vim + tmux 开启真彩色(true color)
FAQ:
tmux 嵌套使用的话,如何将 tmux 命令发送到嵌套内的会话窗口?转载自
很常见的例子是,在本地用 tmux 登陆远程服务器,服务器上又使用了 tmux。问题是,在这种情况下,tmux 指令被外层会话窗口捕获(本地 tmux),根本无法控制服务器上运行的 tmux。例如,想退出服务器上的会话,ctrl + b, d, 结果退出的是本地 tmux 连接, sh*t。
介绍一个简单方法:按着 ctrl,点击两次 b 键,这样发出的 tmux 指令就是发送到内层窗口会话!如此简单!
neovim属于vim的加强版 功能更加强大
注意的是启动neovim的命令式nvim
而不是neovim
同时安装 nerd-fonts
如果安装spacevim 则不需要手动安装nerd-fonts
一个定制化的vim配置,支持vim,neovim
初学的时候可以使用这个省事儿些,但是后面学习使用vim最好采用自己的配置,按需添加插件配置.
检查当前是否为256/真色参考本篇文章
我这里的xshell只能支持256色
这时xshell中只有在tmux下spacevim才能显示256色,不支持真色
在.zshrc文件头添加
1 | sh /${.zshrc的目录}/.change_term.sh |
.change_term.sh文件内容如下
1 | echo "before: $TERM" |
glances: 代替htop的资源监控工具
ranger: ranger是一个以GPL许可证发放源码,默认使用VIM风格键盘绑定、curses图形库,基于字符终端的文件管理器,是自由免费软件。
tig: git的命令行管理软件
dockly: docker的命令行管理软件,ranger就可以显示docker容器运行状况,轻量使用就没必要用它了
wtfutil: 基于 Terminal 的个人 dashboard 实用程序,专为显示不常用的但非常重要的日常数据而设计
JetBrains ToolBox: JB全家桶,管理Clion,IDEA,PyCharm项目
code::blocks
vscode:
Typora: markdown编辑器
Yakuake: 悬挂式命令行,很方便
termite:
alacrity: 一个GPU渲染的终端工具,感觉现在比较火,但是个人还没怎么用过,不过还是推荐一下
GitKraken: git的图形化管理软件
网易云音乐
google-chrome
deepin.com.qq.office: tim
deepin-wechat: 微信
wine程序字体dpi太小导致视觉观感很难受
调整DPI字体
1,先退出deepin-tim或deepin-qq,否则会提示错误。
2,运行env WINEPREFIX=“$HOME/.deepinwine/Deepin-TIM” winecfg(如果是修改QQ界面字体大小,就把Deepin-TIM改成Deepin-QQ),然后将屏幕分辨率拖放到合适的大小(一般120就可以了)。
gitter:
telegram:
docker
virtualbox
albert: linux下的启动器
如果安装manjaro 就不需要手动安装这些了
1 | # lspci | grep VGA # 确定显卡型号 |
所有桌面环境都需要依赖xorg。所以先要安装xorg组。
1 | pacman -S xorg |
输入命令之后首先会询问要安装xorg组下的哪些包,选择全部。然后对于libgl包有个四个不同的实现,选择mesa-libgl。
然后再安装xorg-xinit和xterm:
1 | pacman -S xorg-xinit xterm |
安装完成之后就可以使用startx命令启动xorg的简易界面了。进入成功的话会显示出几个简陋的窗口。然后按Ctrl+D就可以退出了。
安装xfce4桌面和附带的软件包:
1 | pacman -S xfce4 xfce4-goodies |
详细安装和配置看arch-wiki-lighdm
我没有通过startx的方式启动桌面环境,而是使用了登录管理器lightdm
安装:
1 | pacman -S lightdm lightdm-gtk-greeter |
其配置文件为:
/etc/lightdm/lightdm.conf
安装好之后测试启动:
1 | systemctl start lightdm.service1 |
如果正常就会看到熟悉的登录界面了,不过不要登录,现在只是测试lightdm是否可以正常启动
点击画面上的关机小图标,弹出关机对话,选择注销!
注销之后就回到之前的tty命令行模式了,可以看到相关的启动信息
一切正常,所以设置lightdm为开机自动启动,这样以后开机就不会出现tty命令行界面了,而是直接进入登录界面:
1 | systemctl enable lightdm.service |
之后你可以重启进入xfce4图形界面,然后在图形界面中使用终端来继续以下配置步骤,也可以不重启,直接继续
进入xfce4图形界面的命令为startxfce4
好好干活,美化个屁.
]]>在这里记录一下我的毕业设计
链接在GitHub上
md 写个p 面向cv编程就完了
]]>由于hexo的markdown的引擎太烂了 这里的格式会乱点
有时间在换一个好一点的引擎 太乱了!!
移步这里格式好看的正则表达式手册
字符 | 描述 |
---|---|
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n ”匹配字符“n ”。“\n ”匹配一个换行符。串行“\ ”匹配“\ ”而“( ”则匹配“( ”。 |
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n ”或“\r ”之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n ”或“\r ”之前的位置。 |
匹配前面的子表达式零次或多次。例如,zo能匹配“z ”以及“zoo ”。等价于{0,}。 | |
+ | 匹配前面的子表达式一次或多次。例如,“zo+ ”能匹配“zo ”以及“zoo ”,但不能匹配“z ”。+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)? ”可以匹配“does ”或“does ”中的“do ”。?等价于{0,1}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2} ”不能匹配“Bob ”中的“o ”,但是能匹配“food ”中的两个o。 |
{n,} | n是一个非负整数。至少匹配n次。例如,“o{2,} ”不能匹配“Bob ”中的“o ”,但能匹配“foooood ”中的所有o。“o{1,} ”等价于“o+ ”。“o{0,} ”则等价于“o ”。 |
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3} ”将匹配“fooooood ”中的前三个o。“o{0,1} ”等价于“o? ”。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo ”,“o+? ”将匹配单个“o ”,而“o+ ”将匹配所有“o ”。 |
. | 匹配除“\``n ”之外的任何单个字符。要匹配包括“\``n ”在内的任何字符,请使用像“`(. |
(pattern) | 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“( ”或“) ”。 |
(?:pattern) | 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“`( |
(?=pattern) | 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“`Windows(?=95 |
(?!pattern) | 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“`Windows(?!95 |
(?<=pattern) | 反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“`(?<=95 |
(?<!pattern) | 反向否定预查,与正向否定预查类拟,只是方向相反。例如“`(?<!95 |
x|y | 匹配x或y。例如,“`z |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc] ”可以匹配“plain ”中的“a ”。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc] ”可以匹配“plain ”中的“p ”。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z] ”可以匹配“a ”到“z ”范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z] ”可以匹配任何不在“a ”到“z ”范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b ”可以匹配“never ”中的“er ”,但不能匹配“verb ”中的“er ”。 |
\B | 匹配非单词边界。“er\B ”能匹配“verb ”中的“er ”,但不能匹配“never ”中的“er ”。 |
\cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c ”字符。 |
\d | 匹配一个数字字符。等价于[0-9]。 |
\D | 匹配一个非数字字符。等价于[^0-9]。 |
\f | 匹配一个换页符。等价于\x0c和\cL。 |
\n | 匹配一个换行符。等价于\x0a和\cJ。 |
\r | 匹配一个回车符。等价于\x0d和\cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于\x09和\cI。 |
\v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
\w | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9*]* ”。 |
\W | 匹配任何非单词字符。等价于“[^A-Za-z0-9] ”。 |
\xn | 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41 ”匹配“A ”。“\x041 ”则等价于“\x04&1 ”。正则表达式中可以使用ASCII编码。. |
\num | 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1 ”匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。 |
\nml | 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
\un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。 |
用户名 | /^[a-z0-9*-]{3,16}$/ |
密码 | /^[a-z0-9-]{6,18}$/ |
十六进制值 | /^#?([a-f0-9]{6}\|[a-f0-9]{3})$/ |
电子邮箱 | /^([a-z0-9*.-]+)@([\da-z.-]+).([a-z.]{2,6})$/ /^[a-z\d]+(.[a-z\d]+)@(\da-z?)+(.{1,2}[a-z]+)+$/ *` |
URL | /^(https?:\/\/)?([\da-z.-]+).([a-z.]{2,6})([\/\w .-])*\/?$/ *` |
IP 地址 | /((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ |
HTML 标签 | /^<([a-z]+)([^<]+)(?:>(.*)<\/\1>|\s+\/>)$/ |
删除代码\注释 | (?<!http:|\S)//.$ |
Unicode编码中的汉字范围 | /^[\u2E80-\u9FFF]+$/ |
于是乎 过来补补基础
一直在Hackerrank上面做Python的题目.知识点覆盖挺全面的,推荐一波.
1 | '1','2'] n,m,*l = [ |
集合是一个无序的,不重复的数据组合,它的主要作用如下:
去重,把一个列表变成集合,就自动去重了
关系测试,测试两组数据之前的交集、差集、并集等关系
1 |
|
将需要排序的字符集放到一个字符串中
在这个字符串中越靠前的字符排序后越靠前
1 | order = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1357902468' |
1 | N, M = map(int, input().split()) # N行 M列 |
1 | import string |
1 | >>> s = 'abcde' |
个人喜欢最新的'{}'.format()
的形式,不仅写起来更方便一些,还有旧方法不能实现的操作.感觉以后可能完全取缔旧的方法.
输出一行 ‘-’
1 | '{:-{align}{width} }'.format( '',align='>', width = 5) |
输出
1 | ----- |
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
python 函数的参数传递:
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
eval(string) 对于一个字符串,相当与运行这个字符串所代表的python代码
1 | 1 x = |
导入库
1 | import 库 #使用时需要 `库.函数()` |
1 | import collections |
计数用的函数
可以简单理解为一个map,
1 | a = defaultdict([Type of value]) |
1 | from collections import deque |
1 | ''' |
总结下所有的面试, 这样才能慢慢进步呀,
除了问一个多态,没有技术问题,大概是给答上了 意思对,但不专业
小公司估计是真的没人了,待遇实在…拒绝
可能是紧张吧,开始闲聊然后给了个编程题
给一个化学表达式
1 | eg: HMg_{_2}(H_2O(N_3Ag)_2)_3N_2 |
,让算每个元素有多少个.
这种题本就不难 问题就是怎么处理括号
之前在hiho上还遇到过类似的问题http://www.hihocoder.com/contest/offers41/problem/2
然后不知道紧张还是什么的就写的很乱,然后面试官提示递归,然后墨迹了好久才用stack写了下来…
因为我没有项目,就没有问项目.
然后问我们学了数据库,操作系统,网络没有, 嗯 学校确实讲过,但我没听过课…
问了个进程调度,
我就知道有个算法叫FIFO, 具体是啥还忘了, 然后说错了,GG
然后唠了两句面试官说结束,等HR通知, 嗯.感谢面试官浪费40+分钟陪我 hhhh.
总结:
有点紧张. 代码能力差 ,[数据库,操作系统,网络] 知识严重匮乏.
之前看面经说,遇到不会的或者把不准的都应该说不会. 下次注意.
达内这个大家都懂.
突然有天接到达内一个经理的电话,问我能不能去当助教,去教小朋友普及组的NOIP.
我心想,这也还不错呀.
然后去了,开始跟我吹了1个小时的牛逼,达内多么多么牛逼.怎么怎么地.
然后给了我一份NOIP普及组的题让我做…
说来惭愧,中文题面,我竟读错一道题卡了好久,然后花了1个多小时终于把4个题做出来了,最后一题还做得很麻烦…
然后来了一个小伙子,谈了谈对NOIP的认识,以及我的学习情况.
交上去给了一个小姐姐,然后看见三个人对着电脑看了半天…
然后说一定要一年,但我最多只能半年,于是据.
体验美滋滋,没有麻烦的题目,没有操作系统,没有计算机网络,没有数据库.真棒 hhh
深圳打来的电话, 不知道哪里人, 浓重的方言口音, 他说话我都要问好多遍才能听懂…交流真滴有障碍…
一共22分钟,三个问题
1 . 两个字符串,一个大串,一个小串,问小串是不是大串的子串(不连续)的.
我回答了: 遍历大串,然后对小串维护一个遍历的指针就行了
然后他说不是他想要的,问的是正则?
我记得有正则查询可以模糊匹配,只要在两个相邻的字母中插进去就好了,但我忘记了具体插什么,
结束后一查知道是 .*
[. 匹配任意非\n的字符 *是0个或多个]
2 . 给一个100万的字符串,然后找到最短的循环覆盖的子串.
我开始以为是ABCABC这样的 最短就是ABC了 ,拿next数组直接做就行了,
然后说了半天,最后知道,他说的可以是这样ABCABCAB,还可以是ABC
想了想发现和之前的一样, 还是求next数组,然后就可以把结尾的AB给去掉了,然后就和之前一样了.
然后不知怎么就陷入了一阵交流障碍,我不知道他说的啥,他不知道我说的啥.
然后我发现他是想让我说一下next怎么求…
想了想,不能画图 怎么说呀, 问写代码行吗, 额 他也看不见…
然后勉强解释了下 维护两个指针,一个i遍历大串,j是维护匹配到的位置,balabala的,
也不知道他明白没有…
然后他问我用linux还是windows多,
我说用过linux,但还是windows多.
然后问我一个问题,我听成了python… 我说我会python…但他好像问的根本不是这个问题,
3 . 最后问我进程的内存分布
我不会呀…
说了一个堆栈…就说不知道了,
于是结束…
目测GG
总结: 说好的12点,结果15点电话过来了,措手不及,以为没我事儿了呢,
交流障碍导致前面两个问题说的不太好,而且电话面试真的不如视频面试呀,更别说现场面试了,后面确实不会, 操作系统,网络,数据库 多看看呀…
redis和MongoDB的区别。 谈一谈这两个数据库 。 (他以为我是自己搭建的数据库,,但我就是安装然后用的呀)
说一下大数据: hadoop - HDFS,hive 和 MapReduce ,问哪个是存储的,脑抽说了个hive,,, 后来改正了,然后问HDFS里面都有什么,答NameNode 和 DataNode,
问我还有什么,我不知道,他告诉我还有sdk。
然后让我说竞赛中做过的经典,印象深刻的题目,想了好久,随便说了一个题,题目不怎么难,其实说的很模糊,而且说的时候还把那个题给弱化了,,记不太清那个题目了,
然后问了我一个问题,现在都没想明白,说HDFS传3个副本,然后又客户在另一端访问这个。 然后是传完这三个副本告诉客户传完了有一个延迟时间,这两个副本告诉客户传完了有一个延迟时间,,
两个的会比三个的地低,
然后给初问题,给一个T,求N,M。 T是客户允许的最长延迟时间,N是副本总数,M是传完M个告诉客户传完了。
我只知道可以通过传好多次 算一个副本的时间t,但是不会算大T, 跟概率,期望,有关
最后让写了一个编程题,很简单的n个区间 问覆盖的长度总和是多少。 谈了50多分种 脑子有点蒙,写了好几分钟。。 但他看了好长时间,难道是我写的错啦??。。
然后问了面试官几个问题,
大数据如何高效学习,论文,跟进
分布式如何学习,
他们这个是做底层的,,,
然后就是如果通过了 下次面试是什么时候,,,,但估计没有下次了,,,,,
虽然啥都不会,什么都没有答上来。 体验非常好的一次面试,面试官人特别好,面对我这样的垃圾面试人员,应该很无奈,但依然很耐心的面试我,最后还提了好多问题。
但是很奇怪,这次竟然一点操作系统和数据结构的问题都没有问, 之前看到牛客网一个基础平台研发,问了这些问题的呀。
1面
自我介绍,没准备,随便说了下
唠了两句家常.
绳子不均匀,燃烧的问题,一根绳子1个小时烧完.
怎么找30分钟,75分钟.
说下栈和队列
双栈怎么实现队列
计算机网络的几个零碎的小问题,没记住.
然后写了两个代码题
数据库索引怎么实现的 -> b+树
b+树为什么会快 -> 搜索树,有剪枝
非**和**的区别 -> 不知道,没听说过 (告诉我是 index 和 index+data的区别,名字想不起来了)
数据库事务的四个特性ACID -> 我分不清那个是哪个了,就举个例子说了,
还有两个数据库的问题,想不起来了,
问问题,问了技术栈和分布式的东西.
2面
领我进去的小哥哥说是总监面
自我介绍.唠家常.
两个集合求交,写代码 谢了归并排序+二分, 然后过了会说了个更简单的方法,
几个小问题,没记住
给我写了几个词,让我谈一谈
聊了聊最近在学习什么.说我基础薄弱…
问问题. 问了职业规划.答:选择做技术就一直做技术.
可能因为是小公司吧,问的问题都比较简单.算法为了体现水平,学习了网上的套路,先给出一个不是很好的做法,然后再给一个优秀的做法.[斜眼笑]
走的时候小哥哥看了看评价表和我说不错,应该很稳,让我回去等消息就行啦.
面试官都很随和,出去的时候和一个工大研一的同来面试的小哥哥聊天才知道那个总监挺牛逼的.
一面直接给了一个问题,
S_0 = {1}
S_0 = {1,2,1}
…
S_n = S_{n-1},n+1,S_{n-1}
问: 1. |S_n| 开始嘴飘,想当然的就说了,后来说对了 2^{n+1}-1
然后让我证明, 不会证,
2. 让实现一个函数int get_value(int n,int i) ,S_n的第i个元素,从0开始,,,, 然后我写了一个从1开始的,就被嘲讽了,,,然后一个变量打错,被指漏洞百出... 准备说的最优解还没有开始,就不理我了, (第i个数就是0~2^{n+1}-1的第i个数二进制小的最后一个一的长度,或者理解为lowbit(i)的二进制长度)
然后有趣,hr给我打电话,委婉的告诉我挂了,然后突然来了二面,
好吧,二面,啥都不会呀 …
开始看了我一面写的代码,说风格太老了,现在C11已经不这么写了,
然后问我平时用的数据结构是stl的还是C11的,讲道理我只知道STL的,不知道c11有什么数据结构,难道是传说中的那个能重写pushup,pushdown的内个??
谈了谈我用到的那些数据结构,说我只用过基础的数据结构,
然后让说了一下vector的实现,我就说了一下仅了解的它为什么能像数组那个用,
然后问一堆c11的问题,动态指针什么的,不会
其中夹杂着问
问会计组么,tm不会呀,说你问吧,我试试
问了int是反码还是补码,隐隐约约记得是补码,磨磨唧唧说了,
问socket编程, 不会, 没接触过.
问多线程编程, 我说接触过一点点, 只写过多线程循环打印的.
1 | class Test{ |
让我写一个函数验证机器的大小端 表示不知道大小端是什么,
1 | int main(){ |
class 和 struct的区别, 只知道class默认是private,struct默认是public, 问我还有什么 不知道
问我sizeof(一个指针)是多少,不知道,叨咕了一个8,然后他告诉我32位机器是4,64位机器是8;
给了一个代码
1 | void test(int *p){ |
问p改没改变
蒙的改变, p指向了新开辟的那个地址.
编程题,大数加法,不让用char a[],只让用string… 写的稍墨迹
然后问string += 和 +的区别
就是 a+=b 和a=a+b
表示没看过string源码,也不了解string咋实现的,类比vector说了一下. 又错了
问数据库, 我说了解的不是很深入, 然后就没问. (其实以后应该说,试一试,)
然后就问问题,唠家常了,
最后再见,
结果在一个小时之内,听到了两次同一个hr小姐姐的拒绝电话,
体验是真几把刺激,面挂了一面还面了第二面,hhhh,于是二面的时候就很懵逼,
但是确实啥都不会呀…
总结就是多学习吧.
但是有个大失误,问计网,操作系统,数据库的时候,应该说试一下的,毕竟还是看了一些的呀,多少还是能答上来一点的,
开始自我介绍,聊了聊最近看什么数,还有数据库啥的
十分钟过后,跟我说只要Java, 不合适, 嗯 ,然后88
傻逼美团,怎么筛选的简历,岗位要求上不是写的4中语言之一吗,而且不准备培养实习生的吗,还听说之前实习生一个转正的都没有??!
自我介绍
多线程
内联函数和宏函数
python闭包
socket编程
函数内的malloc 存在哪里
内联函数
右值引用
进程间通信
连续子序列最大和
vector
set 和 map的底层数据结构
hash冲突解决
内存泄漏解决
C++调用函数
虚析构函数
一个文本相同的行去除, 保留第一个 (内存存的下/存不下)
还有问题 记不起来了
表现很差呀, 算法也没有问,代码都没让写,,,
自我介绍,
闲聊
介绍了ACM比赛
最近在干什么
技术上的问了
网络编程接触过没 ->没接触过
数据一致性怎么保证 -> 不会
两个文件都是100W个整数,找出相同的 -> 排序,然后归并的过程
进程间通信 并举例说出场景 -> 管道不知道,剩下三个举例了,
说说STL -> 说了下vector怎么保证可变长度而且复杂度还是O(1),map和set都是红黑树啥啥啥的
new/delete 和malloc/free的区别 -> 说没怎么用过后者,一直用前者,因为后者长.面试官笑…然后说了几个new/delete使用的时候需要注意的问题.
谈到指针,问多线程删除map元素怎么办 -> 先回答把多个线程要删除的记下来,然后统一删除, 他说可以, 但是希望我在指针的方式考虑, 想了想不会, 他让我回去看下map的源码关于元素删除的部分, 看过之后会有想法.
多线程有什么了解 -> 说了下ABC循环打印的那个, 然后就没有了
高并发怎么处理, -> 读的不加锁,写的加锁
接上个问我脏读怎么办 -> 我说加个时间戳,他说不太好,然后不会了
对安全了解多少 -> 把只会的凯撒加密和RSA加密说了说
对称加密和非对称加密 -> 忘记了,说不太清了,告诉他不强答
C++的封装/继承/多态-> 说了说多态和继承,封装我觉得没啥说的呀,
还有几个问题,忘了
非技术问题
说给我安排一个任务,一周上线,这个任务我现在不会,怎么办 -> 我觉得时间够用,没有问题,2天时间学习,3天时间实现, 具体实施的时候先请教别人,翻论文
如果我现在时间很紧的赶一个任务,有人请教我会的东西,我怎么做 -> 甩给他相关的资料让他自己学习, 如果还不懂,粗浅的指点一下 还不懂,就对不起了,(这个很坑呀,步步紧逼)
问问题
就问了怎么学习linux,
之前准备问的问题,都忘记问了
面试官挺随和的, 开始挺紧张的 ,后来就不紧张了, 现场面试还是比电面/视频面舒服.
过程就像实在闲聊
还是什么都不会, 面试官让我把学习重心放在网络编程和安全这方面,说用到的多,学习的时候多看看源码.
问的和一面差不多,
多问了几个小问题而已
数据库的东西问了很多, 但不会
然后和一面有重复的问题,但是昨天回去查了下,答得比较完整
Hash处理冲突,解决办法
内存泄露的时候如何定位 -> 说调用系统的函数监控内存
内存分布 -> 有一个忘记了,其他的说的没问题
进程调度算法 -> 先到先服务 , 短作业优先, 多级反馈队列
接上个问现在系统的调度算法 -> 在提示说同时能音乐,处理网页这些 想起来时间片轮转算法,说了些,
std::sort()怎么实现的 -> 内省排序,
接上个std::sort()什么时候采用插入排序,归并排序,快排 -> 举了什么时候插排会更快, 和归并是为了防止快排退化 balabala
剩下的暂时想不起来了,
面试官看起来挺年轻的, 数据库东西确实不太会, 而且又没让写代码, 以为凉凉了,
5点多接到明天hr面的消息,
就两个问题
一个拓扑排序,拓扑序计数,
一个二分check的问题
开始网站打不开,只写了第二个的代码
然后就问我最近学什么, 以后的方向什么的 聊了好久
问了几个问题就结束了
感觉不错,面试官说重视的就是coding能力,其他的都可以在学,
等消息智障,问面试官需要什么样的人才,说我这样的,一周后问面试官,说挂了
刚面完腾讯的hr面回来到实验室扯了两句,就收到面试了
给了个写代码的网页死活打不开,然后就改手写发照片了
写了一个矩阵,一层一层输出的代码
然后说了C++的stl
vector的变长机制
平衡树
tcp的三次握手,四次挥手,为什么三次,为什么四次
网络分层,说了下osi的七层
问tcp在那层,不知道,猜了个网络层,然后面试官问tcp的t是什么,想起是transfer,说出了传输层
然后还有几个问题,忘了
面试官挺nice的
感觉效率很高 上午面完下午5点就来二面了,
面向对象编程谈谈
C++ stl
内存分布
网络的那几个老生常谈的问题
进程间通信
数据库谈了谈
一个linux 操作的问题,不会
还有几个问题 忘了
因为一二面是周五 周一去考科四的时候来的电话
瞎聊天 结束
]]>记录下我针对面试的学习
噗 , 被高大上的名字给吓到了,其实就是简单的C语言入门题.
问题: 两个数组 A 表示一串螺丝 B 表示一串螺帽 螺丝和螺帽能够配对,但是A中螺丝之间不能比较大小,B中螺帽之间也不能比较大小,螺丝和螺帽可以比较大小,返回所有螺丝和螺帽的对应关系,要求复杂度小于O(n^2)
解: 类似快速排序,一个和另一个比较就可以了.
code
https://www.nowcoder.com/test/8537140/summary
一个进程是PCB结构与程序与数据的组合
互斥条件: 即某个资源在一段时间内只能由一个进程占有,不能同事被两个或两个以上的进程占有.这种独占资源如CD-ROM驱动器,打印机等等,必须在占有该资源的进程主动释放它之后,其他进程才能占有该资源.这是有资源本身的属性所决定的.如独木桥就是一种独占资源,两方的人不能同时过桥.
不可抢占条件: 进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者中夺取资源.而只能由该资源的占有者进程自行释放.如过独木桥的人自己不能强迫对方后退,也不能非法地将对方退下桥,必须是桥上的人自己过桥后空出桥面(即主动释放占有资源),对方的人才能过桥.
占有且申请条件: 进程至少已经占有一个资源,但又申请新的资源; 由于该资源已经被另外进程占有,此时该进程阻塞; 但是,它在等待新资源之时,扔继续占用已占有的资源.还以过独木桥为例,甲乙两人在桥上相遇. 甲走过一段桥面(即占有了一些资源),还需要走其余的桥面(申请新的资源),但那部分桥面被已占有(已走过一段桥面).甲过不去,前进不能,又不后退;乙也处于同样的状况.
循环等待条件: 存在一个进程等待序列{P1,P2, … ,Pn}, 其中P1等待P2所占有的某一资源, P2等待P3所占有的某一源, … ,而Pn等待P1所占有的某一资源形成一个进程循环等待环.就像前面的过独木桥问题,甲等待乙占有的桥面,而乙有等待甲占有的桥面, 从而彼此循环等待.
打破互斥条件: 即允许进程同事访问某些资源.但是,有的资源不允许被同时访问的,像打印机等等.这是由资源本身的属性所决定的. 所以,这种办法并无实用价值
打破不可抢占条件: 即允许进程强行从占有者哪里夺取某些资源. 就是说, 当一个进程已占有了某些资源,他又申请新的资源,但不能立即被满足,它必须释放所占有的全部资源, 以后再重新申请. 他所释放的资源可以分配给其他进程.这就相当于该进程占有的资源被隐蔽性地强占了. 这种预防死锁的方法实现起来困难,会降低系统性能.
打破占有且申请条件: 可以实行资源预先分配策略. 即进程在运行前一次地向系统申请它所需要的全部资源. 如果某个进程所需的全部资源得不到满足,则不分配任何资源,此进程在不运行.只有当系统能够满足当前进程的全部资源需求时,才一次性地将所申请的资源全部分配给该进程. 由于运行的进程已占有它所需要的全部资源所以不会发生占有资源有申请资源的现象, 因此不会发生死锁. 但是,这种策略也有如下缺点:
打破循环等待条件:实行资源有序分配策略.采用这种策略,即把资源事先分类编号,按号分配,使进程在申请,占用资源是不会形成环路.所有进程对资源的请求必须严格按字元序号递增的顺序提出.进程占用了小号资源,才能申请大耗资源,就不会产生环路, 从而预防了死锁.这种策略与前面的策略相比, 资源的利用率和系统的吞吐量都有了很大的提高,但是也存在一下缺点:
定义
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
关系
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
区别
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
优缺点
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
####### 为什么需要进程间通信??
进程是一个独立的资源分配单元,不同进程(这里所说的进程通常指的是用户进程)之间的资源是独立的,没有关联,不能在一个进程中直接访问另一个进程的资源(例如打开的文件描述符)。
但是,进程不是孤立的,不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信( IPC:Inter Processes Communication )。
进程间通信的目的:
代码段 | 全局常量(const)、字符串常量、函数以及编译时可决定的某些东西 |
数据段 | 存储初始化的全局变量 和 初始化的静态变量(全局和局部) |
BSS段 | 存储未初始化的全局变量 和 未初始化的静态变量(全局和局部) |
堆 | 动态分配的区域(malloc、new等) |
栈 | l临时声明的局部变量(初始化以及未初始化的,但不包含静态变量),局部常量(const) |
命令行参数和环境变量 | 顾名思义 |
先来先服务 (FCFS,first come first served)
在所有调度算法中,最简单的是非抢占式的FCFS算法。
算法原理:进程按照它们请求CPU的顺序使用CPU.就像你买东西去排队,谁第一个排,谁就先被执行,在它执行的过程中,不会中断它。当其他人也想进入内存被执行,就要排队等着,如果在执行过程中出现一些事,他现在不想排队了,下一个排队的就补上。此时如果他又想排队了,只能站到队尾去。
算法优点:易于理解且实现简单,只需要一个队列(FIFO),且相当公平
算法缺点:比较有利于长进程,而不利于短进程,有利于CPU 繁忙的进程,而不利于I/O 繁忙的进程
最短作业优先(SJF, Shortest Job First)
短作业优先(SJF, Shortest Job First)又称为“短进程优先”SPN(Shortest Process Next);这是对FCFS算法的改进,其目标是减少平均周转时间。
算法原理:对预计执行时间短的进程优先分派处理机。通常后来的短进程不抢先正在执行的进程。
算法优点:相比FCFS 算法,该算法可改善平均周转时间和平均带权周转时间,缩短进程的等待时间,提高系统的吞吐量。
算法缺点:对长进程非常不利,可能长时间得不到执行,且未能依据进程的紧迫程度来划分执行的优先级,以及难以准确估计进程的执行时间,从而影响调度性能。
最高响应比优先法(HRRN,Highest Response Ratio Next)
最高响应比优先法(HRRN,Highest Response Ratio Next)是对FCFS方式和SJF方式的一种综合平衡。FCFS方式只考虑每个作业的等待时间而未考虑执行时间的长短,而SJF方式只考虑执行时间而未考虑等待时间的长短。因此,这两种调度算法在某些极端情况下会带来某些不便。HRN调度策略同时考虑每个作业的等待时间长短和估计需要的执行时间长短,从中选出响应比最高的作业投入执行。这样,即使是长作业,随着它等待时间的增加,W / T也就随着增加,也就有机会获得调度执行。这种算法是介于FCFS和SJF之间的一种折中算法。
算法原理:响应比R定义如下: R =(W+T)/T = 1+W/T
其中T为该作业估计需要的执行时间,W为作业在后备状态队列中的等待时间。每当要进行作业调度时,系统计算每个作业的响应比,选择其中R最大者投入执行。
算法优点:由于长作业也有机会投入运行,在同一时间内处理的作业数显然要少于SJF法,从而采用HRRN方式时其吞吐量将小于采用SJF 法时的吞吐量。
算法缺点:由于每次调度前要计算响应比,系统开销也要相应增加。
时间片轮转算法(RR,Round-Robin)
该算法采用剥夺策略。时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称RR调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
算法原理:让就绪进程以FCFS 的方式按时间片轮流使用CPU 的调度方式,即将系统中所有的就绪进程按照FCFS 原则,排成一个队列,每次调度时将CPU 分派给队首进程,让其执行一个时间片,时间片的长度从几个ms 到几百ms。在一个时间片结束时,发生时钟中断,调度程序据此暂停当前进程的执行,将其送到就绪队列的末尾,并通过上下文切换执行当前的队首进程,进程可以未使用完一个时间片,就出让CPU(如阻塞)。
算法优点:时间片轮转调度算法的特点是简单易行、平均响应时间短。
算法缺点:不利于处理紧急作业。在时间片轮转算法中,时间片的大小对系统性能的影响很大,因此时间片的大小应选择恰当
怎样确定时间片的大小:
多级反馈队列(Multilevel Feedback Queue)
多级反馈队列调度算法是一种CPU处理机调度算法,UNIX操作系统采取的便是这种调度算法。
多级反馈队列调度算法描述:
1、进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。
2、首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3三个队列,只有在Q1中没有进程等待时才去调度Q2,同理,只有Q1,Q2都为空时才会去调度Q3。
3、对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。
4、在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(抢占式)。
在多级反馈队列调度算法中,如果规定第一个队列的时间片略大于多数人机交互所需之处理时间时,便能够较好的满足各种类型用户的需要。
TCP | UDP | |
---|---|---|
传输 | 提供面向连接的、可靠地数据流传输 | 提供的是非面向连接的、不可靠的数据流传输 |
传输单位 | TCP报文段 | 用户数据报 |
安全性 | TCP注重数据安全性 | UDP数据传输快,因为不需要链接等待,少了许多操作,但是起安全性却一般 |
协议 | FTP:定义了文件传输协议,使用21端口; | DNS: 用于域名解析服务,将域名地址转换成IP地址.DNS用的是53号端口. |
协议 | Telnet: 一种用于远程登录的端口,使用23端口,用户可以以自己的身份远程连接到计算机上,可提供基于DOS模式下的通信服务 | SNMP: 简单网络管理协议,使用161端口,是用来管理网络十倍的.由于网络设备很多,无连接的服务就体现出其优势. |
协议 | SMTP: 邮件传送协议,用于发送邮件.服务端开放的是25号端口 | TFTP(Trival File Transfer Protocal): 简单文件传输协议,该协议在熟知端口69上使用UDP服务 |
协议 | POP3: 它是和SMTP对应,POP3用于接收邮件.POP3协议所用的是110端口 | |
协议 | HTTP: 是从Web服务器传输超文本到本地浏览器的传送协议 |
TCP与UDP区别总结:
TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保 证可靠交付
TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
TCP首部开销20字节;UDP的首部开销小,只有8个字节
TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务端
OSI分层(7层): 物理层,数据链路层,网络层,传输层,会话层,表示层,应用层.
TCP/IP分层(4层): 网络接口层,网际层,运输层,应用层.
五层协议(5层): 物理层,数据链路层,网络层,运输层,应用层.
每一层的协议如下:
物理层: RJ45,CLOCK,IEEE802.3(中继器,集线器)
数据链路: POP,FR,HDLC,VLAN,MAX(网桥,交换机)
网络层: IP,UCMP,ARP,RARP,OSPF,IPX,RIP,IGRP(路由器)
传输层: TCP,UDP,SPX
会话层: NFS,SQL,NETBIOS,RPC
表示层: JPEG,MPEG,ASII
应用层: FTP,DNS,Telnet,SMTP,HTTP,WWW,NFS
每一层的作用如下
物理层: 通过媒介传输比特,确定机械及电器规范(比特Bit)
数据链路: 将比特组装成帧和点到点的传递(帧Frame)
网络层: 负责数据包从源到宿的传递和网际互联(包PackeT)
传输层: 提供端到端的可靠报文传递和错误回复(段Segment)
会话层: 简历,管理和中智慧化(会话协议数据单元SPDU)
表示层: 对数据进行翻译,加密和压缩(表示协议数据单元PPDU)
应用层: 允许方位OSI环境的手段(应用协议数据单元APDU)
A类地址: 以0开头, 第一个字节范围1~127(1.0.0.0~127.255.255.255);
B类地址: 以10开头, 第一个字节范围128~191(128.0.0.0~191.255.255.255);
C类地址: 以110开头, 第一个字节范围192~223(192.0.0.0~223.255.255.255);
D类地址: 以1110开头, 第一个字节范围224~239(224.0.0.0~239.255.255.255);
E类地址: 保留
一种A,B,C是基本类,D,E类作为多播和保留使用.
以下是留用的内部私有地址:
A类 10.0.0.0 – 10.255.255.255
B类 182.16.00 – 192.31.255.255
C类 192.168.0.0 – 192.168.255.255
IP地址与子网掩码相与(&)得到网络号
ip 192.168.2.110
&
submask:255.255.255.0
.---------------------------------
网络号 192.168.2.0
注: 主机号,全是0的网络号(例如192.168.2.0),主机号全为1的为广播地址(192.168.2.255)
广播发送ARP请求,单播发送ARP相应.
RARP是逆地址解析协议,作用是完成硬件地址到IP地址的映射,主要用于无盘工作站,因为给无盘工作站配置的IP地址不能保存.
工作流畅: 在网络中配置一台RARP服务器,里面保存者IP地址和MAC地址的映射关系,当无盘工作站启动后,就封装一个RARP数据包,里面有其MAC地址,然后广播到网络上去,当服务器收到请求包后,就查找对应的MAC地址的IP地址装入响应报文中发回给请求者. 因为需要广播请求报文,因此RARP只能用于具有广播能力的网络.
当DNS客户机需要在程序中使用名称时, 它会查询DNS服务器来解析该名称. 客户机发送的每条查询信息包括三条信息: 包括: 指定的DNS域名,DNS域名的指定类型. 基于UDP服务,端口53. 该应用一般不直接为用户使用, 而是为其他应用服务,如 HTTP,SMTO等在其中需要完成主机名到地址的转换.
交换机
在计算机网络系统中,交换机是针对共享工作模式的弱点而推出的.交换机拥有一条高带宽的背部总线和内部交换矩阵.交换机的所有的端口都挂接在这条背部总线上,当控制电路收到数据包以后,处理端口会查找内存中的地址对照表以确定目的端口.目的MAC若不存在,交换机才广播到所有的端口, 接手端口回应后交换机会’学习’新的地址,并把它添加入内部地址表中.
交换机工作于OSI参考模型的第二层,即数据链路层. 交换机内部的CPU会在每个端口成功连接时,通过ARP协议学习它的MAC地址,保存成一张ARP表. 在今后的通讯中, 发往该MAC地址的数据包将仅送往其对应的端口,而不是所有端口. 因此,交换机可用于划分数据链路层广播,即冲突域; 但它不能划分网络层广播, 即广播域.
交换机被广泛应用于二层网络交换,俗称’二层交换机’.
交换机的种类有: 二层交换机,三层交换机,四层交换机,七层交换机分别工作在OSI七层模型中的第二层,第三层,第四层和第七层,并因此而得名.
路由器
路由器(Router)是一种计算机网络设备,提供了路由与传送两种重要机制,可以决定数据包从来源端到目的端所经过的路由路径(host到host之间的传输路径),这个过程称为路由; 将路由器输入端的数据包移送至适当的路由器输出端(在路由器内部进行),这成为传动. 路由工作在OSI模型的第三层 -> 即网络层,例如网际协议.
路由器的一个作用是连通不同的网络另一个作用是选择信息传送的线路. 路由器与交换机的差别, 路由器是属于OSI第三层的产品,交换机是OSI第二层的产品(这里至二层交换机)
网关
网关(Gateway), 网关顾名思义就是连接两个网络的设备,区别与路由器(由于历史的原因,许多有关TCP/IP的文献曾经把网络层使用的路由器成为网关,在今天很多局域网采用的都是路由器来接入网络,因此现在通常指的网关就是路由器的IP),经常在家庭中或者小型企业网络中使用,用于连接局域网和Internet. 网关也经常把一种协议转成另一种协议的设备,比如语音网关.
在传统TCP/IP术语中,网络设备只分成两种,一种为网关(Gateway),另一种称为主机(host). 网关能在网络间传递数据包,但主机不能传送数据包.在主机(又称终端系统,end system)中,数据包需经过TCP/IP四层协议处理,但是在网关(又称中介系统,intermediate system)只需要到达网际层(Internet layer),决定路径之后就可以传送. 在当时,网关(Gateway)和路由(Router)还没有区别.
在现代网络术语中,网关(Gateway)和路由(Router)的定义不同,网关(Gateway)能在不同协议间移动数据,而路由器(Router)是在不同网络间移动数据,相当于传统所说的IP网关(IP Gateway).
网关是连接两个网络的设备,对于语音网关来说,它可以连接PSTN网络和以太网,这就相当于VOIP,把不同电话的模拟信号通过网关而转换成数字信号,而且加入协议再去传输. 在到了接收端的时候再通过网关还原成模拟的电话信号,最后才能在电话机上听到.
对于以太网中的网关只能转发三层以上数据包,这一点和路由是一样的.而不同的是网关中并没有路由表,他只能按照预先设定的不同网段来进行转发.网关最重要的一层就是端口映射,子网内用户在外网看来只是外网的IP地址对应着不同的端口,这样看来就会保护子网内的用户.
答: 常量是存储在内存中的,
*p1 是指针 指向"123"中的"1"的地址
p2[] 是数组 本质是在堆栈中定义的一段内存
答: 4
内存对其,整体占得内存一定是最大数据元素的整数倍.
这里最大的是int(4字节)整体就是(4*n字节)
大概是这个样子
|int|char|
△△△△|△—|
Synchronze(隐式锁) | Lock(显示锁) |
---|---|
在需要同步的对象中加入此控制,synchronize可以加在方法上,也可以加在特定代码块中,括号中表示需要所得对象 | 需要显示指定起始位置和终止位置.一般使用ReentrantLock类作为锁,多个线程中必须要使用一个ReentrantLock类作为对象才能保证锁的生效.且在加锁和解锁处需要通过lock()和unlock()显示指出.所以一般会在finally块中写unlock()以防死锁 |
托管给JVM执行的 | java写的控制锁代码 |
采用的的CPU的悲观锁机制,即线程获得的是独占锁.独占锁意味着其他线程只能依靠阻塞来等待线程释放锁 | 乐观锁方式,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止.乐观锁实现的机制就是CAS操作(Compare and Swap) |
Ps: 在Java1.5中, syncchronize是性能低效的,因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多. 相比之下使用Java提供的Lock对象,性能更高一些.但是到了Java1.6,发生了变化. synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等. 导致在Java1.6上synchronize的性能并不比Lock差.
名称 | 内容 |
---|---|
代码段 | 可执行代码 |
数据段 | 已初始化全局变量,已初始化全局静态变量,局部静态变量,常量数据 |
BSS段 | 未初始化全局变量,未初始化全局静态变量 |
栈 | 局部变量,函数参数 |
堆 | 动态内存分配 |
答:
top
free [-h]
答: 两个作用
僵尸进程: 在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用waitpid()等待子进程结束,又没有显示忽略该信号,则子进程成为僵尸进程.
孤儿进程: 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程. 孤儿进程将被init进程(进程号为1)所收养,并由init进程对他们完成状态收集工作.
守护进程: Linux系统中的守护进程是一种运行在后台的进程. 而守护进程,也就是通常说的Daemon进程. 它通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件. Linux大多数服务器进程就是用这种守护进程实现的, 例如Web服务.守护进程常常在系统引导装入时启动, 在系统关闭时终止. 守护进程最大的特点是运行在后台,与终端无连接, 除非特殊情况下, 用户不能操作守护进程.
MongoDB和Redis都是NoSQL,采用结构型数据存储。二者在使用场景中,存在一定的区别,这也主要由于二者在内存映射的处理过程,持久化的处理方法不同。
MongoDB建议集群部署,更多的考虑到集群方案,Redis更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式。
比较指标 | MongoDB(v2.4.9) | Redis(v2.4.17) | 比较说明 |
---|---|---|---|
实现语言 | c++ | c/c++ | - |
协议 | BSON,自定义二进制 | 类telnet | - |
性能 | 依赖内存,TPS{(transaction per second)代表每秒执行的事务数量}较高 | 依赖内存,TPS非常高 | Redis优于MongoDB |
可操作性 | 丰富的数据表达,索引;最类似于关系型数据库,支持丰富的查询语句 | 数据丰富,较少的IO | MongoDB优于Redis |
内存及存储 | 适合大数据量存储,依赖系统虚拟内存,采用镜像文件存储;内存占用率比较高,官方建议独立部署在64位系统 | Redis2.0后支持虚拟内存特性(VM) 突破物理内存限制;数据可以设置时效性,类似于memcache | 不同的应用场景,各有千秋 |
可用性 | 支持master-slave,replicatset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切片机制 | 依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制;不支持auto sharding,需要依赖程序设定一致性hash机制 | MongoDB优于Redis;单点问题上,MongoDB应用简单,相对用户透明,Redis比较复杂,需要客户端主动解决.(MongoDB一般使用replicasets和sharding相结合,replicasets侧重高可用性以及高可靠,sharding侧重性能,水平扩展) |
可靠性 | 从1.8版本后,采用binlog方式(类似Mysql) 支持持久化 | 依赖快照进行持久化;AOF增强可靠性;增强性的同时,影响访问性能 | - |
一致性 | 不支持事务,靠客户端保证 | 支持事务,比较脆,仅能保证事务中的操作按顺序执行 | Redis优于MongoDB |
数据分析 | 内置数据分析功能(mapreduce) | 不支持 | MongoDB优于Redis |
应用场景 | 海量数据的访问效率提升 | 较小数据量的性能和运算 | MongoDB优于Redis |
更新丢失
两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。
脏读
脏读又称无效数据读出。一个事务读取另外一个事务还没有提交的数据叫脏读。
例如:事务T1修改了一行数据,但是还没有提交,这时候事务T2读取了被事务T1修改后的数据,之后事务T1因为某种原因Rollback了,那么事务T2读取的数据就是脏的。
答:作为应届生,本就应该吃苦耐劳学技术,人都是逼出来的,有压力才有动力,这点压力不算什么.
答: 没有,一心向学,不找女朋友浪费时间.(TM是找不到好不2333)
2018-01-28 13:00:52 Tabris_ 阅读数:410
博客爬取于2020-06-14 22:39:24
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/79186055
以后除了下载东西,应该不会用CSDN了.
搭了个博客.
blog.tabris.top
以后就在这里玩耍了.
因为也没人看,想咋写咋瞎写. 哈哈哈哈哈哈哈哈.
tabris的个人博客终于搭建成功啦,百度不收录的博客权当自己的学习笔记+矫情的地方.
ACM退役啦,不知道学些什么:
机器学习感觉智商和数学水平够不上.
C++也不好找工作.
Java还不想学.
前端更是不想学.
学学大数据
投后台开发岗和大数据岗
失业了就回家种地
所以先学些必备的技能.
]]>let’s begin.
–tabris
this is the summary for my six month internship.
2018-05-24~
5月24日
入职.
半个月后开始参与商户联调.
6月22号
接到手机号同步脚本的需求,7月11号
上线
同时接到自动化用例server需求
8月5号
正式方案评审结束
8月10号
正式开发完,后一直等待测试侧的开发
8月17号
左右接到商户迁移对账脚本的需求 8月24号
开发完毕,但后期有优化
8月底
开始部署自动化测试用例,陆续到9月中旬正式运行.
8月底
接到QA的商户监控报表需求,开始采取监控平台报表定制
,但不能查到商户名称,无奈改成python脚本.
9月10号
左右接到深铁预测提取脚本需求, 9月18号
会议结束,9月25号
脚本开发完毕,等征信侧部署ditto.
这时候基本没有商户联调的工作了
9月14号
接到客服系统优化需求,9月底
前端功能点部分优化结束.然后开始挂起.
9月底
接到薪资offer,心态崩.此事不谈
10月中旬
开始在做后台部分的修改方案
当时考虑的是2.0的兼容,但是沟通问题,导致没有理解到位
10月中旬
接到自动化用例的优化小需求,工时较短,但由于依赖服务还在测试阶段 没有提发.
测试结束后突然又加了个优化点…
10月中旬
接到行业数据预拉取需求 ,于10月17日
方案评审 ,10月25日正式开始编码
,10月26日
提code review,10月27日
提测, 11月5日
评审了代码,同日排上测试,11月9日
测完,11月12日
发布.
接到需求时 客服系统需求挂起 快结束时继续开发
并发程序开发经验匮乏.
同时出现shell脚本 ‘\r\n’和’\n’ 的问题
bug超多,
10月中旬后期
征信侧部署结束,开始联调,后发布
10月底,11月初
接到自动化用例改造需求,11月13日
完成开发,次日联调
cgi,server 改造,基本是从其他模块复用代码,难度不大,但cgi首次开发,进度较慢,
但是写在方案上的点竟然有遗漏,用户白名单没有配置???
同事周5前端换人,进度延期
之前代码仓库申请的是我的git目录下 发布的时候发现不行
11月15日
申请正式代码库,被要求用新框架开发cgi,尝试改造,半天工后,发现框架改动较大,依赖非常不好改,遂放弃,依旧沿用老框架.
11月15,16日
完成客服系统的前后端开发
前端的分支目录未知, 还没有把代码提交到分支上.
后面验证下就可以发布了
11月17,20~24日
,自动化用例与前端联调,同时接到广告/活动/红点查询链路优化需求
前端临时换人, 导致了很多坑,本预计17号收尾的,延误一个多星期.
联调过程,虽然是开发环境缺少数据等因素耽搁了时间.同时前端工作交接出现问题,前端代码中的一处修改/一处打桩,导致两个调了很久的问题.但主要还是我的经验不足,一来导致不管是前端还是导师/leader都觉得是我的问题…
没有对前后端参数进行仔细的对比,对基础工具(apache)的使用不熟练.造成时间上的严重浪费.
很多,
点比较杂,一些零散经验性的东西,很难列出.
能力问题还是经验问题?
经验问题是一定存在的.
能力问题
2017-11-08 15:31:29 Tabris_ 阅读数:571
博客爬取于2020-06-14 22:39:25
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/78479380
2017 青岛 icpc 打铁 退役
正常发挥 玩的很开新
------Update-----
好久没看博客了 ,想想应该更新下.
12月又去了上海打了ECL-FINAL 嗯 铁了.
事实证明了我就是一个铁牌的菜鸡.
这两年多,也后悔也不后悔…
爱咋咋地吧,反正也失业了.
最后希望自己能,
好好学英语!
好好学英语!
…
好好学英语!
这个年头不拿个银牌都不好意思说自己是个ACMer,更何况我也个垃圾万年铁牌菜逼.
引用某大牛的退役帖作结尾巴.(当然我和大牛的失败与遗憾根本不是同一个层面上的,引用大牛的话也真是臭不要脸…)
ACM之于我,真正获得的或许也就两样,表面上的基础、算法之流,深层处的不屈与倔强。当最后比赛输了的时候,没怎么去惋惜学了那么多算法怎么如此啥的,真正感到遗憾的是那一份执着没有完美的结局,果真是不完美的结局才最让人回味么~?
ACM!再见.
]]>2017-10-08 15:24:34 Tabris_ 阅读数:485
博客爬取于2020-06-14 22:39:26
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/78175188
题目链接:https://vijos.org/p/2026
——————————————————————————————————————
描述
我们称一个整数是奇偶等和数,是说它的数位个数是偶数(比如二位数,四位数,六位数等,且特殊说明 是一位数字),且其中所有奇数位数字之和恰好等于所有偶数位数字之和。
我们称一个整数是几乎奇偶等和数,是说在恰好修改其中一位数字后,得到的新数字是一个奇偶等和数。这里说恰好修改一位数字,要求必须发生了实质性修改,也就是说修改后的数字必须与之前的数字不同(例如将修改为就是不合法的,因为修改后的数字和之前是一样的);同时要求不能将最高位修改为 。
现在给定整数 和 ,问有多少几乎奇偶等和数 满足 。
格式
输入格式
输入只有一行,是两个整数 和 ,满足 。
输出格式
输出一个正整数,表示有多少几乎奇偶等和数。
样例1
样例输入1
1 33
Copy
样例输出1
21
Copy
样例2
样例输入2
51 78
Copy
样例输出2
25
Copy
限制
对于 30%30% 的数据,。
对于所有数据,.
存在额外的 的数据, ;还有另外的额外 10%10% 的数据, 。
每一组数据的时限为 秒。
——————————————————————————————————————
注意的是一定要修改一个数字,然后是奇数位上和偶数位上,不算是奇数数字和偶数数字的和的比较,
对于一个数字 判定是否是奇偶等和数 ,只要把奇位和与偶位和的差算出来,然后 逐位判断每个数字的大小关系就行,小的数字变大的,大的数字变小的然后对奇位和与偶位和的差的改变就确定了,到这步就能O(1)判断这个是否合法了.
直接数位dp算下去就行了,然后记忆化一下,
int dp[10][120][10][10][10];
//数位 奇位和与偶位和的差 对差的影响的正值 对差的影响的负值 当前数字的长度
int dfs(int pos,int sub,int posi,int nop,bool limit,int bt)
// 数位 奇位和与偶位和的差 对差的影响的正值 对差的影响的负值 限制 当前数字的长度
附本题代码
——————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-09-21 16:44:50 Tabris_ 阅读数:359
博客爬取于2020-06-14 22:39:27
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/78053974
题目链接:http://codeforces.com/problemset/problem/794/F
——————————————————————————————————————
F. Leha and security system
time limit per test2 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
Bankopolis, the city you already know, finally got a new bank opened! Unfortunately, its security system is not yet working fine… Meanwhile hacker Leha arrived in Bankopolis and decided to test the system!
Bank has n cells for clients’ money. A sequence from n numbers a1, a2, …, an describes the amount of money each client has. Leha wants to make requests to the database of the bank, finding out the total amount of money on some subsegments of the sequence and changing values of the sequence on some subsegments. Using a bug in the system, Leha can requests two types of queries to the database:
1 l r x y denoting that Leha changes each digit x to digit y in each element of sequence ai, for which l ≤ i ≤ r is holds. For example, if we change in number 11984381 digit 8 to 4, we get 11944341. It’s worth noting that Leha, in order to stay in the shadow, never changes digits in the database to 0, i.e. y ≠ 0.
2 l r denoting that Leha asks to calculate and print the sum of such elements of sequence ai, for which l ≤ i ≤ r holds.
As Leha is a white-hat hacker, he don’t want to test this vulnerability on a real database. You are to write a similar database for Leha to test.
Input
The first line of input contains two integers n and q (1 ≤ n ≤ 105, 1 ≤ q ≤ 105) denoting amount of cells in the bank and total amount of queries respectively.
The following line contains n integers a1, a2, …, an (1 ≤ ai < 109) denoting the amount of money in each cell initially. These integers do not contain leading zeros.
Each of the following q lines has one of the formats:
1 l r x y (1 ≤ l ≤ r ≤ n, 0 ≤ x ≤ 9, 1 ≤ y ≤ 9), denoting Leha asks to change each digit x on digit y for each element ai of the sequence for which l ≤ i ≤ r holds;
2 l r (1 ≤ l ≤ r ≤ n), denoting you have to calculate and print the sum of elements ai for which l ≤ i ≤ r holds.
Output
For each second type query print a single number denoting the required sum.
Examples
input
5 5
38 43 4 12 70
1 1 3 4 8
2 2 4
1 4 5 0 8
1 2 5 8 7
2 1 5
output
103
207
input
5 5
25 36 39 40 899
1 1 3 2 7
2 1 2
1 3 5 9 1
1 4 4 0 9
2 1 5
output
111
1002
Note
Let’s look at the example testcase.
Initially the sequence is [38, 43, 4, 12, 70].
After the first change each digit equal to 4 becomes 8 for each element with index in interval [1; 3]. Thus, the new sequence is [38, 83, 8, 12, 70].
The answer for the first sum’s query is the sum in the interval [2; 4], which equal 83 + 8 + 12 = 103, so the answer to this query is 103.
The sequence becomes [38, 83, 8, 12, 78] after the second change and [38, 73, 7, 12, 77] after the third.
The answer for the second sum’s query is 38 + 73 + 7 + 12 + 77 = 207.
——————————————————————————————————————
题目大意:
一个长度为n的序列 ,有两种操作,
解题思路:
还是考虑直接的线段树维护,
每个节点维护10个信息,分别是数位为0~9的和,同时维护延迟标记
求和部分略,
对于数位修改,最大的问题就是考虑 如何维护lazy了,
这里维护的lazy同样有10个,lazy[i]表示的是接下来的数中数位为i的要变成数位lazy[i]
那么问题就是标记下传怎么搞了
和普通的标记下传相比 较为复杂,但也无非是把左右儿子的值先改过来 ,再把lazy合并过去,
还是看代码 比较好理解
1 | 这是对左儿子进行pushdown的 |
附本题代码
——————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-08-18 01:01:18 Tabris_ 阅读数:429
博客爬取于2020-06-14 22:39:28
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/77349012
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6134
———————————————————————————————————————————
Battlestation Operational
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 187 Accepted Submission(s): 100
Problem Description
The Death Star, known officially as the DS-1 Orbital Battle Station, also known as the Death Star I, the First Death Star, Project Stardust internally, and simply the Ultimate Weapon in early development stages, was a moon-sized, deep-space mobile battle station constructed by the Galactic Empire. Designed to fire a single planet-destroying superlaser powered by massive kyber crystals, it was the pet project of the Emperor, Darth Vader, and its eventual commander Grand Moff Wilhuff Tarkin to expound the military philosophy of the aptly named Tarkin Doctrine.
— Wookieepedia
In the story of the Rogue One, the rebels risked their lives stolen the construction plan of the Death Star before it can cause catastrophic damage to the rebel base. According to the documents, the main weapon of the Death Star, the Superlaser, emits asymmetric energy in the battlefield that cause photons to annihilate and burns everything in a single shot.
You are assigned the task to estimate the damage of one shot of the Superlaser.
Assuming that the battlefield is an n×n grid. The energy field ignited by the Superlaser is asymmetric over the grid. For the cell at i-th row and j-th column, ⌈i/j⌉ units of damage will be caused. Furthermore, due to the quantum effects, the energies in a cell cancel out if gcd(i,j)≠1 or i< j.
The figure below illustrates the damage caused to each cell for n=100. A cell in black indicates that this cell will not be damaged due to the quantum effects. Otherwise, different colors denote different units of damages.
Your should calculate the total damage to the battlefield. Formally, you should compute
,
where [(i,j)=1] evaluates to be 1 if gcd(i,j)=1, otherwise 0.
Input
There are multiple test cases.
Each line of the input, there is an integer n (1≤n≤106), as described in the problem.
There are up to 104 test cases.
Output
For each test case, output one integer in one line denoting the total damage of the Superlaser, f(n) mod 109+7.
Sample Input
1
2
3
10
Sample Output
1
3
8
110
Source
2017 Multi-University Training Contest - Team 8
———————————————————————————————————————————
题意:给你一个n让你计算,
考虑$ g[i] = ∑_{j=1}^i⌈\frac{i}{j}⌉,h[i]=∑_{j=1}^i⌈\frac{i}{j}⌉[(i,j)=1],f[n]=\sum_{i=1}^nh[i]$
显然有
所以得到后,可以通过筛法计算出,然后前缀和处理一下就得到了
所以问题就是如何求,
很显然 枚举 有的做法求出来,但是有点爆啊
所以这里采取枚举的做法,
有
转化一下,就是
所以在每个开始的位置加上1,然后前缀和处理一下就行了
我这里写的麻烦了,其实不用把求出来,直接计算就行.
附本题代码
———————————————————————————————————————————
1 | int n; |
2017-08-10 11:26:27 Tabris_ 阅读数:370
博客爬取于2020-06-14 22:39:29
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/77044181
题目链接:https://csacademy.com/contest/archive/task/0-k-multiple/solution/
————————————————————————————————————————
0-K Multiple
Time limit: 1000 ms
Memory limit: 128 MB
You are given an integer and a digit . Find the smallest multiple of that consists only of digits and .
Standard input
The first line contains two integers NN and KK.
Standard output
Print the result on a single line.
Constraints and notes
Input
5 2
Output
20
Input
7 4
Output
4004
Input
13 7
Output
7007
————————————————————————————————————————
题意:
给你一个数N和一个数字K
让你找到一个最小的有K和0组成的数字,能被N整除
解题思路:
对于这个数字能确定第一位一定是K,
有了下一位 就是K*10+0/K了,
这种操作下出现的所有数字对N取模依然会有一个结果,且不超过N的.且最后一定有一个是%N为0的.这种情况就是答案了,
所以我们可以的枚举K*10+0/K这样的数来计算,但是注意题目要求的是最小的,
这时候有 我们可以类似于建立一个有向图
然后bfs下去就好了,先处理0,在处理k,这样到达每个%N的位置均能保证最小,然后处理一个数组记录下路径就好了
附本题代码
————————————————————————————————————
1 |
|
2017-08-03 22:57:34 Tabris_ 阅读数:461
博客爬取于2020-06-14 22:39:30
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/76158441
好久没有更新博客了 更新一波吧,,,
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5239
——————————————————————————————————————
Doom
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1524 Accepted Submission(s): 419
Problem Description
THE END IS COMINGGGGGG!
Mike has got stuck on a mystery machine. If he cannot solve this problem, he will go to his doom.
This machine is consist of n cells, and a screen. The i-th cell contains a number ai(1≤i≤n). The screen also contains a number s, which is initially 0.
There is a button on each cell. When the i-th is pushed, Mike observes that, the number on the screen will be changed to s+ai, where s is the original number. and the number on the i-th cell will be changed to a2i.
Mike observes that the number is stored in radix p, where p=9223372034707292160. In other words , the operation is under modulo p.
And now, Mike has got a list of operations. One operation is to push buttons between from l-th to r-th (both included), and record the number on the screen. He is tired of this stupid work, so he asks for your help. Can you tell him, what are the numbers recorded.
Input
The first line contains an integer T(T≤5), denoting the number of test cases.
For each test case, the first line contains two integers n,m(1≤n,m≤105).
The next line contains n integers ai(0≤ai< p), which means the initial values of the n cells.
The next m lines describe operations. In each line, there are two integers l,r(1≤l≤r≤n), representing the operation.
Output
For each test case, output ‘‘Case #t:’’, to represent this is the t-th case. And then output the answer for each query operation, one answer in a line.
For more details you can take a look at the example.
Sample Input
2
4 4
2 3 4 5
1 2
2 3
3 4
1 4
1 3
2
1 1
1 1
1 1
Sample Output
Case #1:
5
18
39
405
Case #2:
2
6
22
-------------------------------------------------------.
题目大意:
给你一个序列,每个序列有一个值.
每次选择一个区间,将这个区间的数的和加起来,然后让这个区间的每个数都平方.
所有数都是对9223372034707292160取模的
注意这个模数,和正常的模数不一样,那么就一定有问题
然后通过打表能发现,每个数不断自身平方对p取模后经过有限次 就不会变化了,
测试少于30次
所以也就是说每个节点至多会被更新30次,
所以可以直接维护线段树,打上平方标记后,还要打一个标记表示这个区间的数已经不会变化了,这样这个位置就不用再更新了
这样的话 复杂度就是
附本题代码
1 | # include <bits/stdc++.h> |
2017-07-24 20:01:34 Tabris_ 阅读数:357
博客爬取于2020-06-14 22:39:31
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/76037429
感觉今天都好没状态啊。
——————————————————————————————————————
结构体排序没什么好说的。。
——————————————————————————————————————
给你一个整数,问你划分方法有多少种,然后用二进制输出,{1,2}{2,1}算两种
退了一下,发现 结果就是
所以输出个,和个就行了
——————————————————————————————————————
n(2~100)个人参加一个游戏,
每个人选择1~100范围的数。
然后得到所有数的平均数,再*=2/3,设得到的数为m。
如果一个人选的数,比m小,且相距m最为接近,那么其便在所有选数相同的人中等概率中奖。
现在,我们也参加比赛,其他n-1个人所选择的数也已经确定了,并且我们知道。
问你,选什么数拥有最高中奖率,并输出。
数据量比较小,暴力枚举然后在模拟计算就行了
1 | # include <bits/stdc++.h> |
——————————————————————————————————————
给你一个时间,问你下一次时针和分针夹角为a度的时刻是多少,如果不是整数则把秒数向下取整
暴力模拟即可,
为了方便比较 可以扩大倍数,使得时针1s动1个单位
1 | # include <bits/stdc++.h> |
——————————————————————————————————————
一个n*m的网格,每个格子有一个字母 ,问你能构成的girl和cat的个数
爆搜即可
1 | # include <bits/stdc++.h> |
——————————————————————————————————————
给你三个字符串,问你能不能将a,b合并成c,且a,b字符串的字母顺序不被改变
设f[i][j] 表示当前,到达a[i],b[j]的时候,能不能凑成c[0~i+j-1],
转移的时候就是
1 | # include<bits/stdc++.h> |
——————————————————————————————————————
两个人走格子,从(1,1)开始走 ,每次可以从(x,y)走到(x+1,y),(x,y+1),(x+k,y+k)
轮到谁的时候不能走了 就输了.
两个人足够聪明 然后问你谁能赢,Alice先
手写了几组k,然后发现有一个规律, 然后就打表观察了下 ,然后就总结了下规律然后AC.了…
这个规律有点不好描述 自己看吧 打表代码为solve()函数
1 | # include <bits/stdc++.h> |
——————————————————————————————————————
有n(<=1e5)个点的树,每个点都有颜色(颜色可能重复),有m(<=1e5)个询问,每次询问(x,d)问在x的子树中,与x的距离不超过d的节点有多少种不同的颜色。强制要求在线。
维护两颗线段树,并还要有合并的操作,不是特别懂…
看claris的博客吧
1 |
——————————————————————————————————————
我们要找出最小的正整数n满足——
aS(n)==bS(2n)
a,b的范围都在[1,100]
s(x)为x的所有位的和
首先能明确的是
___
因为大于就会进位,相当于
所以有
然后考虑数n的选取,
我们假设有l的长度是[0,4]范围,有L的长度是[5,9]范围
我们不妨假设答案n仅有长度为L,且每一位都是5
然后得到了把数位和sum分撒出去。
对于sum余下的数值,我们依次加到尾巴上。
如果sum最后把长度为L的字串都填充为‘9‘之后,还有剩余,那么在前面贪心填充。
——————————————————————————————————————
n(16)个点
m(n^2)条双向边
K(50)次hack机会
最远走L(2000)路程
队友补的 我还不会 待补…
]]>2017-07-23 20:46:34 Tabris_ 阅读数:422
博客爬取于2020-06-14 22:39:32
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75948179
日常血崩。
菜到爆了.
——————————————————————————————————————————
给你一个序列,可以把每个元素加上k的倍数或者不加, 问你最后能不能组成一个序列,第1个元素是1,第2个元素是2,第3个元素是3,。。
暴力模拟就行,从大小1的数开始,留下本身需要的1个,剩下的不断加K,知道当前的数没出现过。
最后扫一下判断就行
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
在二维坐标系上给你一堆点,然后问你w*h这么大的矩形,最多能包含多少个点
用到了扫描线;
首先考虑一维的情况
如果是一维的,要统计长为w的线段最多能包括多少个位置怎么搞?
可以反过来考虑,然后变成一堆长w的线段覆盖,然后求的就是那个被覆盖最多的点,区间更新后求最大值就行了
而这个题
可以考虑将一个点变成一个矩形,
然后从左向右扫描
使扫描过程中,遇到矩形的左边就+1,右边就-1,
并维护一个线段树区间更新取最大值就好了
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
给你一个矩阵,让你找一个从上到下的路线,使得这个路线经过数的和最小,并且尽量靠右.
注意 a[i][j] 只能走到 a[i+1][j-1],a[i+1][j],a[i+1][j+1]
所以我们知道dp下到每个点的最小和,然后在最后一行找到最后一个最小的位置不算向回找就好了
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
给你一个NM的图,其中’‘可以放传,但是注意同一行一列只能放一个船,除非被’#'隔开,问你最多能放几个船.
首先考虑每个行和列分开之后,没有被隔开的部分就是一个整体了,
然后考虑 ,处理完的这一个个, 行与列没有被隔开的中
假设行1 和列1,列2,列3, 没有被隔开,
那么行1只能找一个列对应的位置来放船,
然后这就是一个二分匹配模型了,、、
然后就用行与列建二分图求最大匹配就好了
1 | # include<stdio.h> |
——————————————————————————————————————————
给你一个图,
二进制枚举状态搜索,
队友A的,待补
-----------------------Update-----------------------------
就是搜索么。
我用a[x][y][0~3] 记录每个位置4个方向的们需要那种钥匙开 用a[x][y][4]记录(x,y)这个位置的钥匙是那种,
因为又9种钥匙, 所以只要用一个9位的二进制数进行枚举就好了
用vis[x][y][1<<10] 来标记每种状态下走到(x,y)、、
然后直接搜索就好了
注意不能走到输出-1;
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
给你10个系数,让你把10项的多项式的最简形式表示出来,
小模拟
注意开始的数是正数的时候没有正号,
系数为1 的要省略
–
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
大模拟,不补.
–
——————————————————————————————————————————
待补…
——————————————————————————————————————————
给你一堆程序,后面带’*‘好的需要重启之后才能生效,’:’ 后面的是需要安装完这个程序,才能开始安装的程序
问你最少需要打印多少次
题目很水,就是题面太长了。没读。。。
只要注意到要把当前需要重启的程序个数最大化就好了。
过程就是个拓扑,
然后就是如何处理这个恶心的读入了。。。
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
给你两个字符串,然后按照规则比较下大小.
我做傻逼了
队友A的
题傻逼不补
1 | # include <bits/stdc++.h> |
2017-07-22 19:13:49 Tabris_ 阅读数:487
博客爬取于2020-06-14 22:39:34
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75687721
上来A题就崩了 上来习惯性long long 确忘了用I64d wa了4发。。
F题 一处爆int 又wa了10发。。。
L题 判断 把a[1][3]打成a[1][2]又wa了3发。。。。
果然我只是个坑队友的坑货,, ,贡献了队伍的全部罚时
————————————————————————————————————
传统的鸡兔同笼问题。。
a个脑袋,b条腿
青蛙个数 = b/2-a;
鸡的个数 = a-青蛙个数;
代码无
————————————————————————————————————
给你两个三角形,问你这两个三角形是包含的,还是相交的,还是相离的。
直接枚举两个三角形,判断一个三角形的三个点 是不是都在另一个三角形里面,如果有就是包含
然后就看是不是相离的, 如果没有任何一个点在另外的三角形里就是相离,但是要注意六芒星这种情况,所以还要枚举下边 看一看有没有相交的
然后就是相交了 …
1 | # include<stdio.h> |
————————————————————————————————————
————————————————————————————————————
给你两个大数,(不含前导零),
两个人轮流操作自己的数,可以除以10(向下取整,没有小数.)或者翻转过去,(翻转之后要去掉前导0).
当有一时刻两个数相等则A赢,否则B赢,所以A想要将两个数变得相同,B想讲两个数变得不同.
问你两个人最后谁赢
考虑到如果B想让两个数不等那么只能是在A中没有B的子串才行,否则A不断的翻转在除以10一定会有一个时刻和B相同,这时候无论B怎么翻转还是除10,最终的一定会有一个时刻相等,
所以只要用kmp匹配一下A的数是否有B或者翻转的B就行了
注意的是 B的数 如果翻转就相当去去掉了后面的0,所以在匹配之前除了一下B,使两端都没有0;
1 | # include <iostream> |
————————————————————————————————————
————————————————————————————————————
有一个根为1的有根树
然后有两种操作
1 v x k : a[v]+=x , a[v’]+=x-k (v’是v的孩子) , a[v’‘]+=x-2*k (v’'是v’的孩子) and so on.
2 v : 输出 a[v] mod 1000000007(10^9 + 7).
考虑单链的时候如何维护-n*k的情况,
对于 5 来讲
可以变成这样
所以我们可以维护两个BIT,一个用来记录 另一个记录
然后翻倍相减即可,
同时在用一个维护,其实和上面的那个放一起就行了,,
考虑是在树上进行
对应的就是节点的深度
在加一个树剖就能做了
1 | int n; |
————————————————————————————————————
有n中物品,你一次只能抽取一个物品,得到每个物品的概率是1/n,然后问你凑齐n种物品的期望
考虑拿到1个物品是的期望是1
那么拿到第二个物品就是在拿到第一个的基础上再拿到一个没拿过的 ,那么概率就是 ,期望就是
那么拿到第三个物品就是在拿到第二个的基础上再拿到一个没拿过的 ,那么概率就是 ,期望就是
。。。
那么拿到第个物品就是在拿到第个的基础上再拿到一个没拿过的 ,那么概率就是 ,期望就是
所以结果就是
因为数据有点大 所以上高精度
1 | # include<stdio.h> |
————————————————————————————————————
————————————————————————————————————
给你n个字符串,每个字符串有一个价值,
然后有两种操作
1 x y 将第x个字符串的价值变成y
2 x 问你以第x个字符串做为后缀的且价值小于等于第x个字符串价值的字符串有多少个
注意一个串是自身的后缀.
本以为这题另有高论, 后缀??! 后缀数组什么的…
但是没想到到啊 这个 都能过…
首先预处理出每个字符串后缀的hash,
然后每次暴力枚举每个字符串判断就好了.
1 | # include<stdio.h> |
————————————————————————————————————
开始你有m钱,有n天,有一个显卡,在每天有不同的价格,你可以在某一天买显卡,或者卖显卡,或者不买不卖,问最后你的钱最多是多少。
显然要在便宜的时候买,贵的时候卖,
然后考虑到 对于两个相邻的天,如果前一天的便宜,今天的贵那么就可以在前一天买然后在今天卖掉,这样就能赚钱了,
然后考虑 的时候 ,应该在天买,天卖,那么其实和在天买,天卖天买,天卖 效果是等价的,所以只要比较两天的价格就好了,
如果 那么就在天买,天卖。
不知道为什么用那个C++的高精度板子,就是过不去,然后用了Java才过。。
1 | import java.io.*; |
————————————————————————————————————
有n个人,每个人有一个物品,问你打乱这些物品后至少有K个人还拿到自己的物品的可能数
考虑错排,
然后将至少有k个人的k+1个人的…n个人能拿到自己物品的方案数累加就行了,
1 | # include<stdio.h> |
————————————————————————————————————
两个人下井字棋,现在轮到Kim下,问你Kim在下两个子的内能不能赢
考虑数据范围这么小 直接暴力枚举就好了,
首先枚举’.’ ,如果Kim下在这里就赢了 那就是Kim win
如果不是的话 要判断当前的局面 Kim是不是有大于两个地方能赢,这样才不会被另一个人扳平,
所以暴力枚举两次就行了
1 | # include<stdio.h> |
2017-07-20 21:19:45 Tabris_ 阅读数:581
博客爬取于2020-06-14 22:39:35
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75578185
#首先膜一发qls
题目质量很高,看样子是训练题而不是套题 ,没有特别简单的题目,
然后再次感到自己菜的一逼
——————————————————————————————————————————
——————————————————————————————————————————
——————————————————————————————————————————
给你一个队列,每个人要做一个事情,他们分别在时刻准备好,并在轮到他的时候花费时间完成.
每次要花费一分钟检查队头的人准没准备好,如果队头的人准备好了就开始做,做完就离开,否则去队尾.
这个和CF div.2 424 E比较像,但是需要多维护这些人的时间什么的。复杂一点
首先能想到维护一个当前的时刻
那么能想到 每次操作 处理一个人,那么这个人一定是接下来的人中第一个准备好的,
于是 考虑每次只维护这些能准备好的人,将这些人的序号放入set中,每次遍历一轮,同时维护当前时刻将能准备好的在加入到set中, 计算两个人之间花了多少时间用一个树状数组维护一下即可
设立一个当前时间, 在当前时间下 走过一圈能准备好的 加入set 然后处理这些,
因为加入一个元素到set后,当前时间不处理 下一次也一定处理了,所以最多也就被访问两遍
总复杂度
set怎么这么强大啊 基本可代替SPLAY啊。
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
给你四个点,问你有没有一个三角形能经过这四个点,能的话输出YES和任意一个这样的三角形,否则输出NO
没写代码,口胡一下
——————————————————————————————————————————
——————————————————————————————————————————
有两个序列A,B,在选择一个数使A数组的每一个元素减去这个数,然后根据建边,然后求最大二分匹配,问你这个最大二分匹配是多少,
首先考虑到应该通过一种什么样的方式枚举这些数,然后求这个二分匹配哦,但是光二分匹配的复杂度就已经O(VE)了, 所以这部分一定能优化
然后考虑到,这是一些序列,而建边的方式又是根据距离,所以这相当于在直线上的匹配,
然后发现对于数组a中的每个元素,如果要是匹配最大,左边的a一定尽量选左边的b, 对于b同理
那么我们可以枚举a和b数组,从左向右找,
那么分析如果当前,那么,否则的话 就选这两个中靠右的留下,因为靠左的已经不能在和他匹配的了
所以这部分就可以用的复杂度处理.
然后想到如何枚举这些数
考虑 这个数的选取最好能使一个a[i]和b[j]匹配上,所以可以枚举a[i]-b[j]
注意的是这两个数能匹配上的点恰好是a[i]-b[j]-e 所以枚举这个就好了
复杂度为
总复杂度
1 | # include<stdio.h> |
——————————————————————————————————————————
给你一个序列,两个相邻的数之间可以放一个乘号或加号,问你所有可能下 放完符号的序列 运算完的结果总和是多少
首先考虑每个数的贡献,但是因为有乘法在,容易重复,于是变成求以每个数结尾的单项式对结果的贡献
于是设
f[i] 表示以第i个数结尾的单项的系数 即:为对结果的贡献
f[i]转移就是
然后加上每个数作为加数的贡献,
算一下就好了 能发现除了首尾 都是
最后计算结果 看代码把
因为是从3开始算得 所以1和2的情况要特判
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
——————————————————————————————————————————
——————————————————————————————————————————
——————————————————————————————————————————
]]>2017-07-18 21:46:10 Tabris_ 阅读数:560
博客爬取于2020-06-14 22:39:36
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75331107
做的怀疑人生啊 最终5题,其中F和J思路都是对的 但是就是不AC啊
看来之前高估了自几的代码能力,以为代码能力已经差不多了,,没想到原来代码能力都这么菜。
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
每回合两个人轮流在一个序列中任意取一个数,谁的数大谁的1分 ,相等 不得分,问你所有可能下先手得分的期望
能确定得分的期望 就是任意顺序下总得分除以总的所有可能的轮数
所有可能的轮数 就是 因为取数是有顺序的 所以就是全排列
然后计算先手的总分
考虑拿先手拿到时对结果的贡献.
那就是
后手取的 是 固定这两个数 然后一共有轮,这是其中的一轮,所以乘一个
而其他的个数 就又是全排列的
然后约分下式子就是
计算的时候只要先对a排个序 然后二分就好了
总复杂度是
1 | LL a[N]; |
————————————————————————————————————————————
和上一题一样
只不过 先手只能那自己的那个序列里面的数 后手同理
公式为
做法和上题一样,只不过计算分子的时候是对b进行二分
1 | LL a[N],b[N]; |
————————————————————————————————————————————
队友写的 我不知道这个题 。。。 等会儿 补、、
1 |
————————————————————————————————————————————
给你两个序列, 然你合并成一个字符串,保证新字符串中每个元素在原字符串中的顺序不该变, 使得这个新的字符串的字典序最大。
想了几个小时的贪心,(虽然有dalao这么做过去了,但是我菜啊 调了很久 还是不行,最终放弃…)
正解是后缀数组
首先能想到对两个序列 进行类似归并的过程,取最大的。
但是如果当前一段的数都相同的时候就会判断出错误。
应该用后缀数组来处理,
将这个两个数组前后拼接成一个
用后缀数组来处理出Rank[]
然后遇到a[la]和b[lb]相同是不知道选哪个的情况
就将Rank[la]和Rank[lb]进行比较,哪个大就选哪个, 因为要大的数,所以选择优先级小的
附带一点数据,
1 | //#include <bits/stdc++.h> |
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
给你几个点,问你有多少对全等三角形,
两个三角形 不能取相同点 ,
判定相等的时候可以旋转图形,但是不能翻转
注意,
然后考虑如何判定三角形全等,
由初中学过的 ,三边相等就行了, 但是题目要求 可以旋转,但是不能翻转
所以们要对两个图形判定一下,只要固定一个旋转另一个判定就好了, 有一次满足就行,
但是要注意 描述这两个三角形的时候要采取同样的顺序,要顺时针都是顺时针,否则都逆时针,
然后n只有10 ,所以
所以总复杂度是
1 | int n,ans; |
————————————————————————————————————————————
给你一个无向图,问你最多去掉多少条边,使得剩下的图中 任意两点间最短路长度不变
首先题目手没有自环,于是 需要去重边,边取最短的。
看到n为 100 就想到是floyd
然后 考虑 floyd 中松弛的过程
那么这个过程中,如果边 被松弛了 那么这条边就可以被删掉了,
注意些细节不要计算重复就好了
给队友说完这个思路,然后作为我队唯一图论选手的XXX居然没有认同,,最后认同了写了代码 还wa。。。 我也很绝望啊
1 | int n,m,ans; |
2017-07-18 09:10:38 Tabris_ 阅读数:892
博客爬取于2020-06-14 22:39:37
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75270526
题目链接:http://www.spoj.com/problems/FTOUR2/
—————————————————————————————————————
FTOUR2 - Free tour II
no tags
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, Travel Agent SPOJ goes on with another discount tour.
The tour will be held on ICPC island, a miraculous one on the Pacific Ocean. We list N places (indexed from 1 to N) where the visitors can have a trip. Each road connecting them has an interest value, and this value can be negative (if there is nothing interesting to view there). Simply, these N places along with the roads connecting them form a tree structure. We will choose two places as the departure and destination of the tour.
Since September is the festival season of local inhabitants, some places are extremely crowded (we call them crowded places). Therefore, the organizer of the excursion hopes the tour will visit at most K crowded places (too tiring to visit many of them) and of course, the total number of interesting value should be maximum.
Briefly, you are given a map of N places, an integer K, and M id numbers of crowded place. Please help us to find the optimal tour. Note that we can visit each place only once (or our customers easily feel bored), also the departure and destination places don’t need to be different.
Input
There is exactly one case. First one line, containing 3 integers N K M, with 1 <= N <= 200000, 0 <= K <= M, 0 <= M <= N.
Next M lines, each line includes an id number of a crowded place.
The last (N - 1) lines describe (N - 1) two-way roads connected N places, form a b i, with a, b is the id of 2 places, and i is its interest value (-10000 <= i <= 10000).
Output
Only one number, the maximum total interest value we can obtain.
Example
Input:
8 2 3
3
5
7
1 3 1
2 3 10
3 4 -2
4 5 -1
5 7 6
5 6 5
4 8 3
Output:
12
Explanation
We choose 2 and 6 as the departure and destination place, so the tour will be 2 -> 3 -> 4 -> 5 -> 6, total interest value = 10 + (-2) + (-1) + 5 = 12
题目大意:
给你一棵树,树上的节点有白点有黑点,其中找到一条路径使得在经过的黑色点数不超过K的时候 路径长度最大,输出这个最大值
注意! 注意! 这里最小值要初始化为0,而不是-INF,可以路径上只有一个点…wa到死有没有!!!
还是采用点分治,
首先 对于每个子树 找 经过根节点的 满足条件 最大值
可以想到在遍历子树的时候
维护一个 记录当前节点到根节点经过i个【黑】点时的距离
处理出一个前缀最大值 然后就能O(k/2)的计算 当前最大值
但是问题时如何 避免以根节点儿子为根的子树中的不满足的值
笨想就是 枚举两个子树 然后维护,但显然这部分复杂度是的
然后就像 其实对一个子树来说 就是要找它和除这个子树外的其他子树的最大值的和
对于n个子树来说 直接将前i-1的结果个合并,
然后就能直接维护第i个子树的答案了
然后这部分操作
然后采用优化策略 只有,找到对每个以根节点儿子为根的子树中 经过最多的黑色点的路径中黑色点数为A,由于A大于K的地方对结果无贡献,就不用计算了, 这里算一个剪枝.
然后对前i-1个结果合并的时候 采取启发式合并,先合并小的,在合并大的,这样的话 维护下来 中的上届会递增,能够优化.
最后总复杂度就是 [详细复杂度分析请移步国家队论文↑]
附本题代码
——————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-07-17 20:37:58 Tabris_ 阅读数:375
博客爬取于2020-06-14 22:39:38
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75267826
题目链接:http://poj.org/problem?id=1741
——————————————————————————————————————————
Tree
Time Limit: 1000MSMemory Limit: 30000K
Total Submissions: 22808Accepted: 7542
Description
Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
Input
The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.
Output
For each test case output the answer on a single line.
Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
Sample Output
8
——————————————————————————————————————————
题目大意:
给你一棵树,问你两点间距离不超过k的点对个数
最好去看论文===>戳这里
考虑到每颗树上 统计路径经过树根的点对,
很容易想到 处理一遍子树 记录每个节点到达根节点的距离,
然后就变成了
给定一个序列,统计两个数加和不超过k的数对的个数
尺取法就能做了
但是注意这里计算之后会有重复的情况
比如当前计算的是根为1 的情况 这个时候如果k比较大 那么还会把<4,6>的情况 给计算上,但是<4,6>的路径是 4->5->6
所以我们还需要减去以1的儿子节点为根的时候的情况
并不断递归下去找一颗颗子树.
但是这样下去的话 能发现 不断递归下去的话
复杂度依赖于 树的形态
如果树是严格平衡的话递归下去的复杂读就是
如果树的形态是一条链的情况 就会变成
于是这里 采取树的重心 作为树根,这样下去的话 能保证 递归下去的深度最低 最终做到复杂度O [证明请移步国家队论文↑]
注意: 对于 递归下去的子树 为了保证复杂读 也要再次采用重心为根来做,
于是最终复杂度就变为
其中一个 为分治 向下递归的复杂度
另一个 为统计的时候 需要保证序列单调的 排序复杂度
附本题代码
——————————————————————————————————————————
1 | # include <stdio.h> |
2017-07-16 18:15:11 Tabris_ 阅读数:934
博客爬取于2020-06-14 22:39:39
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75208683
链接: https://post.icpc-camp.org/d/691-2017
————————————————————————————————————————————————
签到题
注意-2^63 的情况和2^63不能用64位长度的数表示就好了
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————————
————————————————————————————————————————————————
————————————————————————————————————————————————
给你一个DAG图,每个节点不是白的就是黑的,有q次操作,每次将点x变换颜色.然后输出当前< u,v>有多少对,
< u,v>定义为; 当存在一条从u到v的路径使得路径上没有黑色的点是存在.
考虑到DAG图,所以进行拓扑排序,
每次操作完,之后将黑色的点去掉,然后进行拓扑序,在过程中记录能到达每个点的个数,然后一路算过去就行了,然后去个重复采用vis标记,复杂度是 ,然后妥妥的TLE了,
最后想到用二进制来优化,每一位对应表示每一个节点,然后进行TOP过程中与一下就行了.
可以用5个64位整形计算 (这时候注意求1的个数的时候要用lowbit优化)
也可以用bitset来计算
最后复杂度为 ,其中为bitset优化的常数
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————————
给你个序列 问你去除每个数之后剩下的数中的结果
结果定义为 $\displaystyle f_1^2 \xor f_2^2 \xor … \xor f_n^2 f(i)a(i)$结尾的lis的长度
最暴力的想法是求遍复杂度为 ,一定TLE, 然后想如何优化为
然后想到删除一个数之后对的影响至多减少1, 所以在我们有了原序列的之后 我们就可以的求每次新的
过程中只要记录 长度为的上升序列当前的最小结尾是谁 ,然后每次看长度为的序列的结尾和比谁大 就能判断是否减了1
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————————
给你,问你是否永远非负
考虑到数据范围只有,于是选择打表,
判断过程是计算 过程中有没有负的,然后输出
代码太长了 http://paste.ubuntu.com/25102699/
————————————————————————————————————————————————
给你4个数
问你
考虑到2017是素数,满足的情况用坐标系表示的话一定在上 ,所以直接计算就好了
1 | LL cal(LL a,LL b){ |
————————————————————————————————————————————————
————————————————————————————————————————————————
————————————————————————————————————————————————
给你一个n*n的方阵 求每个子矩阵的元素和的三次方的和
其中
其中
我TM是有多无聊 会来补这个题,,,MD 不补了
然后在对于每种情况的求一下对结果的贡献系数
然后推到一下 ,就需要在预处理出几种前缀和,后缀和,
然后统计即可 总复杂度是的
代码没写 看dalao的吧
————————————————————————————————————————————————
对于原根理解的十分不到位,只停留到会计算,
算是强行补题.
将乘法转化为加法
个人理解其实这部分相当去将ax%2017和ay%2017的结果进行了优化,能够方便记录每一位的值
考虑dp[i][j] 表示到第i个点后取模结果为j的数的个数 然后优化下空间到dp[2017];
每次转移就是
然后因为转化为加法后 能够快速找到值, 又有最后的结果要对取模 能够想到二进制的方法做,
这里采用了bitset
1 |
|
————————————————————————————————————————————————
给你一个序列以及
问你
有了s3 , 所以可以先求3个数的情况,然后找第4个数,
然后发现,每次如果第4个数选择,那么结果就多了
所以遍历一遍序列,即固定 同时能求出 从而能求出
1 | # include <bits/stdc++.h> |
2017-07-15 23:48:58 Tabris_ 阅读数:339
博客爬取于2020-06-14 22:39:40
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75194944
题目链接:http://www.ifrog.cc/acm/contest/1020
——————————————————————————————————————————
观察数据范围,发现点只有111111个,那么可以记录每种点的个数,然后平方枚举计数即可,
(话说我当时为什么要写一个树状数组…用数组的话 多么简单…最后处理下前缀和就行了啊)
–
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
要注意k为0的情况 所有 所以答案就是
首先有
然后发现存在长度为p的循环节 然后打表找规律发现
对于一般情况下一段循环节队结果的贡献是0的
如果k为p-1的倍数。则除时贡献为0 其他情况下贡献是1
由费马小定理可知 所以这里有
而由于有 所以不成一个循环节的部分暴力就行了.
成循环节的部分 分类讨论下即可
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
首先考虑暴力做,有一个的dp,
但是考虑到增长极快,所以我只要向左找至多 60个就行了
1 | # include <bits/stdc++.h> |
——————————————————————————————————————————
考虑每条边对结果的贡献,
最大化的利用的就是把a,b放到边的左右两边 ,且使最小时最大就行了,这就是这条边贡献的倍数
就按照边的贡献倍数最大的加最大的c[i] ,次大的加次大的c[i] …就行了
可以dfs一边处理 出每条边的贡献倍数,
然后贪心加过去就好了
然后注意这个爆栈的问题
1 | //#pragma comment(linker, "/STACK:102400000,102400000") |
——————————————————————————————————————————
虽然以我的能力几乎不可能在现场调完这道题,但是还是嘴巴了下
当时考虑了256个颜色就可以用4个64位整形或者长度为256的bitset维护
由于有了区间翻转,所以一定要用splay
对于方阵的处理 可以建立n个splay (后来题解说可以仅简历一个splay,因为每次操作区间都是在一行内的连续区间)
]]>所以对我来说难点就是处理二进制标记上,不是很好处理啊,码力不够啊…
2017-07-14 23:27:34 Tabris_ 阅读数:296
博客爬取于2020-06-14 22:39:41
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75138225
好吧 、我也只能做个嘴炮选手了,,,
——————————————————————————————————————
日常傻逼题,注意明确题意在写、
——————————————————————————————————————
有一个加密方式,把26字母分别映射成一个字母,然后给你密文,让你输出原文
映射一下就好了。注意1~0和大写的情况。、
——————————————————————————————————————
给你n个评委打分的情况,和其中k次分数,问你初始分数的可能数
首先处理出打分的前缀和,能知道到第i个人评分后距离初试分数的差值
然后排序。从小到小枚举 不同的差值。
然后从小到大枚举可能分数,做一个类似双指针的东西 ,找分数相匹配的个数 比n大 则有一个初始分数的可能性
——————————————————————————————————————
有n个人,m个keys,目的地p,
每个人要拿一个keys到达p,
没走1m花费1个单位时间,
问所有人到达p的最小时间
首先考虑这是在直线上,从最左边的人开始枚举,那么为了方便其他人,他所拿的keys一定是尽可能靠左的
所以二分答案 check就行了
——————————————————————————————————————
有n张卡片,成一个队列,每次操作如果队头是队列中最小的就拿出去,否则放到队尾。
问等队列为空 操作了多少次
其实就是个模拟。
但是直接模拟复杂度是的 显然不可取
然后考虑如何维护。
首先由于有删除点,首先想到SPLAY维护,将该删除的删除,或者放到意义上的最后。
每次找当前意义上对头后面的最近的最小值
复杂度大概是 而且实现起来有一定难度,
然后想每一次删除相当于存在,或者不存在, 想到用BIT维护 即可求意义上的两次删点的操作次数。
找最小值,看到1e6的范围想到桶排,然后同样大小的 要记录位置,所以开vector数组即可
维护一个意义上队头,然后二分找那个位置最近。不断维护即可
复杂度是
——————————————————————————————————————
有n个植物,最开始均为0米。每天长1米。可以认为修剪,且修建后植物不生长,。
每隔d天需要人去修剪照看。
问你在剪下去的长度和小于k的情况下 d最大为多少
最先有$ \dfrac{k+\displaystyle\sum_{i=1}^{0}a_i}{n}$ 如果大于 那么就是d的一种可能性
其实就是求其中d的最大值
先排序
考虑暴力的情况,枚举答案是1~a[n] ,然后判定,
然后想二分,但是发现 不满足单调性,所以不行。
考虑如何优化这个枚举过程。
首先考虑这个式子
然后考虑分段枚举d的时候对于只有种情况, 不知道的话 可以先做做这道题<–戳这里
于是枚举即可,考虑这个限制的同时不断维护最大值
注意d对每个a[i] 分段枚举的时候要满足所有的a[i] ,所以要取最小的.
复杂度
]]>2017-07-14 19:00:51 Tabris_ 阅读数:324
博客爬取于2020-06-14 22:39:42
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/75127871
题目链接:
[CDOJ] https://vjudge.net/contest/170394#overview
[hrbust1395~1402(中文题面哦!) ] http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblemVolume
题目其实很简单,可能由于考试周后第一天训练,状态不对吧,题意都搞不清,
再加上C题后台数据应该出了问题卡了好久,在hrbustOJ上能AC…
—————————————————————————————————————————
日常傻逼签到题 不解释
—————————————————————————————————————————
同样傻逼签到题 不解释
—————————————————————————————————————————
模拟题,模拟ICPC赛制的rank,
与现实规则中,多了一条,一血没有罚时的规则
模拟即可
1 | # include <bits/stdc++.h> |
—————————————————————————————————————————
游戏规则很简单,目标是由 1-20 这些区间组成,中心的红点是50分,中心的绿色环是25分,另外两个环一个是分数乘 3 的区域,一个是分数乘 2 的区域(如右图)。 每个运动员现在有 N 分数,每个运动员的目标是把自己的分数变为0,而方式是通过每投掷一次飞镖,总分减去投掷所得的分数,且每个运动员要保证最后一次投掷的飞镖要落在分数乘2的区域,也就是 Double Ring区域。谁先把自己的分数降低为0 谁先赢。
而你的任务是:
给你一个运动员的起始分数,分数为 N,你需要计算出有多少种投掷飞镖的方式能够把分数降到0. 不同的方式意味着: 两两方式之间至少有一种方式的某个步骤和另一个不同,如果两个方式可以通过改变其中某种方式相应步骤的顺序来使其和另一个方式相同的话,这两种方式算作一种。
例如:N=4, 有四种方式达到 0: 一次(1X2)分, 两次1分加上一次(1X2)分,一次2分加上一次(1X2) 分,两次(1X2) 分。
由于结果可能很大,你需要对结果模上 2011。
首先考虑dp[i],表示从0~i的方案数
那么dp过程中相当于进行完全背包,物品的重量分别是
转移过程就是
1 | dp1[0]=1; |
然后要明确,拿分的顺序不影响方案数,所以只要过程中有至少一个2倍的即可
所以考虑两次dp
一次求dp1[],表示所有情况的结果
另一次求dp2[],表示去除2倍的结果
最终结果就是dp1[]-dp2[];
1 | # include <bits/stdc++.h> |
—————————————————————————————————————————
给你两个字符串,问你循环之后能不能相等,最开始相等不算
其实就是最小表示法
1 | # include<stdio.h> |
—————————————————————————————————————————
有n个村庄,有q次询问,每次询问在第i个到第j个村庄找一个位置作为邮局,使得第i个到第j个村庄到邮局的距离和最小,输出这个值
好吧,我并没有写代码,所以思路和代码可能有点细微的差别
村庄的位置时升序的
考虑每次查询的i,j
很容易发现,在第i个和第j个间任选一个位置做邮局对于村庄i,j是一样的
那么对于第i+1个和第j-1个同理,
…
所以能够确定的是邮局位置找中间的那个村庄就行了,(偶数个的话中间两个都一样
然后在计算结果的时候,我们可以先处理一个前缀和,然后能做到O(1)
1 | # include <bits/stdc++.h> |
—————————————————————————————————————————
平面上有n个点,
两个人可以拿在同一条直线上的点,
能拿3个及以上的点或者最后一个点的人获胜.
首先考虑如果有3个点以上在一条直线的情况先手必胜,
所以特判就好,
做法是枚举两个点间的斜率,对于点x,y,z 如果xy的斜率和xz的斜率相等可以了
剩下的就是普通的情况了,当然两点一定贡献,
所以剩下的就等价于一个n个石子最多取2个石子的巴士博弈
1 | # include <bits/stdc++.h> |
—————————————————————————————————————————
XianGe非常喜欢赛车比赛尤其是像达喀尔拉力赛,这种的比赛规模很大,涉及到很多国家的车队的许多车手参赛。XianGe也梦想着自己能举办一个这样大规模的比赛,XianGe幻想着有许多人参赛,那是人山人海啊,不过XianGe只允许最多100000人参加比赛。
这么大规模的比赛应该有技术统计,在XianGe的比赛中所有车辆的起始点可能不同,速度当然也会有差异。XianGe想知道比赛中会出现多少次超车(如果两辆车起点相同速度不同也算发生一次超车)。
首先对x排序,
然后x小的如果速度比x大的大就能超车了
排完序之后用BIT维护一下就好了
1 | # include <bits/stdc++.h> |
—————————————————————————————————————————
相信大家都玩过九连环的游戏 ,九连环的规则是 :
1第一个环可以在任何时候挂到柄上或者从柄上摘下
2在任何时候,你只能操作一个环
3如果前k-2个环都没有在柄上,并且第k-1个环在柄上,这时如果第k个环在柄上的话,可以把它摘下来,如果它不在柄上,可以把它挂上去
给定一个数n,n不大于10的8次方,你的任务是输出从柄上摘下n个环需要的最小操作次数,测试数据不超过100组。
终于理解了九连环怎么玩之后,手动模拟的了一下,
发现最后变成
0000011
1111100(长度为n)
的时候需要的次数均是的
而接下来需要的操作相当于长度为n-2时的操作,
所以有了递推式
然后构造矩阵就行了
1 | # include <bits/stdc++.h> |
—————————————————————————————————————————
给定你一个质数p (p < 10^8),请你确定最小的x^2 + y^2 (其中x, y都是正数),使得x^2 + y^2 = 0 (mod p)
首先根据p为素数,能想到i*i%p的循环节是p.
所以说如果选择数的话 一定在这个循环节里面,
然后能想到$ii+jj=p pp+pp$
然后想到枚举平方数找存不存在$ii+jj=p $ ,复杂度为 1e8差不多能过
然后写出了下列代码,就TLE了
1 | # include <bits/stdc++.h> |
最后贯彻**“遇事不决先打表”**这个思想,发现,如果素数形如4*k+3这种,结果就是 否则就是
1 | # include <bits/stdc++.h> |
2017-07-05 22:42:33 Tabris_ 阅读数:382
博客爬取于2020-06-14 22:39:44
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74505041
题目链接:https://cn.vjudge.net/problem/UVALive-7344
——————————————————————————————————————————
You have N cards and each has an unique number between 1 and N written on it. In how many
ways can you select a non-empty subset of the cards such that the number written on any two of your selected cards don’t have any common digits?
For example, when N = 12, {1, 2, 3}, {2, 11}, {3, 4, 5, 6, 7, 8, 9, 12} are some valid selections. But
{1, 2, 10}, {2, 5, 12} are not allowed.
Input
The first line of the input contains an integer T which is the number of test cases. Each of
the following T lines denote a test case, containing an integer N .
Output
For each test case, output the case number followed by the number of subsets modulo 1000000007.
Sample Input
2
3
12
Sample Output
Case 1: 7
Case 2: 1151
————————————————————————————————————————————
题目大意:
让你在[1,N]内选择一些数构成一个集合,使得集合中任意两个数没有相同的数字,(但一个数可以由相同的数字比如11.22),问你合法的集合的个数
首先能确定的是集合中数最多不超过10个,那么可以枚举来
先选择一个,在选择第二个,保证其两者不没有相同位即可
显然这个过程是可以进行dp的
用长度为10的二进制表示0~9.然后进行转移即可
设dp[i][j],表示取到第i个数是选择了j(二进制)对应的这些数字
从而有dp[i][j]=\displaystyle \sum dp[i-1][k]*A(表示k\xor j这个状态下的数的个数)
显然有一个O(1010241024)即可
但是对于A(表示k\xor j这个状态下的数的个数)我们应该怎么求呢
显然是预处理啊 ,
通过数位dp进行统计,预处理出每种状态下的数的个数。
附本题代码
————————————————————————————————————————————
1 | LL dp_nex[15][(1<<12)]; |
2017-07-05 19:07:23 Tabris_ 阅读数:239
博客爬取于2020-06-14 22:39:45
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74482641
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1404
————————————————————————————————————————————
Digital Deletions
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2891 Accepted Submission(s): 1052
Problem Description
Digital deletions is a two-player game. The rule of the game is as following.
Begin by writing down a string of digits (numbers) that’s as long or as short as you like. The digits can be 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and appear in any combinations that you like. You don’t have to use them all. Here is an example:
On a turn a player may either:
Change any one of the digits to a value less than the number that it is. (No negative numbers are allowed.) For example, you could change a 5 into a 4, 3, 2, 1, or 0.
Erase a zero and all the digits to the right of it.
The player who removes the last digit wins.
The game that begins with the string of numbers above could proceed like this:
Now, given a initial string, try to determine can the first player win if the two players play optimally both.
Input
The input consists of several test cases. For each case, there is a string in one line.
The length of string will be in the range of [1,6]. The string contains only digit characters.
Proceed to the end of file.
Output
Output Yes in a line if the first player can win the game, otherwise output No.
Sample Input
0
00
1
20
Sample Output
Yes
Yes
No
No
————————————————————————————————————————————
题目大意:
给你一个长度不超过6的有数字组成的字符串,两个人分别操作,最后一次操作的人赢,问先手能不能赢.
有两种操作:
将任意一个不为0的数字变成小于它的数字
将任意一个0开始及其右面的左右数字删除.
很容易想到要用SG函数来求解,且第一个数字为0的先手必胜
但是这种时候用mex操作来求解SG函数实在太过麻烦,而且其中对于有前置0的状态很不好表示。
所以这里求解SG函数的时候用定义来求:
SG[]=0 表示必败 SG[]=1 表示必胜
能一步到达必败态的状态一定是必胜态.
所以我们从必败态出发,很容易表示其上一步状态,且不会出现有前置0的情况,
有SG[1]=0;
所以能够确保能够到达所有的状态在[1,1000000)
附本题代码
————————————————————————————————————————————
1 | int sg[1000001]; |
2017-07-05 12:32:49 Tabris_ 阅读数:312
博客爬取于2020-06-14 22:39:46
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74408116
题目链接:http://www.spoj.com/problems/VECTAR1/
——————————————————————————————————————————
VECTAR1 - Matrices with XOR property
no tags
Imagine A is a NxM matrix with two basic properties1) Each element in the matrix is distinct and lies in the range of 1<=A[i][j]<=(NM)2) For any two cells of the matrix, (i1,j1) and (i2,j2), if (i1^j1) > (i2^j2) then A[i1][j1] > A[i2][j2] ,where 1 ≤ i1,i2 ≤ N1 ≤ j1,j2 ≤ M.Given N and M , you have to calculatethe total number of matrices of size N x M which have both the propertiesmentioned above. Input format:First line contains T, the number of test cases. 2T lines follow with N on the first line and M on the second, representing the number of rows and columns respectively.Output format:Output the total number of such matrices of size N x M. Since, this answer can be large, output it modulo 10^9+7Constraints:1 ≤ N,M,T ≤ 1000SAMPLE INPUT 122SAMPLE OUTPUT 4ExplanationThe four possible matrices are:[1 3] | [2 3] | [1 4] | [2 4][4 2] | [4 1] | [3 2] | [3 1]
Imagine A is a NxM matrix with two basic properties
Each element in the matrix is distinct and lies in the range of 1<=A[i][j]<=(N*M)
For any two cells of the matrix, (i1,j1) and (i2,j2), if (i1^j1) > (i2^j2) then A[i1][j1] > A[i2][j2] ,where
1 ≤ i1,i2 ≤ N
1 ≤ j1,j2 ≤ M.
^ is Bitwise XOR
Given N and M , you have to calculatethe total number of matrices of size N x M which have both the properties
mentioned above.
Input format:
First line contains T, the number of test cases. 2*T lines follow with N on the first line and M on the second, representing the number of rows and columns respectively.
Output format:
Output the total number of such matrices of size N x M. Since, this answer can be large, output it modulo 10^9+7
Constraints:
1 ≤ N,M,T ≤ 1000
SAMPLE INPUT
1
2
2
SAMPLE OUTPUT
4
Explanation
The four possible matrices are:
[1 3] | [2 3] | [1 4] | [2 4]
[4 2] | [4 1] | [3 2] | [3 1]
——————————————————————————————————————————
题目大意:
给定规则,问你满足这样的矩阵有多少个
规则:
显然按照升序排列后对应的也是升序
在相同的这个集合内,任意排列即可,
所以问题就是找相同的个数,
很容易想到FWT
,
构造两个向量a,b
a=(0,1,1,1,0,0,0,0,) 从第1个(第一个不是第0个)开始n个1
b=(0,1,1,1,0,0,0,0,) 从第1个开始m个1
然后进行FWT即可
上式即是期望结果,
计算全排列的时候预处理下就能做到O(1)计算
总复杂度
附本题代码
——————————————————————————————————————————
1 | int n,m,len,a[2222],b[2222]; |
2017-07-05 09:31:07 Tabris_ 阅读数:480
博客爬取于2020-06-14 22:39:47
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74374144
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534
————————————————————————————————————————
Partial Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1401 Accepted Submission(s): 693
Problem Description
In mathematics, and more specifically in graph theory, a tree is an undirected graph in which any two nodes are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.
You find a partial tree on the way home. This tree has n nodes but lacks of n−1 edges. You want to complete this tree by adding n−1 edges. There must be exactly one path between any two nodes after adding. As you know, there are nn−2 ways to complete this tree, and you want to make the completed tree as cool as possible. The coolness of a tree is the sum of coolness of its nodes. The coolness of a node is f(d), where f is a predefined function and d is the degree of this node. What’s the maximum coolness of the completed tree?
Input
The first line contains an integer T indicating the total number of test cases.
Each test case starts with an integer n in one line,
then one line with n−1 integers f(1),f(2),…,f(n−1).
1≤T≤2015
2≤n≤2015
0≤f(i)≤10000
There are at most 10 test cases with n>100.
Output
For each test case, please output the maximum coolness of the completed tree in one line.
Sample Input
2
3
2 1
4
5 1 4
Sample Output
5
19
————————————————————————————————————————
题目大意:
有n个节点,让你加n-1条边构建成一棵联通树,使得其权值和最大
题目给定节点度数为i的权值为f(i),
解题思路:
首先能够确定的是对于整棵树度数和为,
如果树联通的话,那么每个节点度数至少为.
于是问题就变成如何分配这几个度数
可以将这个问题变成在容量为的背包中不限次数拿取体积为价值为这样一个完全背包问题.
之后就是因为节点度数至少为了,而在转移的时候至少都是度数为的节点
那么转移过程应该怎么办?
这样考虑,如果多了一个度数为的节点,那么同时也就少了一个度数为的节点
显然在转移的时候先减去,最后在结果加回,那么就把应该有的度数为的节点计算上了.又因为最后这个是常数,不会影响dp转移的结果
附本题代码
————————————————————————————————————————
1 | int n; |
2017-07-04 21:01:07 Tabris_ 阅读数:274
博客爬取于2020-06-14 22:39:48
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74356926
题目链接:https://loj.ac/problem/516
——————————————————————————————————————————
516. 「LibreOJ β Round #2」DP 一般看规律
内存限制:512 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:文本比较
上传者: nzhtl1477
提交
提交记录
统计
测试数据
题目描述
给定一个长度为 n 的序列 a,一共有 m 个操作。
每次操作的内容为:给定 x,y,序列中所有 x 会变成 y。
同时我们有一份代码:
1 | int ans = 2147483647; |
请在每次修改后输出代码运行的结果。
输入格式
第一行两个数,表示 n,m。
第二行 n 个数,表示 。
然后 m 行每行两个数 x 和 y,表示序列中所有 x 会变成 y。
输出格式
对于每次修改,输出答案。
样例
样例输入
5 10
2 7 6 3 8
6 1
7 1
1 3
5 6
1 7
9 5
1 10
7 6
7 5
3 9
样例输出
2147483647
1
1
1
1
1
1
1
1
1
数据范围与提示
每个出现的数字绝对值在 int 范围内。
——————————————————————————————————————————
首先能够明确,两个数的集合合并之后结果一定是越来越小的
所以就是怎么维护两个数的集合的问题了
最开始采用map<int,vector<int> >
来维护
但是发现虽然最后维护的时候合并过程可以启发式优化
但是也需要将这个集合进行进行排序这样复杂度就爆炸了
然后想到用多颗SPLAY维护这个过程 ,然后码啊码,最后码炸了…
然后看了下由乃大佬的代码
发现居然可以用map<int,set<int> >
进行维护
由于set本身就是一颗RB-tree了.所以不需要在手写平衡树了啊 .
事实证明STL非常强大啊 ,强大到爆啊.
附本题代码
——————————————————————————————————————————
1 | int n,m,ans=2147483647; |
2017-07-03 14:51:58 Tabris_ 阅读数:987
博客爬取于2020-06-14 22:39:49
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74198393
题目链接:https://loj.ac/problem/515
——————————————————————————————————
内存限制:256 MiB 时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:文本比较
上传者: nzhtl1477
题目描述
一共有 个数,第 个数 可以取 中任意值。
设 ,求 种类数。
输入格式
第一行一个数 。
然后 行,每行两个数表示 。
输出格式
输出一行一个数表示答案。
样例
样例输入
5
1 2
2 3
3 4
4 5
5 6
样例输出
26
数据范围与提示
——————————————————————————————————
其实这个题目很好想,
显然S的范围在 ,
我们用一个数组标记一下那个位置的值存在,然后就好了
过程很简但维护一下即可,
但是复杂度是
然后当时采取了用两个栈+一个标记数组维护的想法 应该能去掉很多空状态,
写了一发但是还是TLE了
最后听说是用bitset这种东西来维护
其实就是一个可定义长度的01集合
经过内部算法优化了时间和空间复杂度
可以当成一个可变长度的整形来用
支持整形位运算符
本题就一样
将 用来标记
将 用来标记
很容易证明它的正确性
附本题代码
——————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-07-02 19:26:37 Tabris_ 阅读数:591
博客爬取于2020-06-14 22:39:50
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/74153824
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5909
——————————————————————————————————————————
Tree Cutting Accepts: 14 Submissions: 119
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others)
问题描述
Byteasar有一棵个点的无根树,节点依次编号为到,其中节点ii的权值为。
定义一棵树的价值为它所有点的权值的异或和。
现在对于每个的整数,请统计有多少的非空连通子树的价值等于。
一棵树TT的连通子树就是它的一个连通子图,并且这个图也是一棵树。
输入描述
第一行包含一个正整数,表示测试数据的组数。
每组数据的第一行包含两个正整数和,分别表示树的大小以及权值的上界。
第二行包含个整数,分别表示每个节点的权值。
接下来行每行包含两个正整数,表示有一条连接和
的无向边。
输入数据保证是的非负整数幂。
输出描述
对于每组数据,输出一行个整数,其中第个整数表示价值为的非空连通子树的数目。
因为答案很大,所以请模后输出。
输入样例
2
4 4
2 0 1 3
1 2
1 3
1 4
4 4
0 1 3 1
1 2
1 3
1 4
输出样例
3 3 2 3
2 4 2 3
——————————————————————————————————————————
很容易想到树形dp
设 以第个节点为根的联通子树异或和为的数目.
转移的过程就是dp[u][i^j]+=dp[u][i]*dp[to][j];
这部分很好想到,但是复杂度却是的.
显然超时
然后有了一个FWT这种东西,快速沃尔什变换
和FFT类似,同样是将一个的卷积运算转化为的.
FWT是
c[x] = \displaystyle\sum_{i \^ j=x} a[i]*b[j],与本题所求相同,套上去就好了
详细戳这里吧http://blog.csdn.net/liangzhaoyang1/article/details/52819835
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-28 20:14:52 Tabris_ 阅读数:282
博客爬取于2020-06-14 22:39:51
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73863598
题目链接:https://www.codechef.com/problems/MTRNSFRM
———————————————————————————————————————————
Chef has two n × m matrices A and B. He wants to make them completely identical, to achieve this goal, he can perform the following actions in a single move:
Choose one of the matrices, either A or B.
Choose either one row or one column of the selected matrix.
Increment all the numbers in the selected row or column by 1.
Now Chef is wondering, what is the minimal number of moves he has to perform in order to make matrices A and B equal? Or is it just impossible?
Input
The first line of the input contains an integer T denoting the number of test cases.
For each test case, the first line of input contains two integers n and m.
The following n lines contain m space separated integers each ― the matrix A.
The next n lines contain m space separated integers each ― the matrix B.
Warning! The size of the input file can be up to 10 MB!
Output
For each test case, output a single integer ― the minimal number of moves Chef has to perform in order to make matrices A and B equal or -1 if this is not possible.
Constraints
1 ≤ T ≤ 100
1 ≤ n ≤ m ≤ 105
1 ≤ n × m ≤ 105
Let us denote the sum of n × m over all T testcases by S
1 ≤ S ≤ 5 · 105
1 ≤ Aij ≤ 109
1 ≤ Bij ≤ 109
Example
Input:
3
2 2
1 1
1 1
1 2
3 4
2 2
1 9
9 1
9 1
1 9
1 4
4 5 7 1
2 3 4 5
Output:
3
-1
9
Explanation
Example case 1. We can transform the matrix A into B in three moves:
1 1 -> 1 2 -> 1 2 -> 1 2
1 1 -> 1 2 -> 2 3 -> 3 4
Example case 2. It is impossible to make these matrices equal using only the allowed moves.
Example case 3. We can transform matrix A into 4 5 7 7 in six moves and matrix B into the same 4 5 7 7 in three moves.
————————————————————————————————————————————
题目大意:
这两个矩阵 每次操作可以选出一个矩阵在它的任意一行或/列上加1,问你最少多少次操作使两矩阵完全一样
第一点很好想
将两个矩阵合在一起,生成一个新矩阵, 那么题目就相当于这个新矩阵可以再一行/列上加/减,最少多少次能变成全0矩阵.
这样会有两个操作,分别代表第i行/列的操作次数
显然对于新矩阵有
多以不满足这个条件的就是-1了
然后想啊? 怎么搞啊? 看了看这个数据范围,差分约束??! ,好像很牵强啊, 我一个没写过查分约束的还是换个思路吧,
然后考虑,
那么同时有
易得
但是这样 我们要枚举两个点进行判断么? no O(n^2)的复杂度是不能接受的
然后在想
我们能够发现
成立
那么一定有
所我们只要固定a[k][l]枚举a[i][j]就好了,
接下里就是求解了
答案显然是
但是我们求的是最小解。
这时候我们设
易得此时答案是
当t为中间值时最小,证明略
Codechef为什么这个强势,这只是个EASY难度啊啊啊啊
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-28 03:17:32 Tabris_ 阅读数:539
博客爬取于2020-06-14 22:39:52
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73825637
第一次完全凭自己水平进了d2 前50(最后居然变成了36…hhh), 然后因为我没做的C题数据出锅而unrated…
不开心啊…
————————————————————————————————————————————
日常简单模拟题
1 | int main(){ |
————————————————————————————————————————————
给你一个正n变形,和一个角度a
让你找三个点,使得这三个点构成的角,与a相减的绝对值最小
首先我们可以知道多边形的顶点是共圆的,所以以一个点为顶点的时候,其他边的圆周角大小相等,所以固定两个点也就是一个边,枚举另一个点即可
由于数据范围小,O(n) 维护即可,如果大了点的话 需要三分求解
1 | int n; |
————————————————————————————————————————————
题目问题比较大啊 正解最后都没有明确。 不补了
————————————————————————————————————————————
给你一个长度为n的序列
可以旋转n次,
问你$$\sum_{i=1}^n\Big|p[i]-i \Big|$$的值最小的时候是多少 需要旋转几次
其实很简单,
我们可以观察到每次旋转,除了最后一个数之外,其他的数需要减去的值都+1了
那么就是为非正值得数贡献+1,正数的数贡献坚毅
相当于变成 ,那也就是
那么我们可以先算出初始的结果,然后每次按照上述规则计算即可,
方法是用一个数组h[j]记录为j的数有多少个
对于的情况 其实就用一个变量维护一个零线 就可以了
处理下前缀和即可,
由于序列最后一个值要特殊处理,所有会有修改,所以采用BIT进行维护
在每次旋转中维护答案即可
总复杂度:
--------Update------
刚才又想了想 发现这个过程根本不需要BIT,直接数组,零线外加两个变量就行了,是能做到O(1)的。
附本题代码
————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
]]>2017-06-28 02:52:41 Tabris_ 阅读数:355
博客爬取于2020-06-14 22:39:54
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73825606
题目链接:http://codevs.cn/problem/1985/
————————————————————————————————————————
题目描述 Description
[HAOI2008] 排名系统 & [ZJOI2006] GameZ游戏排名系统:
GameZ为他们最新推出的游戏开通了一个网站。世界各地的玩家都可以将自己的游戏得分上传到网站上。这样就可以看到自己在世界上的排名。得分越高,排名就越靠前。当两个玩家的名次相同时,先上传记录者优先。由于新游戏的火爆,网站服务器已经难堪重负。为此GameZ雇用了你来帮他们重新开发一套新的核心。 排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。
输入描述 Input Description
第一行是一个整数n(n>=10)表示请求总数目。
接下来n行每行包含了一个请求。请求的具体格式如下:
+Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为不超过无符号32位整型表示范围的非负整数。
?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。
?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。
输入数据大小不超过2M。
NOTE:用C++的fstream读大规模数据的效率较低。
输出描述 Output Description
对于每条查询请求,输出相应结果。对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。
样例输入 Sample Input
20
+ADAM 1000000
+BOB 1000000
+TOM 2000000
+CATHY 10000000
?TOM
?1
+DAM 100000
+BOB 1200000
+ADAM 900000
+FRANK 12340000
+LEO 9000000
+KAINE 9000000
+GRACE 8000000
+WALT 9000000
+SANDY 8000000
+MICK 9000000
+JACK 7320000
?2
?5
?KAINE
样例输出 Sample Output
2
CATHY TOM ADAM BOB
CATHY LEO KAINE WALT MICK GRACE SANDY JACK TOM BOB
WALT MICK GRACE SANDY JACK TOM BOB ADAM DAM
数据范围及提示 Data Size & Hint
【样例解释】
20
+ADAM 1000000 加入ADAM的得分记录
+BOB 1000000 加入BOB的得分记录
+TOM 2000000 加入TOM的得分记录
+CATHY 10000000 加入CATHY的得分记录
?TOM 输出TOM目前排名
?1 目前有记录的玩家总数为4,因此应输出第1名到第4名。
+DAM 100000 加入DAM的得分记录
+BOB 1200000 更新BOB的得分记录
+ADAM 900000 更新ADAM的得分记录(即使比原来的差)
+FRANK 12340000 加入FRANK的得分记录
+LEO 9000000 加入LEO的得分记录
+KAINE 9000000 加入KAINE的得分记录
+GRACE 8000000 加入GRACE的得分记录
+WALT 9000000 加入WALT的得分记录
+SANDY 8000000 加入SANDY的得分记录
+MICK 9000000 加入MICK的得分记录
+JACK 7320000 加入JACK的得分记录
?2 目前有记录的玩家总数为12,因此应输出第2名到第11名。
?5 输出第5名到第13名。
?KAINE 输出KAINE的排名
【数据范围】
20%数据满足N<=100
100%数据满足N<=250000
————————————————————————————————————————
首先这题考虑到玩家需要加分 ,那么就会产生一个新的排名,可以确定
这是一个SPLAY
因为排名是分数大的在前,所以是降序.我们可以在树上挂负值
那么考虑 怎么能在二叉排序树中找某个人的名字,?
这题光输入就很麻烦啊
名字 用一个map 映射成一个值就好了
考虑到先出现的在前 所以给这个值放大 然后+i就好了
然后在用这个值映射回名字即可,
一共两个map
其实还是很简单的 记录下分数 然后就找就行了
附本题代码
————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-27 19:07:39 Tabris_ 阅读数:203
博客爬取于2020-06-14 22:39:55
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73822126
——————————————————————————————————————————
简单SB题,
问你矩阵中所有大于的数能否用所在行的一个数加上所在列的一个数表示 ,如果都能就YES,否则NO
1 | int n; |
——————————————————————————————————————————
还是SB题,暴力找都不会超时
但是显然答案一定在线下方第一个点,
而直到每个点后的答案是能O(1)计算的
所以维护的最小值即可
1 | int main(){ |
——————————————————————————————————————————
让你维护一个栈,你可以将栈里面的元素重新排列,现在问你至少重新排列多少回 能让出栈的顺序为升序
就是在维护这个栈的操作,
进栈的时候一样
出站的时候看栈顶是不是预期的那个数,是的话就重新排列下即可
而这里的重新排列 可以用清空栈来代替
1 | char s[22]; |
——————————————————————————————————————————
N*M的二维矩阵,有K个位置时初始就是亮着的,一个人要走在当时亮着的格子从(1,1)到(n,m)
站在最初是亮着位置可以花费1来让某一行或某一列全变量,
问你最小花费
同时只能点亮某一行或某一列,那么一定是在最初两者的位置临近的两个行/两个列和本身所在的行/列,
再加上格子相邻的地方
按照这两种规则进行建图计算最短路就行了,
1 | struct node { |
——————————————————————————————————————————
有n条线段,线段平行于x坐标, 每次只能走在线段下方,从(x,y)能走到(x+1,y+1)(x+1,y)(x+1,y-1)这三个位置,问你最后到(k,0)的方案数,
简单的矩阵快速幂
只与必须在线段下方的限制,我们可以再计算之前将不合格的点清0即可
注意I64 要不然会GG
1 | # include <bits/stdc++.h> |
2017-06-27 14:51:27 Tabris_ 阅读数:239
博客爬取于2020-06-14 22:39:56
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73798177
##先附上官方题解:https://media.hihocoder.com/contests/challenge29/sol.pdf
啊啊啊啊啊啊啊啊啊啊啊啊 ,再次感觉到了自己有多弱!!!!!
时间限制:20000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个长度为 n 的序列 a[1…n],定义函数 f(b[1…m]) 的值为在 [0,m-1] 内满足如下条件的 i 的数目:
b 中前 i 个数异或起来的值小于 b 中前 i +1个数异或起来的值。
对于 a[1…n] 的每个子序列 b[1…m],求f(b[1…m])之和。
输入
第一行一个正整数 n。
接下来一共有 n 行。第 i+1 行包含一个非负整数 a[i]。
1 ≤ n ≤ 105
0 ≤ a[i] < 231
输出
输出答案对 998244353 取模后的值。
样例输入
2
1
2
样例输出
4
首先考虑a < a^b的情况, 显然需要a中二进制的0位在b中对应位是1且是b的最高位,不懂可以戳这里
然后就是需要对每个数 求贡献,
也就是找每个数 前面所构成在这个数最高位为0的异或和的个数,
可以设一个dp[31][0/1] 代表每一位位0/1的个数
转移就是
1 | int a[N],n; |
时间限制:20000ms
单点时限:1000ms
内存限制:256MB
描述
在写代码时,我们经常要用到类似 x × a 这样的语句( a 是常数)。众所周知,计算机进行乘法运算是非常慢的,所以我们需要用一些加法、减法和左移的组合来实现乘一个常数这个操作。具体来讲, 我们要把 x × a 替换成: 这样的形式,其中 是+或者-。
举个例子:x × 15 = (x<<4) - (x<<0)。
在本题中,假设左移(包括左移0)和加法、减法所需要的时间都是一个单位的时间,上述的例子所需要的时间是3。
现在给定常数 a 的二进制形式,求实现 x × a 最少需要多少单位的时间。
输入
一个01串,表示 a 的二进制形式,从左到右分别是从高位到低位。
0 < 01串的长度之和 ≤ 10^6。
a > 0。
输出
输出一个数,表示最小需要多少单位的时间可以实现 x × a。
样例输入
1111
样例输出
3
————————————————————————————————————————
是个二分拆幂 http://www.cnblogs.com/atyuwen/archive/2012/08/04/pow2_partition.html
附本题代码
————————————————————————————————————————
1 | # include <bits/stdc++.h> |
时间限制:40000ms
单点时限:2000ms
内存限制:256MB
描述
有 n 个小朋友在投篮,他们的赛制是这样的:对于每轮,每个人投一颗球,没投进的就淘汰掉,无法参加下轮。特别地,如果所有人都没投进,那就没有人被淘汰。他们将一轮轮比下去直到最后只剩1个人。
现在已知每个小朋友投进的概率是 p,求期望几轮结束比赛。
输入
第一行三个整数 n, x, y。
题目中的 p = x / y。
1 ≤ n ≤ 105
1 ≤ x < y < 998244353
输出
输出答案对 998244353 取模后的值。
分数取模的方法:https://math.stackexchange.com/questions/586595/finding-modular-of-a-fraction
样例输入
2 1 2
样例输出
2
——————————————————————————————————
不会
——————————————————————————————————
时间限制:40000ms
单点时限:2000ms
内存限制:256MB
描述
给定一个长度为 n 的非负整数序列 a[1…n]。
你每次可以花费 1 的代价给某个 a[i] 加1或者减1。
求最少需要多少代价能将这个序列变成一个不上升序列。
输入
第一行一个正整数 n。
接下来 n 行每行一个非负整数,第 i 行表示 a[i]。
1 ≤ n ≤ 500000
0 < a[i] ≤ 10^9
输出
一个非负整数,表示答案。
样例解释
[5,3,4,5] -> [5,4,4,4]
样例输入
4
5
3
4
5
样例输出
2
——————————————————————————————————————————
首先这题有个结论, 最后得到的序列中的每一个元素都在原序列中
首先考虑的dp
有了这个结论,我们可以直接dp
把变成第k大的那个序列所需要的最小花费就行了
但是这题数据范围明显需要
可以用左偏树降到,然后就上了个左偏树的模板
附本题代码
——————————————————————————————————————————
1 | # include <iostream> |
2017-06-21 23:51:59 Tabris_ 阅读数:219
博客爬取于2020-06-14 22:39:57
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73556860
题目链接:http://codeforces.com/problemset/problem/557/D
——————————————————————————————————————
D. Vitaly and Cycle
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
After Vitaly was expelled from the university, he became interested in the graph theory.
Vitaly especially liked the cycles of an odd length in which each vertex occurs at most once.
Vitaly was wondering how to solve the following problem. You are given an undirected graph consisting of n vertices and m edges, not necessarily connected, without parallel edges and loops. You need to find t — the minimum number of edges that must be added to the given graph in order to form a simple cycle of an odd length, consisting of more than one vertex. Moreover, he must find w — the number of ways to add t edges in order to form a cycle of an odd length (consisting of more than one vertex). It is prohibited to add loops or parallel edges.
Two ways to add edges to the graph are considered equal if they have the same sets of added edges.
Since Vitaly does not study at the university, he asked you to help him with this task.
Input
The first line of the input contains two integers n and m ( — the number of vertices in the graph and the number of edges in the graph.
Next m lines contain the descriptions of the edges of the graph, one edge per line. Each edge is given by a pair of integers ai, bi (1 ≤ ai, bi ≤ n) — the vertices that are connected by the i-th edge. All numbers in the lines are separated by a single space.
It is guaranteed that the given graph doesn’t contain any loops and parallel edges. The graph isn’t necessarily connected.
Output
Print in the first line of the output two space-separated integers t and w — the minimum number of edges that should be added to the graph to form a simple cycle of an odd length consisting of more than one vertex where each vertex occurs at most once, and the number of ways to do this.
Examples
input
4 4
1 2
1 3
4 2
4 3
output
1 2
input
3 3
1 2
2 3
3 1
output
0 1
input
3 0
output
3 1
Note
The simple cycle is a cycle that doesn’t contain any vertex twice.
——————————————————————————————————————
题目大意:
就是现在一个N个节点,M条边的无向图,问你最少添加多少条边,能找到一个奇圈,添加的方法有多少个
解题思路:
判断奇圈偶圈,很容易想到二分图染色,那么通过二分图染色,就能确定很多信息了,
首先能确定的是最多也就添加3条边, 3条边就能将三个点变成一个奇圈了,
那么添加边就是要变成一个3个节点的奇圈
那么就分这四种情况讨论
1.添加0条边
就是原图中有奇圈了, 通过染色判断,方案数就是1了
2.添加1条边
只需添加一条边的时候就是一个点a连向点b,c. 这时候将b,c连上就好了
这种情况需要在一侧的多个节点都能和另一边的节点直接或间接连上才行,
所以我用了一个并查集维护联通性,然后统计个数
3.添加2条边
如果一个节点至多被一条边连着,
那么想要构成奇圈,就要将边的两个端点连上另外的一个一个节点构成奇圈
方案数就是
4.添加3条边
只有一条边都没有的时候才要添加三条边,
方案数就是在n个点取3个节点的方案数
分类讨论即可
附本题代码
——————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-21 14:52:43 Tabris_ 阅读数:1804
博客爬取于2020-06-14 22:39:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73549164
最近3个月内,无论是现场赛还线上赛中SPLAY出现的概率大的惊人啊啊啊!!!
然而不会的我就GG了,同时发现大家都会SPLAY,,,,然后就学习了一波。
开始怎么学都学不懂,直到看到一句话
想学好splay,只要把伸展和旋转操作弄懂,就好了.
(而这两个想要学会就是需要自己画图自己理解了)
于是茅塞顿开,有了本文,
本文重点是SPLAY维护序列的操作,而非SPLAY本身,这部分会说的比较粗略,二叉树的部分更不会有说明,
菜(sha3)逼我也只是初学,如果有描述不当甚至错误的地方,欢迎指正
伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入、查找和删除操作。
同其他平衡树一样,都是在二叉排序树的基础上进行操作的,但不同于AVL需要记录平衡信息,也没有红黑树实现上的难度.是一种综合考量下很适合应用于信息学竞赛的平衡树.
对于一个基本的SPLAY 我这样定义
1 | int ch[N][2]; //ch[][0] 表示左儿子 ch[][1] 表示右儿子 |
构建的过程也就和普通二叉树一样了,递归下去即可
1 | void newnode(int rt,int v,int fa){ |
对于一颗二叉排序树,根据序列的信息很容易找到某一个值,只要不断的向下搜索下去即可,复杂度是O(树高),
但是二叉树最坏的情况下是会退化成一个单链的,这是后查找的复杂度就是**O(n)**了,非常不可取
而在SPLAY中控制树保持平衡需要的就是旋转操作,是树保持平衡,这样复杂度就变成了均摊的了
通过树的旋转来自我调整来保持平衡,就是基于这两个操作左旋(zag)&右旋(zig),还有其延伸出的操作
下面来实现下旋转操作
总之就是对每次旋转节点间关系信息发生改变的位置调整好就行
需要点耐心,不要调错
1 | void rotate(int x,int k){ // k = 0 左旋, k = 1 右旋 |
经过多次旋转,将节点位置坐出调整的操作就是伸展了
来举个栗子,对于一个退化为单链的树进行旋转
双旋的写法,比较稳定
1 | void splay(int x,int goal){//将x旋转到goal的下面 |
而我发现zig-zag这种两个旋转合在一起的操作,其实是两遍单旋,所以只要每次都向上单旋就行了,
1 | 单旋容易被卡 不懂 百度伸展树单双旋的比较 |
对于SPALY能够做到的操作以【BZOJ3224 普通平衡树】为引,以 【BZOJ 1895 & POJ 3580 supermemo 】做补充,如果不完全,后期会补上
查找部分和普通的二叉查找树一模一样,只要遍历下去即可
1 | int search(int rt,int x){ |
前驱:小于x的最大的数
后继:大于x的最小的数
先找到x所在的节点,然后在左右子树,找最右左的节点即可
1 | //以x为根的子树 的极值点 0 极小 1 极大 |
第k个数,通过记录的sz[],很容易得到每个节点是第几个,不断的在树上二分就行,
1 | //以x为根的子树 第k个数的位置 |
假如要插入的点已经存在了,那么cnt++就行了,
假如要插入的点在x
那么让x-1做为树根,x+1伸展到根节点下面,那么x+1的左儿子就是空出来的 加个值就好了
1 | void _insert(int x){ |
和删除一样,就是反过来了而已,
首先这个值如果不存在,那就直接return即可
如果这个值大于1,那就cnt–即可
如果这个值所在的节点的儿子节点有空的,那么就把需要提上去的儿子节点提上去即可
如果这个值所在的节点的儿子节点都存在,那么就把这个节点的前驱提到根节点,后继提到根节点的下面,那样的话删除ch[ch[root][1]][0]就行了
1 | void _delete(int x){ |
区间操作
对于区间[l,r]
那么让l-1做为树根,r+1伸展到根节点下面,那么r+1的左儿子就是这个区间
打上lazy_tag就行了
但为了更好的处理[1,n]这个区间 加上个0和n+1这两个节点
1 | //区间加 |
同样在一个二叉树中 翻转也就是让每个节点的两个儿子交换一下顺序就好了, 打个标记 就行了,
1 | //区间翻转 |
所以我们可以将后一个区间处理到一个子树上,然后放到l−1,l 这两个节点之间,就好了,先减掉,然后在加上去就好了
1 | //区间交换 |
合并是指两颗SPLAY进行合并,
要求这两颗树没有交错的部分,(可能没有这个限制,但是我不会,)
首先处理好一个树A加入到B中,那么在B中腾出一个空节点来代替A树需要的段,然后把A树的树根放到呢个腾出的空节点位置就行了,
1 |
SPLAY操作非常灵活多变,一定要理解SPLAY然后去使用,不要只会套板子就结束了,
有几点特别要注意的地方
1.插入/删除节点的时候注意父节点要修改
2.sz[]维护不要出错
3. …
附上整体代码-md贴上来太卡了,去题解里看吧
注:这两个板子没有用双旋,用的单旋。。
2017-06-20 20:43:37 Tabris_ 阅读数:611
博客爬取于2020-06-14 22:39:58
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73518838
题目链接:http://poj.org/problem?id=3580
——————————————————————————————————————————
SuperMemo
Time Limit: 5000MSMemory Limit: 65536K
Total Submissions: 15846Accepted: 4992
Case Time Limit: 2000MS
Description
Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1, A2, … An}. Then the host performs a series of operations and queries on the sequence which consists:
ADD x y D: Add D to each number in sub-sequence {Ax … Ay}. For example, performing “ADD 2 4 1” on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
REVERSE x y: reverse the sub-sequence {Ax … Ay}. For example, performing “REVERSE 2 4” on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
REVOLVE x y T: rotate sub-sequence {Ax … Ay} T times. For example, performing “REVOLVE 2 4 2” on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
INSERT x P: insert P after Ax. For example, performing “INSERT 2 4” on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
DELETE x: delete Ax. For example, performing “DELETE 2” on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
MIN x y: query the participant what is the minimum number in sub-sequence {Ax … Ay}. For example, the correct answer to “MIN 2 4” on {1, 2, 3, 4, 5} is 2
To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.
Input
The first line contains n (n ≤ 100000).
The following n lines describe the sequence.
Then follows M (M ≤ 100000), the numbers of operations and queries.
The following M lines describe the operations and queries.
Output
For each “MIN” query, output the correct answer.
Sample Input
5
1
2
3
4
5
2
ADD 2 4 1
MIN 4 5
Sample Output
5
——————————————————————————————————————————
题意:
给出一个数字序列,有6种操作:
(1) ADD x y d: 第x个数到第y个数加d 。
(2) REVERSE x y : 将区间[x,y]中的数翻转 。
(3) REVOLVE x y t :将区间[x,y]旋转t次,如1 2 3 4 5 旋转2次后就变成4 5 1 2 3 。
(4) INSERT x p :在第x个数后面插入p 。
(5)DELETE x :删除第x个数 。
(6) MIN x y : 查询区间[x,y]中的最小值 。
本来不想写来着 但想到 好多天没有更新博客了,加上这题还是挺好玩儿的,还是应该更新一波吧。
就是区间加,翻转,剪切,询问最值。点插入,删除。这几个操作
有翻转了 所以用SPLAY来维护一下
区间加 区间最小值就不说了 和普通的二叉搜索树一模一样.
点插入 删除
假如要插入的点在x
那么让x-1做为树根,x+1伸展到根节点下面,那么x+1的左儿子就是空出来的 加个值就好了
删除发过来一样的
区间操作
对于区间[l,r]
那么让l-1做为树根,r+1伸展到根节点下面,那么r+1的左儿子就是这个区间
但为了更好的处理[1,n]这个区间 加上个0和n+1这两个节点
翻转
同样在一个二叉树中 翻转也就是让每个节点的两个儿子交换一下顺序就好了, 打个标记 就行了,
旋转
其实旋转说白了就是将这个区间分成两段然后交换一下子,
所以我们可以将后一个区间处理到一个子树上,然后放到$l-1, l\ $这两个节点之间,就好了,先减掉,然后在加上去就好了
注: 个人的SPLAY模板正在建设,这个的代码比较杂乱,见谅.
附本题代码
——————————————————————————————————————————
1 | //#include <bits/stdc++.h> |
2017-06-14 16:21:10 Tabris_ 阅读数:349
博客爬取于2020-06-14 22:39:59
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73246276
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1296
———————————————————————————————————————————
1296 有限制的排列
题目来源: HackerRank
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注
计算整数集合{1,2,3,4, … N }满足下列条件的的排列个数:
在位置a1, a2, …, aK小于其邻居(编号从0开始)。
在位置b1, b2, …, bL大于其邻居。
输出符合条件的排列数量Mod 1000000007的结果。例如:N = 4,a = {1}, b = {2},符合条件的排列为:
2 1 4 3
3 2 4 1
4 2 3 1
3 1 4 2
4 1 3 2
Input
第1行:3个数N, K, L,分别表示数组的长度,限制a的长度,限制b的长度(1 <= N <= 5000, 1 <= K, L <= N)。
第2 - K + 1行:每行一个数,对应限制a的位置(1 <= ai <= N - 2)
第K + 2 - K + L + 1行:每行一个数,对应限制b的位置(1 <= bi <= N - 2)
Output
输出符合条件的排列数量Mod 1000000007的结果。
Input示例
4 1 1
1
2
Output示例
5
———————————————————————————————————————————
解题思路:
首先要知道的是排列的生成,
对于一个长度为x的排列,在x+1的位置插入一个元素a,那么就是将原排列中所有大于等于a的数加1,
对于本题来说,看到N的范围就知道是个O(n^2)的dp,但是dp废,,,
首先对每个位置标上状态,state[i]代表第i个位置和前一个位置的大小关系,
还是设dp[i][j]为第i个位置放j的情况数,
那么根据状态的不同转移,
对于求和的过程用一个前缀和优化一下复杂度就能降一维,然后就会发现,转移所需要的信息就是前缀和的信息,所以dp数组也只需要一维就好了,
附本题代码
————————————————————————————————————————————
1 |
|
2017-06-09 20:47:42 Tabris_ 阅读数:358
博客爬取于2020-06-14 22:40:00
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72971158
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1076
———————————————————————————————————————————
1076 2条不相交的路径
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径。(两条路径不经过相同的边)
(注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路)
Input
第1行:2个数M N,中间用空格分开,M是顶点的数量,N是边的数量。(2 <= M <= 25000, 1 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,分别是N条边的起点和终点的编号。例如2 4表示起点为2,终点为4,由于是无向图,所以从4到2也是可行的路径。
第N + 2行,一个数Q,表示后面将进行Q次查询。(1 <= Q <= 50000)
第N + 3 - N + 2 + Q行,每行2个数s, t,中间用空格分隔,表示查询的起点和终点。
Output
共Q行,如果从s到t存在2条不相交的路径则输出Yes,否则输出No。
Input示例
4 4
1 2
2 3
1 3
1 4
5
1 2
2 3
3 1
2 4
1 4
Output示例
Yes
Yes
Yes
No
No
———————————————————————————————————————————
题目问的是 两个点有没有两条不想交的路径,其实就是这两个节点在不在同一个双联通分量里面 如果在就是 否则不是
所以最后就是求双联通了,
双联通用tarjan即可,其实和强连通类似,
只不过对与low 要与所有的儿子进行比较,剩下的就和强连通一模一样了,其实就是一回事儿
附本题代码
———————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-06-09 13:48:43 Tabris_ 阅读数:285
博客爬取于2020-06-14 22:40:01
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72956798
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5934
————————————————————————————————————————
Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1160 Accepted Submission(s): 392
Problem Description
There are N bombs needing exploding.
Each bomb has three attributes: exploding radius ri, position (xi,yi) and lighting-cost ci which means you need to pay ci cost making it explode.
If a un-lighting bomb is in or on the border the exploding area of another exploding one, the un-lighting bomb also will explode.
Now you know the attributes of all bombs, please use the minimum cost to explode all bombs.
Input
First line contains an integer T, which indicates the number of test cases.
Every test case begins with an integers N, which indicates the numbers of bombs.
In the following N lines, the ith line contains four intergers xi, yi, ri and ci, indicating the coordinate of ith bomb is (xi,yi), exploding radius is ri and lighting-cost is ci.
Limits
Output
For every test case, you should output ‘Case #x: y’, where x indicates the case number and counts from 1 and y is the minimum cost.
Sample Input
1
5
0 0 1 5
1 1 1 6
0 1 1 7
3 0 2 10
5 0 1 4
Sample Output
Case #1: 15
Source
2016年中国大学生程序设计竞赛(杭州)
————————————————————————————————————————
题目大意:
在一个直角坐标系上给你n个炸弹,这些炸弹可以被点燃引爆,或者被其他炸弹给连带。 点燃每个炸弹有一个花费,问引爆所有炸弹最少需要多少个。
解题思路:
首先根据能不能被连带引爆的关系建立有向图。
然后发现,只要有入度就一定能被其他节点引爆,没有入度就必须被点燃。
那么就将没有入度的点点燃加起来即可,
但是注意可能出现这样的情况,如果成环了, 那么一定要选择一个点,
所以我们可以缩点,然后新点的花费就是所有节点的花费中最小的。
缩点后后再统计没有入度花费总和即可
附本题代码
————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-06-09 09:58:13 Tabris_ 阅读数:514
博客爬取于2020-06-14 22:40:02
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72953925
题目链接:https://nanti.jisuanke.com/t/11217
——————————————————————————————————————————
百度地图的实时路况功能相当强大,能方便出行的人们避开拥堵路段。一个地区的交通便捷程度就决定了该地区的拥堵情况。假设一个地区有 nn 个观测点,编号从 11 到 nn。定义 d(u,v,w)d(u,v,w) 为从 uu 号点出发,严格不经过 vv 号点,最终到达 ww 号点的最短路径长度,如果不存在这样的路径,d(u,v,w)d(u,v,w) 的值为 -1−1。
那么这个地区的交通便捷程度 PP 为:
现在我们知道了该地区的 nn 个点,以及若干条有向边,求该地区的交通便捷程度 PP。
输入格式
第一行输入一个正整数 ,表示该地区的点数。
接下来输入 n 行,每行输入 n 个整数。第 i行第 j 个数 表示从 i 号点到 j 号的有向路径长度。如果这个数为 −1,则表示不存在从 ii 号点出发到 jj 号点的路径。
输出格式
输出一个整数,表示这个地区的交通便捷程度。
样例输入
4
0 1 -1 -1
-1 0 1 -1
-1 -1 0 1
1 -1 -1 0
样例输出
4
——————————————————————————————————————————
正常做法是枚举每个点之后对其他点进行floyd,这样的话复杂度是显然会TLE
然后想有没有其他优秀的图论东西能够快速的解决,发现没有,
最后我们采取的是分治的思路;
每次分为两段递归分治下去,将另一半所在的点给其他点进行松弛,也就是floyd的过程
然后这题的总复杂度度就能在的时间复杂下解决了
附本题代码
——————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-06-08 20:15:31 Tabris_ 阅读数:214
博客爬取于2020-06-14 22:40:03
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72934503
题目链接:http://poj.org/problem?id=3160
————————————————————————————————————————
Father Christmas flymouse
Time Limit: 1000MSMemory Limit: 131072K
Total Submissions: 3483Accepted: 1187
Description
After retirement as contestant from WHU ACM Team, flymouse volunteered to do the odds and ends such as cleaning out the computer lab for training as extension of his contribution to the team. When Christmas came, flymouse played Father Christmas to give gifts to the team members. The team members lived in distinct rooms in different buildings on the campus. To save vigor, flymouse decided to choose only one of those rooms as the place to start his journey and follow directed paths to visit one room after another and give out gifts en passant until he could reach no more unvisited rooms.
During the days on the team, flymouse left different impressions on his teammates at the time. Some of them, like LiZhiXu, with whom flymouse shared a lot of candies, would surely sing flymouse’s deeds of generosity, while the others, like snoopy, would never let flymouse off for his idleness. flymouse was able to use some kind of comfort index to quantitize whether better or worse he would feel after hearing the words from the gift recipients (positive for better and negative for worse). When arriving at a room, he chould choose to enter and give out a gift and hear the words from the recipient, or bypass the room in silence. He could arrive at a room more than once but never enter it a second time. He wanted to maximize the the sum of comfort indices accumulated along his journey.
Input
The input contains several test cases. Each test cases start with two integers N and M not exceeding 30 000 and 150 000 respectively on the first line, meaning that there were N team members living in N distinct rooms and M direct paths. On the next N lines there are N integers, one on each line, the i-th of which gives the comfort index of the words of the team member in the i-th room. Then follow M lines, each containing two integers i and j indicating a directed path from the i-th room to the j-th one. Process to end of file.
Output
For each test case, output one line with only the maximized sum of accumulated comfort indices.
Sample Input
2 2
14
21
0 1
1 0
Sample Output
35
Hint
32-bit signed integer type is capable of doing all arithmetic.
————————————————————————————————————————
题目大意:
就是给你N个点,M条有向边,每个点一个权值,走过这个点可以取走这个价值,也可以留下,让你找一条路使得能获得的权值最大。
解题思路;
首先这个权值最大 很好处理,权值为正就取,负的就不取,为了方便,将负值全部变为0;
然后考虑到可能存在有向环,所以要缩点做,
缩点后从新建图,然后建一个超级源点,跑最长路就好了
最长路用SPFA即可
附本题代码
————————————————————————————————————————
1 | # include<stdio.h> |
2017-06-06 19:38:38 Tabris_ 阅读数:256
博客爬取于2020-06-14 22:40:04
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72886742
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5636
——————————————————————————————————————————
Shortest Path
Accepts: 40
Submissions: 610
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
有一条长度为n的链. 节点ii和i+1之间有长度为1的边. 现在又新加了3条边, 每条边长度都是1. 给出m个询问, 每次询问两点之间的最短路.
输入描述
输入包含多组数据. 第一行有一个整数T, 表示测试数据的组数. 对于每组数据:
第一行包含2个整数n和m$ (1 \le n,m \le 10^5)a_1, b_1, a_2, b_2, a_3, b_3 (1 \le a_1,a_2,a_3,b_1,b_2,b_3 \le n)(a_1,b_1), (a_2,b_2), (a_3,b_3)s_it_i$ , 表示一组询问.
所有数据中mm的和不超过10^6106.
输出描述
对于每组数据, 输出一个整数, 其中z_izi表示第ii组询问的答案.
输入样例
1
10 2
2 4 5 7 8 10
1 5
3 1
输出样例
7
——————————————————————————————————————————
首先对于给了N个节点求最短路 一定不能直接做了,
发现他加的三条边与查询的边一共就8个点,那么每次对这8个点写folyd不就好了,O(888)然而写了一发TLE
然后想这样怎么能在优化呢?
想到给定的那6个点是固定的,那么多次求就浪费了
然后考虑,让我查询的就一条边,那么其实也就是66条边对这条边松弛,那么复杂度就是O(66),
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-06 12:41:52 Tabris_ 阅读数:603
博客爬取于2020-06-14 22:40:06
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72877015
题目链接:http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=31989&pid=1011
———————————————————————————————————————————
K. paulzhou和方程
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/102400K (Java/Other)
Total Submission(s) : 28 Accepted Submission(s) : 7
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
众所周知,paulzhou的数学不太好。现在他有一个问题,希望你帮他解答:
给定一元n次方程
定义的前k项和
现给出n、n+1个各项的系数以及k,求
其中
Input
第1行输入T(1≤T≤10),代表有T组数据。
紧接着每3行分别为n,各项系数,k,输入数据均为正整数。
Output
每组测试数据输出一行,输出的前k-1项和$$
s_k\sum_{i=0}^{k-1}f_i
并对10007取模。Sample Input141 -2 3 1 03Sample Output21AuthorKirai———————————————————————————————————————————这题用到了差分序列 详情见《组合数学(原书第5版)》翻译版 P169查分序列:设有一个序列$h_0,h_1,h_2,,,,h_n$它的一阶差分序列是
△h_i=h_{i+1}-h_i
△^2h_i=△h_{i+1}-△h_i
h_0\ \ \ \ h_1\ \ \ \ h_2\ \ \ \ h_3 …\△h_0\ \ \ \ △h_1\ \ \ \ △h_2…\…
h_x=\sum_{i=0}^{n}C(x,i)*△^ih_i
\sum_{i=0}^{n} \sum_{j=0}^{k-1}C(j,i)*△^ih_0
\sum_{i=0}^{n}C(m,i) = C(n+1,m+1)
\sum_{i=0}^{n} \sum_{j=0}^{k-1}C(j,i)*△^ih_0\ =\sum_{i=0}^{n}C(k,i+1)*△^ih_0
]]>
2017-06-05 16:38:47 Tabris_ 阅读数:299
博客爬取于2020-06-14 22:40:07
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72868717
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5927
————————————————————————————————————————————
Auxiliary Set
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1525 Accepted Submission(s): 460
Problem Description
Given a rooted tree with n vertices, some of the vertices are important.
An auxiliary set is a set containing vertices satisfying at least one of the two conditions:
∙It is an important vertex
∙It is the least common ancestor of two different important vertices.
You are given a tree with n vertices (1 is the root) and q queries.
Each query is a set of nodes which indicates the unimportant vertices in the tree. Answer the size (i.e. number of vertices) of the auxiliary set for each query.
Input
The first line contains only one integer T (T≤1000), which indicates the number of test cases.
For each test case, the first line contains two integers n (1≤n≤100000), q (0≤q≤100000).
In the following n -1 lines, the i-th line contains two integers ui,vi(1≤ui,vi≤n) indicating there is an edge between uii and vi in the tree.
In the next q lines, the i-th line first comes with an integer mi(1≤mi≤100000) indicating the number of vertices in the query set.Then comes with mi different integers, indicating the nodes in the query set.
It is guaranteed that ∑qi=1mi≤100000.
It is also guaranteed that the number of test cases in which n≥1000 or ∑qi=1mi≥1000 is no more than 10.
Output
For each test case, first output one line “Case #x:”, where x is the case number (starting from 1).
Then q lines follow, i-th line contains an integer indicating the size of the auxiliary set for each query.
Sample Input
1
6 3
6 4
2 5
5 4
1 5
5 3
3 1 2 3
1 5
3 3 1 4
Sample Output
Case #1:
3
6
3
Hint
For the query {1,2, 3}:
•node 4, 5, 6 are important nodes For the query {5}:
•node 1,2, 3, 4, 6 are important nodes
•node 5 is the lea of node 4 and node 3 For the query {3, 1,4}:
• node 2, 5, 6 are important nodes
————————————————————————————————————————————
题意:
是有一颗有n个节点以位根的树,有q次查询,每次查询给定一个集合,集合外的点是重要点,集合内的点是非重要点,如果非重要点是两个重要点的LCA,那么这个非重要点会变成重要点,问你重要点的个数.
解题思路:
开始看数据范围非常大,以为要O(M)查询,后来看哪个乱七八糟的数据范围,感觉带个log啥的,再加上剪剪枝也能做做看,…
首先对于一次查询,我们要知道了非重要点的个数m,那么集合外的重要点就是n-m
对于集合里面的重要点我们可以枚举,存在至少有两个节点在一个非重要点的不同儿子节点为根的子树上,那么这个非重要点就是两个重要点的LCA,就要++.;
那么考虑,会不会有非重要点是非重要点变成的重要点的LCA才计算的呢?,这种情况怎么处理,
其实很好想,如果非重要点变成重要点,那么这个非重要点的树一定有最开始就是重要点的节点,所以忽略这个情况就行了.
那么就是找节点子树中有没有重要点了,对于子树问题,想到dfs序,并用一个数组标记这个点是不是重要点,也就是看子树所包括的连续序列有没有被标记的,维护一个BIT,就能log计算了
然后注意一个剪枝,就是有两个儿子节点的树上有重要点,就可以break了.
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-05 01:35:52 Tabris_ 阅读数:360
博客爬取于2020-06-14 22:40:08
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72863523
题目链接:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2176/pid/3926.html
——————————————————————————————————————
bLue的二叉树
Time Limit: 3000MS Memory Limit: 65536KB
Submit Statistic
Problem Description
Keke 是一个喜爱种树的人,他对各种树都有很深的研究。
MLE 听说 bLue 种了一些新品种的树,就想邀请 Keke 去围观一下。
PBH 在暗中把这一切尽收眼底,作为资深植树行家,他虽不屑,但也决定和他们一起去看一看。
于是,大家便一起到了 bLue 家去看树。
bLue 有两棵二叉树,分别有 n 和 m 个节点,编号分别为 1-n 和 1-m,每个节点都有一个权值,bLue 想知道第一棵树的所有子树中与第二棵树完全相同的个数(不考虑节点编号)。
Input
输入数据有多组,组数不超过 150,到 EOF 结束。
每组第一行有两个整数 n (0 < n <= 1e5)和 m (0 < m <= 1e5),表示第一棵树和第二棵树的节点个数;
接下来 n 行,表示第一棵树:第 i (0 < i <= n) 行有 3 个整数,w[i] (0 < w[i] <= 10), lc[i], rc[i] (0 < lc[i], rc[i] <= n),分别表示节点 i 的权值,该节点的左孩子编号和右孩子编号,若某个孩子不存在,则为 0 (数据保证每棵树都是合法的有根二叉树);
接下来 m 行,表示第二棵树:格式同第一棵树;
保证:树的最大深度不会超过 10000。数据量比较大,请用 scanf 读入!
Output
对于每组数据,输出一行一个整数 num,表示第一棵树的所有子树中与第二棵树完全相同的个数。
Example Input
7 4
1 6 3
2 0 4
1 7 0
3 0 0
1 2 1
2 0 0
2 0 0
2 0 0
1 4 0
1 1 2
2 0 0
3 3
1 0 0
2 1 3
3 0 0
1 0 3
2 1 0
3 0 0
Example Output
1
0
Hint
Author
不得不放弃、
——————————————————————————————————————
首先确定的是严格确定 二叉树的左子树和左子树对 上右子树和右子树对上才行
对于子树问题考虑dfs序
对于一个dfs序,区间内的东西都是子树的,那么对于两个完全一样的子树.遍历出来的区间也是一模一样的.
但是为了避免有多个子树遍出结果一样的,我们只需把空节点当作一个不一样的权值加入到树中,这样既能确保区间序列一样,同时又不会冲突.
最后对两个dfs序KMP即能求解
其实这题是能够hash做的 ,最开始我也在想hash的方法,但是想不到怎么处理左右儿子的左/右儿子到底在那,所以不太行,,== 现在想到对dfs序后他的位置l的x^l的系数 感觉很可行啊 ,同时也要做dfs==! 其实还是字符串hash了,,,,,
附本题两份KMP+hash代码
——————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 03:07:10 Tabris_ 阅读数:386
博客爬取于2020-06-14 22:40:09
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849801
端午几天没有碰键盘,开场A题就炸了。
现场的时候只AC了6个,最后2个小时M由于题目描述有问题,后台有非法数据,wa了两个小时,心态爆炸,怀疑人生,GG(其实是能AC的代码)
后面有几个水题都没有看到,比如这个C,还有很好想的E。。
题目质量真心好啊,给举办方大大的赞啊。。
同时学到了好多东西,以前lca只会树剖,现在会写倍增了,又学会了可持久化01字典树。和树重构。 美滋滋啊。
话说同步赛大家玩的都很开心,但是。。。额。心疼现场玩家。
---------------------fen·ge·xian-------------------------------
据说每题单开一贴能增加阅读体验
2017-06-03 03:04:48 Tabris_ 阅读数:467
博客爬取于2020-06-14 22:40:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849797
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=12
——————————————————————————————————————————
Problem M: qwb与二叉树
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 159 Solved: 35
[Submit][Status][Web Board]
Description
某一天,qwb正在上数据结构课。老师在讲台上面讲着二叉树,qwb在下面发着呆。
突然qwb想到一个问题:对于一棵n个无编号节点,m个叶子的有根二叉树,有多少种形态呐?你能告诉他吗?
Input
多组输入,处理到文件结束,大约有104组数据。
每一组输入一行,两个正整数n,m(0≤m≤n≤50),意义如题目所述。
Output
每一行输出一个数,表示相应询问的答案,由于答案可能很大,请将答案对109+7取模后输出。
Sample Input
4 2
10 5
Sample Output
6
252
HINT
样例1的6种形态:
——————————————————————————————————————————
心态爆炸的一道题,现场后2hours wa到死… 其实是题目描述错了1~50 但后台数据是0~50,后来修改了
题目而言是好题目,
设dp[i][j]是i个节点j个叶子的树的种类
那么转移就是以当前点为根,左右子树方案数的乘积,
我开始采取记忆化的方式,然后处理答案要交表,然后发现时间比较快 交完就wa,补题的时候发现数据范围描述有误。。。
但其实如果我输出不是dp[n][m],而直接dfs(n,m)也就诶问题了,,,也算长个记性。。。
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:55:21 Tabris_ 阅读数:656
博客爬取于2020-06-14 22:40:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849794
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=11
——————————————————————————————————————————
Problem L: qwb与整数对
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 171 Solved: 18
[Submit][Status][Web Board]
Description
qwb又遇到了一道数学难题,你能帮助他吗?
给出两个整数n和m,请统计满足0<a<b<n并且使得 (a2+b2+m)/(ab) 的结果是整数的整数对(a,b)的个数。
Input
本题包含多组测试例 。当测试例数据是n=m=0时,表示输入结束。(测试例数量<6000)
每个测试例一行,是两个整数n和m。输入保证0≤n≤1000,-20000< m< 20000。
Output
对每个测试例,输出测试例的编号(Case X:Y) 以及满足上述要求的整数对(a,b)的个数,输出格式如样例输出所示。
Sample Input
10 1
20 3
30 4
0 0
Sample Output
Case 1: 2
Case 2: 4
Case 3: 5
——————————————————————————————————————————
在线的复杂度实在不科学
看dalao离线做了,我也做了下
离线之后n^2枚举到每个位置计算贡献的时候类似筛法只要找(i*j)的倍数就好了
然后记下这个时候的值询问,满足n的情况就ans++
感觉没有代码直观啊.
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:50:11 Tabris_ 阅读数:389
博客爬取于2020-06-14 22:40:12
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849793
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=10
——————————————————————————————————————————
Problem K: qwb与小数
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 382 Solved: 71
[Submit][Status][Web Board]
Description
qwb遇到了一个问题:将分数a/b化为小数后,小数点后第n位的数字是多少?
做了那么多题,我已经不指望你能够帮上他了。。。
Input
多组测试数据,处理到文件结束。(测试数据<=100000组)
每组测试例包含三个整数a,b,n,相邻两个数之间用单个空格隔开,其中0 <= a <1e9,0 < b < 1e9,1 <= n < 1e9。
Output
对于每组数据,输出a/b的第n位数,占一行。
Sample Input
1 2 1
1 2 2
Sample Output
5
0
HINT
——————————————————————————————————————————
在dalao们的帮助下,会了
a10^(n-1)%b10/b;
a10^(n-1)%b前面留在其他位的都不影响结果
最后10/b也就是我们要的结果了
其实没后面一位就是a*10/b 做了n次而已
附本题代码
——————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-06-03 02:44:15 Tabris_ 阅读数:572
博客爬取于2020-06-14 22:40:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849792
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=9
——————————————————————————————————————————
Problem J: qwb又偷懒了
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 599 Solved: 93
[Submit][Status][Web Board]
Description
qwb最近在做一个群众收入统计。ta非常懒,以至于忘记了今天领导要来视察。所以急忙催下属去做统计。
在接下来长度为n的时间里,每个单位时间都有事情发生,可能会发下以下两种事件:
1)下属递交了一份调查报告,由于太匆忙,上面只有一个整数x,代表一个居民的收入。
2)领导来视察了,领导会来询问,收入在区间[l,r]内的居民的平均收入,qwb需要给出回答。
qwb非常讨厌小数,所以qwb上报时都会省略小数部分。如果上报时统计的人数为0,qwb就暴露了他偷懒的事情,他就会zhizhiwuwu。
Input
多组测试数据,处理到文件末尾。
每组测试数据的第一行为一个正整数n(0<=100000),确保所有的n的和不超过300000
接下来n行,
当第一个数为0时,代表操作1,后面跟着一个整数x(0<=x<=1000000),意义如题目所述。
当第一个数为1时,代表操作2,后面跟着两个整数l,r(0<=l<=r<=1000000),意义如题目描述。
Output
对于每一个领导的询问,给出一个回答,如果统计区间的人数为零,则输出"zhizhiwuwu"。(不带引号)
每个测试例之后输出一个空行。
Sample Input
3
0 1
0 3
1 1 3
2
0 1
1 2 2
Sample Output
2
zhizhiwuwu
HINT
输入输出包含大规模数据,建议使用scanf,printf.
样例1中,收入为1的居民有一个,收入为3的居民有1个,所以收入在1-3范围内的居民有2个,总收入是4,4/2=2
——————————————————————————————————————————
BIT入门级别 没啥说的
数据范围小,直接两个BIT就好
其实1个就够了,另一个主要是记录0的个数,,,我也没注意这里wa了一发
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:41:12 Tabris_ 阅读数:969
博客爬取于2020-06-14 22:40:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849787
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=8
——————————————————————————————————————————
Problem I: qwb VS 去污棒
Time Limit: 2 Sec Memory Limit: 256 MB
Submit: 74 Solved: 26
[Submit][Status][Web Board]
Description
qwb表白学姐失败后,郁郁寡欢,整天坐在太阳底下赏月。在外人看来,他每天自言自语,其实他在和自己的影子“去污棒”聊天。
去污棒和qwb互相出题考验对方,去污棒问了qwb这样一个问题:
现已知一个有n个正整数的序列a[1],a[2]…a[n],接下来有m个操作
操作一共有两种:
1.在序列末尾添加一个数x。
2.查询suf[p] xor x的最大值,其中xor是异或 ,l<=p<=r,
suf[t]表示从t开始的后缀的异或和,即suf[t]=a[t] xor a[t+1] xor …xor a[len],len为序列长度。
Input
第一行一个整数T(<=5),表示一共有T组数据。
每组数据第一行两个整数n(<=200000),m(<=200000),意义如上所述。
随后一行有n个数,表示初始序列。
随后m行,每行表示一个操作。
操作有两种,1: x 表示在末尾添加一个x,2: l r x表示查询suf[p] xor x的最大值,其中l<= p <= r,
所有数及x不超过224 且保证所有操作合法。
Output
每组测试数据的第一行输出"Case x:",x为数据组数的标号,从1开始。
接下来,对每个操作2输出一行答案。
Sample Input
1
5 5
1 2 3 4 5
2 1 3 4
1 10
1 7
2 4 4 5
2 1 5 19
Sample Output
Case 1:
6
9
31
——————————————————————————————————————————
以下是边做题时边写的
可持久化Trie 离线,维护后缀异或和 然后在区间上进行查找
其实通过消去率能将suffix变成前缀,不对么
yes
假如序列长度为 n
那么prexor[n]^prexor[k] = suf[k+1]; 所以在线就好了;
可持久化01字典树,那就用一个可持久化线段树来实现,怎么搞呢。
算了还是先改了别人的吧。。。
异或最大值就想到了01trie
但是限制区间所以要可持久化
可持久化01字典树可以借鉴主席树来写,
但是我这个最后被卡常了,加了读入挂才AC
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:36:00 Tabris_ 阅读数:735
博客爬取于2020-06-14 22:40:15
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849743
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=7
——————————————————————————————————————————
Problem H: qwb与学姐
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 113 Solved: 44
[Submit][Status][Web Board]
Description
qwb打算向学姐表白,可是学姐已经受够了他的骚扰,于是出了一个题想难住他:
已知一幅n个点m条边的无向图,定义路径的值为这条路径上最短的边的长度,
现在有 k个询问,
询问从A点到B点的所有路径的值的最大值。
qwb听完这个问题很绝望啊,聪明的你能帮帮他吗?
Input
一组数据。
第一行三个整数n,m,k (1<=N<=50000,m<=200000,k<=100000)。
第2…m+1行:三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N,1<=D<=215) 表示X与Y之间有一条长度为D的边。
第m+2…m+k+1行: 每行两个整数A B(1<=A,B<=n且A≠B),意义如题目描述。
保证图连通。
Output
对于每个询问输出一行,一共k行,每行输出A点到B点的所有路径的值的最大值。
Sample Input
4 5 3
1 2 6
1 3 8
2 3 4
2 4 5
3 4 7
2 3
1 4
3 4
Sample Output
6
7
7
——————————————————————————————————————————
他要找所有路径的最大值,那么我只需要留校路径最大的那个就好了
这里有一个贪心策略,就是最大生成树,
这样能保证,两点间在图上其他的路径的值都小于最大生成树的
然后问题就是如何求两点间路径最小值了
最开始写了个树剖,发现由于是边权在维护的时候lca位置不好维护
于是GG,在提示下学习了倍增求lca
知识点不介绍了,
因为同样是变成了点权
我们只需要求路径最小的时候变成两个路径的最小值,非别是(u,x(fa[x]=lca)),(v,y(fa[y]=lca))
这样下来就好办多了,找到lca之后维护最小值就好了
附本题代码
——————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-06-03 02:27:50 Tabris_ 阅读数:593
博客爬取于2020-06-14 22:40:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849668
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=6
——————————————————————————————————————————
Problem G: qwb去面试
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1627 Solved: 260
[Submit][Status][Web Board]
Description
某一天,qwb去WCfun面试,面试官问了他一个问题:把一个正整数n拆分成若干个正整数的和,请求出这些数乘积的最大值。
qwb比较猥琐,借故上厕所偷偷上网求助,聪明的你能帮助他吗?
Input
第一行为一个正整数T.(T<=100000)
接下来T行,每行一个正整数n(n<=1e9),意义如题目所述。
Output
每一行输出一个整数,表示乘积的最大值,由于答案可能很大,请将答案对109+7取模后输出。
Sample Input
2
2
5
Sample Output
2
6
HINT
2=2
5=2+3
——————————————————————————————————————————
一定是素数的成绩会最大
最开始以为要素因子展开,然后发现,不对,
222<3*3
然后就发现了是尽可能的拆成3
余1就将一个变成4
余2就在乘2
应该有严谨的证明之类的吧,但是我不会。
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:22:20 Tabris_ 阅读数:400
博客爬取于2020-06-14 22:40:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849663
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=5
——————————————————————————————————————————
Problem F: qwb has a lot of Coins
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 699 Solved: 220
[Submit][Status][Web Board]
Description
qwb has a lot of coins. One day, he decides to play a game with his friend using these coins. He first puts some of his coins into M piles, each of which is composed of Ni (1<=i<=M) coins. Then, the two players play the coin game in turns. Every step, one can remove one or more coins from only one pile. The winner is the one who removes the last coin.
Then comes the question: How many different ways the first player can do that will ensure him win the game?
Input
Input contains multiple test cases till the end of file. Each test case starts with a number M (1 <= M<= 1000) meaning the number of piles. The next line contains M integers Ni (1 <= Ni <= 1e9, 1 <= i<= M) indicating the number of coins in pile i.
Output
For each case, put the method count in one line.
If the first player can win the game, the method count is the number of different ways that he can do to ensure him win the game, otherwise zero.
Sample Input
3
1 2 3
1
1
Sample Output
0
1
——————————————————————————————————————————
题意:就是问你Nim游戏先手第一步能赢的方案数
显然就是然你模拟下Nim游戏呗,如果第一步选当前堆能赢就++,
能赢就是这个堆的石子个数大于其他堆得石子个数异或和
简单nim游戏不解释
虽然给了1000,但是这题是可以预处理前后缀异或和达到O(n)的
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:17:40 Tabris_ 阅读数:1339
博客爬取于2020-06-14 22:40:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849660
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=4
——————————————————————————————————————————
Problem E: qwb和李主席
Time Limit: 4 Sec Memory Limit: 128 MB
Submit: 391 Solved: 39
[Submit][Status][Web Board]
Description
qwb和李主席打算平分一堆宝藏,他们想确保分配公平,可惜他们都太懒了,你能帮助他们嘛?
Input
输入包含多组测试数据,处理到文件结束。
每组测试数据的第一行是一个正整数N(0 <= N <=36 )表示物品的总个数.。
接下来输入N个浮点数(最多精确到分),表示每个物品的价值V(0< V<=1e9)。
Output
对于每组测试数据,输出能够使qwb和李主席各自所得到的物品的总价值之差的最小值(精确到分),每组测试数据输出占一行。
Sample Input
3 0.01 0.1 1
2 1 1
Sample Output
0.89
0.00
——————————————————————————————————————————
n=36,如果直接枚举的话超时
然后先到分成两部分进行枚举,先枚举出一部分的所有可能结果,然后枚举另一部分在这个部分二分找最优就好
找的时候要找加和最靠近total/2的,然后维护最小值就好了
讲道理说如果*100用整形处理比较美滋滋,但是wa到死,改成double直接ac。。。。
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 02:12:15 Tabris_ 阅读数:721
博客爬取于2020-06-14 22:40:20
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849656
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1003&pid=3
——————————————————————————————————————————
Problem D: qwb与神奇的序列
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1107 Solved: 163
[Submit][Status][Web Board]
Description
qwb又遇到了一道题目:
有一个序列,初始时只有两个数x和y,之后每次操作时,在原序列的任意两个相邻数之间插入这两个数的和,得到新序列。举例说明:
初始:1 2
操作1次:1 3 2
操作2次:1 4 3 5 2
……
请问在操作n次之后,得到的序列的所有数之和是多少?
Input
多组测试数据,处理到文件结束(测试例数量<=50000)。
输入为一行三个整数x,y,n,相邻两个数之间用单个空格隔开。(0 <= x <= 1e10, 0 <= y <= 1e10, 1 < n <= 1e10)。
Output
对于每个测试例,输出一个整数,占一行,即最终序列中所有数之和。
如果和超过1e8,则输出低8位。(前导0不输出,直接理解成%1e8)
Sample Input
1 2 2
Sample Output
15
——————————————————————————————————————————
先不管x,y的值是什么看看每次x,y对结果贡献多少?
定义(n,m)其中n为x的贡献,m为y的贡献 答案就是nx+my
次数 | fac | tot |
---|---|---|
0 | (1,0)(0,1) | (1,1) |
1 | (1,0)(1,1)(0,1) | (2,2) |
2 | (1,0)(2,1)(1,1)(1,2)(0,1) | (5,5) |
3 | (1,0)(3,1)(2,1)(3,2)(1,1)(2,3)(1,2)(1,3)(0,1) | (14,14) |
然后推出第3列的递推式
由此构造矩阵
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 01:51:32 Tabris_ 阅读数:575
博客爬取于2020-06-14 22:40:21
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849551
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=2
——————————————————————————————————————————
g输出请用%lld 参赛请加qq群160384471获取最新消息
Problem C: 勤劳的ACgirls
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 100 Solved: 39
[Submit][Status][Web Board]
Description
zjc的ACgirls队的队员最近比较忙,为了能够取得更好的比赛成绩,他们制定了一个m天a掉n题的计划,a掉一题可以是这m天的任何时候。
为了表示对acmer事业的热爱,队长wc要求每天必须至少要ac掉k题,这m天每天ac掉的题数可以用一个m元组表示。
设不同的m元组一共有c个,请问c的末尾有多少个0?(如果c是0,输出0)
Input
多组测试数据,处理到文件结束。(测试例数量<=160000)
输入的每一行是一个测试例,分别是m、n和k(0<=m,n,k<=1e9),含义如前所述。
Output
每组测试例中m元组的数量的末尾0的个数,占一行。
Sample Input
3 11 0
3 11 1
999 99999 4
Sample Output
0
0
5
——————————————————————————————————————————
就是将n-m*k个题放到m天做,
就是简单的组合么,
在n+m-1个东西选m-1个 (-1的意思是挡板,将n个题分成m天)
结果就是
分别计算中2,5的个数就好了
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 01:43:28 Tabris_ 阅读数:924
博客爬取于2020-06-14 22:40:22
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849513
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=1
———————————————————————————————————————
Problem B: qwb与矩阵
Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 1030 Solved: 189
[Submit][Status][Web Board]
Description
做完了辣么多的数学题,qwb好好睡了一觉。但是他做了一个梦:
有一个n*m的矩阵,qwb在这个矩阵的左上角(1,1),终点在右下角(n,m)。
每个格子中有小钱钱,也可能没有,还有可能是要交过路费的,并且行走方向必须是靠近终点的方向。
往下走一次只能走一格,往右走一次可以走一格也可以走到当前列数的倍数格。
比如当前格子是(x,y),那么可以移动到(x+1,y),(x,y+1)或者(x,y*k),其中k>1。
qwb希望找到一种走法,使得到达右下角时他能够有最多的小钱钱。
你能帮助他吗?
Input
第一行是测试例数量 T (T<=100),接下来是T组测试数据。
每组测试数据的第一行是两个整数n,m,分别表示行数和列数(1<=n<=20,1<=m<=10000);
接下去给你一个n*m的矩阵,每个格子里有一个数字 k (-100<=k<=100)代表小钱钱的数量。 ∑nm<=3,000,000
Output
每组数据一行,输出L先生能够获得小钱钱的最大值(可能为负数)。
Sample Input
1
3 8
9 10 10 10 10 -10 10 10
10 -11 -1 0 2 11 10 -20
-11 -11 10 11 2 10 -10 -10
Sample Output
52
HINT
————————————————————————————————————————
很明显的dp
dp[i][j]为到(i,j)位置时的最大值.
转移方程大家都会,但是如果暴力可能会超时
所以在考虑走倍数的时候采用类似筛法的方法转移就好了
附本题代码
————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-06-03 01:36:38 Tabris_ 阅读数:1047
博客爬取于2020-06-14 22:40:23
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72849484
题目链接:http://115.231.222.240:8081/JudgeOnline/problem.php?cid=1005&pid=0
————————————————————————————————————————
Problem A: qwb与支教
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1457 Solved: 268
[Submit][Status][Web Board]
Description
qwb同时也是是之江学院的志愿者,暑期要前往周边地区支教,为了提高小学生的数学水平。她把小学生排成一排,从左至右从1开始依次往上报数。
玩完一轮后,他发现这个游戏太简单了。于是他选了3个不同的数x,y,z;从1依次往上开始报数,遇到x的倍数、y的倍数或z的倍数就跳过。如果x=2,y=3,z=5;第一名小学生报1,第2名得跳过2、3、4、5、6,报7;第3名得跳过8、9、10,报11。
那么问题来了,请你来计算,第N名学生报的数字是多少?
Input
多组测试数据,处理到文件结束。(测试数据数量<=8000)
每个测试例一行,每行有四个整数x,y,z,N。( 2≤x,y,z≤107,1≤N≤1017)。
Output
对于每个测试例,输出第N名学生所报的数字,每个报数占一行。
Sample Input
2 3 5 2
6 2 4 10000
Sample Output
7
19999
————————————————————————————————————————
学过容斥的人应该都会,不会的话坐下hdu 1796
附本题代码
——————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-28 17:03:47 Tabris_ 阅读数:2717
博客爬取于2020-06-14 22:40:24
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72793781
hdu的题目,我挂到了VJ上
VJ链接: https://cn.vjudge.net/contest/165580#overview
hdoj链接:太长了 戳这里就好了
给妹子们出的题目,貌似没有那么凶。。但是渣渣也仅会7道题。。。
没有队友搅屎,个人切题的感觉还不错。。 也是把会的题都做了。。
这个D 虽然出的人数比较多一点,但我就是不会,没有办法, 、、、
知识广度不够,刷题太少了。
————————————————————————————————————————
就是有n道题,m次提交,ICPC赛制,让你计算最终的成绩(题数+分数)
附本题代码
——————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————
在直线上是有n(<=3k)的屋子,每个屋子可以花费$C_i\ $建一个商店,或者去左边最近的去买花费是距离的差, 问你现在n个屋子的最小花费。
看到n的范围很明显的左右的解法,
然后想到在按照x升序排列后 dp
设dp[i][0/1] 表示第i个屋子建商店不建商店的最小花费
转移就是
附本题代码
——————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————
给你一个序列,任选一个元素去掉,使得剩下的元素gcd值最大,问你gcd的最大值是多少
因为要去掉一个,很容易想到预处理前缀gcd和后缀gcd,然后O(n)枚举去掉的元素即可,同事维护结果的最大值
附本题代码
——————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————
打给就是给你一个完全图,然后问你满足每个点到0节点的距离都是原图上的最小距离的生成树的个数
不会、、
------------------------Update-----------------------------
首先处理出来 两点间最短路,用floyd即可
然后考虑枚举每一条边,如果这条边<u,v>在最短路上那么对于点v来说,生成树上有这条边就能保证距离最短
然后统计每个点的这样的边的个数,乘一起就好.
1 | # include <bits/stdc++.h> |
————————————————————————————————————————
让你计算
因位数据范围较小,只要快速幂计算 就好了,如果数据特别大的话 需要矩阵乘法做
附本题代码
——————————————————————
1 | # include <bits/stdc++.h> |
#FHDU 6028Forgiveness
————————————————————————————————————————
没读题,不会,没人出啊.
————————————————————————————————————————
按照规则有一个图,然你在这个图上找一个完美匹配
规则如下:
1 将这个点u和标号小于u的点连一个边,
2 没有操作.
其实很简单,我们只要顺序遍历下来,如果是1的时候,前面有一个节点没有匹配,那就和当前点匹配上,
最后所有节点都匹配上yes否则no
附本题代码
——————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————
现在有n这么长的手链,你有红色的,蓝色的石子,保证在连续奇数的区间内红色石子数不小于蓝色石子数,问方案数
首先对于保证在连续奇数的区间内红色石子数不小于蓝色石子数,
,很容易发现只要满足不存在
‘蓝蓝’,‘蓝红蓝’,这两种子串就好了,
然后应该就能构造了,但是我这智商够早不出来啊,
于是贯彻遇事不决先打表
的宗旨,
x | 2 | 3 | 4 | 5 | 6 | … | n |
---|---|---|---|---|---|---|---|
ans(x) | 3 | 4 | 6 | 9 | 13 | … | ans(i-1)+ans(i-3) |
然后构造矩阵就好了
附本题代码
————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————
这题是有一棵节点个数为n树,有m次查询,
查询是有两个集合,在集合中分别选出一个元素,求其LCA,问LCA的深度最大是多少
解题思路:
注意数据范围 ,那么就从这里着手么,
显然分别枚举一定不行,所以可以枚举一个集合,对另一个集合,我们可以先进行处理
大概就是进行一个dfs序,然后出现的节点我们就标记一下,这样我就能知道,当前集合的每个节点的子树有没有另一个集合的节点了,
找的时候我们将一个节点不断向上找其父节点,如果这个父节点的子树有另一个集合的元素,那么LCA就是这个父节点
然后注意几个剪枝就好了,
1,采取启发式搜索的思路,将集合内元素及其祖宗节点个数多的标记上去,对另一个小的查找
2,深度小于当前维护的最大值得父节点直接退出就好了,
3,可以先维护下这两个集合内相同元素的深度的最大值,
附本题代码
——————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————————————
]]>2017-05-26 23:11:56 Tabris_ 阅读数:1019
博客爬取于2020-06-14 22:40:25
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72775704
我记得前几天就传上来了的呀。。。
邀请赛总结 ,
前几天玩的太浪了,还包了一次宿。休息就跟不上了,正式赛时候脑子一直蒙蒙的。而且之前想前一天去安排下战术,然而热身发挥的比较稳,再加上酒店问题比较大,换房间什么的浪费很长时间就没有去安排战术,正式赛只做的4题,铜牌第6.。
发挥的很差,全场题总是不出。。
其实A题正解我早早就推出来了,但是对1,0的可能居然是相同的抱有疑问。。我做的时候不敢相信最后居然能变成一个式子,,认为一定是我想错了,,自以为这种题套路很明显,枚举A矩阵1的个数然后统计答案就好了,,,就还在那么写了,最终GG,,最后交的几发,有一发是等价正解的,但是1的个数为0的特判,指数我少加了个m。。所以依旧时WA。
想一想, 最后100min如果和mengxiang000全力去做K,或者叫他俩帮我我看看A。而不是我和mengxiang000各自开一题,叫My_stage做数据hack这种打发,哪怕只是和他俩随便一个人交流下我A题的做法,至少能再出一题的。。 当时3个人脑子都抽了么,为什么最后的那么长时间内没有任何交流呢??!!作为队长 我很失败啊。。。。。
自身缺陷很严重,硬实力的缺陷还需要时间学习来弥补。但能做出的水题不能在现场作出,这问题实在太大了,
一是赛中与队友交流很少。
二是个人做题时一直是要将每个结果证明出来才敢写,不敢去猜。这也对于算是一大弊病吧,,,。
队伍配合急需加强,以后比赛还是要有战术分配的。
多刷题,多看论文(切掉例题),
2017-05-26 22:57:22 Tabris_ 阅读数:681
博客爬取于2020-06-14 22:40:26
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72775494
题目比较好,就是描述有的时候很不清晰,还有不带数据范围的。。。
10个题写了1天?! 好菜啊。。。。
但是发觉阅读能力见长啊,。。可能还是题目比较简单吧,,,
至今不会搞死小圆啊 。。。 回头去学习一波。。
明天补题。
听说每题单开一贴能增加阅读体验? 难道不是访问量++??!
题目比较简单【10/12】
Problem ALittle Red Riding Hood
Problem BChoosy in Food
Problem CFriends
Problem DGCD
Problem EOne Stroke
Problem FEscape from the Darkness
Problem GSequence Number
Problem HMathematicalGame
Problem ICandies
Problem JColor Circle
Problem KDeadline
Problem LHappiness
傻逼签到题,实在不想单开一贴,计算AB的数目就好了。
2017-05-26 22:49:23 Tabris_ 阅读数:265
博客爬取于2020-06-14 22:40:27
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72775216
题目连接:http://acm.hzau.edu.cn/problem.php?id=1209
——————————————————————————
1209: Deadline
Time Limit: 2 Sec Memory Limit: 1280 MB
Submit: 1195 Solved: 139
[Submit][Status][Web Board]
Description
There are N bugs to be repaired and some engineers whose abilities are roughly equal. And an engineer can repair a bug per day. Each bug has a deadline A[i].
Question: How many engineers can repair all bugs before those deadlines at least?
1<=n<= 1e6. 1<=a[i] <=1e9
Input
There are multiply test cases.
In each case, the first line is an integer N , indicates the number of bugs. The next line is n integers indicates the deadlines of those bugs.
Output
There are one number indicates the answer to the question in a line for each case.
Sample Input
4
1 2 3 4
Sample Output
1
————————————————————————————
题目大意:
就是有n个bug,每个bug有一个ddl,问你最少需要多少人才能在保证在每个bug的ddl之前修好所有bug。
解题思路:
其实很好想,枚举ddl,计算这个ddl内有多少个bug需要解决,除一下向上取整就是当前所需要的最少人数,维护最大值就行了,
附本题代码
————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 22:41:01 Tabris_ 阅读数:317
博客爬取于2020-06-14 22:40:28
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72774870
题目连接:http://acm.hzau.edu.cn/problem.php?id=1208
——————————————————————
1208: Color Circle
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 344 Solved: 104
[Submit][Status][Web Board]
Description
There are colorful flowers in the parterre in front of the door of college and form many beautiful patterns. Now, you want to find a circle consist of flowers with same color. What should be done ?
Assuming the flowers arranged as matrix in parterre, indicated by a N*M matrix. Every point in the matrix indicates the color of a flower. We use the same uppercase letter to represent the same kind of color. We think a sequence of points d1, d2, … dk makes up a circle while:
Every point is different.
k >= 4
All points belong to the same color.
For 1 <= i <= k-1, di is adjacent to di+1 and dk is adjacent to d1. ( Point x is adjacent to Point y while they have the common edge).
N, M <= 50. Judge if there is a circle in the given matrix.
Input
There are multiply test cases.
In each case, the first line are two integers n and m, the 2nd ~ n+1th lines is the given n*m matrix. Input m characters in per line.
Output
Output your answer as “Yes” or ”No” in one line for each case.
Sample Input
3 3
AAA
ABA
AAA
Sample Output
Yes
————————————————————————————
题目大意:
问你能不能找到一个由一种颜色构成的圈
有求,
1.至少有4个点
2.所有点首尾相接构成一个圈
3.颜色相同
4.点是不同的
解题思路:
由于图很小,所以暴力搜就好了,
附本题代码
——————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 22:03:13 Tabris_ 阅读数:309
博客爬取于2020-06-14 22:40:30
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773996
题目链接:http://acm.hzau.edu.cn/problem.php?id=1207
——————————————————————————————————————
1207: Candies
Time Limit: 2 Sec Memory Limit: 1280 MB
Submit: 249 Solved: 39
[Submit][Status][Web Board]
Description
Xiao Ming likes those N candies he collects very much. There are two kinds of candies, A and B. One day, Xiao Ming puts his candies in a row and plays games. And he can replace the Lth candy to the Rth candy with the same kind of candies. Now, he wonder that if he eats the Lth candy to Rth candy, he can eat how many B candy continuously at most. For each Xiao Ming’s query, give the number of the B candy he can eat continuously at most.
Input
In the first line, there is an integer T, indicates the number of test cases.
For each case, there are two integers N and M in the first line, indicate the number of candies and the time of Xiao Ming’s operations.
The second line is a N-length string consist of character A and B, indicates the row of candies Xiao Ming put.
The next M line is Xiao Ming’s operations. There are two kind of operations:
1 L R v, indicate Xiao Ming replaces the Lth candy to the Rth candy with A candies (v==1) or B candies ( v == 2 ).
2 L R, indicate Xiao Ming wonder that there are how many continuous B candies between the Lth candy to the Rth candy most.
Output
In each case, the first line is “Case #k: “, k indicates the case number.
For each query, output the number of the most continuous B candies.
Sample Input
1
5 3
ABABB
2 1 3
1 2 3 2
2 1 3
Sample Output
Case #1:
1
2
————————————————————————————————————————————
题目大意:
给你一个序列,分别代表AB两种果实,
有两种操作,
1 将区间l,r 全变为(A或B)中操作
2 问你区间l,r 中连续的B最长是多长
解题思路:
线段树维护就好了
因为要有维护两个区间并的情况,所以要维护
sum 当前区间内连续的B的长度
ls 当前左边界开始向右连续B的长度
rs 当前右边界开始向左连续B的长度
lazy 懒标记
然后注意下维护的细节就好
Ps: 本来自己写了份代码,但是写到最后query的时候发现,合并时需要的信息得需要一个结构体来存诸,然而我写的时数组的。。。。。心态爆炸。。 最后厚颜无耻的贴了代码。。。
附本题代码
————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 21:55:54 Tabris_ 阅读数:467
博客爬取于2020-06-14 22:40:31
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773955
题目链接:http://acm.hzau.edu.cn/problem.php?id=1206
——————————————————————————————————————
1206: MathematicalGame
Time Limit: 2 Sec Memory Limit: 1280 MB
Submit: 170 Solved: 26
[Submit][Status][Web Board]
Description
Xiao Ming likes to play mathematical games very much. One day, he gets a sequence of n positive integers. XOR (l , r) is defined as the XOR and of all numbers in a continuous interval. Now, Xiao Ming wants to know the intervals which make the XOR (l , r) become largest.
Require l, r.
Input
There is an integer T at the first line, indicate the case of data.
In each case, there is an integer N at the first line, indicate the length of the sequence. And there are N integers, a1, a2, … , an, at the second line. (N <= 1,000,000)
Output
In each case, the first line is “Case #k:”, k is the number of test cases, the next line includes two integers l and r, which separated by a space.
l, r output in lexicographic order if there are multiple results.
Sample Input
1
5
1 2 3 4 5
Sample Output
Case #1:
3 4
————————————————————————————————————————
题目大意:
问你区间异或值最大的区间是多少,如果值有多个,输出字典序最小的那个
解题思路:
相信大家都会 区间内选两个值,异或最大
那么这个也一样,只要维护的是前缀异或和就好了,这样就变成了经典问题。
然后维护结果就好了
附本题代码
——————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 21:50:28 Tabris_ 阅读数:401
博客爬取于2020-06-14 22:40:32
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773915
题目链接:http://acm.hzau.edu.cn/problem.php?id=1205
————————————————————————————————————————————
1205: Sequence Number
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 934 Solved: 242
[Submit][Status][Web Board]
Description
In Linear algebra, we have learned the definition of inversion number:
Assuming A is a ordered set with n numbers ( n > 1 ) which are different from each other. If exist positive integers i , j, ( 1 ≤ i < j ≤ n and A[i] > A[j]), < A[i], A[j]> is regarded as one of A’s inversions. The number of inversions is regarded as inversion number. Such as, inversions of array <2,3,8,6,1> are <2,1>, <3,1>, <8,1>, <8,6>, <6,1>,and the inversion number is 5.
Similarly, we define a new notion —— sequence number, If exist positive integers i, j, ( 1 ≤ i ≤ j ≤ n and A[i] <= A[j], < A[i], A[j]> is regarded as one of A’s sequence pair. The number of sequence pairs is regarded as sequence number. Define j – i as the length of the sequence pair.
Now, we wonder that the largest length S of all sequence pairs for a given array A.
Input
There are multiply test cases.
In each case, the first line is a number N(1<=N<=50000 ), indicates the size of the array, the 2th ~n+1th line are one number per line, indicates the element Ai (1<=Ai<=10^9) of the array.
Output
Output the answer S in one line for each case.
Sample Input
5
2 3 8 6 1
Sample Output
3
——————————————————————————————————————
题目大意:
就是给你一个序列,然你求下的最大值
解题思路:
首先记录每个数的索引,
然后按数值大小升序排序
然后遍历每次将索引更新到树上,并查找索引在他之前最小的那个位置是多少.
维护最大值就好了
复杂度
听说用单调栈降到
附本题代码
————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 21:39:29 Tabris_ 阅读数:343
博客爬取于2020-06-14 22:40:33
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773828
题目链接:http://acm.hzau.edu.cn/problem.php?id=1204
————————————————————————————————————————
1204: Escape from the Darkness
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 99 Solved: 3
[Submit][Status][Web Board]
Description
Xiao Ming, a high school student, learnt blackbody radiation from the physics class. The black body on the book is indicated approximately by black body cavity as below:
from the small hole if total reflection occurs on the surface of the cavity.
Assuming in the two-dimensional coordinates, the center of the oval is at origin, and the vertexes of it is respectively (a, 0), (-a, 0), (0, b), (0, -b). There is a small hole at (a/2,sqrt(3)*b/2) (whose areas can be ignored). A beam of light (whose diameter can be ignored) shoot into the oval through the small hole. The direction of the light is (-1, 0). Assuming the light totally mirror reflects on the surface of the oval, the question is how many times can the light reflect before shooting out through the small hole. (If a point is away from the small hole less than 0.01, we think light shoot out from that point.)
Input
The first line is a positive integer T (1 <= T <= 55) which indicates the numbers of the test cases. Then flowing next T lines, there are two positive integer a, b (1 <= b<= a<= 10) in each line as a group of cases.
Output
The output of each case is one line with a positive integer which indicates the times of reflects.
Sample Input
1
1 1
Sample Output
5
HINT
The path of the light in the sample is looked as the picture shows. The light reflected five times.
————————————————————————————————————————
题目大意:
好像很难啊 ,占坑待补。
2017-05-26 21:36:14 Tabris_ 阅读数:461
博客爬取于2020-06-14 22:40:34
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773799
题目链接:http://acm.hzau.edu.cn/problem.php?id=1203
——————————————————————————————————————
1203: One Stroke
Time Limit: 2 Sec Memory Limit: 1280 MB
Submit: 274 Solved: 58
[Submit][Status][Web Board]
Description
There is a complete binary tree which includes n nodes. Each node on the tree has a weight w, each edge on the tree is directed from the parent node to the child node. Give you a pen, draw from the any node along the directed edge at one stroke. It is required that the sum of those drawn nodes’ s weight is no more than k. How many node can be drawn at most in one stroke?
Input
The first line input an positive integer T(1<=T<=10)indicates the number of test cases. Next, each case occupies two lines. The first line input two positive integers n(1<=n<=10^6) and k,(1<=k<=10^9)
The second line input n integers w(1<=w <=10^3), indicate the weight of nodes from the first level of the tree and from left to right.
Output
For each test cases, output one line with the most number of nodes can be drawn in one stroke. If any node likes this doesn’t exists, output -1.
Sample Input
1
5 6
2 3 4 1 7
Sample Output
3
——————————————————————————————————————————
题目大意:
就是给你一棵树,每个树上有一个权值,让你找一条最长的从上向下的链,使其权值和不大于k,问你最长的长度是多少。
解题思路:
限制了链式从上到下的,
所以我们可以枚举每个节点所在的链,然后找最远的权值和不到k的点,就是到这个节点最长的长度,
找的时候用二分就好了,当时脑抽写了个BIT,其实发现数组就好了啊,。。
枚举节点在dfs遍历树的过程创建链就好了,
总复杂度
注:代码是 把BIT换成普通数组就好了.
附本题代码
———————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 21:26:18 Tabris_ 阅读数:409
博客爬取于2020-06-14 22:40:35
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773724
题目链接:http://acm.hzau.edu.cn/problem.php?id=1202
————————————————————————————————————————
1202: GCD
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 241 Solved: 44
[Submit][Status][Web Board]
Description
Input
The first line is an positive integer T . (1<=T<= 10^3) indicates the number of test cases. In the next T lines, there are three positive integer n, m, p (1<= n,m,p<=10^9) at each line.
Output
Sample Input
1
1 2 3
Sample Output
1
————————————————————————————————————————
题目大意:
就是让你求
解题方法:
问什么叫方法,因为暴力啊。。。
首先暴力的打了一个的表,然后惊奇的发现这就是fibonacci数列
然后就变成了
然后根据fibonacci数列的性质
所以同一个矩阵乘法就可以了
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 21:17:40 Tabris_ 阅读数:413
博客爬取于2020-06-14 22:40:36
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773662
题目链接:http://acm.hzau.edu.cn/problem.php?id=1201
————————————————————————————————————————
1201: Friends
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 151 Solved: 40
[Submit][Status][Web Board]
Description
In a country, the relationship between people can be indicated by a tree. If two people are acquainted with each other, there will be an edge between them. If a person can get in touch with another through no more than five people, we should consider these two people can become friends. Now, give you a tree of N people’s relationship. ( 1 <= N <= 1e5), you should compute the number of who can become friends of each people?
Input
In the first line, there is an integer T, indicates the number of the cases.
For each case, there is an integer N indicates the number of people in the first line.
In the next N-1 lines, there are two integers u and v, indicate the people u and the people
v are acquainted with each other directly. People labels from 1.
Output
For each case, the first line is “Case #k :”, k indicates the case number.
In the next N lines, there is an integer in each line, indicates the number of people who can become the ith person’s friends. i is from 1 to n.
Sample Input
1
8
1 2
2 3
3 4
4 5
5 6
6 7
7 8
Sample Output
Case #1:
6
7
7
7
7
7
7
6
——————————————————————————————————————————
题目大意:
就是有n个人,他们的朋友关系是一个树,现在通过至多5个人能联系到的也会成为朋友。问你现在的情况下,每个人会有多少个朋友。
解题思路:
很明显的树形dp
设dp[i][j] 为第i个节点的子树中距离i为j的节点个数.
设ans[i][j] 为整棵树中距离i为j的节点个数.
dp可以通过一次dfs计算出来,
ans稍麻烦些,
对于一个节点,
转移很好理解,画棵树理解下就好了.
注意的是根节点要特殊处理一下
附本题代码
———————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-26 21:08:14 Tabris_ 阅读数:338
博客爬取于2020-06-14 22:40:37
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773595
题目链接:http://acm.hzau.edu.cn/problem.php?id=1200
————————————————————————————————————————
1200: Choosy in Food
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 48 Solved: 12
[Submit][Status][Web Board]
Description
Xiao Ming find n trees (labeled 0…n-1) which join a circle in a magical land. Each tree
is covered with ripe berries. Xiao Ming wants to find the tree whose berries are most delicious. He starts from the tree X, walks clockwise to find the target. Each time the probability of him walking k trees is Pk% . P1+P2+…+Pk = 100
Now we know the target of Xiao Ming is the tree Y. Require to know expectation of the number of the trees which Xiao Ming walk through
Input
The first parameter is T, indicates the case number.
In each case, there are four integers at the first line, N, M, X , Y (Tree labels from 0 to N-1, N < 100, M < N).
Output
The expectation of the number of trees Xiao Ming walk through. It will be reserved two decimal places. If Xiao Ming will never arrive the tree, output -1.
Sample Input
2
4 2 0 1
50 50
4 1 0 2
100
Sample Output
4.20
2.00
————————————————————————————————————————
题目大意:
就是有一些树(真的树,能结果子那种),围城一圈,编号0~n-1。一个人从X开始顺时针出发,可以走1~M步,每步的概率是,问你走到Y的期望步数是多少.
解题思路:
这种套路很明显的高斯消元啊.,但是我不会高斯消元啊.....
占坑待补…
]]>2017-05-26 21:02:33 Tabris_ 阅读数:596
博客爬取于2020-06-14 22:40:38
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72773556
题目链接:http://acm.hzau.edu.cn/problem.php?id=1199
——————————————————————————————————————————
1199: Little Red Riding Hood
Time Limit: 1 Sec Memory Limit: 1280 MB
Submit: 937 Solved: 166
[Submit][Status][Web Board]
Description
Once upon a time, there was a little girl. Her name was Little Red Riding Hood. One day, her grandma was ill. Little Red Riding Hood went to visit her. On the way, she met a big wolf. “That’s a good idea.”,the big wolf thought. And he said to the Little Red Riding Hood, “Little Red Riding Hood, the flowers are so beautiful. Why not pick some to your grandma?” “Why didn’t I think of that? Thank you.” Little Red Riding Hood said.
Then Little Red Riding Hood went to the grove to pick flowers. There were n flowers, each flower had a beauty degree a[i]. These flowers arrayed one by one in a row. The magic was that after Little Red Riding Hood pick a flower, the flowers which were exactly or less than d distances to it are quickly wither and fall, in other words, the beauty degrees of those flowers changed to zero. Little Red Riding Hood was very smart, and soon she took the most beautiful flowers to her grandma’s house, although she didn’t know the big wolf was waiting for her. Do you know the sum of beauty degrees of those flowers which Little Red Riding Hood pick?
Input
The first line input a positive integer T (1≤T≤100), indicates the number of test cases. Next, each test case occupies two lines. The first line of them input two positive integer n and
k (2 <= n <= 10^5 ) ,1 <= k <= n ), the second line of them input n positive integers a (1<=a <=10^5)
Output
Each group of outputs occupies one line and there are one number indicates the sum of the largest beauty degrees of flowers Little Red Riding Hood can pick.
Sample Input
1
3 1
2 1 3
Sample Output
5
———————————————————————————————————————————
题目大意:
就是一个序列,拿取的最大价值,拿取一个后,半径为k的位置价值都变为0了。
解题思路:
很明显更的dp
设dp[i]为到拿取第i个位置的最大价值,
转移就是
由于最大值是前缀最大值,所以用一个树状数组维护就好了
附本题代码
———————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-17 01:28:43 Tabris_ 阅读数:2198
博客爬取于2020-06-14 22:40:39
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72355760
好吧,还是需要总结下最近的省赛和东北赛,本来想等西安回来在一起写的,但是发现省赛、东北赛暴露出的问题是在太严重了。
还是简单叙述下敝队的这两场比赛吧
省赛:
热身:AB是考察队伍会不会编程语言,C是一个简单的dp 。但是队友却写了好久。。。然后随便测了测环境就走了。
正式:
AB还是考察这个队伍会不会编程语言。 然后看有队伍A了C 然后想啊想,还是没想出来,又看到有好多队伍A了E ,然后就去搞E,我想了想好像结果就是输出n到1. 又做过山东某省赛输出-1是没意义的就直接交了一发,果断的WA了,然后mengxiang000看了D,说D出了,就交给它去写,期间My_stage说分奇偶,偶数是-1.当时我这在找偶数的解,确实找不出来,然后交了一发A了。然后My_stage在推C,mengxiang000在交D,WA了之后改了几个小细节,然后再交,还是WA。于是我去看了看这题,咦?怎么和湖南某年省赛的某题很像啊,枚举边然后TOP不就好了,队友怎么可能不过。算了我上去写一发,因为队友已经写出来。所以我写的时候细节上就参照mengxiang000的写,然后看mengxiang000的这个TOP怎么这么奇怪??!!啊 原来mengxiang000只把点1放到了队列中,没有将其他入度为0的点放入队列,这怎么能对,然后给mengxiang000一组数据告诉他错了,发现确实这样.于是改了AC。此时4题,罚时也有点爆表。这时候三个人没一个对C有思路。看有人A了 F,让My_stage给我讲了F的题意,懂了,然后不会做啊。后来想到我可以倒叙处理这些删的边。然后维护答案,然后维护的时候mengxiang000说是并查集,想了想,确实没有问题。然后交给mengxiang000去写,写完后测了几组小样例。好像没问题,交WA。多次WA之后我想到可能两个堆都挂上但是合并了,这样的话按照最开始染的颜色就错了,然后我想用一个数组将颜色映射过去,然后开始调。对了几个小数据,交,WA。。改了交,WA。 就这样WA到结束。
想了想封榜前的rk和罚时,1=是没有希望了。。。
但最后发现终榜rk并没有掉?!! 于是捡了个1=。。。
东北赛:
热身:
很有意思的热身,因为前天测试过机器,长老说答30min就退场买东西,然后返校。然后热身A题,嗯,是个水题,没错,非常水,自己不想写,甩给mengxiang000和My_stage。自己去看B. B题堆到满足的一对结果就是a*b是平方数,然后想到某年山东省赛的G题H题。知道b一定是a的倍数,然后筛一晒就好了。但是没读懂题目要求的集合是什么意思。然后过去20分钟a题竟然没A??!! 虽然看他们的做法很迷,但是相信他们能在很短时间内A了的。然而并没有A。而且mengxiang000心态还非常炸??!!反正是热身,治治他这个毛病,(其实我在现场赛的时候是很炸的,从去年省选到现在,但是没办法为了不影响队友的心情只能强憋,但队友这样我受不了啊,趁热身赛治治他)于是交了几发WA到点我就走了,我很不解啊,这个题不是大一入学是做的题么,字符串整体倒过来,在翻转单词不就好了。问什么这俩人没AC?迷。于是鄙队第一次爆0了。。。还好是热身赛。。。。。
正式赛:
正式赛更迷啊。
开始看A Huffman??!! 我还能记得huffman树,但是怎么玩来的?想不到啊,过了几分钟看有人过了E,嗯是个签到题,于是mengxiang000上去写,写到一半思路有点不清晰,换给我写,我接着他写的15min 1Y。之前我在看C。觉得特别的亲切,让mengxiang000先给翻译了,然而这时候很多人过的是A,于是三个人还是主要在思考huffman的,然后发现敝队就我能记得huffman了,,,然后开始还想错了,WA了2发,想起不对正确的huffman姿势不对啊。期间我让My_stage去数据结构书上找,他说没找到。好吧没找到,然后凭印象给mengxiang000讲了个huffman树是怎么建的,让他去模拟.这时看了看榜,我们1题,rk1 4题。Orz。。同时队友给了我C题意,我去看C,刚换完座位,我看了看C?这不sb题,秒了,于是又换了座位,过样例、交,然后就换了座位,过了一会结果返回TLE??!! 怎么可能TLE。然后我读了读代码,嗯,应该是卡了map的log,问mengxiang000,数据范围多大,答5e5,嗯,换成数组85min 2Y。然后换回mengxiang000去敲A。交WA。然后我去调了调,发现有错,然后mengxiang000改了。120min 4Y、、然后rk还是很不好,但是感觉2=应该稳了。然后My_stage说J是个dp。嗯,甩给mengxiang000,后My_stage给了G题题意?嗯有意思,看了看数据范围和时限,发现对新子串Manachar就差不多了,然后手痒,没让My_stage敲。自己写。过样例,交,RE。。数组小了。。又交…RE?!! 看了看Manachar,嗯有处可能越界,改了交。。TLE?!!!!,woc,这么科学的复杂度怎么可能TLE。。然后交换mengxiang000上机,同时想了想G。觉得多次询问用map记录下?然后自己立马就给否了,觉得这么玩不是很科学。然后就想了想J,嗯,好像维护两个序列就好了, 一个买的一个卖的,保证买的比卖的多,就好了于是上去写。期间My_stage上厕所回来说用map记录下之前处理过的值,我直接就给否了,说没什么意义。继续敲J,同时mengxiang000和My_stage一直在想map为什么被我否了,几分钟后mengxiang000说只有3e4个1 0的时候才是最坏,那么记录下的话就会快很多,想了想确实很有道理啊,于是改了交,196min 5Y。。。这时感觉自己是在太智障和自以为是。但是不能表现出来。。。继续写J,过了样例。测了几组队友出的数据没问题。于是交204min 1Y。
然后看了看榜,5题倒第一啊,罚时爆表。。于是想着在出一题冲个1=啊。
看榜有过了I的,但是我之前就看了,没什么思路啊,一定是用什么维护的啊,想了想我会的数据结构BIT?不是。线段树?也不对。主席树?没啥用。Splay?好像大概行,但是Splay只会贴版子,变一点就不会了。。于是mengxiang000在乱搞,交了几发TLE。然后看了看气球,冠军队过了F,于是问My_stage是什么意思。给我说了大概,感觉根树剖有点像,但是一个比较关键的次expacted我们三个没一个认识的,那本小字典上还没有。看了看样例还很迷(当时忘了样例可能是错的,正确的样例在PC上,现在想想可能是纸质版上样例错了啊。树剖我觉得我掌握的还是很好的啊 说不定就A了呢。),不知道最终到底要求什么,于是就放弃了。。。于是后40min 敝队就在那开心的聊天了,因为后期不发气球了,我队整场只有一个气球,看旁边别的队瞅我们就一个气球还乐呵呵的傻逼样的那种奇怪的表情。。。。直到结束…
但是最终去礼堂的时候jeh老师说我们是1=、 ?!! woc这有意思了啊。
两场比赛都是罚时爆表啊。但都捡了个1=。。。。
比赛大概就是这样。。
记得省赛结束的那句“比赛结束”的时候我终于想起F题哪里少了一个映射。。那时整个人都是绝望了,感觉这次又因为我最后没调出代码而GG了。 (16年的省赛/东北赛都是我在奋力敲代码然而赛终GG)。而这时我们已经大二了,如果连HLJ的省一都拿不到,那我们拿什么去打接下来的东北赛,西安邀请赛,甚至下半年的ICPC??,当时我脑子里就两个字“退役”,这两个字不断的重复,在想自己怎么这么菜。赛前训练了十几场省赛,区域赛和强校的校赛。但无论过了多久代码力依然那么菜。细节多点的题仍然要调很长时间。任何一场比赛都不能多输出两个?还打什么比赛啊,还TM队长呢。。。
那时真的整个人都是懵逼的,mengxiang000也不说话了,My_stage也没什么表情。学弟看到我那张驴脸还过来安慰我,,最后大家去溜达买东西了,我们三个还坐在赛场门口旁的,哪里也不想去。
知道看到长老在群里发的我们拿了1= .???!!!woc这1=是怎么拿的 封榜前rk多少终榜rk还多少???!!!太给面子了。于是心情大好,滚去礼堂zhuangb了。。。
东北赛也差不多,但东北赛本来的目标就是2=头,所以没什么压力,最后告诉我们还是1=的时候真的有点不敢相信,运气是在是太好了。两次都是一样rk,都是1=倒第3,省赛如果罚时在多4min,就是2=了。。这运气实在太好了。
然后领奖,返校。
然后这两天比赛确实很累,做了湘潭重现。然而发现题都已经读不懂了。。。。于是回寝咸鱼。
一直在想这两场比赛,暴露了太多的问题。
1 我们队真的太菜了。
2 签到题迟迟不AC。
3 一些简单东西不熟练了,比如省赛的top序。 (如果没有耽误太长时间F是不是能调出来?
4 现场心态急躁
5 这是我个人的,作为队内的数学选手,对这C题却没有思路??!!经人一说,才会做??!
6 还是我个人的,作为队内数据结构选手,F题却迟迟调不出来??!!
7 依旧是我个人的。思维死板,有时候猜到的东西就可以用20分钟的罚时换一换么。总想只有证明出来的东西才稳妥,现场哪有那么多时间给你证明??!
8 仍然是我个人的。不读题,读题大多靠队友,浪费了队友思考的时间。
9 这是全体的,三个人的知识点太偏,思维广度不够。做题太少。训练太少。
虽然结果上看还不错,但是其实还是菜到家了。
想毕姥爷知乎上说的“各位不怎么强啊,也就能做做ACEGJ了啊”。
也确实,敝队还是菜的飞起。
简单的5题做完就只能咸鱼了,会的东西还太少了。
其实这两场比赛也并不能完全代表敝队的水平。
mengxiang000更擅长搞图论,dp,但这两天没题啊。随便给我网络流让他做做么。
My_stage 更擅长搞字符串和递推啊。还是没有题啊、、、、
像省选时 ,个人会做的题即使不限时间的话也就能A 13个水题、 什么AC机,网络流,K短路,都是队友大力AC的啊。我是一丁点都不会啊。
最后还是努力训练吧,我个人还有一个陕西宴请赛就结束这个赛季了。努力点,少把时间浪费在学校的课堂上。回头学学图论+dp+字符串 这些东西,不用学太深,起码把算法裸题切了。
然后就是自己数学+数据结构这方面要继续深入学习啊。连个Splay都不会啊。。。 暑假就要队内的训练了,没时间大块时间学习了。
]]>2017-05-16 19:19:16 Tabris_ 阅读数:294
博客爬取于2020-06-14 22:40:40
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/72329005
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798
————————————————————————————————————————————
1798: [Ahoi2009]Seq 维护序列seq
Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 6402 Solved: 2284
[Submit][Status][Discuss]
Description
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
Input
第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
Output
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
Sample Input
7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7
Sample Output
2
35
8
HINT
【样例说明】
初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。
测试数据规模如下表所示
数据编号12345678910
N=10100010001000060000700008000090000100000 100000
M=10100010001000060000700008000090000100000 100000
————————————————————————————————————————————
其实对于只有一种操作的情况,我们只要做一个lazy标记就行了,
但是对于两种操作的时候就有点不知所措了,
其实道理都是一样的,既然有两种操作了,呢么就用两个lazy标记不就好了么
一个add[] 一个mul[] 分别记录加法和乘法操作,
然后直接维护就好了
注意的是pushdown的时候这两个标记是要合并的,
还是代码表述的好一些。
1 | void pushdown(int rt,int l,int r){ |
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-11 21:10:00 Tabris_ 阅读数:635
博客爬取于2020-06-14 22:40:42
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/71698163
迟来的总结
队友缺席一人,两人,vj 5h模拟,1+小时从下开始看榜。
F题很迷,同时我很智障,居然浪费全队2个小时,个人3+小时的时间,,,,,导致最后的GG
做题的时候要更加细心,思维要缜密,同时不能有一点懒惰,有些认为可有可有的操作还是写上更为保险一点。
因为F题我只判了 而另一个解想当然的没有判。。。炸锅 看F之前3题。期间我清清脑子A了C,然后就GG了,
K题最后因为实验室清楼,时间不够了,算上回寝室走路的时间,队友晚了6分钟AC,然后这个A,D 都是我的题,当时想F想的,脑子一片浆糊,没有想出。赛后想到了。。。。
比赛时头脑要清晰,思维要严谨,尤其是不能懒,
————————————————————————————————————————————
有n(n 是素数)堆石子,两个人轮流玩,每次可以再一堆拿走任意个,或者在剩下的所有堆拿走相同的个数的石子,取走最后一个石子的人赢,问你谁赢
n是素数,所以切入点一定是这里,想了所有素数的性质,想不出什么所以然来,
然后玩了玩,其实可以发现,
对于n=2 时就是威佐夫博弈,
对于n=other 的时候,n是奇数,那么对于在所有堆拿走相同的石子,其实就是相当于两个人玩了多次的正常Nim, 因为Nim的最优策略就是对方拿了x个石子,我就在其他堆也拿x个石子,所以这就划归为基本的Nim游戏了,,
附本题代码
————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
还没弄懂题意,等邀请赛回来,
————————————————————————————————————————————
就是在一个坐标轴上,有一些点(x)有一个价值(a)
每秒这些点和他们临近的点的价值变成(x-0) (x+1 - a) (x-1 - a)
价值会叠加,问你t秒后w位置有多少个值
写了写就会发现,每个点经过t妙对其他点的贡献是一个杨辉三角,
那么我们就枚举每个点对结果的贡献最后在加和就好了
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
这个题就是一个点可以走到下面临近的三个位置上,问你从(1,1)到(n,m)的走法有多少个,
其实可以划到直角坐标系上,走法就是(0,1)(1,1)(1,0)
然后我们类比只有两种走法的情况 - (0,1)(1,0)
答案很明显是C(n+m,n), 那么对于三种情况当然也一样啊,
但是注意当(1,1)存在的时候(0,1)(1,0)相对就会变少结果也不一样,
然后我们可以枚举(1,1)的个数,然后就能确定三种走法的总数了,然后求下组合数就好了
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
队友认为是01分数规划,,但是有不太一样,最后没出。
————————————————————————————————————————————
让你判断“对于任意的x,如果方程成立,x一定是正数”这句话是不是对的,
所以就是方程不成立的时候也是YES
对于命题P->Q
P Q P->Q 0 0 1 0 1 1 1 0 0 1 1 1
所以这题注意下判断的符号就行了
附本题代码
————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
水签到题 不解释
————————————————————————————————————————————
不会
————————————————————————————————————————————
很容易发现循环节 1 1 0
然后大数取模就好了, 并不用写高精度
附本题代码
——————————————————————————————————————————
1 | # include<stdio.h> |
————————————————————————————————————————————
队友自己做的 ,我没读题
————————————————————————————————————————————
队友自己做的 ,
贪心+01包
]]>2017-05-09 14:02:21 Tabris_ 阅读数:566
博客爬取于2020-06-14 22:40:43
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/71453698
题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1681
————————————————————————————————————————————
回文串
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 121(25 users)Total Accepted: 30(12 users)Rating: Special Judge: No
Description
现在我们有一个很长很长的字符串,并且我们将有两种操作。
C i y:将第i个字符变成y
Q i j:检查第i个字符到第j个字符是否为一个回文串
Input
输入的第一行是一个整数T,表示一共有T组测试数据;
对于每组测试数据,第一行包含一个字符串长度不超过1000000。
接下来一行为一个整数N代表操作次数。N不超过1000000
接下来N行包含一种操作。
所有的字母都是小写字母。
Output
对于每种操作,如果相应的字符串为回文串输出"yes",后则输出"no"。
Sample Input
1
aaaaa
4
Q 1 5
C 2 b
Q 1 5
Q 1 3
Sample Output
yes
no
yes
————————————————————————————————————————————
我们判定一个字符串是不是回文的只需判断正过来和倒过来是不是相等的就好了.
对于字符串是不是相等的 ,正常需要O(length)判定,对于本题,显然是不可取的。
所以介绍下字符串hash算法,
hash就是映射吧,将一个字符串集合中的每个映射为一个值,这些值互不相同
随意设一个常数x
这样就能将一个字符串映射为一个正整数,
虽然这样计算的结果很可能是相同的,但是可喜的是相同的概率十分小.所以可以直接使用.
但是一般我们采用的是unsigned long long int,在计算中也不需要取模操作,因为运算的自然溢出就相当于对取模了。
这样下来,我们只需要将字符串正着hash一遍,倒着hash一遍,就可以了,
因为有修改操作,所以我们采用BIT维护下。
注意:判定两个子串的时候,x的指数不对应,只需要在小的那个结果乘上差的那部分就好了
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-09 11:30:44 Tabris_ 阅读数:1236
博客爬取于2020-06-14 22:40:44
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/71440571
日常6题 然后GG
最后这个B题和D题也没有过掉
套路啊 智商还是不行啊
————————————————————————————————————————————
这个A题开场几分钟队友就匆忙上机给秒了 666啊
我们这样考虑
对于一个说对的概率是1/m ,那么n个人的期望就是n/m
然而这个期望其实就是
E = n/m =\sum_{i=1}^n {(p_i\times i)} \tag{p_i为i个人答对的概率}
最大值显然是 n/m=
所以最后答案就是1/m
————————————————————————————————————————————
对于一个序列我们将其变成升序序列,可以直接 a[i]-i 然后求LIS. 但是这样的结果可能是负数或者0的,
然而其实很简单 对于每个a[i]-i 如果小于0 那就一定要变化,所以就对剩下的序列求LIS就可以了,求得的结果就是不用修改的,那么修改的就是n减去
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
这个题就是用50条直线,将平面内的一些点给分堆了,
如果直接找两个点之间的关系的话是复杂度是O(NKM)的,不可取,
但是问什么这个M给的是50呢? 仔细想一想,这个50 一定是一个可以枚举的,
然后想到,对于每一条直线来说,都会将平面内的点分成两部分,那么我们给直线一边的标记为1,另一边的标记为0,这样就能将每一个点的状态压缩下来,然后将titan的状态map一下,在判每一个村庄他的状态就行了。
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
这个题简直666 啊
本质就是一个区间覆盖问题,
但是直接区间覆盖会TLE ,然后就一直想怎么做到O(n),最后GG了
其实我们可以逆序覆盖,然后每次更新的时候lazy_tag如果有,那就不给它更新了,算是上一个大剪枝了.
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
签到水题,不解释
————————————————————————————————————————————
稍微多点细节的搜索, 队友A的 不想补
————————————————————————————————————————————
没什么说的直接二分答案就好了
附本题代码(队友代码 不要脸的贴过来了)
————————————————————————————————————————————
1 | # include<stdio.h> |
————————————————————————————————————————————
这题如果直接计算的话,会涉及每次到甲的概率,通式推不出来
然后当时就分成两个值
然后很容易构造矩阵
然后矩阵乘法即可
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
————————————————————————————————————————————
]]>2017-05-07 19:48:25 Tabris_ 阅读数:1295
博客爬取于2020-06-14 22:40:45
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/71366392
虽然只是校赛,但是题目质量真的很高啊,
学到了新姿势,自己的思维还是太局限了.,
————————————————————————————————————————————————
水题, 注意队伍名可能是bnuu这类
————————————————————————————————————————————————
其实还是一个基础的题目,维护区间和就行了,树状数组,线段树都可以
维护的时候,维护所有位置的真实值,即如果当前值是b那么就是a[b]
再求区间和的时候就是基本的区间求和的操作了,
对于交换操作,很容易发现,交换的时候只对四个值有影响,
a[l],a[r]还有a[i]==l的位置,a[i]==r的位置,
先处理交换操作,然后在去修改就可以了,
复杂度是
附本题代码
——————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————————
不会
————————————————————————————————————————————————
其实很容易想到以一个点作为参照,然后计算另一个点,
然后讨论一下,动点与静点越来越远的轻况 那么最开始的距离就是最近的
然后列方程可以求得静点到动点轨迹的垂足坐标,然后计算就可以了,
但是!但是!但是! 无论怎么修精度什么的就是过不去,最后GG,如果思路有纰漏请指正
最后用三分的方法过掉的,
首先我们能确定两个运动轨迹是直线,那么两点距离是先变小,在变大,这就是一个凹函数,可以三分求得极值,
给定时间了,就能求出两点当前的位置,然后算距离就好了
如果这个距离大于半径和,那就是不碰撞
否则就是碰撞了,在[0,三分结果]二分就能得到刚好相切的时刻
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
一个大模拟,没有卡复杂度之类的,但是模拟SQL也是很复杂的,有时间补上
————————————————————————————————————————————
水dp,队友出的,过会儿补上
————————————————————————————————————————————
这个题很有意思,初看的时候没有什么想法,就想,要是像往常那样的n*m图bfs就好了,怎么搞了呢?
于是想到我将这个图按照原本的规则建立一个正常一点的图不就好了么.
然后将一个/\ 变成了3*3的方阵里的对角线,刚好能满足.
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
其实重点就是那个10滴上面,所以只要对边爆搜即可,滴过得边就不用在滴,如果滴的大于10个就return
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-07 11:24:54 Tabris_ 阅读数:696
博客爬取于2020-06-14 22:40:46
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/71310488
题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1503
————————————————————————————————————————————
1503: 点到圆弧的距离
Submit Page Summary Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 850 Solved: 221 SpecialJudge
Description
输入一个点P和一条圆弧(圆周的一部分),你的任务是计算P到圆弧的最短距离。换句话说,你需要在圆弧上找一个点,到P点的距离最小。
提示:请尽量使用精确算法。相比之下,近似算法更难通过本题的数据。
Input
输入包含最多10000组数据。每组数据包含8个整数x1, y1, x2, y2, x3, y3, xp, yp。圆弧的起点是A(x1,y1),经过点B(x2,y2),结束位置是C(x3,y3)。点P的位置是 (xp,yp)。输入保证A, B, C各不相同且不会共线。上述所有点的坐标绝对值不超过20。
Output
对于每组数据,输出测试点编号和P到圆弧的距离,保留三位小数。你的输出和标准输出之间最多能有0.001的误差。
Sample Input
0 0 1 1 2 0 1 -1
3 4 0 5 -3 4 0 1
Sample Output
Case 1: 1.414
Case 2: 4.000
Hint
Source
湖南省第十届大学生计算机程序设计竞赛
————————————————————————————————————————————
首先能确定的是,在圆弧所在的扇形的角内的点,最近距离是dis(p,r)
,否则是min(dis(p,a),dis(p,c))
.
所以就是如何确定在不在扇形所在的角内了 扇形所在的角如下图所示
分为劣弧和优弧,
在判断上要有所不同,
劣弧
劣弧的时候很好判定这里运用了向量叉积的判定方法,只要$ \overrightarrow{r a} 和\overrightarrow{rp}在\overrightarrow{r c} 的同一侧 且 \overrightarrow{r c} 和\overrightarrow{rp}在\overrightarrow{r a} 的同一侧$ 就能保证了,
优弧
优弧的时候麻烦一些,对于p’ 可以和劣弧相同,不赘述
对于p和p’‘却要不一样, 首先我们只要b可以再弧上的任意位置,以b为参考点是不行的.
但其实仔细观察和点p’’ 其实发现这就是反过来的劣弧的情况,所以在判断是优弧的情况下来重复劣弧的过程就行了,
那么就只剩下怎么判断优劣弧,
其实只要判断的角度就好了 大于90度就是劣弧,小于90度就是优弧,(不解释)
为了方便计算我们转化为余弦公式计算,判断正负就好了
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-05-03 21:21:46 Tabris_ 阅读数:557
博客爬取于2020-06-14 22:40:47
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/71155475
题目很6,我也很菜。和一年前比,水平没有丝毫进步。只能把AB做出来。WHY? Sorry,I don’t know.
没心情,题解瞎写,一点不清楚
————————————————————————————————————————————
翻译清楚就能AC了
————————————————————————————————————————————
枚举一个目标串,统计所有串变成这样的操作次数,维护最小值。
————————————————————————————————————————————
给一个序列,仅有如下一种操作,将a[i],a[i+1] 变成a[i]-a[i+1],a[i]+a[i+1]。问你最少操作多少次,能使序列的gcd>1?
不会 ,懵逼,只知道解题方向是这个操作,然后并没有发现这个操作的什么性质。。。。
然后看了别人的题解,
大家都能发现
奇±偶=奇
偶±偶=偶
偶±奇=奇
奇±奇=偶
然后又发现 至多两次能将 相邻的两个数 变成偶偶的,这样gcd就是2了
然后贪心,现将每个相邻的奇奇一次操作变成偶偶,然后再将相邻的奇偶两次操作变成偶偶, 然后统计次数就好了。
————————————————————————————————————————————
给你两个序列,然你找k个索引相同的数,使得这些数分别加和乘2大于等去分别的总序列和,k<=n/2+1;
将其放到结构体中
按a降序排列,然后尽量找前面的就好,
然后考虑相邻的两个每次找b大的那个选,那么是能满足题意的。
模拟下这过程就好了
————————————————————————————————————————————
题我都没敢看
2017-04-29 21:20:32 Tabris_ 阅读数:422
博客爬取于2020-06-14 22:40:48
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70990783
这套题 ,难度并不高,水题很多,中期题不少
但是发挥并不是特别理想,
一部分是训练态度不够,中间一段时间在聊天,并没有全力出题,
还有队友赶紧回来啊 ,两个人磕还是不行啊,罚时爆表.
最后40分钟搞的G却没有及时出,足足晚了12分钟才AC.
封榜时间出题也应该是一个强队的标志,很明显,我队距离强队差距很远,水平差很多.
个人的话卡题时间比较长,还是对解题的正确方法思考慢,越接近正解的时候越容易乱.越乱越容易出差错.
还有就是不常用算法要及时复习,平时一直写线性筛,训练的时候一个埃斯托尼筛法硬是写了好久才调对.
还有就是思路要清晰, 其实大部分题的编码时间并不长,10~15分钟够用了,除了模拟题,非小规模数据结构题,等…
————————————————————————————————————————————
水签到题 ,结构体排序 加和 比较输出即可
————————————————————————————————————————————
有三种操作,
1.b x 插入一个x
2.c x 删除一个x
3.q 查询当前仅有一个的最小的数
其实这种题一般都是用STL做 但是渣渣并不会STL
所以每次都是用树状数组+二分来搞。
但是这题我们有一个限制,就是只在当前仅有一个的数中找?
所以我们可以定义一个数组,标记每个数出现的次数,将数组中的不是1的数拿下去,是一的数放到树状数组中,然后通过二分找到第一个有数的位置就好了
复杂度虽然是但是没有STL的大常数。所以还是可以的。
————————————————————————————————————————————
算是个博弈吧
但考虑对称性, 除了1,2之外不论先手拿1个还是2个,后手都能将局面变成对称的,先手必败
————————————————————————————————————————————
在一个二维坐标系上,给你个点,问你找一个面积最小的矩形,使得这个矩形内有k个点
点坐标的范围在[0,400]
一看到这400个点我就觉得可以做,然后发现坐标就在[0,400]内连离散化都不用了
我们要的是最小面积,首先想的是二分,但是发现面积又涉及长又涉及宽,我无法再O(n^2)内处理出,所以放弃
然后发现我可以固定一个长,然后找长为定值的时候的面积最小值,然后维护最小值就好了
发现这样在加上一个尺取法和每行的前缀和 的复杂度能做到O(n^3),可以做,
然后就A了
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
给你一个序列,问你两个数的乘积是立方数的数对有多少个?
其实和H题差不多,但是又差了很多,
假如ab是立方数,那么ab*(k^3)也是立方数,那么所有的形如ab(k^3)的数都能划归为a*b的形式,
那也就是说如果数x = (k^3)*b 那么k^3这部分就没有意义,消掉就好了。
这个时候考虑a*b在什么时候成立,显然
那么对
那么对于所有的
那么对于每一个数,我都能找到与其相乘为立方数的数了
只要找这个数的素因子的指数与其对应的就好了
这个部分我们仍然可以预处理,先把每个数划归成没有(k^3)这样的因子的数.然后对其素因子分解就好了,
但是发现如果直接这样的话预处理部分会超时,
所以我们仍然利用埃斯托尼筛法,在过程中找到每个数的因子,用一个vector存就好了,素因子个数小于log
然后对每个数找到其对应的能乘出立方数的数
然后O(n)统计就好了
注意LL
————————————————————————————————————————————
给你一个序列,问你两个数的乘积是平方数的数对有多少个?
然后发现如果ab,ac是平方数那么b*c也是平方数. 其是具有传递性的,
那么我们就可以记录每个堆得数有多少个,然后统计就好了
考虑a*b是平方数,
那么对于定值a,
b一定是a的倍数.
这点很好发现因为ab要是平方数的话那么其开根号一定是aa*k(k也是可平方)的,
所以我们依据这个分堆就好了
分堆的方法是预处理. 预处理出每个数在那一堆,
因为在一堆的一定是某个数的倍数,那么我们可以通过埃斯托尼筛法的过程计算每个数是属于那一堆的,
标记的数组变成指向那个堆得映射就好了,
然后在统计答案的时候就可以在O(n)下统计了,
注意LL
————————————————————————————————————————————
————————————————————————————————————————————
问你有N个男的,M个女的,分成11组,每组的男女都是成对的。问你成不成立。
水,
就是比较下N,M相不相等,相等的话男女才都能成对。
但是要分成11组,所以对数要是11的倍数,
判断一个大数是不是11的倍数,其实并不用高精度,只要for一遍就好了。
————————————————————————————————————————————
————————————————————————————————————————————
图论题,队友出的,我不会图论。
2017-04-28 20:22:26 Tabris_ 阅读数:367
博客爬取于2020-06-14 22:40:49
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70940766
经过BNUCPC,发现KMP完全不会了,于是找几个水KMP/NEXT题 压压惊。
VJ链接:https://cn.vjudge.net/contest/151711#overview
————————————————————————————————————————————
问你A字符串在B字符串中出现了几次,
只要在KMP 的过程中记录匹配到子串尾的次数就好了
————————————————————————————————————————————
给你一个字符串,让你找出所有的公共前后缀,升序输出它们的长度,
公共前后缀那么就是每次找字符串结尾的NEXT值,其表示的就是它前面字符串的最长公共前后缀,
然后再对这个最长的公共前后缀重复此过程,直到找不到为止,因为找到的最长公共前后缀所能够包含母串的前后缀信息了。
实现上我们可以做一个递归,这样长度依次变小,每次里层递归结束在输出就好了。
————————————————————————————————————————————
给你一个字符串,定义字符串A*B=AB :即 “abc”“def”=“abcdef”。问你这个字符串表示成A^x形式的时候,x的最大值
很好发现,我们要找的就是字符串的最小的那个循环节罢了。
而求这个循环节我们 可以很容想到只要找到字符串的最长公共前后缀就好了,总长度减去最长公共前后缀的长度就是最小的循环节了,如果这个循环节能整除母串长度,那就可行,
如果不行那答案就是字符串本身了,也就是1.
*画一画 很好想的,
————————————————————————————————————————————
给你一个字符串,问你有多少个前缀可以由一个循环节 循环两次以上组成,输出每个前缀的长度和最多的循环次数
还是对每个位置找循环节就好了,
————————————————————————————————————————————
给你一个字符串,问你每个前缀在字符串中出现了多少次,输出次数和mod 10007。
显然不能枚举每个字符串来KMP。
那么我们先虑暴力对每个前缀进行KMP,然后加和就好.,复杂度是O(n^2)的,
但是我们发现的是 如果对前缀ab进行KMP 那么我们找到的信息一定是包括前缀a的信息的
那么通过这一层关系我们可以统计了.
既然这是一个统计问题,那么很自然的想到了每个位置对结果的贡献.
那么每个位置对结果的贡献有
1.自己本身这个前缀,
2.这个前缀的最长的公共前后缀中 后缀部分对结果的后弦和前缀贡献是一样的加上去就好了
有事最长公共前后缀,那么就是求一遍NEXT数组
然后ans[i] = ans[NEXT[i]]+1;
最后加和就好了.
————————————————————————————————————————————
给你一个字符串,问你最少添加几个字符使其能变成某个前缀循环至少2次组成的字符串。
首先如果这个字符串本身就能表示成某个前缀循环多次组成的那么就是0了
然后我们想要添加尽量少的字符,那其实也就是找循环节,方法和C题是一样的,
找到了循环节 然后统计一下最后需要加几个字符就好了 简单计算不再赘述。
————————————————————————————————————————————
问你母串中有多少个子串,要求子串不想交,
其实和A还是一样的只不过在匹配到子串尾的时候下一步我们让它去匹配子串头就好了
————————————————————————————————————————————
给你两个串stra,strb,让你求stra的前缀和strb的后缀的最大公共部分。
那么我们就直接将stra作为子串想strb上匹配就好了,然后最后匹配完strb,此时子串匹配的状态就是公共部分了。
————————————————————————————————————————————
据说是个EXKMP?
不做了。
2017-04-27 23:29:20 Tabris_ 阅读数:1131
博客爬取于2020-06-14 22:40:50
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70880837
中期被学弟艹到爆啊。。。。
这套题目相对简单点AC8题(相对别的套题,对鄙队来说还是很难的。。还是这套题 有陈题,签到题偏多,面上还不错)
前期交gcc CE2发,不读题,直接写wa了一发。。。 还是我训练态度不认真,,,
模拟没时间出,难题没有时间开,出题速度慢,菜的一逼,要加强
比赛策略来说,前期努力找水题,找一个A一个,中期思考,轮流上机,到此还不错,但是后期还是空机很长时间,1是缺了一名模拟翻译字符串队友,2是后期题没有开,模拟没人做,3是D题卡了好久,最后十几分钟才AC, 总体表现良好 待加强。
————————————————————————————————————————————
没读题 队友A的 签到题 ,
————————————————————————————————————————————
就是问你一个数能不能被一些fibonacci数的加和表示出 要求fibo数不能连续 能输出这个式子,不能输出-1
根据齐肯拉夫定理? 好像叫这个名字,任何数都能被多个fibonacci数表示,所以那个-1的输出是没有意义的,所以只要从大的数向下找就好了
至于有些人纠结如果其中有连续的怎么办,加入 结果中有f(x)和f(x+1)的话一定能被 f(x+2)代替。
————————————————————————————————————————————
简单的最短路,反向建图,计算n到其他节点的最短路,然后枚举0能到达的点维护答案即可,
主体队友写的,我的贡献只有"然后枚举0能到达的点维护答案即可,"…
------------------------------------------------update------------------------------------------------------
自己实现了发虽然1A,但是花了40min,还看了dij的模板,,图论这一块好弱了。。。。
————————————————————————————————————————————
这题就是给你n*2个队伍,每个队伍有一个积分,还有一个能力值
现在来n轮比赛
每次比赛将当前积分第1大的和第2大的比,当前积分第3大的和第4大的比,当前积分第5大的和第6大的比,以此类推
能力值大的能比赢,且积分+1,
问你最后能力值第q大的队伍是那支。
*积分一样按队伍编号小的来。
这题很简单了 模拟一下就是一个水题,写完交了一发TLE.。。。卡了排序,
然后手写了归并排序,本机测试了极限数据结果时间和sort比就少了1/7,,,
然后考虑这个比赛的过程
发现对于比赛顺序来说,
前面的大的一定比后面的大的大。小的同理,
那么我们维护两个序列,一个存每场比赛的大的,另一个存每场比赛的小的,
然后做一个归并的工程,就能在O(n)的复杂度完成了。。
————————————————————————————————————————————
也是个水签到题,
就是给你一个NM的图
问你在(N+2)(M+2)的图上有几个位置四周只有一个’#’
(开始没仔细读题,以为只会出现在N*M这个范围的四周…
————————————————————————————————————————————
是个dp 我不会dp 队友出的
————————————————————————————————————————————
Nim游戏,Alice先手,现在有N个石子,分成三堆,问让Alice数的分发有多少种,
*(a,b,c) <=>(a,c,b) and so on…
首先考虑最基本的博弈,就是(a^b^c)==0的时候Alice才会输,
然后考虑怎么分? 枚举复杂度是O(n^2)的显然不可取,
就考虑先分成两堆,那么这两堆一定是一样的,
考虑二进制
那么一定是
这样的
这时候从中找几个1拿出来给第三堆就好了,
然后枚举,dp,各种思路都试了,没有什么能做的…
但也发现了
1.n为奇数的时候一定是0,
2.结果的贡献只和二进制下1的个数有关,
那么答案就是ans[1的个数]…
然后有了qls的一个至理名言"遇事不决先打表"…
于是发现
1的个数 | ans[1的个数] |
---|---|
1 | 0 |
2 | 1 |
3 | 4 |
4 | 13 |
5 | 40 |
6 | 121 |
… | … |
n | ans[n-1]*3+1 |
有了表,看了一眼发现递推式,然后就AC了。。。
*注意: 要long long int 3^x会报
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
c语言入门题 签到题
————————————————————————————————————————————
]]>2017-04-27 00:45:08 Tabris_ 阅读数:368
博客爬取于2020-06-14 22:40:51
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70835664
做这套的时候 很迷啊 感觉回到了杭州的时候签到题半天没有A,明明很水的 题目我竟要去想容斥那套理论GG,3小时AC签到题??! 果然是菜的可以。,
但仔细想想,可能这套题真的偏难吧,
最后补题只A了4个 H是看了题解的。。
————————————————————————————————————————————
真的是水题 啊 上来就想到容斥那一套理论,然后GG。(也暴露了我容斥反演那一套学的并不好的事实啊
其实就是考虑每一个20162016的块,对结果的贡献是相同的,所以就变成了求有几个20162016的块 然后边界的在计算一下就好了,如果预处理二维前缀和的话,就能O(1)做了
————————————————————————————————————————————
其实就是大概这意思,
对于里层的就是一个常数了 ,提出来就好了
这个时候我们只要统计就好了
现在是1->2->3 的
那么能到达2 的是{1}, 能到达3的是{1,2}
脑补下再长一点的结果,发现如果能到达 那么能到达的点都能到达,通过这个我们就可以直接计数
只要将点的个数变成点的就好了,最后的结果就是
因为给的是有向无环图,我们可以在拓扑过程中计数,能够保证每个节点的值不会有后效性。
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
这题很容易想到对’(’ +1, ‘)’ -1 我们在处理前缀和的时候能够知道当前位置能不能匹配上,
那么对于一次交换的时候可以知道这个符号有没有能和他匹配的 最开始想用树状数组维护,然后直接找,
然后考虑了交换符号一样时一定是yes。还有写了好多个)(的情况发现总会找到匹配的(不会证明),
然后对()的时候用树状数组进行维护,
提交wa。。
后来发现一组数据 交换粗体的时候 换完之后这两个符号都有匹配的
((())(()))()
()())(()()()
但是这两个就不匹配了
()()) (()()()
然后发现当一个位置的括号不匹配了一定是‘)’,在前面没有与它相配的’)',这个位置的前缀和是-1的,
那么也好想,‘)’在原序列上贡献了-2,在交换的区间如果有<2的位置就一定存在不匹配的,
注意这个区间是左闭右开的,因为左边还有多个2的贡献,
然后就是查询区间内有没有<2的就好了, 维护这个方法就很多了,RMQ,BIT.SEGMENT_TREE…
————————————————————————————————————————————
做这题开始的时候思路还是很清晰的,
一定是求每个位置的贡献,然后统计,
然后这个贡献怎么求,
对于这个位置的值是本身,
一个是交换的区间不包含它,那就是
第二个是交换的区间以i为轴 那区间就是min(i,n-i)
然后关键就是这个位置的值是被交换过来的值,我们要怎么求? 这里我就想蒙蔽了…
交换多次要多统计的a[j]~a[k]中的数,然后想了想乱糟的,就放弃了
中间还思路想到了一个奇怪的想法…过了第一个样例…
后来看了题解,
发现在上述基础上接着再按求贡献的思路找,
找每个对这个贡献的贡献就好了,
依然考虑每个 有几种交换能交换到的位置.
对于每个交换到的位置的情况数$min(j,n-j+1)\ $
其实细分啊 在左边的就是 右边的就是
维护的时候就线预处理处理前缀和就好了,这样就能在O(n)复杂度计算每个位置的贡献了…
————————————————————————————————————————————
————————————————————————————————————————————
因为图形和坐标轴是平行的 ,扫描线走一遍就行;
当然还可以暴力的求凸包交,然后面积和减去面积交就是面积并了…
————————————————————————————————————————————
]]>一开始都是别人建好远程库,克隆下来就行了。
下面内容只是带你git入门,一些基础的东西,是开发过程中一些基本的操作,单单这些你会用了之后就能发现他的好处,以及使用命令行Enter敲击时的快感,还能提高逼格。
当然我们还是为了方便项目管理。
git工具下载地址,可以选择适合自己的操作系统:https://git-scm.com/downloads
安装完git,要配置环境变量,拷贝git安装目录下的bin文件目录,如D:\Program Files\Git\bin
,将目录拷贝添加到PATH变量后。
注意:与前面的值要用“;”号隔开
具体步骤:
右键计算机-属性-高级系统设置-环境变量-PATH将目录添加到后面,%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;D:\Program Files\Git\bin
安装完成后使用 git --version
命令查看一下git版本,测试是否安装、配置成功。
使用cmd(安装过git直接可以右键文件夹使用git bash here
)定位到要放置仓库的目录git clone [远程仓库地址]
远程仓库就是托管到第三方平台上面的库。
常用的有github,这个私有是收费的,要用免费的只能是公共的。
目前国内用的比较多的coding ,和开源中国的码云。原理都一样,只不过看起来会有点视觉上的差别,个人觉得coding比较简洁,适合学习,刚入门git的新手练习。而且视图更直观。
码云是我现在用的,功能要比coding多,包括直接下载上传文件以及打包好的apk文件。
在这里要说一下克隆的时候有的坑,要克隆远程仓库必须是你在这个项目中,就是项目所有者(管理员)把你添加进这个项目成员。输入克隆的指令后,如果是第一次使用会提示你输入用户名,和密码。
前面步骤如果无误,之后会显示克隆的进度,直到完成克隆。
包括远程库(第三方平台)、本地库(存放代码信息)。
创建远程库:根据第三方平台提示进行创建,一般都有步骤说明,按照说明来就好。
创建完成后建议初始化一下仓库,
可以在远程上根据提示,创建使用README.md文件初始化项目。
也可以使用git命令:
1 | git init |
建议使用前者,直接在第三方上创建。
创建本地仓库:有两种方法
1、使用git命令git init
2、android Studio中(这里使用AS为例,其它的IDEA、webStorm操作都一样)
点击VCS-import into version control-create git repository
会弹出选择仓库的路径,直接选当前项目就行,然后确定。
创建完之后,找到项目路径会发现文件夹下多了个.git文件,这个就是存放代码的仓库。
而且项目中的文件的名称都会变为红色,说明已经有仓库了,但是这些红色的项目文件,并没有加到本地仓库(.git仓库文件中)。
(关于颜色后面我会具体说,各种颜色代表的状态)
关联本地和远程库
关联就是把本地仓库的.git仓库文件,和远程(coding)创建的仓库联系起来,每次提交代码,将本地.git中代码,提交到远程库。
使用命令:git remote add origin [远程仓库地址]
如果是首次使用,会提示输入用户名+密码,用户名一般是邮箱,输错是关联不成功的。
关联成功则无提示,接着输入命令git push origin master
如果失败,很大可能是远程仓库已存在文件。可以执行git push -f origin master
强制提交。
提交过程是能看到进度的。
提交完成后可以去平台上查看有没有代码就知道是否成功。
注意:所有命令行操作必须使用cmd或者git bash定位到项目目录下
提交过程:右键项目-git-add,弹框,选择是
;
这时候只是把代码添加到本地仓库,再右键项目选择commit directory 在弹框的commit message中输入提交信息,选择commit and push
然后会显示进度。
在多人协作开发一个项目的时候,提交之前一定要先pull一下(VCS - pull
),如果有冲突,选择合并或者是选择远程的,还是本地的,三者选一。
处理好这些再进行提交操作。
分支作为git一个重要的存在,可以进行版本回退,或者协作开发都是一个很便利的存在。
在创建仓库的时候,默认会有个master分支,如果是首次开发,则不需要创建分支。
但是在版本迭代的时候,特别是大版本迭代,就用到了分支,分支是相互独立存在的仓库。
互不影响,在克隆的时候切换一下分支,就会把不同分支下的仓库内容拷贝过来,就像1.0、2.0版本,是分开的,1.0在master分支,2.0版本在maste2分支,可以随时修改历史版本。
__常用命令
创建并切换到新建分支:git checkout -b master2
切换分支:git checkout master2
删除分支:git branch -d fmaster2
将分支推送到远程仓库:git push origin <branch>
白色(正常色):未改动或者没有仓库时的颜色。上
红色:未添加仓库的,在创建仓库时会出现。
绿色:已添加到本地仓库,没有进行commit push提交远程的。
蓝色:修改已经提交到本地仓库的代码。
有一种情况是提交/强制提交的时候出现
1 | error: src refspec master does not match any. |
说明是本地代码库为空
解决办法:
1、在项目中,如android studio,打开项目,右键->Git->+Add,然后重新右键->Git->commit Directory->commit and push->commit。执行之后会发现代码文件颜色都变成正常的白色,之后回到命令行执行提交操作
2、在本地仓库创建一个文件,推送到仓库touch README git add README git commit -m 'first commit' git push origin master
如果按照上面的步骤来的话是不会出现这种情况的,这种情况出现于已有现成的项目,并且本地项目的代码未提交到本地仓库。这时候提交到远程,就会判定你本地仓库为空。
补充一个在提交过程中出现无法解决问题的办法
如果在使用命令行操作时出现无法解决的错误,直接进入到项目文件,删除.git
文件,然后右键该项目目录,或者使用cmd定位到该目录,重新执行
1 | git init #初始化本地仓库 |
关于这些只是对于刚入门的学习者有些帮助,在我学习的时候也遇到了好多坑,至今有些问题还能遇到,但是不至于手忙脚乱,起码知道问题出在了哪个环节。
Git是一个很强大的版本控制工具,有很多功能,需要尝试去深入研究,希望学习者能够感受到他带来的便捷。
https方式每次都要输入密码,按照如下设置即可输入一次就不用再手输入密码的困扰而且又享受https带来的极速
设置记住密码(默认15分钟):
1 | git config --global credential.helper cache |
如果想自己设置时间,可以这样做:
1 | git config credential.helper 'cache --timeout=3600' |
这样就设置一个小时之后失效
长期存储密码:
1 | git config --global credential.helper store |
增加远程地址的时候带上密码也是可以的。(推荐)
1 | http://yourname:password@git.oschina.net/name/project.git |
补充:使用客户端也可以存储密码的。
如果你正在使用ssh而且想体验https带来的高速,那么你可以这样做: 切换到项目目录下 :
cd projectfile/
移除远程ssh方式的仓库地址
1 | git remote rm origin |
增加https远程仓库地址
1 | git remote add origin http://yourname:password@git.oschina.net/name/project.git |
2017-04-24 01:09:43 Tabris_ 阅读数:695
博客爬取于2020-06-14 22:40:53
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70565596
23号和队友用一个账号一起做这套题,开了挂,用了两台电脑,由于我们做的时候还不能添加到BNUVJ,队内交流还少,因为中文题面嘛,基本相当于两个人分别打个人了。。。
但是鄙队实在是菜的抠脚啊,最后仅出6题。j题连题意都没懂有木有(这可是中文题面 qaq。
qls说封顶8题,那最后我怎么也要补题补到9题啊…
————————————————————————————————————————————
思维题队友过的。明天起来补上.
原来就是傻逼题,,,
题目说的是第i条边链接的是[i+1/2]和[i+1/2]+1,我竟当成了第i个点…
懵逼到怀疑人生,全场最水的不出 有木有啊… ,最后仔细看了发题,…
其实连起来发现是
1=2=3=4=…=n .(等号代表一个线,)
只要求 就好了嘛。。。
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
明确题意后很好确定,这是LCA相关问题
只要满足
满足以上任何一条都是yes的情况 ,否则就是no
由于涉及了[C马上到1的那个节点],我是先预处理了一下这个然后直接判断
找树上两点关系的时候渣渣只会写树剖,代码长的一逼啊…
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
水签到,不解释
————————————————————————————————————————————
思维题吧, 就是画了画发现,因为是一个完全图,只要加一个节点,那么其最长链都是n的,所以无脑输出n-1个0 和一个(1<<(n*(n-1)/2))就好了
1 | int main(){ |
————————————————————————————————————————————
开始想的是枚举最长的边上的圆的半径,从0到边长。开始以为是一个凸函数,三分就行了,但是写完样例没有过,然后发现其实最大的园面积的和 相当于在
求w的最大值,显然的时候w最大.
回来思考最大的面积和,也就是使一个圆的半径最大化,因为有不能相交的限制,所以最大的圆的半径就是第二长的边的长读,然后在算上当前状态下另外的两个园就好了(其中有一个是半径为0的园,另一个半径就是最长边减次长边.
1 |
|
————————————————————————————————————————————
神题啊 我是不会补的,
————————————————————————————————————————————
还没看题.尽量补
————————————————————————————————————————————
看N的大小,我想大力分块,
然后细节还没想好,想好补上.
————————————————————————————————————————————
完全没想法啊
————————————————————————————————————————————
在我理解的题意中,字符串长什么样无关结果…hhh…gg
懂了字符串对结果的影响了
比如说我有一个字符串,这个时候我找到的是f(i,j) ,
XXXABCABCABCXXX f(6,10)
那么strA:XXXABC strB:ABC strC:ABCXXX
并不一定是前后缀相交的那个串才是B
然后考虑怎么计算结果,
直接暴力算的话+KMP的话也是的
很好考虑,我们一定是枚举(i,j)找到前后缀,
然后找这个前后串的那个公共部分.
一般我们固定一个值去枚举另一个值,这里也是一样,
考虑KMP的过程中就是一个子串在一个母串上匹配,
然后我们惊奇的发现这个过程不就是在整个穿上进行KMP,母串每个位置的时候匹配的子串最长是多长?
统计的过程直接放到KMP就好了
最后就是在枚举后缀的,对整个字符串进行KMP,在KMP的过程中统计,
1 | char a[N],*p; |
————————————————————————————————————————————
简单模拟
1 | int _,n; |
2017-04-23 04:05:38 Tabris_ 阅读数:991
博客爬取于2020-06-14 22:40:54
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70481823
————————————————————————————————————————————
一个人要从0骑马到D,路上可能有多个骑马者,为了表示尊重,后面追过来的马不能超过前面的马,要减速到与前面的马相同的速度,现在问你这个人最开始的速度为多大的时候能保证在整个过程中不会超过别人,
很明显的二分答案。
注意浮点型二分的次数即可。
判断的时候只要判断中间有没有马在这个人到D的时候还没有到达D就行了。。
附本题代码
————————————————————————————————————————————
1 |
|
————————————————————————————————————————————
这个大数据的我不会做,
就是一种东西的头发空有6种颜色的可能其中有红,黄,蓝,橙色,紫色,绿色
橙色=红+黄
紫色=红+蓝
绿色=黄+蓝
现在有相同颜色的两个东西不能挨着,(注意:像橙色和红色这种也不能挨着,),问你存不存在一个排列,使得N各这些东西能够围城一圈。
给了你每个颜色的东西有多少个。
大数据没搞
我就不会图论,怎么建图实在弄不明白,然后水了发小数据
小数据就很好写了
只有RYB三种颜色,只要不相同就能挨着,
那么考虑不可能的情况就是当其中两种小的个数和小于最大的那个的个数,这样的话一定会有同色挨着的。
然后对于可行的时候我们只要在颜色最大的那个基础上进行插入另外两种颜色就好了,
一种从左边开始挨个插,另一种从右边开始挨个插就好了,
附小数据代码
————————————
1 | int _,n,r,o,y,g,b,v; |
————————————————————————————————————————————
给你N的N个城市上每个有一匹马(马最多能走,速度是) 到每个城市可以选择换马或者不换马 然后Q次询问 问你从点到点 最快的时间
数据范围很小 ,尤其是 ,很明显的提示了floyd
我们可以这样做,先对距离进行floyd,找到两点间的最短距离,
然后根据这个距离和的关系确定一个最少时间的图,对其跑floyd,就是我们所有的结果了,查询的时候O(1)查询就好了.
附本题代码
————————————————————
1 |
|
2017-04-22 23:30:04 Tabris_ 阅读数:829
博客爬取于2020-06-14 22:40:55
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70478134
EF是纯自己做的,G,H是参(chao)考(xi)了dalao们的思(dai)路(ma)才补上的.
————————————————————————————————————————————
现在就是有一个8位16进制的一个数x,数字[0,F]有自己的贡献 ,问你[x,x+n]的数中的贡献和是多少,
(注意FFFFFFFF+1 是00000000)
解题思路:
当时想的是数位dp
每次计算当前数字为i的时候的结果,然后超时了, 最后测试发现是被卡卡常了
最最后终于观察到,有几个数字的贡献是一样的,贡献只有[2,7]6种,这样的话 ,我就枚举6种贡献的数字,算式优化了下常数,然后AC…
其他处理的时候就是注意要是超过了0xffffffff 将区间变成首尾的两段和就行了.
附本题代码
————————————————————————————————————————
1 | # include<stdio.h> |
————————————————————————————————————————————
现在有一个序列,让你把它分成几个集合,使得每个集合中的数能被放到最大堆上,其父子节点关系满足
首先很容易想到,就是找这个数前面有没有比它小的,有就作为这个数的儿子就好了,
注意的是一个节点只有两个儿子,明确这个,随便搞搞就行了。
(其实我这个并查集是不用的,只需要写个数组映射过去就好,当时纯属脑抽
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
有N堆石子,Alice和Bob轮流取石子,现在规定对于每堆石子Bob想怎么拿怎么拿,但是堆Alice不一样
如果对应$b_i = 0\ $ 那么对Alice也没有限制
如果对应$b_i = 1\ $ 那么对Alice只能拿奇数个石子
如果对应$b_i = 2\ $ 那么对Alice只能拿偶数个石子
对于不能操作的人输,Alice先手,问你谁是赢家
首先考虑,如果$b_i = 0\ $恒成立,那么就是退化为最基本的Nim游戏即可。
然后考虑有$b_i = 1\ a_i = 1\ b_i = 0\ a_i = 1\ b_i = 1\ $Alice一定输。
然后考虑有$b_i = 2\ a_i %2= 1 \ b_i = 2\ $ 那么Bob至少能使其中一堆变成$a_i %2= 1 \ $,那么Alice还是输。
能确定$b_i = 1\ b_i = 2\ $之多只能由一种且只有一个Alice才有可能赢。
最后大力讨论一下就好了。
(学习了这种分类讨论实现起来666的姿势
附本题代码
————————————————————————————————————————————
1 | int _,n; |
————————————————————————————————————————————
给你一个二叉树的两种dfs遍历的顺序,让你构造出一个满足这两种dfs序的二叉树.(有SPJ);
首先考虑我们在讲一个树形结构转化为线结构的时候,通过dfs序,可以将一个节点为根的子树中其他节点包含起来,编号是连续的,从而能够采用线段树and so on的数据结构维护.
同理在dfs序中一个连续的区间即可能是一个子树中的结构
同时思考dfs序不同是因为遍历的不知道是按左儿子先,还是右儿子先.于是产生了多种dfs序…
也就是说
对于A,B两个序列来说,会各自有一个区间相互对应为同一个子树.(且这两个区间内的元素的集合是相同的.
明确了这个我们只要对相同的区间搜下去并记录父亲节点就好了.
注意的是这个节点的父亲节点一定在两个序列中比最早出现的那个出现的还早.
还有就是一个节点只能由两个儿子,如果满了拿这颗子树就应该网上找节点加上去.(维护过程就类似并查集了.
附本题代码
————————————————————————————————————————————
1 | int _,n,q,mx; |
2017-04-21 16:27:27 Tabris_ 阅读数:1004
博客爬取于2020-06-14 22:40:56
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70328966
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1765
————————————————————————————————————————————
1765 谷歌的恐龙
基准时间限制:1 秒 空间限制:1048576 KB 分值: 80 难度:5级算法题 收藏 关注
相信网络不好的选手一定很熟悉Chrome里面那个恐龙的游戏,这个题目就是根据那个游戏简化得来的。
给出一个正整数n,把恐龙的跳跃简化成一个[0,n)的随机数,再给出一个正整数m,把障碍简化为[0,n)中m个不同的的整数,把分数简化成所有生成的随机数的和。
把整个游戏简化为,每次生成一个[0,n)的随机数,如果这个随机数和给出的m个数字中的其中一个数字相等,那么就停止生成随机数,否则继续生成,求出所有生成的数的和的期望。
Input
第一行两个正整数n(1<=n<=10000000),m(1<=m<=n)
第二行m个整数a_i表示障碍(0<=a_i< n)
Output
一行一个实数E表示期望,保留6位小数。
注意了本题没有SPJ,必须和答案完全相同才能通过本题
样例解释:当生成的是0的时候继续,生成的是1的时候停止
E=1/2+1/4+…=1
Input示例
2 1
1
Output示例
1.000000
————————————————————————————————————————————
本题就是简单的求期望
设x为选择的数的期望和
然后就…
附本题代码
——————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-04-21 13:11:03 Tabris_ 阅读数:702
博客爬取于2020-06-14 22:40:57
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70313683
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1718
————————————————————————————————————————————
1718 Cos的多项式
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注
小明对三角函数充满了兴趣,有一天他突然发现一个神奇的性质。
2cos(nx)似乎可以表示成2cos(x)的一个多项式。
但是小明并不能证明它的正确性。
现在给定n,问是否可以表示成这样的多项式,如果可以,只需输出各项系数的和。(Tip:如果这个和很大,那就高精度咯:))
否则输出No
样例解释:2cos(3x)=(2cosx)^3-3*(2*cosx),系数为1和-3,他们的和为-2。
Input
一个数表示n(n<=1e15)
Output
如果能表示 输出各项系数和
不能 输出No
Input示例
3
Output示例
-2
————————————————————————————————————————————
我们知道
|n|$2con(nx)\ $|系数和|
|:|:|:|
|1|$2cos(x)\ $ | 1|
|2|$(2cos(x))^2-2\ $|-1|
|然后不会了…|
考虑
设
有$f(n-1)+f(n+1)=f(n)f(1)\ \Rightarrow f(n+1)= f(n)f(1) - f(n-1)\ \Rightarrow f(n+1)= f(n)\times 2cos(x) - f(n-1)\ $
这样就有了推出所有公式了
然后计算出系数和 震惊的发现其结果竟是有循环节的!!!
然后打表AC
附本题代码
————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-04-20 20:53:09 Tabris_ 阅读数:494
博客爬取于2020-06-14 22:40:58
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70304674
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
————————————————————————————————————————————
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 12058 Solved: 5154
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
106465
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
Source
平衡树
————————————————————————————————————————————
这两天不知怎地 一点思考能力都没有。 于是学了学Splay
其实Splay很好懂 只要知道平衡树的左旋和右旋操作,知道作用是吧一棵树做矮,就是不使它的某一条链变成。
本质还是一颗二叉树,只不过多了伸展的操作,也就是能通过左旋,右旋降低树高,保证某些操作总是在O(logn)的 不会变成O(n)。
----------------------------update--------------------------
若干年过去了 终于我会写了SPLAY 补上一发自己的代码 放到上面了,,,
附模板
————————————————————————————————————
1 | /************************** |
2017-04-18 20:20:01 Tabris_ 阅读数:585
博客爬取于2020-06-14 22:40:59
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70232210
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243
————————————————————————————————————————————————
2243: [SDOI2011]染色
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 7492 Solved: 2803
[Submit][Status][Discuss]
Description
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
Input
第一行包含2个整数n和m,分别表示节点数和操作数;
第二行包含n个正整数表示n个节点的初始颜色
下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。
Sample Input
6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output
3
1
2
HINT
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
Source
第一轮day1
————————————————————————————————————————————————
在树上两点间的路上进行修改 那么就是树链剖分,
根据操作 是区间染色 所以要用线段树维护
注意在维护的时候线段树上的每个点要多维护一个最左边和最右边的颜色。
方便合并的时候计算颜色个数
然后就是注意颜色可能为0
lazy标记的时候改成-1, 习惯性的用0 WA到死啊。
附本题代码
————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-04-18 13:59:30 Tabris_ 阅读数:423
博客爬取于2020-06-14 22:41:00
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/70227611
##AVicious Keyboard
————————————————————————————————————————————
数据量很小
直接暴力枚举所有情况 维护个最大值过去就行了
————————————————————————————————————————————
开始读错题了
正确的题意应该是L
现在有f(s1,s2) = s3 ,s3是s1,s2两个字符串对应位置上值小的字母组成的新字符串
现在给你s1,s3 问你有没有满足的s2 有的话输出一个,没有输出=1
所以就判断有没有s1上的字母小于s3上的字母的情况就行了 有的话就是-1
不然直接出书s3就行了
————————————————————————————————————————————
就是有一堆机器,每个机器每秒需要消耗a能量,最开始有b能量,现在有一个充电器,每秒能充p点能量,
问你我这些机器到第一个能量值为0的情况的最长时间是多少。(实数范畴内)
很明显如果的时候能无限的使用下去
对于其他情况,很容易想到二分答案,
————————————————————————————————————————————
给你一个凸包,让你找一个最大的可移动距离 ,使得所有点都任意的在这个最大距离内移动后还是一个凸包,
很显然 对于一个图形是不是凸包这要考虑三个点有没有凹的情况就可以了.
那么就枚举每个点的情况 然后维护最小值就好了.
对于每个点的时候 我们考虑与其相邻的两个点,
那么这时候最大的情况就是这3个点在一条直线上的时候
三个园的半径就是我们所求的最大范围, 转换过来就是高的一半
————————————————————————————————————————————
还不会 待补
]]>2017-03-29 23:29:07 Tabris_ 阅读数:233
博客爬取于2020-06-14 22:41:01
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/68234083
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1520
————————————————————————————————————————————
Anniversary party
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10549 Accepted Submission(s): 4415
Problem Description
There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure of employees. It means that the supervisor relation forms a tree rooted at the rector V. E. Tretyakov. In order to make the party funny for every one, the rector does not want both an employee and his or her immediate supervisor to be present. The personnel office has evaluated conviviality of each employee, so everyone has some number (rating) attached to him or her. Your task is to make a list of guests with the maximal possible sum of guests’ conviviality ratings.
Input
Employees are numbered from 1 to N. A first line of input contains a number N. 1 <= N <= 6 000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality rating is an integer number in a range from -128 to 127. After that go T lines that describe a supervisor relation tree. Each line of the tree specification has the form:
L K
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line
0 0
Output
Output should contain the maximal sum of guests’ ratings.
Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
Sample Output
5
————————————————————————————————————————————
题意:
一个树,每个节点有一个权值,这些节点不能拿挨着的,
一些节点会获得他们的权值,问你最大的权值和是多少
解题思路:
树形dp的入门题目
很容易想,
dp[N][2]
其中dp[u][0],代表不选节点u的最大权值和 ,
dp[u][1]代表选节点u的最大权值和 ,
转移就是
dp[fa][0]=max(dp[u][0],dp[u][1])
dp[fa][1]=dp[u][0];
很好想.
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-29 20:35:11 Tabris_ 阅读数:1086
博客爬取于2020-06-14 22:41:02
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/68083224
总结一波 :
还是读题不清,中文题关键部分读错,导致最终GG,
计算几何薄弱,模板匮乏。
虽然题目说打完一次k–,但是没有限定顺序 所以这个限制可以忽略不计
然后说正常怎么来,
先从小到大排序一遍,然后每一次遇到与其相等的就升级战斗力.
为了确保我下一次还能升级战斗力,我就变成比当前战斗力+k小的最大的那个战斗力就行了,
然后扫一遍即可,
(当时以为遇到相等的不能赢.wa一发…
1 | # include <bits/stdc++.h> |
这个题还是很简单的
我们要找一个长度为k的区间使得其中元素升序后连续,
那么也就说明了这个区间是没有重复元素的,
那么确保了区间内没有相同元素的后
其实也就是找这个区间的最大值和最小值的差是不是等于k-1 ,
确定区间有没有相同元素,可以预处理出每个位置的数出现过的在前面的最近位置,
然后计算的时候我们可以枚举右界,
根据预处理相同元素的位置,能够维护左界,
因为元素没有变化,所以最大最小值可以用ST表预处理出来
一次O(n)就能统计了
1 | # include <bits/stdc++.h> |
这个题也很水,
如果直接进行求解 很困难,那么反过来想想,如果知道了一个数 来判断可不可行是不是非常好做了呢,
显然是的 ,
左边的尽量让他小就行了,
我们考虑如果花费为$x\ \big[x,+\infty\big)\ $都是满足的
所以我们可以二分来做就好了
(最开始把所求看成了 mabi
1 | # include <bits/stdc++.h> |
这题就是一个模拟,我这里是离线+二分+树状数组做的时间复杂度是
首先离线出来每个数,按照题意的顺序操作,但是每次都是插入到树状数组中,这样我就能用的复杂度来处理查询操作了,对于其他操作,我先拿一个数组来存每次的操作元素是谁,那么也可以处理了
1 | # include <bits/stdc++.h> |
不会玩魔方啊 不会做…(这两点可能惯性并不是很大,)
这题很明显的是要对所有的矩形求凸包,然后求最小面积的矩形覆盖,旋转卡壳可过,
贴上模板就行了.
1 | # include <map> |
2017-03-29 19:57:49 Tabris_ 阅读数:425
博客爬取于2020-06-14 22:41:03
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/68070650
题目链接:http://poj.org/problem?id=2187
————————————————————————————————————————————
Beauty Contest
Time Limit: 3000MSMemory Limit: 65536K
Total Submissions: 36877Accepted: 11417
Description
Bessie, Farmer John’s prize cow, has just won first place in a bovine beauty contest, earning the title ‘Miss Cow World’. As a result, Bessie will make a tour of N (2 <= N <= 50,000) farms around the world in order to spread goodwill between farmers and their cows. For simplicity, the world will be represented as a two-dimensional plane, where each farm is located at a pair of integer coordinates (x,y), each having a value in the range -10,000 … 10,000. No two farms share the same pair of coordinates.
Even though Bessie travels directly in a straight line between pairs of farms, the distance between some farms can be quite large, so she wants to bring a suitcase full of hay with her so she has enough food to eat on each leg of her journey. Since Bessie refills her suitcase at every farm she visits, she wants to determine the maximum possible distance she might need to travel so she knows the size of suitcase she must bring.Help Bessie by computing the maximum distance among all pairs of farms.
Input
Line 1: A single integer, N
Lines 2…N+1: Two space-separated integers x and y specifying coordinate of each farm
Output
Line 1: A single integer that is the squared distance between the pair of farms that are farthest apart from each other.
Sample Input
4
0 0
0 1
1 1
1 0
Sample Output
2
Hint
Farm 1 (0, 0) and farm 3 (1, 1) have the longest distance (square root of 2)
————————————————————————————————————————————
没啥说的就是一个旋转卡壳,算是留个模板
————————————————————————————————————————————
1 | # include<cstdio> |
2017-03-27 00:47:49 Tabris_ 阅读数:300
博客爬取于2020-06-14 22:41:05
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/66652353
总结下,
看题慢,读错题,代码能力渣,思维不敏捷,菜的一逼。
————————————————————————————————————————————
傻逼题,,
明确题意
枚举下所有情况 就能AC了。。
1 | int main(){ |
————————————————————————————————————————————
贪心题
先对两个序列排序,
对于两个问题要分开考虑,
但是大同小异 ,
第一个就是尽量抗伤害
第二个就是尽量输出,类似田忌赛马
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
给你一个N*M的方阵,每个方阵有一个值,有Q次询问,
问你第x行到第y行中存不存在一列是单调不减的 存在yes 否则no
其实很简单,我预处理出来到每一行的最长的那个列就好了,
然后询问的时候就能做到O(1)
详看代码吧
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
给你一堆字符串 对于每个字符串只能删除后缀, 删除最少的字符 使得这些字符串字典序单调不减
正着考虑 很明显 无法解决,
但是因为只能删后缀,那么从后向前考虑就没有问题了
只要使得s[i-1]的字典序依次小于s[i]就行了
自己的代码太丑了
献上巨巨优美的代码
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
给你一堆圆圈,有内半径和外半径 还有厚度,现在让你将其摞在一起 ,
外半径大的不能再外半径小的上面,
不能从内半径中掉出去
问你能摞成的厚度最大是多少
很简单,先对外半径升序排相等的使内半径升序
然后从前开始找,能摞在这个圆圈上的厚度最大的为多少,
维护个最大值就行了
用线段树维护半径就行了,注意要离散化.
(后看到有人使用树状数组维护的因为维护的是前缀最大,所以没毛病,当时可能脑袋有点浑,并没有看太清晰就写了。。
1 | # include <bits/stdc++.h> |
2017-03-26 23:00:02 Tabris_ 阅读数:2051
博客爬取于2020-06-14 22:41:06
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/66548177
先总结:
个人方面:审题不清,代码不稳。套路题过不掉。GG
比赛环境方面,判题慢到死,简直没法玩,做的最累的一套水题,如果能及时返回结果,对个人做题心态,感觉都会有提升的.
————————————————————————————————————————————
首先考虑对于假如一只老虎只有两个耳朵或一个尾巴 ,那么总老虎数就是a/2+b,但是一共只有c/4个老虎,那么多出来的就是正常老虎的个数。即a/2+b-c/4
1 | int main(){ |
————————————————————————————————————————————
比赛的时候理解错了题,以为是每轮两个人都走一格,然后看不懂样例,
目测就是两点的曼哈顿距离和N比较下,
如果两个人不能相遇 ,则 -1
能相遇 那么 结果就是1or2 讨论一下就好
瞎猜的 没写代码 。。 等重现,,,
——————————————update————————————————
事实就是这样
考虑一个点能不能走到另一个点
如果能走到
—如果距离是奇数
------如果n是奇数 那么先手多2
------如果n是偶数 那么平
—如果距离是偶数
------如果n是奇数 先手多1
------如果n是偶数 后手多1
不能走到
—如果n是奇数 先手多1
—如果n是偶数 平
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
出烂了的题目,
f[i]=f[i-1]+f[i-2]+f[i-3];
代表转移个过程,
1 | int f[200]; |
————————————————————————————————————————————
这个明白题意就能AC了
1 | int main(){ |
————————————————————————————————————————————
其实这题贪心就好,
我们要最少的水杯,那就倍增的将若干个杯子变成一个就好了,
那么也就是说最后都能变成一个水杯, 这是不花费是最少的杯子个数
而我们要是最后的杯子个数<=k
那么只要最贪心的这个最小的两个 变成一个就好了,
那么就是不断的加上最小的一个,最后能将这两个凑成一个
暴力写就好了 时间上不会超过\logn的.
(其实就是一个树状数组更新的过程么。。
1 | # define lowbit(x) (x&-x) |
————————————————————————————————————————————
这题只知道要对树进行剖分,但是对于链上能不能构成三角形,我实在没有想到一个合适的复杂度来处理,
最后在他人的提示下才知道怎么处理,
先反过来想,一个序列里的数不能构成三角形,那么是fibo数列,没有问题,(详见2016CCPC长春签到题)
那么在的范围内fibo的长度也不超过50
那么也就是说如果数列的长度大于50 那么一定可以构成三角形,
所以对于大数据我们这样处理就好, 小数据就可以处理就好了
个人用的是树剖,将边权转化为点权,
S->T路径上的所有点权处理一下就行了
(注意要去掉LCA(S,T)的点权
后来知道这是一个陈题,赛后在别处AC了一发
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
这道题最开始以为是一个数位dp,想在求区间回文数个数的代码上改一改 ,但是因为渣渣实在太菜,没有调出来,
快结束暴力处理了一下范围内所有等凹数字,发现只有180k+,
那么我们只要对区间进行二分就好了.
注:这题只是意念AC,等重现赛在提交一下 (已经AC)
后来看题解说数位DP也能过 等下课回来补一个
(数位dp做法已更新 在下面)
1 | # include <bits/stdc++.h> |
--------------Update--------------
数位dp是可解的
在基础的求回文数的数位dp上面多开两个维度,记录最高位的数字和前一位的数字即可
dp[最高位][当前位][前一位的数字][最高位的数字][可不可行(其实可以去掉这一维)]
dfs(最高位,当前位,前一位的数字,最高位的数字,数位限制,可不可行)
转移的时候 只要考虑等凹数字的性质搜下去就行了 对于不满足的 可以不用搜
最开始并没有想到要记录最高位的数字 这时候不记忆化 也能能AC(因为数据水 没有卡t)
最后在**Dei.**的提示下 才写对 鸣谢
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
这道题被Pending Rejudging了 但绝对能AC
51nod上有一个加强版的题目 题号1821
就是先升序排一下,在维护一个从0开始的变量,如果ans+1>=a[i]
的话就说明元素都能凑出来
处理一下就好了
1 | int a[N]; |
2017-03-25 16:34:26 Tabris_ 阅读数:551
博客爬取于2020-06-14 22:41:07
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/65937719
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5936
————————————————————————————————————————————
Difference
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 733 Accepted Submission(s): 192
Problem Description
Little Ruins is playing a number game, first he chooses two positive integers y and K and calculates f(y,K), here
then he gets the result
As Ruins is forgetful, a few seconds later, he only remembers K, x and forgets y. please help him find how many y satisfy.
Input
First line contains an integer T, which indicates the number of test cases.
Every test case contains one line with two integers x, K.
Limits
1≤T≤100
0≤x≤109
1≤K≤9
Output
For every test case, you should output ‘Case #x: y’, where x indicates the case number and counts from 1 and y is the result.
Sample Input
2
2 2
3 2
Sample Output
Case #1: 1
Case #2: 2
————————————————————————————————————————————
题目大意:
就是给你k,x,问y的可能数
解题思路:
首先看到这个题实在没有好的想法,后发现,最大也不过,这样也才不到10位,
但是即使这样 还是不太好找 后想到将这10位分成前5位和后5位,预处理出来然后就行匹配,
这个匹配我们有很多种方法搞了,
首先在预处理的时候进行排序,在前5位时注意要 $f(y,k)-y*100000\ $ 后5位$f(y,k)-y\ $即可
那么就是找两集合的元素加和为x的方案数了,
可以枚举一个来二分另一个, $ O(100000\log(100000))\ $
也可以对一个从前找,另一个从后找,(双指针法) $O(100000*2)\ $
代码注意细节就好
]]>2017-03-25 12:38:34 Tabris_ 阅读数:422
博客爬取于2020-06-14 22:41:08
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/65935956
题目链接:http://www.spoj.com/problems/SUBXOR/en/
————————————————————————————————————————————
SUBXOR - SubXor
no tags
A straightforward question. Given an array of positive integers you have to print the number of subarrays whose XOR is less than K.
Subarrays are defined as a sequence of continuous elements Ai, Ai+1, …, Aj . XOR of a subarray is defined as Ai^Ai+1^ … ^Aj.
Symbol ^ is Exclusive Or. You can read more about it here:
http://en.wikipedia.org/wiki/Exclusive_or
Input Format:
First line contains T, the number of test cases. Each of the test case consists of N and K in one line, followed by N space separated integers in next line.
Output Format:
For each test case, print the required answer.
Constraints:
1 ≤ T ≤ 10
1 ≤ N ≤ 10^5
1 ≤ A[i] ≤ 10^5
1 ≤ K ≤ 10^6
Sum of N over all testcases will not exceed 10^5.
Sample Input:
1
5 2
4 1 3 2 7
Sample Output:
3
Explanation:
Only subarrays satisfying the conditions are [1],[1,3,2] and [3,2].
————————————————————————————————————————————
题目大意:
给你一个序列,问你有多少个区间的所有元素异或和小于k
解题思路:
首先我们很容易想到,
对于一个区间异或和 可以先预处理出前缀异或和pre[],这样的话区间的异或和成就变成了pre[r]^pre[l-1]
现在问题就变成了序列中选取两个元素异或结果小于K的方案数有多少了
如果是等于k的话 相信大家都会做了,但是要小于k怎么处理呢 ,
其实一样的 ,只是在计算等于K的过程中进行统计,对于k当前二进制位下为1的时候我们就记录下和当前位异或为0的组合有多少 ,然后遍历下去重复此过程就好了,
注意要把pre[0]先插入字典树,这样才能统计区间的结果
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-21 08:02:33 Tabris_ 阅读数:558
博客爬取于2020-06-14 22:41:09
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/64432631
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3772
————————————————————————————————————————————
Calculate the Function
Time Limit: 2 Seconds Memory Limit: 65536 KB
You are given a list of numbers A1 A2 … AN and M queries. For the i-th query:
The query has two parameters Li and Ri.
The query will define a function Fi(x) on the domain [Li, Ri] ∈ Z.
Fi(Li) = ALi
Fi(Li + 1) = A(Li + 1)
for all x >= Li + 2, Fi(x) = Fi(x - 1) + Fi(x - 2) × Ax
You task is to calculate Fi(Ri) for each query. Because the answer can be very large, you should output the remainder of the answer divided by 1000000007.
Input
There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:
The first line contains two integers N, M (1 <= N, M <= 100000). The second line contains N integers A1 A2 … AN (1 <= Ai <= 1000000000).
The next M lines, each line is a query with two integer parameters Li, Ri (1 <= Li <= Ri <= N).
Output
For each test case, output the remainder of the answer divided by 1000000007.
Sample Input
1
4 7
1 2 3 4
1 1
1 2
1 3
1 4
2 4
3 4
4 4
Sample Output
1
2
5
13
11
4
4
————————————————————————————————————————————
题目大意:
给一段序列 对于每一段查询区间,序列的值为
解题思路:
训练的时候一直想 会有什么技巧/黑科技一类的将其转化成一个O(1)查询的问题
最后还是没有想出来,最后看了题解 才知道这是一个线段树+矩阵乘法的
跟那个博主一样进入了 矩阵一定是求高次幂的误区
这题就是fibonacci数列
$\left[\begin{array}{cc}\ Fi(x + 1) && Fi(x) \\ 0 &&0 \end{array}\right] \times \left[\begin{array}{cc}
\ 1&& 1\\ A_x+2 &&0 \end{array}\right]=\left[\begin{array}{cc}\ Fi(x + 2) && Fi(x+1) \ 0 &&0 \end{array}\right] $
我们只要用线段树处理出一段区间的右矩阵的乘积就好了
查询就变成了
附本题代码
———————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-20 13:37:14 Tabris_ 阅读数:296
博客爬取于2020-06-14 22:41:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/64124556
题目链接:http://www.ifrog.cc/acm/problem/1109
————————————————————————————————————————————
1109 - Niro plays with snow
Time Limit:2s Memory Limit:128MByte
Submissions:50Solved:8
DESCRIPTION
Ah, it snows.
Niro picks up a snowflake. It grows every second. At every second, each of the smallest triangles splits and one of the two rotates by 180 degrees. The process is shown below. In the picture, blue represents the areas that are one layer thick, red two layers thick, yellow three layers thick, and green four layers thick.
Now let be the number of smallest triangles that are one layers thick at order , and be the number of smallest triangles thar are three layers thick at order . For example,
Given , can you tell Niro and modulo 1234321237?
INPUT
T+1 lines.
The first line contains one integer T, the number of test cases.
Each of the following T lines contains one integer n.
OUTPUT
T lines.
Each line contains two integers, and for each query.
SAMPLE INPUT
5
3
4
5
52
100
SAMPLE OUTPUT
30 6
138 78
606 654
540534048 39147304
978578590 88026038
HINT
————————————————————————————————————————————
题目大意:
就是问你 第n个图形中 一层 和三层的三角形有多少个
解题思路:
看了看数据范围,想到是个矩阵乘法,也推出了的矩阵乘法
$ \left[\begin{array}{cc}\ 0&&6&&0&&0&&0&&0&&0&&0 \0&&3&&2&&0&&1&&0&&0&&0 \0&&1&&2&&1&&2&&0&&0&&0 \0&&0&&0&&3&&3&&0&&0&&0 \0&&0&&0&&0&&0&&6&&0&&0 \0&&0&&0&&0&&0&&3&&2&&0 \0&&0&&0&&0&&0&&1&&2&&1 \0&&0&&0&&0&&0&&0&&0&&3 \\end{array}\right]\times \left[\begin{array}{cc} F_0(i)\F_1(i)\F_2(i)\F_3(i)\G_0(i)\G_1(i)\G_2(i)\G_3(i)\ \end{array}\right] = \left[\begin{array}{cc} F_0(i+1)\F_1(i+1)\F_2(i+1)\F_3(i+1)\G_0(i+1)\G_1(i+1)\G_2(i+1)\G_3(i+1) \end{array}\right]$
-其中表示三角形三边中有条变邻近红色(两层)
-其中表示三角形三边中有条变邻近红色(两层)
然而交上去就TLE了,
复杂度 …
然后听了Q 的说法 预处理出所有的A矩阵的次幂 然后在计算的时候只要用向量乘上矩阵就好了 复杂度就变成了 然后就过了
然而当时听说还有用4*4的矩阵过得…
最后看了题解 ,真是玄妙无比啊…有兴趣的戳一下题解的传送阵
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-16 11:12:44 Tabris_ 阅读数:354
博客爬取于2020-06-14 22:41:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/62418811
#A Anton and Polyhedrons
————————————————————————————————————————————
傻逼题不解释
————————————————————————————————————————————
傻逼题不解释
————————————————————————————————————————————
就是给你仓库的容积N,最开始每天运来M,但仓库里至多有N,第天被鸟吃,问你至多撑几天,使得仓库里面不为,(先被吃,在运,如果吃完就成了,那么就已经算撑不住了)
首先考虑的情况,最多撑n天,没有问题。
然后考虑其他情况,
开始几天,鸟吃的没有运来的多,所以相当于没有变化,
那么m天后,相当于每天减少1,2,3,4,······。
那么就是 (1+ans)*ans/2>=n-m
最后的结果就是ans+m
计算那个式子可以用不等式开根号,也可以二分,注意下二分的时候别溢出就行了。
————————————————————————————————————————————
给你一个字符串,问你字串中前半段为’(‘,后半段为’)'的子串有多少个,子串不要求必须连续。
很明显,我们可以枚举每一个’(‘,来计算以这个为前半段结尾的子串有多少个,
首先预处理出前缀’(‘的个数和后缀’)‘的个数,
在遍历一遍母串,每当到’('的时候我们就计算以这个跟为前半段结尾的子串有多少个,
因为前半段的最后一个’('是固定的,所有我们要求
$ \sum_{i=1}^{n} C(n-1,i-1)\times C(m,i)$
然后推导了半天还是不会,最后Q给了个公式
$ when(n\leq m), \ \sum_{i=1}^{n} C(n,i)*C(m,i)\=\sum_{i=1}^{n} C(n,i)*C(m,m-i)\=C(n+m,m)\=\dfrac{(n+m)!}{(n)!\times {(m)}!}$
然后我们就可以计算了.
————————————————————————————————————————————
不会,待补
]]>2017-03-15 07:46:22 Tabris_ 阅读数:426
博客爬取于2020-06-14 22:41:12
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/62213988
题目链接 http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2054
——————————————————————————————————————————
Boring Counting
Time Limit: 3000 MSMemory Limit: 32768 K
Total Submit: 70(22 users)Total Accepted: 6(6 users)Rating: Special Judge: No
Description
In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each query, please tell us among [L, R], how many Pi is not less than A and not greater than B( L<= i <= R). In other words, your task is to count the number of Pi (L <= i <= R, A <= Pi <= B).
Input
In the first line there is an integer T (1 < T <= 50), indicates the number of test cases.
For each case, the first line contains two numbers N and M (1 <= N, M <= 50000), the size of sequence P, the number of queries. The second line contains N numbers Pi(1 <= Pi <= 10^9), the number sequence P. Then there are M lines, each line contains four number L, R, A, B(1 <= L, R <= n, 1 <= A, B <= 10^9)
Output
For each case, at first output a line ‘Case #c:’, c is the case number start from 1. Then for each query output a line contains the answer.
Sample Input
1
13 5
6 9 5 2 3 6 8 7 3 2 5 1 4
1 13 1 10
1 13 3 6
3 6 3 6
2 8 2 8
1 9 1 9
Sample Output
Case #1:
13
7
3
6
9
——————————————————————————————————————————
解题思路:
其实就是一个简单的主席树入门,奈何练习赛的时候刚学主席树不到2天,还没理解主席树.于是GG了
其实仔细想想啊,其实 和 SPOJ DQUERY 一样,而且更简单一点,
我们不需要删除操作,只需要保存所有的历史版本,然后找之间在区间的数的个数就行了
只需要离散化后,一次向树上更新即可,
但要注意查询的时候,
离散化A是大于等于A的第一个元素
离散化B是小于等于B的最后一个元素
附本题代码
————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-14 12:37:34 Tabris_ 阅读数:704
博客爬取于2020-06-14 22:41:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/62040995
题目链接:http://www.ifrog.cc/acm/problem/1098
————————————————————————————————————————————
DESCRIPTION
按顺序把一个1~n的排列插入一棵原来是空的排序二叉树,求所有节点的高度的和以及积(其中跟节点的高度算为1),这个结果可能有点大,所以你只需要输出和以及积对10^9+7求与的结果。
INPUT
输入数据第一行一个整数T(<=15)表示数据组数。
接下来每组数据一行四个整数,n(1<=n<=1000000)、a、b、c(1<=a,b,c<=10^9),然后利用下面一段程序生成插入排序二叉树的排列。
(注意:此处应有代码,两段代码放于描述图中,请仔细观看,代码贴于下方网站)
http://paste.ubuntu.com/24106406/
运行make_data得到的num数组就是插入的排列。
OUTPUT
每组数据输出一行两个数,分别表示所有节点的高度之和对10^9+7求余以及高度之积对10^9+7求余的结果。
SAMPLE INPUT
2
3 4 5 6
4 1 5 9
SAMPLE OUTPUT
6 6
8 12
HINT
提示:两个样例生成的排列分别为
3 1 2
2 3 1 4
————————————————————————————————————————————
解题思路:
其实这题很容易就想到了的做法,
我们只要用一个树状数组维护,再加上一个二分,
每次将一个元素插入到树中,那么对于待插得元素,它一定是在树中元素中比它大的最小元素或比它小的最大元素的下面,并且一定是其中深度大的那个点的孩子,
那么我们很容易用二分和树状数组维护处待插元素的父节点,
但是交上去T了 ,然后看群里讨论,说可以去掉
先附上的代码
1 | int n,a,b,c; |
然后冥思苦想 ,有意识的倒过来插元素,但却不知道怎么维护, 知道比赛后看到题解说用并查集维护
官方题解:
第三题、当一课排序二叉树建立起来之后我们可以发现,从某个点x往上走,第一个往左的节点的值是在x前插入的小于x的最大值,第一个往右的值是在x前插入的大于x的最小值,所以x所在的层数就是在插入x之前比x大的最小值的层数和比x小的最大值的层数中,较大值加一,若把问题反过来看,不是插入而是从二叉树中把一个个点拿走,那么可以很简单地用并查集找到上述的两个值。
但是本菜真的想不出如何用并查集进行维护,
直到今天向格格姐姐要来了标程…
虽然还不是特别懂,但也感受到了这个姿势的妙<
正常的并查集仅仅是单一的维护父节点,再简单点就是堆与堆之间的关系,
这个则不同,不仅开了两个并查集维护左边和右边的关系,
同事每个并查集都用了一个pair,来维护
一边维护左边的,一边维护了右边的关系,使得确保我在记录每个节点的左父节点和右父节点(大概可以这么理解)的关系时能做到.
附本题代码(我写的太丑了 还是贴标程吧)
————————————————————————————————————————————
1 | # include <stdio.h> |
我抄来的代码
]]>2017-03-13 21:19:02 Tabris_ 阅读数:211
博客爬取于2020-06-14 22:41:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61929040
Virtual Contest 4AC GG E题根本读不懂啊…
读题太慢,傻逼题还错,难题还不会, 总结就是菜!!
——————————————————————————————————
日常傻逼题:
给你两个只含有{1,2,3,4,5}序列,让你使其平衡,就是两边1的个数,2的个数…5的个数相同,
问你最少交换几次, 不能输出-1;
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
日常傻逼题2:给你一个数,问你最少删除几位使得这个数能被整除
字符串模拟做即可 ,注意 如果是 100 要被整除,那么只能变成0,那么删除的是2位,而不仅仅是1这一位.
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
贪心题:
给你n个商品的两种价格,一种是现在的价格,一种是过几天的价格,今天最少买k个,问你最后每个商品买一次,最少的总花费。
排序,先买现在的价格-过几天价格的差大的。现在买的话 至少买k个或者买现在便宜的 剩下的都过几天买就好了
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
就是在字符串上按顺序依次删除第个字符串,问你最多删除几次,能保证在省下的字符串中能找到字符串
很明显是不能的
但是我们可以发现,在答案位置左边,一定是不能找到字符串得,右边一定是能找到字符串得,
那么根据这个 我们可以对答案进行二分,最后复杂度
1 | # include <bits/stdc++.h> |
————————————————————————————————————————————
待补
————————————————————————————————————————————
待补
2017-03-13 18:16:52 Tabris_ 阅读数:402
博客爬取于2020-06-14 22:41:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61923707
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919
——————————————————————————————————————
Sequence II
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1654 Accepted Submission(s): 420
Problem Description
Mr. Frog has an integer sequence of length n, which can be denoted as There are m queries.
In the query, you are given two integers and . Consider the subsequence .
We can denote the positions(the positions according to the original sequence) where an integer appears first in this subsequence as (in ascending order, i.e.,.
Note that ki is the number of different integers in this subsequence. You should output p(i)⌈ki2⌉for the i-th query.
Input
In the first line of input, there is an integer T denoting the number of test cases.
Each test case starts with two integers n (n≤2×10^5) and m (m≤2×10^5). There are n integers in the next line, which indicate the integers in the sequence(i.e., ).
There are two integers and in the following lines.
However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to$ l‘_i,r‘_i(1≤l‘i≤n,1≤r‘i≤n). $As a result, the problem became more exciting.
We can denote the answers as . Note that for each test case .
You can get the correct input li,ri from what you read (we denote them as )by the following formula:
Output
You should output one single line for each test case.
For each test case, output one line “Case #x: ”, where is the case number (starting from 1) and is the answer.
Sample Input
2
5 2
3 3 1 5 4
2 2
4 4
5 2
2 5 2 1 2
2 3
2 4
Sample Output
Case #1: 3 3
Case #2: 3 1
Hint
————————————————————————————————————————————
题目大意:
给定一个长度为n的序列,然后有m个查询,问你在区间中所有不相同元素第一次出现的位置,按这个位置升序以后的中间(向上取整)的那个位置是多少(这个位置指的是原序列)?
解题思路:
因为这个题对的限制,这题强制在线,就不能离线树状数组做了,只能主席树做了,
然后他说在询问区间,不相同元素第一次出现的位置的中间那个,
如果是从正序挂到主席树上的话 确实不好维护,
考虑倒叙插入到主席树上,那么每次都只会记录最左边的数,更新的时候如过当前数出现过就删去之前的那个,
就不需要排序过程了,只需要在区间内找第中间的那个就行了
查询的时候我们只要对rt[l]进行查找就行了
于是就变成了找区间内不同数的个数,
然后找区间内第k大的问题,
这样的话就是主席树的基本操作了,
总体复杂度
附本题代码
——————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-13 08:56:49 Tabris_ 阅读数:575
博客爬取于2020-06-14 22:41:17
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61912463
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1255
————————————————————————————————————————————
1255 字典序最小的子序列
题目来源: 天津大学OJ
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注
给出一个由a-z组成的字符串S,求他的一个子序列,满足如下条件:
1、包含字符串中所有出现过的字符各1个。
2、是所有满足条件1的串中,字典序最小的。
例如:babbdcc,出现过的字符为:abcd,而包含abcd的所有子序列中,字典序最小的为abdc。
Input
输入1行字符串S,所有字符均为小写,字符串的长度为L。(1 <= L <= 100000)。
Output
输出包含S中所有出现过的字符,每个字符各1个,并且字典序最小的S的子序列。
Input示例
babbdcc
Output示例
abdc
————————————————————————————————————————————————
解题思路:
我们贪心做这道题
既然他让我们找包含所有出现过的字符的字典序最小的子串,
那么对于左右出现过的字符是很好判定的,没出现过 就加进去就好了
问题是怎么找字典序最小的,
我们可以维护一个待定的子串,
首先将没有出现过的字符加进去
但加进去的同时呢,判断下待定子串的尾字符和当前待加进去的字符那个大,
如果尾字符大,并且这个尾字符在后面还有出现,我们就把尾字符删除,
这样维护下来,我们得到的一定是字典序最小的
复杂度是的
附本题代码
——————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-12 20:26:05 Tabris_ 阅读数:814
博客爬取于2020-06-14 22:41:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61631979
题目链接:http://www.spoj.com/problems/COT/en/
——————————————————————————————————————
COT - Count on a tree
#tree
You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.
We will ask you to perform the following operation:
u v k : ask for the kth minimum weight on the path from node u to node v
Input
In the first line there are two integers N and M.(N,M<=100000)
In the second line there are N integers.The ith integer denotes the weight of the ith node.
In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).
In the next M lines,each line contains three integers u v k,which means an operation asking for the kth minimum weight on the path from node u to node v.
Output
For each operation,print its result.
Example
Input:
8 58 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2
Output:
2
8
9
105
7
Submit solution!
——————————————————————————————————————
题目大意:
就是求在树上 (u,v)的路上的第K小的权值
解题思路:
首先对于求第K小的问题 我们可以用主席树搞 ,没有问题,
但是对于一个树形结构,我们需要将其转化为线性,然后需要树剖才能做.
然后考虑链上的第k值怎么维护 ,
发现如果树剖计算的话 维护不了啊
因为(u,v)的路 可能在很多个链上,那么不能对每个求第K值,这样明显是错误的啊,
然后我们知道主席树其实就是维护了一个前缀和
那么我们可以对每一个节点到根节点建立前缀和,就能找任意一个节点到根节点的第K值,
那么根据主席树的性质,我们就能够计算(u,v)的路上的第K值了
只要在查询的时候稍改变一下就行了
1 | cnt = sum[ls[u]]+sum[ls[v]]-sum[ls[lca(u,v)]]-sum[ls[fa[lca(u,v)]]]; |
不理解其实可以将主席树画出来 思考下 挺好理解的.
附本题代码
——————————————————————————————————————
1 | # pragma comment(linker, "/STACK:1024000000,1024000000") |
2017-03-12 00:03:17 Tabris_ 阅读数:190
博客爬取于2020-06-14 22:41:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61466246
题目链接:http://acm.upc.edu.cn/problem.PHP?id=2219
————————————————————————————————————
2219: A^X mod P
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 142 Solved: 28
[Submit][Status][Web Board]
Description
It’s easy for ACMer to calculate A^X mod P. Now given seven integers n, A, K, a, b, m, P, and a function f(x) which defined as following.
f(x) = K, x = 1
f(x) = (a*f(x-1) + b)%m , x > 1
Now, Your task is to calculate
( A^(f(1)) + A^(f(2)) + A^(f(3)) + … + A^(f(n)) ) modular P.
Input
In the first line there is an integer T (1 < T <= 40), which indicates the number of test cases, and then T test cases follow. A test case contains seven integers n, A, K, a, b, m, P in one line.
1 <= n <= 10^6
0 <= A, K, a, b <= 10^9
1 <= m, P <= 10^9
Output
For each case, the output format is “Case #c: ans”.
c is the case number start from 1.
ans is the answer of this problem.
Sample Input
2
3 2 1 1 1 100 100
3 15 123 2 3 1000 107
Sample Output
Case #1: 14
Case #2: 63
————————————————————————————————————
题目大意:
就是给你7个数:
$ n, A, K, a, b, m, P f(x) = \left{\begin{array}{rcl}\ K &&, x = 1 \ (a*f(x-1) + b)%m && ,x>1\end{array}\right.$
问:
$( A^{f(1)} + A^{f(2)} + A^{f(3)}+ … + A^{f(n)} ) \mod P. $
解题思路:
其实思路很好构建 ,
只要求出然后的快速幂就能求解
但是这题卡了 ,所以不能快速幂
对于求一次幂 用快速幂会非常快 但是求多次就不是很快了
我们要先预处理出所有
发现根本存不下 ,,
但是我们可以预处理出
和
这样我们就可以通过一次相乘,开快速求出了
这样下来复杂度就变成了
附本题代码
——————————————————————————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-03-11 23:13:13 Tabris_ 阅读数:375
博客爬取于2020-06-14 22:41:20
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61441552
题目链接:hrbust的oj上有题目
————————————————————————————————
A-Number and B-Number
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 22(8 users)Total Accepted: 5(5 users)Rating: Special Judge: No
Description
Tom is very interested in number problem. Nowadays he is thinking of a problem about A-number and B-number.
A-number is a positive integer whose decimal form contains 7 or it can be divided by 7. We can write down the first 10 A-number ( a[i] is the ith A-number)
{a[1]=7,a[2]=14,a[3]=17,a[4]=21,a[5]=27,a[6]=28,a[7]=35,a[8]=37,a[9]=42,a[10]=47};
B-number is Sub-sequence of A-number which contains all A-number but a[k] ( that k is a A-number.) Like 35, is the 7th A-number and 7 is also an A-number so the 35 ( a[7] ) is not a B-number. We also can write down the first 10 B-number.
{b[1]=7,b[2]=14,b[3]=17,b[4]=21,b[5]=27,b[6]=28,b[7]=37,b[8]=42,b[9]=47,b[10]=49};
Now Given an integer N, please output the Nth B-number.
Input
The input consists of multiple test cases.
For each test case, there will be a positive integer N as the description.
Output
For each test case, output an integer indicating the Nth B-number.
You can assume the result will be no more then 2^63-1.
Sample Input
1
7
100
Sample Output
7
37
470
——————————————————————————————————
题目大意:
A数组就是民间游戏"敲七"的序列
B数组就是
然后输出B数组中第n个元素即:
解题思路:
如果直接求第i个元素的话 无论是A数组还是B数组都不能求(反正我不会)
但是他求得是第个元素 我们可以换一个角度来思考
首先我们可以用一个入门级别的数位dp来统计小于的元素个数,
那么反过来 [1,n]中 最小的有x个元素的n 就是第x个元素
那么我们就可以用二分答案来统计了
对于A数组我们很好数位dp
但是对于B数组我们不能直接求出来
但是考虑A与B数组的关系,发现,只要对cal(x)统计的结果ans在统计一下相减即可;
即:
1 | A = cal(x); |
注意
二分溢出的问题
最大值要(1<<63)-1,
附本题代码
——————————————————————————————————————————————
1 | # include<bits/stdc++.h> |
2017-03-11 14:18:35 Tabris_ 阅读数:312
博客爬取于2020-06-14 22:41:21
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61416622
题目连接:http://www.spoj.com/problems/DQUERY/
——————————————————————————————————————————
DQUERY - D-query
#sorting #tree
EnglishVietnamese
Given a sequence of n numbers a1, a2, …, an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, …, aj.
Input
Line 1: n (1 ≤ n ≤ 30000).
Line 2: n numbers a1, a2, …, an (1 ≤ ai ≤ 106).
Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).
Output
For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, …, aj in a single line.
Example
Input
5
1 1 2 1 3
3
1 5
2 4
3 5
Output
3
2
3
——————————————————————————————————————————
题目大意:
就是给你一个序列 ,和q次询问,
询问区间不同元素的个数
解题思路:
本来是做的主席树专题 ,然而主席树怎么做 还不会,
于是就用离线树状数组的做法水了一发
主要就是对询问的r值 排序。
然后遍历一遍序列,
每次对在树状数组上更新最后一次出现的位置,如果已经出现了 就将之前出现过的删掉就好了
每次维护查询 就是计算区间标记的个数
============== 主席树的做法 Update===================
仔细想了想主席树的做法,
其实思路上和离线的树状数组并没有什么区别,
但是因为主席树的特性,我们可以维护一颗颗树,所以能拿到线上解决这个问题
在一颗颗树进行更新的时候,当这个值出现过,我们就将之前的删去,然后在更新,就好了
对树的维护和线段树基本相同,不赘述了
但是在处理的时候发现一个问题
1 | int tem; |
上面的能AC 而下面的却不能
1 | for(int i=1;i<=n;i++){ |
最后也没弄明白怎么回事
附本题代码
——————————————————————————————————————————
1 | /*** |
2017-03-10 21:51:50 Tabris_ 阅读数:487
博客爬取于2020-06-14 22:41:22
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61209605
题目链接:http://poj.org/problem?id=2104
————————————————————————————————————————————————
K-th Number
Time Limit: 20000MSMemory Limit: 65536K
Total Submissions: 53824Accepted: 18506
Case Time Limit: 2000MS
Description
You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment.
That is, given an array a[1…n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: “What would be the k-th number in a[i…j] segment, if this segment was sorted?”
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2…5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.
Input
The first line of the input file contains n — the size of the array, and m — the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000).
The second line contains n different integer numbers not exceeding 109 by their absolute values — the array for which the answers should be given.
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).
Output
For each question output the answer to it — the k-th number in sorted a[i…j] segment.
Sample Input
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
Sample Output
5
6
3
Hint
This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.
——————————————————————————————————————————————————————
题目大意:
求区间第k大的数值
解题思路:
算法不用想 妥妥的主席树啊
之前一直没有学习主席树,就是理解不了主席树,
今天找到了一个很好的
博客1
博客2
算是明白了什么是主席树,
主席树为了保存历史版本的状态 ,于是在每次更新的时候都在开出一条链来代表新建出来的节点,
这样就不用每次在建一颗树了
其实主席树是一种函数式线段树
寻找区间的值其实也就成了找 第个版本-第个版本 就是我们要查询的值了
附本题代码
——————————————————————————————————————————————————
1 | # pragma comment(linker, "/STACK:1024000000,1024000000") |
2017-03-10 00:33:47 Tabris_ 阅读数:239
博客爬取于2020-06-14 22:41:23
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/61023246
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5416
————————————————————————————————
CRB and Tree
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2145 Accepted Submission(s): 648
Problem Description
CRB has a tree, whose vertices are labeled by 1, 2, …, N. They are connected by N – 1 edges. Each edge has a weight.
For any two vertices u and v(possibly equal), f(u,v) is xor(exclusive-or) sum of weights of all edges on the path from u to v.
CRB’s task is for given s, to calculate the number of unordered pairs (u,v) such that f(u,v) = s. Can you help him?
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer N denoting the number of vertices.
Each of the next N - 1 lines contains three space separated integers a, b and c denoting an edge between a and b, whose weight is c.
The next line contains an integer Q denoting the number of queries.
Each of the next Q lines contains a single integer s.
1 ≤ T ≤ 25
1 ≤ N ≤ 105
1 ≤ Q ≤ 10
1 ≤ a, b ≤ N
0 ≤ c, s ≤ 105
It is guaranteed that given edges form a tree.
Output
For each query, output one line containing the answer.
Sample Input
1
3
1 2 1
2 3 2
3
2
3
4
Sample Output
1
1
0
Hint
For the first query, (2, 3) is the only pair that f(u, v) = 2.
For the second query, (1, 3) is the only one.
For the third query, there are no pair (u, v) such that f(u, v) = 4.
————————————————————————————————
题目大意:
在一棵n个节点的生成树树上,每个边有一个边权
就是定义f(u,v)为树上u->v路径上边权的异或和 ,
有q次查询,每次问你在这棵树上,f()=s的情况有多少种
解题思路:
这其实是一个思维题
通过遍历我们能够知道每一个点到根节点路径上的异或和
因为异或运算满足消去律,所以f(1,u)^f(1,v)=f(u,v);
通过这些我们就好计算了, 只要一遍dfs预处理出每个点到根节点的f(),hash一下 ,
最后计算就行
注意一下 0的情况就行了
附本题代码
—————————————————————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-09 22:59:37 Tabris_ 阅读数:279
博客爬取于2020-06-14 22:41:24
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/60982742
题目连接:http://poj.org/problem?id=2763
--------------------------------------------------------------------------.
Housewife Wind
Time Limit: 4000MSMemory Limit: 65536K
Total Submissions: 10703Accepted: 2969
Description
After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beautiful huts. There are some pairs of huts connected by bidirectional roads. We say that huts in the same pair directly connected. XX Village is so special that we can reach any other huts starting from an arbitrary hut. If each road cannot be walked along twice, then the route between every pair is unique.
Since Jiajia earned enough money, Wind became a housewife. Their children loved to go to other kids, then make a simple call to Wind: ‘Mummy, take me home!’
At different times, the time needed to walk along a road may be different. For example, Wind takes 5 minutes on a road normally, but may take 10 minutes if there is a lovely little dog to play with, or take 3 minutes if there is some unknown strange smell surrounding the road.
Wind loves her children, so she would like to tell her children the exact time she will spend on the roads. Can you help her?
Input
The first line contains three integers n, q, s. There are n huts in XX Village, q messages to process, and Wind is currently in hut s. n < 100001 , q < 100001.
The following n-1 lines each contains three integers a, b and w. That means there is a road directly connecting hut a and b, time required is w. 1<=w<= 10000.
The following q lines each is one of the following two types:
Message A: 0 u
A kid in hut u calls Wind. She should go to hut u from her current position.
Message B: 1 i w
The time required for i-th road is changed to w. Note that the time change will not happen when Wind is on her way. The changed can only happen when Wind is staying somewhere, waiting to take the next kid.
Output
For each message A, print an integer X, the time required to take the next child.
Sample Input
3 3 1
1 2 1
2 3 2
0 2
1 2 3
0 3
Sample Output
1
3
--------------------------------------------------------------------------.
题目大意:
一颗n个节点的生成树,有边权,一个人开始在s位置,有两种操作,
1) 0 a 从s走到n 输出路径长度
2) 1 a b 将第a条边的权值变成b
解题思路:
这题就是基于边权的树链剖分。找路径的和我们可以采用树状数组维护
其实边权对于点权来说,基本一样,我们只要将u->v的权值给u,v中距离根节点远的就行了
然后查找的时候再讲lca(u,v)这个点的权值减去 得到的就是u->v的路径长度
注意下本题卡时间卡的非常紧
vector是不行的 要用前向星 .
附本题代码
--------------------------------------------------------------------------.
1 | # include <stdio.h> |
2017-03-09 12:32:57 Tabris_ 阅读数:430
博客爬取于2020-06-14 22:41:25
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/60957820
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3966
-------------------------------------------------------------------------------.
Aragorn’s Story
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10824 Accepted Submission(s): 2838
Problem Description
Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges connect them. It is guaranteed that for any two camps, there is one and only one path connect them. At first Aragorn know the number of enemies in every camp. But the enemy is cunning , they will increase or decrease the number of soldiers in camps. Every time the enemy change the number of soldiers, they will set two camps C1 and C2. Then, for C1, C2 and all camps on the path from C1 to C2, they will increase or decrease K soldiers to these camps. Now Aragorn wants to know the number of soldiers in some particular camps real-time.
Input
Multiple test cases, process to the end of input.
For each case, The first line contains three integers N, M, P which means there will be N(1 ≤ N ≤ 50000) camps, M(M = N-1) edges and P(1 ≤ P ≤ 100000) operations. The number of camps starts from 1.
The next line contains N integers A1, A2, …AN(0 ≤ Ai ≤ 1000), means at first in camp-i has Ai enemies.
The next M lines contains two integers u and v for each, denotes that there is an edge connects camp-u and camp-v.
The next P lines will start with a capital letter ‘I’, ‘D’ or ‘Q’ for each line.
‘I’, followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, increase K soldiers to these camps.
‘D’, followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, decrease K soldiers to these camps.
‘Q’, followed by one integer C, which is a query and means Aragorn wants to know the number of enemies in camp C at that time.
Output
For each query, you need to output the actually number of enemies in the specified camp.
Sample Input
3 2 5
1 2 3
2 1
2 3
I 1 3 5
Q 2
D 1 2 2
Q 1
Q 3
Sample Output
7
4
8
Hint
1.The number of enemies may be negative.
2.Huge input, be careful.
-------------------------------------------------------------------------.
题目大意:
给一棵树 ,n个节点,m条变,q个操作,
操作有三种,
1) I C1 C2 K 将点c1 到点c2的每个点 权值+k
2) D C1 C2 K 将点c1 到点c2的每个点 权值-k
3) Q C 查询当前点C的权值
解题思路:
还是树链剖分的入门 ,
但是这题简单在 只要用树状数组维护就行了,
坑比的我居然折在了输入上,
也后输入字符一论用输入 ,
附本题代码
---------------------------------------------------------------------------.
1 | # include<bits/stdc++.h> |
2017-03-09 08:47:18 Tabris_ 阅读数:16
博客爬取于2020-06-14 22:41:26
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/60953673
题目连接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
-------------------------------------------------------------------------------------.
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 15527 Solved: 6328
[Submit][Status][Discuss]
Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
-----------------------------------------------------------------------------------------.
解题大意:
就是裸的树链剖分
树链剖分其实和dfs序一样,都是将树形结构转化为线性结构,然后借用线段树维护的东西。
dfs序转化的线性结构是能查询节点的子树中的什么什么值,
而树链剖分就是对树进行链的分割,然后求解某两个节点间的什么什么值
主要思想就是对树丛根节点开始对分出一个个重链来,然后编号。
通过两遍dfs ,第一遍求出重儿子,第二遍进行标号,将树转化成线性,使得每条链上的节点在线段树中是连续的
附本题代码
----------------------------------------------------------------------------。
1 | # include<bits/stdc++.h> |
2017-03-06 20:44:59 Tabris_ 阅读数:1084
博客爬取于2020-06-14 22:41:28
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/60594774
题目连接:http://www.51nod.com/contest/problem.html#!problemId=1601
------------------------------------------------------------------------------.
完全图的最小生成树计数
SkyDec (命题人)
基准时间限制:1 秒 空间限制:131072 KB 分值: 160
给定一个长度为n的数组a[1…n],有一幅完全图,满足(u,v)的边权为a[u] xor a[v]
求边权和最小的生成树,你需要输出边权和还有方案数对1e9+7取模的值
注意边权和是不需要取模的
注意边权和是不需要取模的
注意边权和是不需要取模的
(重要的事情要说三遍)
Input
第一行一个正整数n
第二行n个整数表示a[1…n]
1<=n<=10^5
0<=a[i]<2^30
Output
第一行输出边权和
第二行输出方案数
Input示例
5
2 2 3 4 5
Output示例
8
6
--------------------------------------------------------------------------------.
解题思路:
首先对于最小生成树来说边一定是最小了,
那么 我们只要将 树分成两个,使得一颗子树的高位为,另一颗为,显然最好仅用一条边将这两颗子树连接起来能使得最后的权值和最小,那么对于这两颗子树分别递归的用这种方法求解得到就一定是最小生成树了。
那么对于很容易想到字典树,
然后我们发现字典树的左右儿子就是我们需要分开的两颗子树,
那么我们只要对字典树树进行dfs遍历,然后遇到同时存在左右儿子的就去计算一下选择哪条边且有多少种选法,我们就能知道结果了
计算选择哪条边的时候,我们可以枚举一棵子树的每个叶子节点,然后通过字典树在另一颗子树中查找与其异或值最小的,然后记录就行了.
然后注意的是:
1. 本题需要读入优化
2. 位运算括起来,因为优先级地
3. 枚举节点的时候最好用启发式选择,选择叶子节点少的枚举.
4. 然后注意的是 点值相同的完全图共有颗生成树
附本题代码
——————————————————————————————————
1 | # include <bits/stdc++.h> |
2017-03-03 19:21:28 Tabris_ 阅读数:393
博客爬取于2020-06-14 22:41:29
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/60145283
题目链接:https://vjudge.net/problem/UVA-10951
-----------------------------------------------------------------------.
UVA的都是pdf ,复制粘贴不方便 去https://vjudge.net/problem/UVA-10951看吧
------------------------------------------------------------------------.
题目大意:
就是给你两个多项式,让你求解两个多项式的gcd ,其中系数对n去摸,且最高次幂的系数为1.
解题思路;
还是当做正常的gcd来做,这样的话,还是经典的欧几里得算法
1 | template<typename T> |
那么这个问题就转化为如何对多项式取模。
这个很容易了,注意其中用逆元来计算除法就行了
多项式取模
附本题代码
----------------------------------------------------------------。
1 | # include <bits/stdc++.h> |
2017-03-03 16:05:08 Tabris_ 阅读数:265
博客爬取于2020-06-14 22:41:30
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/60141601
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4366
---------------------------------------------------------------------------------------------------------------.
Successor
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4173 Accepted Submission(s): 1032
Problem Description
Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty and ability.Some times Sean will fire one staff.Then one of the fired man’s Subordinates will replace him whose ability is higher than him and has the highest loyalty for company.Sean want to know who will replace the fired man.
Input
In the first line a number T indicate the number of test cases. Then for each case the first line contain 2 numbers n,m (2<=n,m<=50000),indicate the company has n person include Sean ,m is the times of Sean’s query.Staffs are numbered from 1 to n-1,Sean’s number is 0.Follow n-1 lines,the i-th(1<=i<=n-1) line contains 3 integers a,b,c(0<=a<=n-1,0<=b,c<=1000000),indicate the i-th staff’s superior Serial number,i-th staff’s loyalty and ability.Every staff ‘s Serial number is bigger than his superior,Each staff has different loyalty.then follows m lines of queries.Each line only a number indicate the Serial number of whom should be fired.
Output
For every query print a number:the Serial number of whom would replace the losing job man,If there has no one to replace him,print -1.
Sample Input
1
3 2
0 100 99
1 101 100
1
2
Sample Output
2
-1
Author
FZU
Source
2012 Multi-University Training Contest 7
----------------------------------------------------------------------------------------------------------------.
题目大意:
给一个公司的上下级关系图,每个员工有一个上级,一个忠诚度,一个能力值,
现在老板(0),要开除一个员工,然后在这个员工的直接或间接能力值大于这个员工下级中找忠诚度最大的人来代替这个员工,如果有输出代替的员工的编号,没有输出-1
解题思路:
首先,要明白如何将一个数形转化为线形
其实就是从根节点进行搜索,
然后向下dfs遍历树,依次进行编号,
同时能保证子树的编号一定大于父节点的编号,
同时借用两个数组,$L[_],R[_] u\big(L[u],R[u]\big),开区间$ 内。
这样在进行对子树 进行的操作的时候 可以借助数据结构 对区间进行查找,
然后将员工按能力值排序,
依次将一个个员工插入到线段树中,单点更新即可,
找这个员工下属忠诚度的最大的,直接区间查询就行了,
因为我们已经将树形转化成了线形,所以能够确保结果的正确性
然后注意下代码细节就好了。
操他妈的 两处笔误,卡了2个小时
1 sort (+1,+n +1)
2 j打成i
怎么这么菜!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
附本题代码
----------------------------------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-03-02 12:40:48 Tabris_ 阅读数:234
博客爬取于2020-06-14 22:41:31
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/59488912
题目连接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163
-----------------------------------------------------------------------------------------------.
1163 最高的奖励
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注
有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。
Input
第1行:一个数N,表示任务的数量(2 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,表示任务的最晚结束时间E[i]以及对应的奖励W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)
Output
输出能够获得的最高奖励。
Input示例
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
Output示例
230
------------------------------------------------------------------------------------------------.
解题思路:
本题看别人的思路都是贪心+优先队列
按照题意,可以从最晚结束时间和完成任务奖励分别展开求解。
从最晚结束时间考虑贪心策略的话,那么应该将最晚结束时间升序排序。
具体(PS):
用贪心思想,从0开始,每完成一件任务,消耗时间为1,按最晚时间递增,第n个任务如果最晚时间大于已消耗掉时间量,则可算入总和,若不大于已耗时间量,
则可以替换掉总和里最小奖励的一个任务(如果当前任务的奖励更多的话)。
这个过程可以用堆维护。nlog(n);
然而我是贪心+双数组
定义h[]数组,表示时刻内做没有做任务
定义m[]数组,表示一个"指针",指向距离时间点最近的没有做任务的时间点。其实这一步有点像并查集
排序的时候以w递减,e没什么所谓。
然后一次遍历,判断这个任务能不能做,能做就计算上。
排序是的,在统计的时候确实的
贪心+优先队列
------------------------------------------------------------------------------------------------.
1 | # include"stdio.h" |
贪心+加上双数组
------------------------------------------------------------------------------------------------.
1 | struct node { |
2017-03-02 09:28:49 Tabris_ 阅读数:477
博客爬取于2020-06-14 22:41:32
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/59480949
题目连接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1048
-------------------------------------------------------------------------------------------------------------.
整数分解为2的幂
基准时间限制:3 秒 空间限制:131072 KB 分值: 1280 难度:9级算法题
任何正整数都能分解成2的幂,给定整数N,求N的此类划分方法的数量!
比如N = 7时,共有6种划分方法。
7=1+1+1+1+1+1+1
=1+1+1+1+1+2
=1+1+1+2+2
=1+2+2+2
=1+1+1+4
=1+2+4
Input
输入N(1 <= N <= 10^30)
Output
划分方法的数量
Input示例
7
Output示例
6
-------------------------------------------------------------------------------------------------------------.
首先能够dp
设dp[i][j]表示组成的数是,方案中最大的数是的方案数。
为了避免重复,dp[i][j]转移时枚举下一个数必须大于等于
那么可以得出:
能够做到的复杂度
通过打表找规律等 ,可以递推得到如下规律
这样的话复杂度就是
然而对于51nod 1383 这个复杂度就够用了,但是对于1048的,就完全不够用了,
如果n很大怎么办?
那样就要挖掘一下分解方案的性质了。
1.对于一个数n,假设它二进制下有m个1,分别是第位。对于n的任意一种分解方案,把所有2的幂升序排序,然后可以划分成m段,其中第i段的和是
2.对于一个数的一种划分方案,如果不是只有它本身一个数,一定可以把这些2的幂升序排序,然后分成两段,每一段的和都是
证明并不难。有了这些性质,就可以设新的状态了。
首先设g[i][j]表示做完了前i段(即n二进制下的前i个1位),最大的数是,方案数是多少。
再设一个辅助数组f[i][j],表示组成,最大的数是的方案数。
接下来枚举第段的最大数是多少,假设是,那么$g[i][j]=\sum^{j}_{k=0}g[i−1][k]∗f[i−k][j−k] i-k,j-k$的意义在于:要控制后面的数都大于等于,每个数都要除掉,那么就不会算重了。
f[i][j]的转移类似
时间复杂度
附本题代码
----------------------------------------------------------------------------------.
1 | int dp[N]; |
1 | # include <cstdio> |
2017-02-14 21:02:29 Tabris_ 阅读数:619
博客爬取于2020-06-14 22:41:33
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/55106268
题目连接:https://vjudge.net/problem/10581/origin
--------------------------------------------------------------------------------------------.
PGCD - Primes in GCD Table
Johnny has created a table which encodes the results of some operation – a function of two arguments. But instead of a boring multiplication table of the sort you learn by heart at prep-school, he has created a GCD (greatest common divisor) table! So he now has a table (of height a and width b), indexed from (1,1) to (a,b), and with the value of field (i,j) equal to gcd(i,j). He wants to know how many times he has used prime numbers when writing the table.
Input
First, t ≤ 10, the number of test cases. Each test case consists of two integers, 1 ≤ a,b < 10^7.
Output
For each test case write one number - the number of prime numbers Johnny wrote in that test case.
Example
Input:
2
10 10
100 100
Output:
30
2791
--------------------------------------------------------------------------------------------.
题目大意:
问你在中素数的个数.
解题思路:
很好想到
设 (其中P为素数,[] 括号内式子成立为1,否则0)
设
显然
两种形式反演后得到
$f(d) = \sum _{d|n}\mu(\frac{n}{d})F(d) $ (1)
$f(n) = \sum _{d|n}\mu(d)F(\frac{n}{d}) $ (2)
我们取(1)式
(1)
最终结果就是
直接计算复杂度太高 显然不可取。
令t = pk;
其中对于我们可以在线性筛中预处理出来,然后求其前缀和
最后通过分段优化一下即可,
难死了,看了好久都不是很懂、,(Ps:线性筛真TM强大)
附本题代码
--------------------------------------------------------------------------------------------.
1 | int const MAX = 1e7 + 5; |
2017-02-13 22:59:18 Tabris_ 阅读数:268
博客爬取于2020-06-14 22:41:34
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/55060453
题目连接:https://vjudge.net/problem/HYSBZ-1257
----------------------------------------------------------------------------------------------------------.
1257: [CQOI2007]余数之和sum
Time Limit: 5 Sec Memory Limit: 162 MB
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<=n, k<=1000
100%的数据满足:1<=n ,k<=10^9
-----------------------------------------------------------------------------------------------------------.
暴力来看就是for(int i=1;i<=n;i++) ans += k%i;
对于i>k的时候结果都是0,所以开始是ans+=(a-b)*b,a=b;
然后就是计算
然后我们可以发现的集合中只有个元素,测试发现其实应该是个
对于相等的集合中 的解是呈等差数列的,所以可以将for(int i=1;i<=k;i++) ans += k%i;
分成求解个等差数列的和,这就是分段
附本题代码
-----------------------------------------------------------------------------------------------------------.
1 | LL a,b,ans; |
2017-02-13 22:15:06 Tabris_ 阅读数:634
博客爬取于2020-06-14 22:41:35
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/55058123
题目连接:https://vjudge.net/problem/HYSBZ-1853
------------------------------------------------------------------------------------------------------------.
1853: [Scoi2010]幸运数字
Time Limit: 2 Sec Memory Limit: 64 MB
Submit: 2284 Solved: 834
[Submit][Status][Discuss]
Description
在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”。lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”。 现在lxhgww想知道在一段闭区间[a, b]内,“近似幸运号码”的个数。
Input
输入数据是一行,包括2个数字a和b
Output
输出数据是一行,包括1个数字,表示在闭区间[a, b]内“近似幸运号码”的个数
Sample Input
【样例输入1】
1 10
【样例输入2】
1234 4321
Sample Output
【样例输出1】
2
【样例输出2】
809
HINT
【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
------------------------------------------------------------------------------------------------------------.
首处理出所有的幸运数字,
只有个.
然后找到这些数中的"幸运素数"(就是这些数组成的序列中不能被其他元素整除的数~~(类似线性基?!)~~)
找到这些数,那么 其实就把这个问题就是成求[a,b]内那些"幸运素数"的倍数有多少个就好了.
答案就是
很明显的一个容斥原理,
上述问题很容易 不再赘述
附本题代码
------------------------------------------------------------------------------------------------------------.
1 | LL l,r,a[10000],cnt,ans; |
2017-02-12 22:06:35 Tabris_ 阅读数:585
博客爬取于2020-06-14 22:41:36
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/55006530
题目连接:https://vjudge.net/problem/HYSBZ-2301
--------------------------------------------------------------------------------------------------------------.
2301: [HAOI2011]Problem b
Time Limit: 50 Sec
Memory Limit: 256 MB
Description
对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。
Input
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k
Output
共n行,每行一个整数表示满足要求的数对(x,y)的个数
Sample Input
2
2 5 1 5 1
1 5 1 5 2
Sample Output
14
3
HINT
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000
--------------------------------------------------------------------------------------------------------------.
解题思路:
对于求区间内的解 我们可以用容斥原理解决
那么对于求每一个时首先要明确的是求就是求的解,
证明 :
——证毕
然后设$f(i)为gcd(x,y)=i时(x,y)的对数,F(i)表示满足i|gcd(x,y)的(x,y)的对数,显然F(i)=⌊\dfrac{n}{i}⌋⌊\dfrac{m}{i}⌋ $
然后根据莫比乌斯反演公式的到
当i=1时,
由于的取值最多只有个(这个很容易证明:在时,$ y = \left{\begin{array}{rcl}1&&\frac{n}{2}<i<=n\2 && \frac{n}{3}<i<=\frac{n}{2}\ …\ \sqrt {n} && \frac{n}{\sqrt {n}+1}<i<=\frac{n}{\sqrt {n} }\end{array}\right.\sqrt {n}⌊\dfrac{n}{i}⌋\sqrt{n}O(2(\sqrt{n}+\sqrt{m}))$的时间(即分块优化)回答每次询问。
但是有一个奇怪的地方,就是我用%I64d输出 显示PE %lld输出 显示WA 用%d输出就AC了。。。。醉了。。。
附本题代码
--------------------------------------------------------------------------------------------------------------.
1 | int a,b,c,d,k; |
2017-02-11 23:09:40 Tabris_ 阅读数:981
博客爬取于2020-06-14 22:41:37
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54989141
练习题目VJ:https://vjudge.net/contest/77876#overview
这题应该是整错了 不是容斥原理,看题解都是IDA*搜索
对于替换的先不管 最后暴力处理即可,
不替换的时候可以分两段处理
分别计算[1,a-1]和[a,b]的 然后相减就好了
处理先对p素因子分解,然后容斥原理计算,
显然能够知道题目要求的是
满足的数量
由于数据量不大 ,可以枚举n值然后计算[1,m]中与n不互质的数的个数,然后用m减去即可
对于计算[1,m]中与n不互质的数的个数,我们还是要用到容斥原理,
最大公约数因子个数最大也就是8 因为2357111317*19 > 1e6
所以爆搜也不会超时
乱搞题,首先居然是想到线段树,要不是做专题就陷进去了。
然后想到求多个矩形相交面积的方法搞,因为n比较小但(1<< n)远大于1e5,所以不用预处理出所有情况,只要对待查询的情况容斥原理计算就好.
]]>2017-02-11 14:04:07 Tabris_ 阅读数:366
博客爬取于2020-06-14 22:41:39
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54982748
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2204
------------------------------------------------------------------------------------------------------------------.
2017 口碑商家客流量预测大赛》
Eddy’s爱好
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2436 Accepted Submission(s): 1118
Problem Description
Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣。
这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1。
正当他再度沉迷的时候,他发现不知道什么时候才能知道这样的数字的数量,因此他又求助于你这位聪明的程序员,请你帮他用程序解决这个问题。
为了简化,问题是这样的:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。
Input
本题有多组测试数据,每组包含一个整数N,1<=N<=1000000000000000000(10^18).
Output
对于每组输入,请输出在在1到N之间形式如M^K的数的总数。
每组输出占一行。
Sample Input
10
36
1000000000000000000
Sample Output
4
9
1001003332
Author
Eddy
Recommend
lcy
------------------------------------------------------------------------------------------------------------------.
题目大意:
求在[1,n]中能用表示的数的个数,
解题思路:
,所以K一定小于60,
又因为 ,所以只要求指数为质数的就行了,
,即x的就是指数为p的个数
利用容斥原理,去掉重复的就行了,
于2^60>10^18,235*7>60,所以只要枚举到三即可。
注:最后一个样例应该有问题, 我的代码和网上代码结果都是1001003331,找了好久的精度…
附本题代码
------------------------------------------------------------------------------------------------------------------.
1 | LL n,ans; |
2017-02-11 12:49:25 Tabris_ 阅读数:360
博客爬取于2020-06-14 22:41:40
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54982226
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1796
----------------------------------------------------------------------------------------------.
看详情——《IJCAI 2017 口碑商家客流量预测大赛》
How many integers can you find
Time Limit: 12000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7728 Accepted Submission(s): 2281
Problem Description
Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.
Input
There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0< N<2^31,0< M<=10, and the M integer are non-negative and won’t exceed 20.
Output
For each case, output the number.
Sample Input
12 2
2 3
Sample Output
7
Author
wangye
-----------------------------------------------------------------------------------------------.
题目大意:
求小于n的能够被集合中任意数字整除的数的个数
解题思路:
容斥原理入门题,
实现很好实现 可以状压搞,也可以dfs,但是发现dfs明显要块与状压啊。。
附本题代码
-----------------------------------------------------------------------------------------------.
状压枚举形式 655ms;
1 |
|
dfs形式 202ms
1 | int n,m; |
2017-02-11 11:49:26 Tabris_ 阅读数:160
博客爬取于2020-06-14 22:41:41
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54981815
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2222
-------------------------------------------------------------------------------------------------------.
Keywords Search
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 59295 Accepted Submission(s): 19490
Problem Description
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
Input
First line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters ‘a’-‘z’, and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.
Output
Print how many keywords are contained in the description.
Sample Input
1
5
she
he
say
shr
her
yasherhs
Sample Output
3
--------------------------------------------------------------------------------------------------------.
题目大意:就是有n个单词,问你这n个单词在文本中出现的有几个
解题思路:
AC自动机入门题,
多模式匹配
附本题代码
--------------------------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-02-10 21:31:20 Tabris_ 阅读数:440
博客爬取于2020-06-14 22:41:42
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54974236
题目连接:http://www.ifrog.cc/acm/problem/1084
----------------------------------------------------------------------------------------------------------.
A – Check-in Problem
Time Limit:5s Memory Limit:128MByte
Submissions:921 Solved:55
DESCRIPTION
A positive integer x is called p-bizarre number if the number of the divisors of x is p exactly.
Your task is testing whether the given positive integer n is a p-bizarre number or not.
INPUT
The first line contains a positive integer T, which represents there are T test cases.
The following is test cases. For each test case:
The only one line contains a positive integer n and an odd prime p.
1≤T≤10^5,1≤n≤10^18,2< p≤10^9
OUTPUT
For each test case, output in one line, print “YES” (without quote) if n is a p-bizarre number, print “NO” (without quote) otherwise.
SAMPLE INPUT
3
9 3
971528476274196481 7
150094635296999121 37
SAMPLE OUTPUT
YES
NO
YES
----------------------------------------------------------------------------------------------------------.
题目大意:
就是问你n的因子个数是不是p个
解题思路:
对于一个素数n的因子个数 我们可以对n做算术基本定理展开
那么数的因子个数就是
input里面又说
The only one line contains a positive integer n and an odd prime p.
那么对于p是素数的情况 只能说明n的质因子只有一种,
因为上述,所以我想到以对1e6(因为题目说p最小是3,n最大是10^18,所以1e6就够了)内的素数筛法取一遍,然后二分寻找答案即可注意会爆LL ,但是无论怎么控制溢出,最后代码写成了这样但是还是WA…心塞…
献上官方题解
注意到 是质数,只有当 是质数的 $p−1 $次幂时, 的约数才可能恰好有 个,所以判定一个正整数 是 奇异数,只需检验 是整数,且 是质数。预处理 以内的素数(共 个),进行开根和判断素数即可,时间复杂度$ O\left(\dfrac {\sqrt n}{ \ln n}\right) $。
事实上 的情况很少有解,直接预处理所有有解的情况即可,可以防止写出有问题的开根,而 的判断素数也可以用 Miller-Rabin 算法判定(需要 的模乘法)。
改了2个小时的溢出,最后都没签到。。。。。。
献上标程一枚
----------------------------------------------------------------------------------------------------------.
1 | # include <cmath> |
2017-02-10 16:24:08 Tabris_ 阅读数:184
博客爬取于2020-06-14 22:41:43
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54971709
题目链接:https://vjudge.net/problem/HUST-1588
--------------------------------------------------------------------------------------------------------.
1588 - 辗转数对
时间限制:1秒 内存限制:128兆
139 次提交 23 次通过
题目描述
假设当前有一个数对(a, b),我们可以通过一步将这个数对变为一个新数对(a + b, b)或者是(a, a + b)。
初始的数对为(1, 1),你的任务是找到一个数字k,即通过最少的步数使得这个数对中至少一个数字等于n。
输入
输入包括多组数据,每组数据包括一行,每行有一个整数n。
输出
每组数据输出一行,每行一个整数n。
样例输入
5
3
样例输出
3
0
提示
第一个样例的方法是 (1,1) → (1,2) → (3,2) → (5,2),共3步。
来源
--------------------------------------------------------------------------------------------------------.
解题思路:
这个题不难发现,对于我们累加出来的(a,b)一定是互质的
然后想到Gcd(x,y)过程中的x,y就是要保证互质一直处理下去的
那么其实就是在问gcd过程中x%y要减多少次
那么接下来我们枚举终点(i,n)维护最小值即可
附本题代码
--------------------------------------------------------------------------------------------------------.
1 | int ans; |
2017-02-10 14:11:00 Tabris_ 阅读数:751
博客爬取于2020-06-14 22:41:44
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54969932
题目连接:http://www.51nod.com/contest/problem.html#!problemId=1675
-------------------------------------------------------------------------------------------------------.
序列变换
alpq654321 (命题人)
基准时间限制:1 秒 空间限制:131072 KB 分值: 40
lyk有两序列a和b。
lyk想知道存在多少对x,y,满足以下两个条件。
1:gcd(x,y)=1。
2: abx = bay 。
例如若a={1,1,1},b={1,1,1}。那么存在7对,因为除了x=2,y=2或x=3,y=3外都满足条件。
Input
第一行一个数n(1<=n<=100000)。
接下来一行n个数,表示ai(1<=ai<=n)。
接下来一行n个数,表示bi(1<=bi<=n)。
Output
一行表示答案
Input示例
3
1 1 1
1 1 1
Output示例
7
-------------------------------------------------------------------------------------------------------.
本题是在裸求的基础上加上了 的限制,然后我就不会了,
最后看了题解发现是同容斥原理来解决,
结果来说,
然后就引入了莫比乌斯反演
当x,y均满足题意的时候
f(k) 表示gcd(x,y) == k的个数
F(k) 表示gcd(x,y) == k的倍数 的个数
$f(k)=\sum^{n}_{d=1}μ(d)\times F(d) $
那么系数也就是莫比乌斯函数了
附本题代码
-------------------------------------------------------------------------------------------------------.
1 | int n; |
2017-02-09 00:22:39 Tabris_ 阅读数:726
博客爬取于2020-06-14 22:41:45
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54935260
题目连接:http://codeforces.com/contest/766/problem/E
------------------------------------------------------------------------------.
------------------------------------------------------------------------------.
题目大意:
就是在一个生成树上求任意两点的距离的和,距离定义为两点间路上所有点权值的异或和,
解题思路:
想法就是将结果的异或和拆分成每一位的,就是对于二进制数上对于第i位,有多少个距离为1的路径,然后在总结果上即可,这样最多按二进制位数个的搜索一遍树就行了.
cnt[][0]是以u为根0的个数,cnt[][1]同理.
听闻这题还有树分治和树dp的做法,有兴趣可以百度一发.
附本题代码
------------------------------------------------------------------------------.
1 | int a[N],b[N],cnt[N][2]; |
对于对树、图进行dfs的要好好练练 总是搜不明白.
]]>2017-02-08 23:55:44 Tabris_ 阅读数:552
博客爬取于2020-06-14 22:41:46
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54934767
题目连接:http://codeforces.com/contest/766/problem/D
----------------------------------------------------------------------------------------.
D. Mahmoud and a Dictionary
time limit per test4 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Mahmoud wants to write a new dictionary that contains n words and relations between them. There are two types of relations: synonymy (i. e. the two words mean the same) and antonymy (i. e. the two words mean the opposite). From time to time he discovers a new relation between two words.
He know that if two words have a relation between them, then each of them has relations with the words that has relations with the other. For example, if like means love and love is the opposite of hate, then like is also the opposite of hate. One more example: if love is the opposite of hate and hate is the opposite of like, then love means like, and so on.
Sometimes Mahmoud discovers a wrong relation. A wrong relation is a relation that makes two words equal and opposite at the same time. For example if he knows that love means like and like is the opposite of hate, and then he figures out that hate means like, the last relation is absolutely wrong because it makes hate and like opposite and have the same meaning at the same time.
After Mahmoud figured out many relations, he was worried that some of them were wrong so that they will make other relations also wrong, so he decided to tell every relation he figured out to his coder friend Ehab and for every relation he wanted to know is it correct or wrong, basing on the previously discovered relations. If it is wrong he ignores it, and doesn’t check with following relations.
After adding all relations, Mahmoud asked Ehab about relations between some words based on the information he had given to him. Ehab is busy making a Codeforces round so he asked you for help.
Input
The first line of input contains three integers n, m and q (2 ≤ n ≤ 105, 1 ≤ m, q ≤ 105) where n is the number of words in the dictionary, m is the number of relations Mahmoud figured out and q is the number of questions Mahmoud asked after telling all relations.
The second line contains n distinct words a1, a2, …, an consisting of small English letters with length not exceeding 20, which are the words in the dictionary.
Then m lines follow, each of them contains an integer t (1 ≤ t ≤ 2) followed by two different words xi and yi which has appeared in the dictionary words. If t = 1, that means xi has a synonymy relation with yi, otherwise xi has an antonymy relation with yi.
Then q lines follow, each of them contains two different words which has appeared in the dictionary. That are the pairs of words Mahmoud wants to know the relation between basing on the relations he had discovered.
All words in input contain only lowercase English letters and their lengths don’t exceed 20 characters. In all relations and in all questions the two words are different.
Output
First, print m lines, one per each relation. If some relation is wrong (makes two words opposite and have the same meaning at the same time) you should print “NO” (without quotes) and ignore it, otherwise print “YES” (without quotes).
After that print q lines, one per each question. If the two words have the same meaning, output 1. If they are opposites, output 2. If there is no relation between them, output 3.
See the samples for better understanding.
Examples
input
3 3 4
hate love like
1 love like
2 love hate
1 hate like
love like
love hate
like hate
hate like
output
YES
YES
NO
1
2
2
2
input
8 6 5
hi welcome hello ihateyou goaway dog cat rat
1 hi welcome
1 ihateyou goaway
2 hello ihateyou
2 hi goaway
2 hi hello
1 hi hello
dog cat
dog hi
hi hello
ihateyou goaway
welcome ihateyou
output
YES
YES
YES
YES
NO
YES
3
3
1
1
2
----------------------------------------------------------------------------------------.
题目大意:
就是有n个单词,有m个关系,q个查询,
关系是两个单词是同义词还是反义词,对于当前的这条关系如果与前述关系不符则忽略,
查询是两个单词之间的关系是同义词还是反义词还是未知.
解题思路:
很好想到并查集来维护同义词,然后用另一个数组怎样的表示两堆之间的反义词关系,
最开始是想对每堆进行染色,两个堆中一个染成+n,另一个染成-n,加和为零表示敌对关系,然后可以在维护一个并查集或者怎样 ,但是最后GG了
看了题解 发现用另一个数组来维护本堆的反义词的堆是哪一个,真是奥妙重重。666
这样的话 这个题目就简单清晰多了,直接维护就行了。
注意对于m条关系的判定时的细节就好了,详见代码。
附本题代码
----------------------------------------------------------------------------------------.
1 | int n,m,q,op; |
2017-02-08 22:42:09 Tabris_ 阅读数:499
博客爬取于2020-06-14 22:41:47
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54934055
题目连接:http://codeforces.com/contest/766/problem/C
-----------------------------------------------------------------------.
C. Mahmoud and a Message
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Mahmoud wrote a message s of length n. He wants to send it as a birthday present to his friend Moaz who likes strings. He wrote it on a magical paper but he was surprised because some characters disappeared while writing the string. That’s because this magical paper doesn’t allow character number i in the English alphabet to be written on it in a string of length more than ai. For example, if a1 = 2 he can’t write character ‘a’ on this paper in a string of length 3 or more. String “aa” is allowed while string “aaa” is not.
Mahmoud decided to split the message into some non-empty substrings so that he can write every substring on an independent magical paper and fulfill the condition. The sum of their lengths should be n and they shouldn’t overlap. For example, if a1 = 2 and he wants to send string “aaa”, he can split it into “a” and “aa” and use 2 magical papers, or into “a”, “a” and “a” and use 3 magical papers. He can’t split it into “aa” and “aa” because the sum of their lengths is greater than n. He can split the message into single string if it fulfills the conditions.
A substring of string s is a string that consists of some consecutive characters from string s, strings “ab”, “abc” and “b” are substrings of string “abc”, while strings “acb” and “ac” are not. Any string is a substring of itself.
While Mahmoud was thinking of how to split the message, Ehab told him that there are many ways to split it. After that Mahmoud asked you three questions:
How many ways are there to split the string into substrings such that every substring fulfills the condition of the magical paper, the sum of their lengths is n and they don’t overlap? Compute the answer modulo 109 + 7.
What is the maximum length of a substring that can appear in some valid splitting?
What is the minimum number of substrings the message can be spit in?
Two ways are considered different, if the sets of split positions differ. For example, splitting “aa|a” and “a|aa” are considered different splittings of message “aaa”.
Input
The first line contains an integer n (1 ≤ n ≤ 103) denoting the length of the message.
The second line contains the message s of length n that consists of lowercase English letters.
The third line contains 26 integers a1, a2, …, a26 (1 ≤ ax ≤ 103) — the maximum lengths of substring each letter can appear in.
Output
Print three lines.
In the first line print the number of ways to split the message into substrings and fulfill the conditions mentioned in the problem modulo 109 + 7.
In the second line print the length of the longest substring over all the ways.
In the third line print the minimum number of substrings over all the ways.
Examples
input
3
aab
2 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
output
3
2
2
input
10
abcdeabcde
5 5 5 5 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
output
401
4
3
Note
In the first example the three ways to split the message are:
a|a|b
aa|b
a|ab
The longest substrings are “aa” and “ab” of length 2.
The minimum number of substrings is 2 in “a|ab” or “aa|b”.
Notice that “aab” is not a possible splitting because the letter ‘a’ appears in a substring of length 3, while a1 = 2.
-----------------------------------------------------------------------.
题目大意:
一个长度为n的仅含26小字母的字符串,要将其按要求分割成几段,其中26种字母只能在长度为Ax的字串中,问你划分的种类数是多少,字串的长度最长是多少,划分出来的字符串个数最少是多少,
解题思路:
还是dp
对于子串中以第i个字符为止时,我们可以将其划分到 $ \in \left[ i-A_i+1,i \right]$的位置上,我们从这个位置向前寻找,一次次判断就行了…
同时就能维护字串的最长长度了
字串的最少个数在一次次向前找中,维护最小值即可.
详见代码及注释
附本题代码
-----------------------------------------------------------------------.
1 | int a[30]; |
2017-02-08 10:59:08 Tabris_ 阅读数:267
博客爬取于2020-06-14 22:41:48
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54924305
题目读的懵逼,。。。水题还卡,难题不会。。。。GG
水签到题,
注意等时计费是要转化为每分钟几毛钱计算
首先明确题意,然后用set暴力来就行了
其实就是树的同构,但是实在不知道该如何判断,
最后看了题解发现,hash每棵树就好了,将每一样的数用一个整数表示出来,两遍dfs就好.
详解戳这里
D题也是签到题
注意数组开大些就好了
这道题有点复杂,单开了一贴
请戳这里
只知道dp能做,但是dp废…来日再补…
好难想啊 ,最开始真的想二分了,最后看了题解才知道是个线段树…
详解链接戳这里
这是上一题的简化版本,因为数据量太小直接枚举既可,
一套题出这样的两道题是要闹哪样…
未补待续
就是求a对m的逆元
入门难度题,注意逆元不要为0就好了
签到题,
明确题意,枚举3中情况就好了
不是题目太难,只是自己太菜,路漫漫,加油吧,,,
]]>2017-02-07 18:40:56 Tabris_ 阅读数:297
博客爬取于2020-06-14 22:41:49
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54914010
!!! 摘自
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3604
---------------------------------------------------------------------------------------------------.
Tunnel Network
Time Limit: 2 Seconds Memory Limit: 65536 KB
Country Far-Far-Away is a big country with N cities. But it is now under a civil war. The rebel uses the ancient tunnel network which connects all N cities with N-1 inter-city tunnels for transportation. The government army want to destroy these tunnels one by one. After several months fighting, some tunnels have been destoryed. According to the intel, the tunnel network have excatly S connected components now. And what government army further knows is that city 1, 2, … , S belong to each of the S connected components. Since the government have little knowledge about the remaining tunnels, they ask you to calculate the number of possible networks of remaining tunnels.
Input
There are multiple test cases. The first line of input contains an integer T (T ≤ 500) indicating the number of test cases. Then T test cases follow.
Each case contains one line containing two integer N (2 ≤ N ≤ 2000) and S (2 ≤ S ≤ N), as described above.
Output
The number of possible networks now. Since the number might be very large, you should output the answer after modulo 1000000007.
Sample Input
4
3 2
4 2
5 3
100 50
Sample Output
2
8
15
113366355
---------------------------------------------------------------------------------------------------.
题目大意:n个城市(标记1…n)由n-1条通道组成,其中的一些通道已经被破坏了,已知现有s个联通,城市1…s分别属于第1…s个联通,想要知道剩下通道网络可能的数目。
解题思路:
Prüfer编码与Cayley公式 from matrix67
明确了上述公式就简单了.
首先要知道Prufer sequence.这是一个双射,能把一棵节点为n个的标号树树唯一映射成一个n-2的序列,反之一个n-2的序列能唯一映射成一个树。这题求树的形态数目可以转化为求序列的数目。
因为是要得到s棵树,所以可以增加一个节点0,让1…s的父节点都为0。Prufer seq是每次找最小的标号,这里每次找最大的标号,本质一样的。
然后就是构造将s+1…n添加到1…s之后的事情。构造如下的图的树:
但是要如何保证构造出来的序列能映射成根为0,第一层为1…s , 剩下的为 s+1…n 呢?
1、序列最后s-1个数字为0,
2、倒数第s个数字在1…s之间
第一个理由是很容易想的。因为我们构造的Prufer seq每次找最大标号的叶子(度为1)节点,所以在第一层的叶子被消去之前第一层以下的所有节点一定会被消去。而1…s的父节点都是0
第二个的话要一点证明:
假如第一层存在一个最大值x(x>s),那么第一层一下存在一个y(1<=y<=s)。
因为最后s-1个数字都为0,所以x是在y之后被消去的。
假如y的父节点是x:
因为y比第一层之下所有节点标号都大,所以必定是第一层一下所有节点中最后消去的,所以序列倒数第s个数字为x,大于s
假如y的父节点不是x:
那么第一层一下最后一个消去的节点还是x的子节点(条件1)。所以倒数第s个数字还是x,大于s
结论: 若第一层中存在最大数字x大于s,则序列的倒数第s个数字必定为x。
所以第二条也是成立的。
然后构造序列就很简单了最后s-1个数字都为0,倒数第s个为1…s,剩下为1…n。
公式 : s*n^(n-s-1)
不过当s=n的时候答案为1要另外处理,因为第一层下面没有东西了。
附本题代码
---------------------------------------------------------------------------------------------------.
1 | LL qmod(LL a,LL b){ |
2017-02-06 22:31:40 Tabris_ 阅读数:256
博客爬取于2020-06-14 22:41:51
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54897814
题目连接:http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=347
套题是真TM酸爽。
英语题 特别复杂的模拟 注意细节 细节 细节 细节 细节 。。。。
签到题 直接暴力就好了
理解题意,首先x很明显要求个逆元,因为m不是素数,所以只好用扩展欧几里德求了,
对于S[n] 是很明显的fibonacci数列(S[n]=fib[n+2] ),枚举两个就出来了,别忘了还有空集…
然后就不会了,
最后才知道fibonacci的一个性质
1.
证明:可以通过反证法先证fibonacci数列的任意相邻两项一定互素,然后可证时,递归可求,最后,不然继续递归。是通过展转相减法求出,易证,所以。
所以只有当 gcd(n,m)=1或2时(fib[1]==fib[2]==1) fib[n]与fib[m]互质
所以若S[n] 要是一个 PrimeS
则n+2必须是一个质数或者4 ,自己画画就知道为什么4是特殊的了
所以构造一个特殊的素数表
P[i] 3 4 5 7 11 13…
所以第K个PrimeS 就是fib[P[k]]
还有一个结论:
计算 其中b能整除a
如果b与c互素,则
如果b与c不互素,则
对于b与c互素和不互素都有成立
就是枚举出能够整除x的PrimeS 用快速幂求取PrimeS
最后计算 就好了 注意下可能会爆int就好了
明白题意让求的是去掉平行线后,线与节点数的比值就好了
签到题 暴力做
不会 还找不到题解…
这个题比较6
确定题意后,直接暴力加边就好了,直到不能在加边为止
看题解是个dp 然而dp废。。。。
来日在补
签到题 明白题意直接做就好了,
阅读题 明白题意 直接处理就好了
签到题 找环上和最大的长度为k的连续区间, 前缀和处理然后枚举即可.
题面比较有意思,一群幼儿园同学要投票选个老大,(不能选自己),每个人都有一个心仪的老大目标,然后1号小朋友要当老大,可以拿糖贿赂其他小朋友来确保自己当老大。问1号小朋友最少需要多少个糖果能确保自己当上老大。
枚举加贪心,
枚举1号小朋友当上老大时的票数,然后贪心选择贿赂谁,维护下结果的就行了。
题目不难,就是不好想到枚举,想直接进行贪心,然后就会各种GG
最后发现这套题是之前省选训练过的题…
总结:
英语读题水平太菜,
模拟水平太差,
代码能力有待加强
思维不够开阔,胆子不够大,至少暴力的想法是有的 但是却不敢写.
写代码的速度可以放慢些,写快了细节上出错率大.
2017-02-06 00:21:44 Tabris_ 阅读数:587
博客爬取于2020-06-14 22:41:52
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54885329
题目连接:http://codeforces.com/problemset/problem/763/B
-------------------------------------------------------------------------------------------.
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
One of Timofey’s birthday presents is a colourbook in a shape of an infinite plane. On the plane n rectangles with sides parallel to coordinate axes are situated. All sides of the rectangles have odd length. Rectangles cannot intersect, but they can touch each other.
Help Timofey to color his rectangles in 4 different colors in such a way that every two rectangles touching each other by side would have different color, or determine that it is impossible.
Two rectangles intersect if their intersection has positive area. Two rectangles touch by sides if there is a pair of sides such that their intersection has non-zero length
The picture corresponds to the first example
Input
The first line contains single integer n (1 ≤ n ≤ 5·105) — the number of rectangles.
n lines follow. The i-th of these lines contains four integers x1, y1, x2 and y2 ( - 109 ≤ x1 < x2 ≤ 109, - 109 ≤ y1 < y2 ≤ 109), that means that points (x1, y1) and (x2, y2) are the coordinates of two opposite corners of the i-th rectangle.
It is guaranteed, that all sides of the rectangles have odd lengths and rectangles don’t intersect each other.
Output
Print “NO” in the only line if it is impossible to color the rectangles in 4 different colors in such a way that every two rectangles touching each other by side would have different color.
Otherwise, print “YES” in the first line. Then print n lines, in the i-th of them print single integer ci (1 ≤ ci ≤ 4) — the color of i-th rectangle.
Example
input
8
0 0 5 3
2 -1 5 0
-3 -4 2 -1
-1 -1 2 0
-3 0 0 5
5 2 10 3
7 -3 10 2
4 -2 7 -1
output
YES
1
2
2
3
2
2
4
1
-------------------------------------------------------------------------------------------.
题目大意:
就是在一个二维平面上有n个矩形,现在让你给这n个矩形4种涂色之一,使得相邻的矩形颜色不同.
(矩形的两条边都是整数)
解题思路:
我这种智障是做不出来的,本来并不想写题解,但是无意中看了Tutorial中的discuss发现一个特别容易理解的.
We may assume that our rectangles are drawn on an infinite sheet of squared paper. Divide it into squares 2 × 2 and mark the cells in each square by 1, 2, 3, 4 clockwise starting from the upper left corner. Since both sides of each rectangle are of odd length, its corner cells are marked by the same number. Let us number four different colors by 1, 2, 3, 4 and paint each rectangle with the color whose number marks the corner cells. It is readily seen that the numbers in the corners of any two adjacent rectangles are distinct.
我们可能会认为我们的矩形被画在无限平方的纸。将纸分成一个个2×2方块,然后从左上角顺时针方向开始标上1,2,3,4(代表颜色)。由于每个矩形的两边都是奇数长度,所以它的所有格子标记为相同的数。让我们用1,2,3,4个不同的颜色编号,并绘制每个矩形的颜色的数字标记的格子。很容易看出,任何两个相邻矩形的角的数是不同的。
(基本是机翻…可以自己画一画就容易理解了,Orz)
附本题代码
-------------------------------------------------------------------------------------------.
1 | int main(){ |
2017-02-02 23:26:20 Tabris_ 阅读数:251
博客爬取于2020-06-14 22:41:53
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54838954
浪费生命 啊
以后还是消停的一套一套的套题起刷吧 , 盲目刷题起得那是反作用啊。
]]>2017-02-01 16:40:41 Tabris_ 阅读数:218
博客爬取于2020-06-14 22:41:54
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54809490
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5818
---------------------------------------------------------------------------.
I 2017 口碑商家客流量预测大赛》
Joint Stacks
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1522 Accepted Submission(s): 709
Problem Description
A stack is a data structure in which all insertions and deletions of entries are made at one end, called the “top” of the stack. The last entry which is inserted is the first one that will be removed. In another word, the operations perform in a Last-In-First-Out (LIFO) manner.
A mergeable stack is a stack with “merge” operation. There are three kinds of operation as follows:
After an operation “merge A B”, stack A will obtain all elements that A and B contained before, and B will become empty. The elements in the new stack are rearranged according to the time when they were pushed, just like repeating their “push” operations in one stack. See the sample input/output for further explanation.
Given two mergeable stacks A and B, implement operations mentioned above.
Input
There are multiple test cases. For each case, the first line contains an integer N(0< N≤105), indicating the number of operations. The next N lines, each contain an instruction “push”, “pop” or “merge”. The elements of stacks are 32-bit integers. Both A and B are empty initially, and it is guaranteed that “pop” operation would not be performed to an empty stack. N = 0 indicates the end of input.
Output
For each case, print a line “Case #t:”, where t is the case number (starting from 1). For each “pop” operation, output the element that is popped, in a single line.
Sample Input
4
push A 1
push A 2
pop A
pop A
9
push A 0
push A 1
push B 3
pop A
push A 2
merge A B
pop A
pop A
pop A
9
push A 0
push A 1
push B 3
pop A
push A 2
merge B A
pop B
pop B
pop B
0
Sample Output
Case #1:
2
1
Case #2:
1
2
3
0
Case #3:
1
2
3
0
---------------------------------------------------------------------------.
题目大意
就是有三种操作,
对于pop的时候直接pop当前栈就行了,如果栈是空的话 那么我们就对栈C pop就行了。因为输入数据均为合法数据,不会对空栈进行pop操作,所以正确性是有保证的。
最后注意一下输入就行了。
附本题代码
---------------------------------------------------------------------------.
1 | char op[20],ch,hc; |
2017-01-29 23:14:26 Tabris_ 阅读数:240
博客爬取于2020-06-14 22:41:55
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54780836
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869
---------------------------------------------------------------------------------------------------------.
Different GCD Subarray Query
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1172 Accepted Submission(s): 444
Problem Description
This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Divisor). After studying some of them, Bob thinks that GCD is so interesting. One day, he comes up with a new problem about GCD. Easy as it looks, Bob cannot figure it out himself. Now he turns to you for help, and here is the problem:
Given an array a of N positive integers a1,a2,⋯aN−1,aN; a subarray of a is defined as a continuous interval between a1 and aN. In other words, ai,ai+1,⋯,aj−1,aj is a subarray of a, for 1≤i≤j≤N. For a query in the form (L,R), tell the number of different GCDs contributed by all subarrays of the interval [L,R].
Input
There are several tests, process till the end of input.
For each test, the first line consists of two integers N and Q, denoting the length of the array and the number of queries, respectively. N positive integers are listed in the second line, followed by Q lines each containing two integers L,R for a query.
You can assume that
1≤N,Q≤100000
1≤ai≤1000000
Output
For each query, output the answer in one line.
Sample Input
5 3
1 3 4 6 9
3 5
2 5
1 5
Sample Output
6
6
6
Source
2016 ACM/ICPC Asia Regional Dalian Online
---------------------------------------------------------------------------------------------------------.
题目大意:
给长度为N的序列,M次询问,每次询问【L,R】之间所有子区间的不同GCD有多少个、
解题思路:
固定左端点,然后离线预处理出结果,用树状数组或者线段树均可。
首先预处理出每一个查询右区间位置渐近到达1位置的所有gcd的结果,这个结果显然是单调递减的,且不超过
个数的, 这个显然很好想…
然后在采取更新数值,
将每一个新旧的gcd更新到树状数组即使的最靠右的位置(+1,-1),即可,每一次查询的时候 就直接在树状数组查询区间里的个数就行了.
然后vis[1e6]居然RE。。。。最后改了map才过、
时间复杂度
附本题代码
---------------------------------------------------------------------------------------------------------.
1 |
|
2017-01-26 21:45:01 Tabris_ 阅读数:473
博客爬取于2020-06-14 22:39:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54746580
#图
二维数组 map[i][j] 表示i到j的边 值为边得大小 ,定义一个值代表不存在这条边 一般为0
空间复杂度
vector
G[i][j] 表示有一条i->j的有向边
1 | void add(int u,int v){ |
空间复杂度
1 | struct edge{ |
空间复杂度
不解释
1 | vector<pair<int ,int > >G[N]; |
1 | LL d[N]; |
1 | vector<int>G[N]; |
算法介绍
最大匹配数:最大匹配的匹配边的数目
最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择
最大独立数:选取最多的点,使任意所选两点均不相连
最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。
定理1:最小点覆盖数 = 最大匹配数(这是 Konig 定理)
定理2:最大独立数 = 顶点数 - 最大匹配数
定理3:最小路径覆盖数 = 顶点数 - 最大匹配数
匈牙利算法求解二分图匹配问题
1 | int k,n,m; |
2-SAT
强联通分量一个很重要的用途就是解布尔方程可满足性问题(SAT)。需要学习这一部分知识我们需要一点布尔代数的知识。
下文中我们约定(^表示交v表示并)
例如:(a v b v …)^(c v d v …)^…
这样的我们叫做合取范式。其中(a v b v …)这样的叫做子句。类似a,b…叫做文字。
我们把合取范式中一个子句中包含文字不超过两个的问题成为2-SAT问题。在SAT问题中只有这一类我们可以用线性时间内得出答案。
最常规的2-SAT题目分为大致两种,一种是让你判断有没有解,另一种是让你输出一组解。针对这两种给出模版。
在这之前先来介绍一下2-SAT题目的大致解题步骤:
对于2-SAT问题我们需要构建一张有向图每个文字拆为两个节点 例如 a 变为 a, !a
首先我们从题目中总结出来的都是一些比较杂乱的逻辑表达式,不过一般都是两两之间的关系,我们需要做的第一步是化简成用^连接。然后对于每个子句建边。
建边的规则是这样的 a -> b那么在有向图中建一条a到b的边
我们可能得到的子句有:
a v b 我们可以化简 !a->b ^ !b->a
a -> b 直接连边
a 转化为!a -> a
其中每个文字及其的非对应相应的结点,若是出现在文字前有非的关系例如 !a v b 那么变通一下 就化成 a -> b ^ !b -> !a就可以了。
到这里我们要做的事(建图)就完成了,接下来交给模版,我们来看一下模版做了什么:
首先我们对建完的有向图求强连通分支,若是出现有一个逻辑变量和他的反在同一个联通分之内就无解,否则有解。
若a所在的强连通分支的拓扑序在!a之后a为真,否则为反。怎么样很简单吧。
1 |
|
1 | const int MAXN = 210; |
树被定义为没有圈的连通图,具有以下几个性质:
树的直径(Diameter)是指树上的最长简单路。
直径的求法:两遍搜索 (BFS or DFS)
任选一点w为起点,对树进行搜索,找出离w最远的点u。
以u为起点,再进行搜索,找出离u最远的点v。则u到v的路径长度即为树的直径。
树的重心:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
树的重心可以通过简单的两次搜索求出,第一遍搜索求出每个结点的子结点数量son[u],第二遍搜索找出使max{son[u],n-son[u]-1}最小的结点。
实际上这两步操作可以在一次遍历中解决。对结点u的每一个儿子v,递归的处理v,求出son[v],然后判断是否是结点数最多的子树,处理完所有子结点后,判断u是否为重心。
1 | 例题 1655 |
2017-01-26 21:31:23 Tabris_ 阅读数:194
博客爬取于2020-06-14 22:41:56
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54746352
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5943
--------------------------------------------------------------------------------------.
Kingdom of Obsession
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 789 Accepted Submission(s): 215
Problem Description
There is a kindom of obsession, so people in this kingdom do things very strictly.
They name themselves in integer, and there are n people with their id continuous (s+1,s+2,⋯,s+n) standing in a line in arbitrary order, be more obsessively, people with id x wants to stand at yth position which satisfy
xmody=0
Is there any way to satisfy everyone’s requirement?
Input
First line contains an integer T, which indicates the number of test cases.
Every test case contains one line with two integers n, s.
Limits
1≤T≤100.
1≤n≤109.
0≤s≤109.
Output
For every test case, you should output ‘Case #x: y’, where x indicates the case number and counts from 1 and y is the result string.
If there is any way to satisfy everyone’s requirement, y equals ‘Yes’, otherwise y equals ‘No’.
Sample Input
2
5 14
4 11
Sample Output
Case #1: No
Case #2: Yes
Source
2016年中国大学生程序设计竞赛(杭州)
--------------------------------------------------------------------------------------.
题目大意:
现在有N个人分别标号为现在要在这些位置上按照下列要求给这N个人串个座位,使得每个人的座位号整除标号.问你有没有可行方案.
解题思路:
很明显,区间中只能有一个素数,要坐在1的位置上,其余地方都不行.
然后查了一下素数间隔,最大的素数间隔只有777.那么就是N>777的时候都是NO,
这样的话就可以大数据直接NO,小数据在考虑了,
特别考虑的就是当S< N的时候可以直接放到本位置,那么只需要考虑这些数就好了,将S,N互换一下即可。
每个标号能做的位置是固定的,那么将人和位置分开就是一个二分图了,接着对二分图进行完美匹配就好了.
附本题代码
--------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-24 17:26:37 Tabris_ 阅读数:305
博客爬取于2020-06-14 22:41:57
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54709231
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5726
-----------------------------------------------------------------------.
GCD
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3164 Accepted Submission(s): 1146
Problem Description
Give you a sequence of N(N≤100,000) integers : a1,…,an(0 < ai≤1000,000,000). There are Q(Q≤100,000) queries. For each query l,r you have to calculate gcd(al,al+1,…,ar) and count the number of pairs(l′,r′)(1≤l< r≤N)such that gcd(al′,al′+1,…,ar′) equal gcd(al,al+1,…,ar).
Input
The first line of input contains a number T, which stands for the number of test cases you need to solve.
The first line of each case contains a number N, denoting the number of integers.
The second line contains N integers, a1,…,an( 0 < ai ≤ 1000,000,000).
The third line contains a number Q, denoting the number of queries.
For the next Q lines, i-th line contains two number , stand for the li,ri, stand for the i-th queries.
Output
For each case, you need to output “Case #:t” at the beginning.(with quotes, t means the number of the test case, begin from 1).
For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,…,ar) and the second number stands for the number of pairs(l′,r′) such that gcd(al′,al′+1,…,ar′) equal gcd(al,al+1,…,ar).
Sample Input
1
5
1 2 4 6 7
4
1 5
2 4
3 4
4 4
Sample Output
Case #1:
1 8
2 4
2 4
6 1
Author
HIT
-----------------------------------------------------------------------.
题目大意:
有一个长度为N的序列,Q次查询,每次查询需求解出及与区间gcd值相同的区间有多少个.
解题思路
首先对与区间gcd 我们可以用线段树或者ST表预处理下,因为没有元素更改,相比之下后者更好(复杂度上,代码量上)
然后就是如何就解与区间gcd值相同的区间有多少个.
这个我们只能枚举一端,然后向右找,然后用个map来存储结果,这样的话复杂度是,显然不可取.
但是对于一个区间上的gcd来说一定是不增的.这样就有了单调性,我们就可以二分做了,但这样需要三层循环解决.,而且在枚举不同端点的时候还会有重复统计的情况.
然后考虑,一个gcd的递减的过程最多也就这能递减因子数个,那么我们每一次记录的就是一种gcd值的区间,然后接下来串过来就好了,
最后的复杂度就是
附本题代码
-----------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-24 13:51:16 Tabris_ 阅读数:283
博客爬取于2020-06-14 22:41:58
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54707350
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5724
-----------------------------------------------------------------------------------.
Chess
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2320 Accepted Submission(s): 985
Problem Description
Alice and Bob are playing a special chess game on an n × 20 chessboard. There are several chesses on the chessboard. They can move one chess in one turn. If there are no other chesses on the right adjacent block of the moved chess, move the chess to its right adjacent block. Otherwise, skip over these chesses and move to the right adjacent block of them. Two chesses can’t be placed at one block and no chess can be placed out of the chessboard. When someone can’t move any chess during his/her turn, he/she will lose the game. Alice always take the first turn. Both Alice and Bob will play the game with the best strategy. Alice wants to know if she can win the game.
Input
Multiple test cases.
The first line contains an integer T(T≤100), indicates the number of test cases.
For each test case, the first line contains a single integer n(n≤1000), the number of lines of chessboard.
Then n lines, the first integer of ith line is m(m≤20), indicates the number of chesses on the ith line of the chessboard. Then m integers pj(1≤pj≤20) followed, the position of each chess.
Output
For each test case, output one line of “YES” if Alice can win the game, “NO” otherwise.
Sample Input
2
1
2 19 20
2
1 19
1 18
Sample Output
NO
YES
Author
HIT
-----------------------------------------------------------------------------------.
题目大意:
就是有n个一维的棋盘,两个人轮流走,每次可以将一个棋子移到距离它最近的右边的空位上。最后谁不能移动棋子了就输了。
解题思路
题目中给定的每一维的状态可以用长度为20的二进制数表示,1为有棋子,0为没有棋子。
表示出来之后可以转移出每种状态的后继状态求出对应的SG值,最后将N个SG值异或一下就好了。
在每一次移动的时候对应的二进制数都会变小,所以从1->(1<<20)预处理一下结果就好了.
开始写的记忆化搜索的形式怎么都是WA,后来改了一发预处理就AC了.
附本题代码
-----------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-23 21:38:29 Tabris_ 阅读数:662
博客爬取于2020-06-14 22:41:59
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54695958
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3949
--------------------------------------------------------------------------------.
碑商家客流量预测大赛》
XOR
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2533 Accepted Submission(s): 858
Problem Description
XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A XOR B, then for each bit of C, we can get its value by check the digit of corresponding position in A and B. And for each digit, 1 XOR 1 = 0, 1 XOR 0 = 1, 0 XOR 1 = 1, 0 XOR 0 = 0. And we simply write this operator as ^, like 3 ^ 1 = 2,4 ^ 3 = 7. XOR is an amazing operator and this is a question about XOR. We can choose several numbers and do XOR operatorion to them one by one, then we get another number. For example, if we choose 2,3 and 4, we can get 2^3^4=5. Now, you are given N numbers, and you can choose some of them(even a single number) to do XOR on them, and you can get many different numbers. Now I want you tell me which number is the K-th smallest number among them.
Input
First line of the input is a single integer T(T<=30), indicates there are T test cases.
For each test case, the first line is an integer N(1<=N<=10000), the number of numbers below. The second line contains N integers (each number is between 1 and 10^18). The third line is a number Q(1<=Q<=10000), the number of queries. The fourth line contains Q numbers(each number is between 1 and 10^18) K1,K2,…KQ.
Output
For each test case,first output Case #C: in a single line,C means the number of the test case which is from 1 to T. Then for each query, you should output a single line contains the Ki-th smallest number in them, if there are less than Ki different numbers, output -1.
Sample Input
2
2
1 2
4
1 2 3 4
3
1 2 3
5
1 2 3 4 5
Sample Output
Case #1:
1
2
3
-1
Case #2:
0
1
2
3
-1
Hint
If you choose a single number, the result you get is the number you choose.
Using long long instead of int because of the result may exceed 2^31-1.
Author
elfness
--------------------------------------------------------------------------------.
题目大意:
就是给你长度为N的学列,有Q次查询,每次查询这写序列中能异或出来的第k小的值
解题思路
本题是一个线性基的入门题。
线性基的介绍或者参考2014国家集训队论文《浅谈线性相关》
其实线性基的求解过程就是一个高斯消元,它构建了一个二维的空间,N*bits这么大,
通过列与列相消,求解出基向量也就是空间的极大无关组,通过这几个元素能得到含盖空间中所有元素的无关组.
本题求的就是这个无关组能构建出来的第K小的值.
求这个值我们可以类比最理想情况下的无关组,
1 0 0 0 0 0 … 0
0 1 0 0 0 0 … 0
0 0 1 0 0 0 … 0
0 0 0 1 0 0 … 0
0 0 0 0 1 0 … 0
0 0 0 0 0 1 … 0
…
0 0 0 0 0 0 … 0
那么对于第K小的值就是将K二进制展开,第位上为1,就在结果上异或就好了,
至于为什么对呢?
因为是将K二进制展开,而这种特殊数据下,得出的刚好是K,这显然是正确的。
但是无关组不可能都是这么理想的
但这个规律对于普通的情况也是使用的,不太好表述,就是如果其他位上如果有1 的话,对于异或出来的结果的集合中的顺序是不影响的。 可以写两个数据验证一下,,,
附本题代码
--------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-22 13:52:08 Tabris_ 阅读数:308
博客爬取于2020-06-14 22:42:00
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54668103
题目链接:http://codeforces.com/contest/382/problem/B
----------------------------------------------------------------------------------------------------.
B. Number Busters
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Arthur and Alexander are number busters. Today they’ve got a competition.
Arthur took a group of four integers a, b, w, x (0 ≤ b < w, 0 < x < w) and Alexander took integer с. Arthur and Alexander use distinct approaches to number bustings. Alexander is just a regular guy. Each second, he subtracts one from his number. In other words, he performs the assignment: c = c - 1. Arthur is a sophisticated guy. Each second Arthur performs a complex operation, described as follows: if b ≥ x, perform the assignment b = b - x, if b < x, then perform two consecutive assignments a = a - 1; b = w - (x - b).
You’ve got numbers a, b, w, x, c. Determine when Alexander gets ahead of Arthur if both guys start performing the operations at the same time. Assume that Alexander got ahead of Arthur if c ≤ a.
Input
The first line contains integers a, b, w, x, c (1 ≤ a ≤ 2·109, 1 ≤ w ≤ 1000, 0 ≤ b < w, 0 < x < w, 1 ≤ c ≤ 2·109).
Output
Print a single integer — the minimum time in seconds Alexander needs to get ahead of Arthur. You can prove that the described situation always occurs within the problem’s limits.
Examples
input
4 2 3 1 6
output
2
input
4 2 3 1 7
output
4
input
1 2 3 2 6
output
13
input
1 1 2 1 1
output
0
----------------------------------------------------------------------------------------------------.
题目大意:
就是两个人,一个人有4个数字,另一个人有1个数字,每一秒第二个人的数字减一c--
,每一秒第一个人的数字变化如下,if(b>=x) b=b-x;else a--,b=w-(x-b);
现在问你最少多长时间之后a<=c?
解题思路:
很明显的二分答案,但是对于check
部分还是要推敲一下,
首先if(b>=x) b=b-x;else a--,b=w-(x-b);
可以改变成 if(b>=x) b=b-x;else a--,b=b-x+w;
显然就是 在b<0的时候将+w,与此同时a–,
那么在c减少n的时候a减少的数m就满足 b=b-nx+mw&&b>0,(m取最小值);
与此同时注意a,c可能小于0,所以二分答案的边界要大一点.
附本题代码
----------------------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-22 10:51:55 Tabris_ 阅读数:341
博客爬取于2020-06-14 22:42:02
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54667131
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6012
----------------------------------------------------------------------------------------.
Lotus and Horticulture Accepts: 91 Submissions: 641
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
问题描述
这几天Lotus对培养盆栽很感兴趣,于是她想搭建一个温室来满足她的研究欲望。
Lotus将所有的nn株盆栽都放在新建的温室里,所以所有盆栽都处于完全相同的环境中。
每一株盆栽都有一个最佳生长温度区间,在这个范围的温度下生长会生长得最好,但是不一定会提供最佳的研究价值(Lotus认为研究发育不良的盆栽也是很有研究价值的)。
Lotus进行了若干次试验,发现若第株盆栽的生长温度适宜,可以提供的研究价值;若生长温度超过了适宜温度的上限,能提供 的研究价值;若生长温度低于适宜温度的下限,则能提供$c_i $ 的研究价值。
现在通过试验,Lotus已经得知了每一株盆栽的适宜生长温度范围,也知道了它们的a、b、c的值。你需要根据这些信息,给温室选定一个温度(这个温度可以是任意实数),使得Lotus能获得的研究价值最大。
输入描述
多组数据,第一行一个整数T表示数据组数
每组数据第一行一个整数,表示盆栽数量
接下来行每行五个整数 .,意义如上所述
输出描述
每组数据输出一行一个整数表示答案
输入样例
1
5
5 8 16 20 12
10 16 3 13 13
8 11 13 1 11
7 9 6 17 5
2 11 20 8 5
输出样例
83
-----------------------------------------------------------------------------------------.
解题思路:
最开始的想法是离散化+线段树,后来想到用树状数组就行了,通过离散化后,将区间进行覆盖,至于小数的时间很好处理,只要将维护的区间值均*2操作就行了,比如说那么维护的时候就维护 这样的话就能空出来一个 ,这样维护就行了.但是最后居然超时了…加了读优还是没有过。。。
然后按照题解的做法写了一发,
官方题解
首先考虑应该尝试选择哪些点:区间的左右端点、与区间左右端点距离0.5的点,这样就一定可以包括所有情况。 为了方便处理与区间左右端点距离0.5的点,只要将所有坐标扩大一倍,然后这些点就变成了“与区间左右端点距离1的点”了 考虑选出这些点后如何进行统计。显然先要将可以选的位置进行离散。假如我们选择的温度一开始是负无穷,这时答案是所有的c之和,考虑选择的温度不断升高,答案会如何变化。 每当选定的温度达到一个区间xx的左端点时,答案加上,每当选定温度超过xx的右端点时,答案会加上 。 维护一个数组v,初始全为0。我们在xx的左端点处加上在xx的右端点处加上,然后某个位置的前缀和就是选择这个位置作为最终温度的答案了。
据说这个东西叫做扫描线?!!(我计算几何白学了hhh),学习一波。。。
其实就是个前缀和处理,然后从左到右扫描而已。
但是写出来还是超时了,当时我离散化的方式的map,于是看了别人写的二分,写了一发二分,这样才过了这道题。。最后 1912ms AC。。。。
附本题代码
-----------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-21 16:26:30 Tabris_ 阅读数:934
博客爬取于2020-06-14 22:42:03
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54646369
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5923
-------------------------------------------------------------------------------.
Prediction
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 693 Accepted Submission(s): 167
Problem Description
There is a graph G=⟨VG,EG⟩ with |VG|=n and |EG|=m, and a magic tree T=⟨VT,ET⟩) rooted at 1, which contains m vertices.
Each vertex of the magic tree corresponds to an edge in the original graph G and each edge occurs in the magic tree exactly once.
Each query includes a set S(S⊆VT), and you should tell Mr. Frog the number of components in the modified graph G‘=(VG,E‘G), where E‘G is a set of edges in which every edge corresponds to a vertex v in magic tree T satisfying at least one of the following two conditions:
∙v∈S.
∙v is an ancestor of some vertices in S.
Note that the queries are independent, and namely one query will not influence another.
Input
The input contains several test cases and the first line of the input data is an integer T, denoting the number of test cases.
For each test case, the first line contains two integers n and m(1≤n≤500,1≤m≤10000), where n is the number of vertices and m is the number of edges.
The second line contains m - 1 integers describing the magic tree, i-th integer represents the parent of the (i + 1)-th vertex.
Then the following m lines describe the edges of the graph G. Each line contains two integers u and v indicating the two ends of the edge.
The next line contains only one integer q(1≤q≤50000), indicating the number of queries.
Then the following q lines represent queries, i-th line represents the i-th query, which contains an integer ki followed by ki integers representing the set Si.
It is guarenteed that
Output
For each case, print a line “Case #x:”, where x is the case number (starting from 1).
For each query, output a single line containing only one integer representing the answer, namely the number of components.
Sample Input
1
5 4
1 1 3
1 2
2 3
3 4
4 5
3
1 2
2 2 3
2 2 4
Sample Output
Case #1:
3
2
1
Hint
magic tree and the original graph in the sample are:
1 | In the first query, S = {2} and the modified graph G' = {{1, 2, 3, 4}, {(1, 2), (2, 3)} }, thus the number of the components in the modified graph is 3. |
-------------------------------------------------------------------------------.
题目大意:
就是有一个n个节点,m条边的图和一个m-1个节点的树(根结点是1)。
树的每个节点对应图的一个边,
每次在树中选中一些节点的集合,就将图中对应集合中所有元素与所有的父节点的边连接起来,问你现在图中有多少个联通块。
解题思路:
对于每一个节点的父节点我们都可以用并查集来处理,这样就能知道在选边的时候都选哪些边了,但是对于直接处理之后我们不能很好的将父节点和子节点相区分开,所以对于每个点的情况,分别做一个并查集,这样的话就能区分父节点和子节点了。
之后在对图进行并查集的操作,来统计有几个联通块就行了。
在处理并查集的时候,对于子节点来说,是满度父节点的集合关系的,所以只要把之前的并查集规则复制一遍,在新处理一下当前节点的就行了。处理过程就是dfs一次树,同时处理并查集 复杂度是
这种算是访问历史版本的并查集应该也算是可持久化并查集了
在每次查询的时候,我们对每个点均处理依次,也只是将跟节点的在一个集合的点放到一个集合.复杂度是
总复杂度就是
附本题代码
-------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-21 11:15:08 Tabris_ 阅读数:260
博客爬取于2020-06-14 22:42:04
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54645157
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5269
----------------------------------------------------------------------------------------.
ZYB loves Xor I Accepts: 142 Submissions: 696
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
问题描述
ZYB喜欢研究Xor,现在他得到了一个长度为nn的数组A。于是他想知道:对于所有数对,
之和为多少.由于答案可能过大,你需要输出答案对998244353取模后的值
定义
,其中k是最小的满足的数
特别地:lowbit(0)=0
输入描述
一共组数据,对于每组数据:
第一行一个正整数n,表示数组长度
第二行n个非负整数,第个整数为
输出描述
每组数据输出一行Case #x: ans。x表示组数编号,从1开始。ans为所求值。
输入样例
2
5
4 0 2 7 0
5
2 6 5 4 0
输出样例
Case #1: 36
Case #2: 40
----------------------------------------------------------------------------------------.
解题思路:
这道题首先想的是用数组处理二进制每一位的0,1的个数,然后进行统计,在处理一下细节,但是最后发现只有在处理二进制下最后一位为1的数才好统计.于是GG
最后看了题解,提到了字典树,顿时茅塞顿开,
我们只要从低位开始插入字典树中,并统计个数,每次统计就是二进制位上和它相反的数的个数*,
边插入边统计就好了.
附本题代码
----------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-18 16:28:55 Tabris_ 阅读数:239
博客爬取于2020-06-14 22:42:05
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54602437
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4417
------------------------------------------------------------------------------.
Super Mario
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6059 Accepted Submission(s): 2635
Problem Description
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss’s castle as a line (the length is n), on every integer point i there is a brick on height hi. Now the question is how many bricks in [L, R] Mario can hit if the maximal height he can jump is H.
Input
The first line follows an integer T, the number of test data.
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
Output
For each case, output "Case X: " (X is the case number starting from 1) followed by m lines, each line contains an integer. The ith integer is the number of bricks Mario can hit for the ith query.
Sample Input
1
10 10
0 5 2 7 5 4 3 8 7 7
2 8 6
3 5 0
1 3 1
1 9 4
0 1 0
3 5 5
5 5 1
4 6 3
1 5 7
5 7 3
Sample Output
Case 1:
4
0
0
3
1
2
0
1
5
1
Source
2012 ACM/ICPC Asia Regional Hangzhou Online
------------------------------------------------------------------------------.
题目大意:
就是给你长度为N个序列,每个序列由一个高度为的木棍,现在有M个询问,问你在[L,R]区间内小于等于H的木棍有多少,即 。
解题思路:
如果题目中没有要求,那么可以直接求[L,R]区间内的数就行了,
很明显,直接在线的话并不能在良好复杂度内解决问题(后来发现是有的只不过我不会。。),离线的话考虑还是很容易的。
首先题目既然要求比h小的,那么我们可以对从小到大排序,每次都将比查询的h小的放入数据结构中,然后在[L,R]查询到的一定满足.这个时候我们同样将查询操作,按照h操作从大到小排序,每次查询的时候我们都将满足的放入数据结构中,这样的话不算查询的复杂度一共是,通过数据结构的优化,查询操作的复杂度就是的。综复杂度就是,
这种查询区间的操作用[树状数组/线段树]都能很好完成,树状数组的话实现相对容易,所以我采用了树状数组.
因为每次查询的时候,计算的数都是的,所以我们不用考虑他的大小,只要在其对应的位置下**+1**就行了,这样每次查询的时候就是查询其查询区间内有几个1即可,最后用一个数组来记录结果就行了.
最后的最后!!!
“Case X:”!!!
它的这里居然没有***“#”***号,我cacacaca,找了800年的bug…
附本题代码
------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-17 18:09:15 Tabris_ 阅读数:216
博客爬取于2020-06-14 22:42:06
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54585519
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4829
--------------------------------------------------------------------------------.
Information
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 367 Accepted Submission(s): 61
Problem Description
军情紧急,我们需要立刻开发出一个程序去处理前线侦察兵发回的情报,并做出相应的分析。现在由你负责其中的一个子模块,你需要根据情报计算出敌方坦克的位置。
当敌方坦克静止时,侦察兵会尽力估算出它们之间的位置,而每当敌方坦克移动时,侦察兵都会记录下坦克新的位置并向你报告。每个坦克的位置可以由一个二维整数坐标来描述。
前线发回的情报有四种格式:
1 A B X Y
表示A坦克移动到了与B坦克的相对位置是(X,Y)的地方,即XA = XB + X, YA=YB+Y。
2 A X Y
表示A坦克移动到了绝对位置是(X,Y)的地方,即XA = X, YA = Y。
3 A B X Y
表示发现了A坦克与B坦克的相对位置是(X,Y),即XA = XB + X, YA=YB+Y。
4 A X Y
表示发现了A坦克的绝对位置是(X,Y),即XA = X, YA = Y。
我们需要你对于如下两种询问及时做出回应:
5 A B
表示询问A坦克与B坦克的相对位置是多少,即分别求出XA - XB 以及YA -YB。
6 A
表示询问A坦克的绝对位置是多少,即求出XA 和YA。
其中A和B代表的是任意的一个坦克的编号,(X,Y)表示了坦克的二维坐标。你可以假设初始时刻我们对于敌方任何坦克的位置都一无所知,在此之后坦克的每一次移动都被侦察兵侦察到了。
请注意两个坦克的坐标有可能相同。
Input
输入的第一行是一个整数T(T < 1000),表示共有T组数据。
对于每组数据,第一行有一个整数N,表示这组数据有N次查询。接下来的每行表示一次查询,每次查询第一个数字代表是哪种询问,询问的格式详见上文。
数据范围:
0 < N <=100000, 0 < A,B<=N 且 A<>B, X和Y都是整数且 0 <=X,Y<=10000 .
测试数据中98%的数据N不超过50。
Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每一个类型(1)或者(2)的询问,请把它们加入到你的记录中。
对于每一个类型(3)或者(4)的询问,如果与之前记录的内容有矛盾,请输出”REJECT”并将这个情报忽略掉,如没有矛盾,请把它们加入到你的记录中。
对于每一个类型(5)或者(6)的询问,如果根据之前的记录能推出结论,请输出两个整数X和Y,两个整数之间有一个空格;如果不能推出结论,请输出”UNKNOWN”。输出的所有信息都不包括引号。
Sample Input
2
7
1 1 2 3 4
2 3 4 5
3 4 5 2 1
4 6 2 2
3 2 4 6 2
5 4 1
6 3
6
6 3
4 3 2 2
6 3
2 4 2 3
5 3 4
3 3 4 1 2
Sample Output
Case #1:
-9 -6
4 5
Case #2:
UNKNOWN
2 2
0 -1
REJECT
Source
2014年百度之星程序设计大赛 - 初赛(第一轮)
--------------------------------------------------------------------------------.
解题思路:
就是维护一堆数据之间的关系,读完题很容易想到带权并查集,权值为两个点之间的相对距离.但是在维护上不是怎么好维护啊。
不好维护的地方
1坦克移动到(x,y)时,那么之前的位置变化产生的相对关系就错了,但是并查集是不可逆向操作的.
2.我们仅表示的相对位置关系,但是对于绝对位置的坐标求解如何考虑.
3,一个点的相对位置比如a相对b的位置是[x,y],但是a,b的位置还不知道的情况下,我们怎么处理这个值.
解决;
1,放弃这个点a,在创建一个新的点p来表示a,映射a->p进行运算即可.
2,我们可以多创建一个点来表示原点(是其他所有点的父节点),那么任何一个点的绝对位置都是与原地的相对位置.
3,假设存在这样的情况,我们可以假设b的坐标是一个随意的值(0,0)就行.
解决了上述几个问题,这道题就不难解决了.
附本题代码
---------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-16 14:50:23 Tabris_ 阅读数:376
博客爬取于2020-06-14 22:42:07
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54574086
转自这里!!!
欧几里得旅行商问题是对平面上给定的n个点确定一条连接各点的最短闭合旅程的问题。图a给出了7个点问题的解,这个问题的一般形式是NP完全的,故其解需要多于多项式的时间。
J.K.Bentley建议通过只考虑双调旅程来简化问题,这种旅程即为从最左点开始,严格从左到最右点,再严格地从最右点回到最左点。图b显示了同样的7个点的问题的最短双调路线,在这种情况下,多项式的时间的算法是有可能的。
描述一个确定最优双调路线的O(n^2)时间的算法。可以假设任何两点的x坐标都不相同。
解法:
读了很多遍这个题,也看了网上好几篇关于这个问题的博客,有很多一部分是错误的却没有更正,于是自己实践整理了一份这个问题的解法。首先最大的疑惑在于理解什么叫做双调(Bitonic),读了很多解释的词条大概了解了双调的用处,我所理解的双调在这道题之中的思路就是将整个闭合的路线一个点展开,因为题中要求的是从左端向右端扫描,再从右端扫描回来。那么不妨将最左端的点作为出发点开始进行计算(从右端完全一致,不再赘述)。
我们需要一个辅助的矩阵a[iLen+1][iLen+1],和所有动态规划问题一样矩阵的大小都是问题的规模+1,整个的计算过程是从左端到右端,也就是我们计算的最短路经从左端向右端生长的过程,辅助矩阵a[i][j]指的是p[i]到p[1]和p[1]到p[i-1]“共通”的最短路径,计算过程只利用矩阵的下三角部分,所以使前一个索引小与后一个索引。首先,将iLen个点存储到一个结构体/类数组之中,用来存放所有的点的坐标,记作数组p,p1,p2之间的距离记作dist(p1,p2)。
核心思想:
1)(前提)当我们计算第i个点或者将它并入最短路径的时候,前1.2.3…i-1个点已经形成了一条最短路径。
2)若要计算a[i][j],新加入的点p[j]的选择分支有三种,也就是路线规划“生长”情况有且只有三种:
(一)当j-1〉i时,根据第(1)条我们需要做的就是在辅助矩阵中已经形成的子最短路径加上新增的边(按定义必然是先添加在更长的那半部分路线)
就有 a[i][j]=a[i][j-1]+dist(j-1,j);
(二)当j-1=i时,就是一次总结前面的子最短路径生成更长的新子最短路径的时候。
表示为 a[i][j]=min{(a[k][j-1]+dist(k,j)) , (a[k-1][j-1])+dist(k-1,j)…}////k为遍历值
(三)当j=i 时,将整个图形封闭起来需要最后的两条边,实质上是(二)过程的一个分支
即 a[i][j]=min{(a[k][j-1]+dist(k,j)+dist(j-1.j))…}/////////k为遍历值
1 | # include<iostream> |
例题
hdu 2224
1 | # include <bits/stdc++.h> |
1 | # include <bits/stdc++.h> |
2017-01-15 23:22:04 Tabris_ 阅读数:410
博客爬取于2020-06-14 22:42:08
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54565617
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2158
--------------------------------------------------------------------------------.
最短区间版大家来找碴
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1173 Accepted Submission(s): 442
Problem Description
给定一个序列,有N个整数,数值范围为[0,N)。
有M个询问,每次询问给定Q个整数,可能出现重复值。
要求找出一个最短区间,该区间要包含这Q个整数数值。
你能找的出来吗?
Input
第一行有两个整数N,M。(N<100000, M<1000)接着一行有N个整数。再有M个询问,每个询问的第一行有一个整数Q(Q<100),第二行跟着Q个整数。当N,M同时为0时,输入结束。
Output
请输出最短区间的长度。保证有解。
Sample Input
5 2
1 2 2 3 1
3
1 2 3
3
1 1 3
0 0
Sample Output
3
2
Hint
第二个查询,找到的区间是[4,5]
Author
Wiskey
Source
2008信息工程学院集训队——选拔赛
---------------------------------------------------------------------------------.
开始想暴力尺取法但是这样的话的话复杂度就变成了O(N*M) 1e8 不可取…
然后想来想去,也想不到有什么复杂度上更优的算法,
最后百度了一发题解,
思路 其实没什么难的,就是在细节上做了改善,使运算量减少了一点罢了,
基本就是先确定一个大概的范围,然后在枚举维护两个区间的界限而已.(心累…)
附本题代码
----------------------------------------------------------。
1 | # include <bits/stdc++.h> |
2017-01-15 21:48:17 Tabris_ 阅读数:258
博客爬取于2020-06-14 22:42:09
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54564954
题目连接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5997
----------------------------------------------------------------.
rausen loves cakes
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
问题描述
rausen喜欢吃蛋糕。某天,他买了nn个蛋糕,每个蛋糕都有一个颜色,用\left[1,1000000 \right][1,1000000]中的整数来表示。rausen将它们从左到右排成一行,然后准备开始吃。
在吃之前,rausen想对蛋糕进行qq个操作。
某些时刻,rausen会把所有颜色为xx的蛋糕替换成颜色为yy的蛋糕。
另一些时刻,rausen会计算一段区间\left[x,y \right][x,y]内颜色的段数,所谓一段颜色,就是指极长的只有一种颜色的区间。例如1 4 4 1 1即为3段颜色。
然而,rausen发现,他并不会统计区间内的颜色段数,无助的rausen伤心地哭了起来(误)。而你为了安慰他,决定帮他解决这个问题。
输入描述
输入包含多组数据。第一行有一个整数TT,表示测试数据的组数,对于每组数据:
第一行输入2个整数nn,qq分别表示蛋糕的数目和操作的数目。
接下来一行nn个正整数,第ii个正整数{a}_{i}a
i
表示第ii个蛋糕的颜色。
接下来qq行,每行3个整数op\left(1\leq op\leq 2 \right)op(1≤op≤2),xx,yy,描述一个操作
对于op=1op=1,表示rausen进行替换操作,将颜色为xx的蛋糕替换成颜色为yy的蛋糕,xx、yy满足\left(1\leq x,y\leq 1000000 \right)(1≤x,y≤1000000),请注意xx可能等于yy。
对于op=2op=2,表示rausen进行计数操作,此时你需要输出区间\left[x,y \right][x,y]内颜色的段数,xx、yy满足\left(1\leq x\leq y\leq n \right)(1≤x≤y≤n)
\left(1\leq T\leq 5 \right)(1≤T≤5),\left(1\leq n\leq {10}^{5} \right)(1≤n≤10
5
),\left(1\leq q\leq {10}^{5} \right)(1≤q≤10
5
)
输出描述
对于每组测试数据的每一个计数操作,单独输出一行表示答案。
输入样例
1
5 3
1 4 4 10 1
2 1 5
1 4 10
2 3 5
输出样例
4
2
----------------------------------------------------------------.
藏了好久终于补了这个,虽然还是感觉有点乱乱的。。。。
首先考虑暴力的把一种颜色替换成另一种颜色,那么这一部分就是
那么考虑将每一种颜色所在的位置记录下来,这样的话就能降到,虽然看着没什么提升,但其实已经提升很大了,
但是考虑如果NUM(x) = n-1,NUM(y)=1,那么直接将x替换为y实在是太浪费了,于是可以将y替换成x,这样的话,运算量将大大减少。而且只需要用一个数组映射就能够实现。(这就是启发式合并了。。。)
用树状数组来维护拐点( 那么就是一个拐点)
那么来统计区间内的颜色段数就是求区间内的拐点个数+左端点是不是拐点。。
维护这个就是简单的树状数组的操作了,不再赘述,其实用线段是也可以维护的,但是线段树的代码量…
代码中有详细点的注释,可以看看…
附本题代码
------------------------------------------------------------。
1 | # include <bits/stdc++.h> |
2017-01-15 16:02:25 Tabris_ 阅读数:155
博客爬取于2020-06-14 22:42:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54562544
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4825
------------------------------------------------------------------------------------.
Xor Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 1803 Accepted Submission(s): 773
Problem Description
Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
Input
输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。
Sample Input
2
3 2
3 4 5
1
5
4 1
4 6 5 6
3
Sample Output
Case #1:
4
3
Case #2:
4
Source
2014年百度之星程序设计大赛 - 资格赛
-------------------------------------------------------------------------------------.
解题思路:
就是用trie树来解决。
为了方便寻找最大的数,那么我们按照从高位到低位的顺序将每一个数字的二进制数依次插入到trie树中,
这样在查询的时候,我们只要按顺序,从高到低依次找就好了,否则我们从低到高实在不好判断这个数是不是最大的。
查询的时候因为有个异或操作,所以尽可能找的数的每一位与待查找的数是取反关系的,没有这样的数的时候在找相同的。这样下来最终的结果一定是最大的。
注意题目最后说数不会超过,但是可能等于,所以不能用int,
附本题代码
------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-14 18:08:40 Tabris_ 阅读数:431
博客爬取于2020-06-14 22:42:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54427994
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4609
-----------------------------------------------------------.
3-idiots
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4437 Accepted Submission(s): 1561
Problem Description
King OMeGa catched three men who had been streaking in the street. Looking as idiots though, the three men insisted that it was a kind of performance art, and begged the king to free them. Out of hatred to the real idiots, the king wanted to check if they were lying. The three men were sent to the king’s forest, and each of them was asked to pick a branch one after another. If the three branches they bring back can form a triangle, their math ability would save them. Otherwise, they would be sent into jail.
However, the three men were exactly idiots, and what they would do is only to pick the branches randomly. Certainly, they couldn’t pick the same branch - but the one with the same length as another is available. Given the lengths of all branches in the forest, determine the probability that they would be saved.
Input
An integer T(T≤100) will exist in the first line of input, indicating the number of test cases.
Each test case begins with the number of branches N(3≤N≤105).
The following line contains N integers a_i (1≤a_i≤105), which denotes the length of each branch, respectively.
Output
Output the probability that their branches can form a triangle, in accuracy of 7 decimal places.
Sample Input
2
4
1 3 3 4
4
2 3 3 4
Sample Output
0.5000000
1.0000000
Source
2013 Multi-University Training Contest 1
-----------------------------------------------------------.
题目大意:
就是跟你N个数代表长度为的木棒,现在问你随便拿出来三个就能构成三角形的概率为多少
解题思路:
首先考虑暴力的
就是求 满足题意的这样的值有多少个,那么这样的话,我们就需要知道,这N个数两两加的和是什么样的,计算出这个之后,我们在预处理出前缀和之后就可以通过枚举最长边来计算三角形的情况数,再除以就是概率了,
所以最严重的问题就是如何求这N个数的两两相加.
这时候如果把加法换成乘法那么就可以转化为向量相乘,用FFT就可以解决了
然后我们考虑将加法换成乘法,其实很简单,我们只要将加数代换成幂指数的指数就可以了,
我们可以用一个hash[a[i]]来记录每个大小的数都有几个
那么FFT之后的结果稍加一点简单处理就是两个不同的木棍长度加和wei的情况数
而我们要的就是这个情况数,所以就不需要在继续处理了
附本题链接
-----------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-13 23:52:02 Tabris_ 阅读数:636
博客爬取于2020-06-14 22:42:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54413679
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1402
---------------------------------------------------------------------------------.
A * B Problem Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19099 Accepted Submission(s): 4406
Problem Description
Calculate A * B.
Input
Each line will contain two integers A and B. Process to end of file.
Note: the length of each integer will not exceed 50000.
Output
For each case, output A * B in one line.
Sample Input
1
2
1000
2
Sample Output
2
2000
Author
DOOM III
---------------------------------------------------------------------------------.
就是个FFT入门题 。
因为题目给的字符串长度达到了,如果普通的大数乘法复杂度为必定会超时.
FFT其实就是一个快速求取卷积的过程.
而一个乘法计算其实也就是一个卷积
对于个数
也就是
所以这个题就可以用FFT来计算了。。
复杂度能降到
附本题代码
----------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-12 15:48:15 Tabris_ 阅读数:326
博客爬取于2020-06-14 22:42:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54378682
题目连接:http://lightoj.com/volume_showproblem.php?problem=1265
--------------------------------------------------------------------------------.
1265 - Island of Survival
PDF (English)StatisticsForum
Time Limit: 2 second(s)Memory Limit: 32 MB
You are in a reality show, and the show is way too real that they threw into an island. Only two kinds of animals are in the island, the tigers and the deer. Though unfortunate but the truth is that, each day exactly two animals meet each other. So, the outcomes are one of the following
a) If you and a tiger meet, the tiger will surely kill you.
b) If a tiger and a deer meet, the tiger will eat the deer.
c) If two deer meet, nothing happens.
d) If you meet a deer, you may or may not kill the deer (depends on you).
e) If two tigers meet, they will fight each other till death. So, both will be killed.
If in some day you are sure that you will not be killed, you leave the island immediately and thus win the reality show. And you can assume that two animals in each day are chosen uniformly at random from the set of living creatures in the island (including you).
Now you want to find the expected probability of you winning the game. Since in outcome (d), you can make your own decision, you want to maximize the probability.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing two integers t (0 ≤ t ≤ 1000) and d (0 ≤ d ≤ 1000) where t denotes the number of tigers and d denotes the number of deer.
Output
For each case, print the case number and the expected probability. Errors less than 10-6 will be ignored.
Sample Input
4
0 0
1 7
2 0
0 10
Output for Sample Input
Case 1: 1
Case 2: 0
Case 3: 0.3333333333
Case 4: 1
--------------------------------------------------------------------------------.
题目大意:
就是一座岛上有1个人t个老虎d只鹿,
现在每天都会有两只动物相遇,
老虎和人, 老虎会吃了人。
老虎和鹿,老虎会吃了鹿。
老虎和老虎,两只老虎都会死。
鹿和人,人可以吃鹿也可以不吃鹿。
鹿和鹿,什么也不会发生。
现在问你,最后人能活下来的概率。
解题思路:
首先还是分析一下,我们可以得到
1.鹿的存在对人能不能活下来是没有影响的。——所以考虑d的值没有任何意义
2.只有老虎全部死亡,人才能活下来。——又因为老虎只能两两自相残杀,所以只有t为偶数的时候人才有活下来的概率。
这时候问题其实可以转化为求在人与老虎相遇之前、偶数只老虎自相残杀全部死亡的概率,除此之外的其他相遇组合对结果无影响。
所以只要求每天人活下来的概率,累乘直到老虎全死了为止。
对于每一天人活下来的概率 = (两只老虎相遇的情况数)/(人和老虎总共可能相遇的情况数);即
约分一下
因为我们结果事t为2为止 所以总式子就是
通过约分最后剩下的式子就变成了
这题就做完了
==================分割线==================
之后看了下题解,居然给的概率dp!
作为DP废还是学习下,
首先确定的是dp[t][d]就是t只老虎d只鹿的概率.
首先dp[0][0]=1;
算了 直接上菊苣的方法吧
1 | 设dp[t][d]表示还有t只老虎,d只鹿的时候,存活的概率。 |
附本题代码
-------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-12 14:25:19 Tabris_ 阅读数:552
博客爬取于2020-06-14 22:42:15
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54377643
题目连接:http://codeforces.com/contest/607/problem/B
-------------------------------------------------------------------------.
B. Zuma
time limit per test2 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
Genos recently installed the game Zuma on his phone. In Zuma there exists a line of n gemstones, the i-th of which has color ci. The goal of the game is to destroy all the gemstones in the line as quickly as possible.
In one second, Genos is able to choose exactly one continuous substring of colored gemstones that is a palindrome and remove it from the line. After the substring is removed, the remaining gemstones shift to form a solid line again. What is the minimum number of seconds needed to destroy the entire line?
Let us remind, that the string (or substring) is called palindrome, if it reads same backwards or forward. In our case this means the color of the first gemstone is equal to the color of the last one, the color of the second gemstone is equal to the color of the next to last and so on.
Input
The first line of input contains a single integer n (1 ≤ n ≤ 500) — the number of gemstones.
The second line contains n space-separated integers, the i-th of which is ci (1 ≤ ci ≤ n) — the color of the i-th gemstone in a line.
Output
Print a single integer — the minimum number of seconds needed to destroy the entire line.
Examples
input
3
1 2 1
output
1
input
3
1 2 3
output
3
input
7
1 4 4 2 3 2 1
output
2
Note
In the first sample, Genos can destroy the entire line in one second.
In the second sample, Genos can only destroy one gemstone at a time, so destroying three gemstones takes three seconds.
In the third sample, to achieve the optimal time of two seconds, destroy palindrome 4 4 first and then destroy palindrome 1 2 3 2 1.
-----------------------------------------------------------------------.
题目大意:
就是在长度为n的序列中,每次能够消去任意一段回文字串,问最少多少次才能使这个序列全部消去
解题思路:
区间DP
dp[i][j] 表示消去区间的最小次数
那么首先对于回文的时候也就是
的时候 dp[i][j]=dp[i+1][j-1];
对于其他情况我们可以枚举断点,计算区间dp[i][j]的最优解.即:
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
写的时候用得记忆化搜索的形式,相比for循环会少思考dp的先后关系,能减少一些错误.
附本题代码
--------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-11 23:28:45 Tabris_ 阅读数:293
博客爬取于2020-06-14 22:42:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54354875
题目连接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1189
----------------------------------------------------------------------------------.
1189 阶乘分数
题目来源: Spoj
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注
1/N! = 1/X + 1/Y(0< x<=y),给出N,求满足条件的整数解的数量。例如:N = 2,1/2 = 1/3 + 1/6,1/2 = 1/4 + 1/4。由于数量可能很大,输出Mod 10^9 + 7。
Input
输入一个数N(1 <= N <= 1000000)。
Output
输出解的数量Mod 10^9 + 7。
Input示例
2
Output示例
2
-------------------------------------------------------------------------------------.
解题思路:
对于这种题目就是转换下式子
由于
同理可得
可得
化简为
这个时候由于N事确定的,那么将看成一个整体,那么其为的因子,有多少个X就有多少个,
Y同理.
这样的话就是求的因子个数了.
但是由于题目要求,,所以结果是
除2很简单,求一下逆元即可
1 | # include <bits/stdc++.h> |
2017-01-11 22:32:31 Tabris_ 阅读数:288
博客爬取于2020-06-14 22:42:17
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54350683
题目连接:http://codeforces.com/contest/484/problem/D
----------------------------------------------------------------------------.
D. Kindergarten
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a nonempty segment of consecutive children of a line. A group’s sociability is the maximum difference of charisma of two children in the group (in particular, if the group consists of one child, its sociability equals a zero).
The teacher wants to divide the children into some number of groups in such way that the total sociability of the groups is maximum. Help him find this value.
Input
The first line contains integer n — the number of children in the line .
The second line contains n integers ai — the charisma of the i-th child .
Output
Print the maximum possible total sociability of all groups.
Examples
input
5
1 2 3 1 2
output
3
input
3
3 3 3
output
0
Note
In the first test sample one of the possible variants of an division is following: the first three children form a group with sociability 2, and the two remaining children form a group with sociability 1.
In the second test sample any division leads to the same result, the sociability will be equal to 0 in each group.
--------------------------------------------------------------------------------.
题目大意:
就是给你长度为n的序列,然后让你将其分成任意段,每段的贡献是这段区间的最大值减最小值的差.求最终结果最大为多少.
解题思路:
通过对序列的分析我们能够知道,对于每一个单调的部分段 如果我们将其拆开了的话 其对结果的贡献就会变小,比如{1,2,3,4,5}对结果的贡献事4(5-1),如果拆开两段那么结果最多也就只能为3了,所以每一段区间我们都选取单调的。
然后对于整个数组,其结果事波动的,那么对于每两段区间会有一个相交的值,也就是拐点,我们只要在计算的时候要考虑其在左右区间哪一个对结果的贡献大我们就要怎么分就好了。
计算的时候采用dp的想法
dp[i] 表示以i结尾的结果最大值.
我们可以通过遍历找到最接近i的拐点位置,那么计算的时候判断这个拐点是在哪一个区间对结果的贡献大就好了…
dp[i]=max(dp[pre-1]+abs(a[i]-a[pre]),dp[pre]+abs(a[i]-a[pre+1]));
我这种dp废 ,不看题解基本都没想过dp,还在考虑单调队列,
1 | # include <bits/stdc++.h> |
2017-01-11 01:41:15 Tabris_ 阅读数:293
博客爬取于2020-06-14 22:42:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54336383
题目链接:http://codeforces.com/contest/509/problem/E
-----------------------------------------------------------------------------------------.
E. Pretty Song
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
When Sasha was studying in the seventh grade, he started listening to music a lot. In order to evaluate which songs he likes more, he introduced the notion of the song’s prettiness. The title of the song is a word consisting of uppercase Latin letters. The prettiness of the song is the prettiness of its title.
Let’s define the simple prettiness of a word as the ratio of the number of vowels in the word to the number of all letters in the word.
Let’s define the prettiness of a word as the sum of simple prettiness of all the substrings of the word.
More formally, let’s define the function vowel© which is equal to 1, if c is a vowel, and to 0 otherwise. Let si be the i-th character of string s, and si…j be the substring of word s, staring at the i-th character and ending at the j-th character (sisi + 1… sj, i ≤ j).
Then the simple prettiness of s is defined by the formula:
The prettiness of s equals
Find the prettiness of the given song title.
We assume that the vowels are I, E, A, O, U, Y.
Input
The input contains a single string s (1 ≤ |s| ≤ 5·105) — the title of the song.
Output
Print the prettiness of the song with the absolute or relative error of at most 10 - 6.
Examples
input
IEAIAIO
output
28.0000000
input
BYOB
output
5.8333333
input
YISVOWEL
output
17.0500000
Note
In the first sample all letters are vowels. The simple prettiness of each substring is 1. The word of length 7 has 28 substrings. So, the prettiness of the song equals to 28.
-----------------------------------------------------------------------------------------.
题目大意:
就是求所有子串中元音字母占比的和
解题思路:
这种题很明显就是贡献求解 。
然后对于每一个位置我们考虑如下
我们只要知道每一个元音字符中所有在的子串都有哪些就好了
对于每一个元音字符我们能够确定在这些区间范围内它贡献1.
$e.g. : _ s_i {[0,i],[0,i+1]…[0,n-1]}{[1,i],[1,i+1]…[1,n-1]}{[i,i],[i,i+1]…[i,n-1] } $
那么结果就是
…
上面的可能看着不太清晰
换成这个看一下就清晰了
——
—— ——
——————————————
—— —— —— .
(总感觉上面那里写错了呢,,,,,)
我们发现这样是很有规律的
我们可以把这个想象成
通过预处理
我们就能在O(1)的时候计算每个位置的贡献了.
就是把上面的平行四边形部分和变成3个左下为直角的三角形部分和的差的形式.
=========================华丽的分割线==========================
AC之后在standing里面看到另一种做法,
这种做法其实也是求贡献,只不过是以长度做的贡献,
把长度为1 为2 为n 的计算出来再累加起来就是了,
(感觉这样的不是怎么好想。。。所以不要脸的贴过来)
以下盗用这个博客
用数组s来存储前缀和。即s[i]表示前i个字符中元音字母个数,这样可以方便统计区间[l,r]元音字母个数。设串总长为L
则有:
长度为1的子串中元音字母出现的个数之和为:ans[1]=s[L]
长度为2:ans[2]=ans[1]+s[L-1]-s[1]
长度为3:ans[3]=ans[2]+s[L-2]-s[2]
……
最后结果即为 ans[1]/1+ans[2]/2+ans[3]/3+……+ans[L]/L
附本题代码
--------------------------------------------.
1 | //方法一 |
2017-01-11 00:06:46 Tabris_ 阅读数:241
博客爬取于2020-06-14 22:42:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54319679
题目链接:http://www.spoj.com/problems/IITWPC4F/
-------------------------------------------------------------------------------------.
IITWPC4F - Gopu and the Grid Problem
no tags
Gopu is interested in the integer co-ordinates of the X-Y plane (0<=x,y<=100000). Each integer coordinate contain a lamp, initially all the lamps are in off mode. Flipping a lamp means switching it on if it is in off mode and vice versa. Maggu will ask gopu 3 type of queries.
Type 1: x l r, meaning: flip all the lamps whose x-coordinate are between l and r (both inclusive) irrespective of the y coordinate.
Type 2: y l r, meaning: flip all the lamps whose y-coordinate are between l and r (both inclusive) irrespective of the x coordinate.
Type 3: q x y X Y, meaning: count the number of lamps which are in ‘on mode’(say this number be A) and ‘off mode’ (say this number be B) in the region where x-coordinate is between x and X(both inclusive) and y-coordinate is between y and Y(both inclusive).
Input
First line contains Q-number of queries that maggu will ask to gopu. (Q <= 10^5)
Then there will be Q lines each containing a query of one of the three type described above.
Output
For each query of 3rd type you need to output a line containing one integer A.
Example
Input:
3
x 0 1
y 1 2
q 0 0 2 2
Output:
4
-------------------------------------------------------------------------------------.
题目大意:
就是有一个横纵坐标范围均为的二位平面 ,每个位置的值只有0/1,初始的时候均为0.
定义三种操作,
x a b 将x轴坐标范围的区域翻转,即0/1互换
y a b 将y轴坐标范围的区域翻转,即0/1互换
q a b A B 查询范围内的区间中1的个数有多少.
解题思路:
因为题目提示的是整行的操作,所以很容易想到用两个数组分别标记对应行/列的翻转次数,奇数次为1,偶数次为0.
然后因为动态求区间和,想到树状数组,
然后发现一点,树状数组虽然能够很好的维护某一个值增减的变化,但是对于区间内翻转的变化既有增也有减,所以不可行,于是换成麻烦写的线段树维护就好了,
用区间更新就能很好的维护翻转标记了.
然后查询的操作与二维树状数组求和的操作一模一样,不再赘述.
附本题代码
-------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2017-01-10 02:05:58 Tabris_ 阅读数:360
博客爬取于2020-06-14 22:42:20
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54300967
题目链接:http://codeforces.com/contest/349/problem/C
-----------------------------------------------------------------------------------------------------------------------.
C. Mafia
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
One day n friends gathered together to play “Mafia”. During each round of the game some player must be the supervisor and other n - 1 people take part in the game. For each person we know in how many rounds he wants to be a player, not the supervisor: the i-th person wants to play ai rounds. What is the minimum number of rounds of the “Mafia” game they need to play to let each person play at least as many rounds as they want?
Input
The first line contains integer n (3 ≤ n ≤ 105). The second line contains n space-separated integers a1, a2, …, an (1 ≤ ai ≤ 109) — the i-th number in the list is the number of rounds the i-th person wants to play.
Output
In a single line print a single integer — the minimum number of game rounds the friends need to let the i-th person play at least ai rounds.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
Examples
input
3
3 2 2
output
4
input
4
2 2 2 2
output
3
Note
You don’t need to know the rules of “Mafia” to solve this problem. If you’re curious, it’s a game Russia got from the Soviet times: http://en.wikipedia.org/wiki/Mafia_(party_game).
-----------------------------------------------------------------------------------------------------------------------.
题目大意:就是有n个人做游戏,每次需要有一个人作为"Mafia",剩下的人作为“player”,现在有n个人每个人想做“player”的次数,问你满足所有人想做“player”的次数意愿的同时最小游戏次数是多少。
题目大意:
我是用二分答案做的,然后看了下别人的 发现直接贪心就可以了。。
对结果进行二分,然后check的时候,只要判断所有人能做"Mafia"的次数能不能满足mid就行了。
但是神TM二分范围啊 ,本来想找找自信,结果r的范围TM的WA三发、、、
首先l一定是
然后r的范围我设居然不行。居然还TM不行。?
最后1e12才过、、
附本题代码
-----------------------------------------------------。
1 | # include <bits/stdc++.h> |
2017-01-10 00:13:01 Tabris_ 阅读数:422
博客爬取于2020-06-14 22:42:21
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54297591
题目链接:http://www.spoj.com/problems/TBATTLE
------------------------------------------------------------------------------------------.
TBATTLE - Thor vs Frost Giants
Thor is caught up in a fierce battle with Loki’s army. This army consists of frost giants that have magical powers with them. Their strength levels gets multiplied when they are together. Giants are not highly skilled in the arts of combat, but their sheer size and strength make them formidable opponents even for the Asgardian gods. Thor is no exception. They recover very fast from physical injury but their recovery slows down when they are exposed to extreme heat.
Thor’s hammer can generate heat only in multiples of heat quantum N. Frost giants get killed only when their combined strength level is exactly equal to the heat level of the hammer. Thor is interested in killing a continuous stretch of frost enemies with a throw of his hammer with a preference to kill closer enemies first.
Continuous stretch is defined as a set of consecutive elements.
Help Thor to determine the minimum stretch of frost giants that could be killed in a throw. In case of multiple minimal stretches, output the indices of that stretch that has lowest starting index. If there is no such continuous stretch possible then print -1.
Input
The first line will contain N, the number of Frost Giants in Loki’s army and the Heat quantum.
The second line will contain N integers (a_0, a_2…, a_n-1) - the strength of each frost giant.
Minimum stretch of the army should be 1.
1 ≤ N ≤ 100000
1 ≤ a_i ≤ 100000
Output
Output the range of the minimum stretch of frost giants that could be killed in a throw. In case of multiple minimal stretches, output the indices of that stretch that has lowest starting index.
If there is no such continuous stretch possible then print -1.
Example
Input:
3
1 2 9
Output:
2 2
Input:
5
2 3 4 8 9
Output:
-1
Input:
10
2 4 3 5 17 4 7 5 2 15
Output:
7 8
Explanation
Input #1:
Thor can only kill the stretch [2,2] as this is the minimum length range with strength, multiple of 3.
Input #2:
There is no stretch of frost giants that have combined strength as a multiple of 5.
Input #3:
There are many stretches of frost giants that have strength as multiple of 10. But the minimal stretch with the least indices is from [7,8]. Minimum size stretches are [7, 8] and [8, 9]. Out of them we select [7,8].
------------------------------------------------------------------------------------------.
题目大意:就是给你长度为n的序列.找一个最短的区见使得 求最小区间,如果多个就输出最左边的,没有输出.
解题思路:
首先看到这个题我有两个思路,
思路一: 我可以把每个数根据算数基本定理展开,向右扫,就是单调的了,我们可以确定区间的一个值来二分另一个值,这样复杂度为
思路二: 我利用线段树维护区间的乘积取模,然后用尺取法的方法来确定区间 ,这样复杂度同样为,但是我写了一发wa了…
附本题代码
----------------------------------------------------------------.
1 | // 尺取法的WA了........ |
2017-01-09 00:44:19 Tabris_ 阅读数:496
博客爬取于2020-06-14 22:42:22
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54263566
题目链接:http://www.spoj.com/problems/STC02/
-----------------------------------------------------------------------------------------.
STC02 - Antisymmetry
no tags
Byteasar studies certain strings of zeroes and ones. Let S be such a string. By Sr we will denote the reversed (i.e., “read backwards”) string S, and by SI we will denote the string obtained from S by changing all the zeroes to ones and ones to zeroes.
Byteasar is interested in antisymmetry, while all things symmetric bore him. Antisymmetry however is not a mere lack of symmetry. We will say that a (nonempty) string S is antisymmetric if, for every position i in S, the i-th last character is different than the i-th (first) character. In particular, a string S consisting of zeroes and ones is antisymmetric if and only if S=SIr. For example, the strings 00001111 and 010101 are antisymmetric, while 1001 is not.
In a given string consisting of zeroes and ones we would like to determine the number of contiguous nonempty antisymmetric fragments. Different fragments corresponding to the same substrings should be counted multiple times.
Input
The first line of the standard input contains an integer N (1 <= N <= 500000) that denotes the length of the string. The second line gives a string of 0 and/or 1 of length N. There are no spaces in the string.
Output
The first and only line of the standard output should contain a single integer, namely the number of contiguous (non empty) fragments of the given string that are antisymmetric.
Example
For the input data:
8
11001011
the correct result is:
7
Antisymmetric fragments are: 01 (occurs twice), 10 (also twice), 0101, 1100, and 001011.
------------------------------------------------------------------------------------------.
题目大意:
就是给你一个字符串,然你统计满足0/1互换之后在翻转等于原串的子串有多少个
解题思路:
这个可以利用求最长回文子串的Manacher算法解决,只要把check换成下述就可以
1 | bool check(int x,int y){ |
这样题目就变得非常简单了
计算子串的方法一样,与标准的Manacher一模一样.都是用p[i]来维护以i为中心的最长子串的半径,但由于题意的限制,这个中心只能是’#'.最后累加下就好了.
但是为什么我的代码还是不能过掉 test61!!!! 调了好久还是不知道问题出在哪里 ,最后无奈只好贴了OMRailgun的代码。。。。
然后改了改,已经和OMRailgun的代码一模一样了,但是最后一组样例还是过不去 ,ZTMDCD。。
===================Update=========================
问题已发现 ,因为!!!因为!!!
p[i]=(p[(id<<1)-i]<(mx-i))?p[(id<<1)-1]:(mx-i);
应该是
p[i]=(p[(id<<1)-i]<(mx-i))?p[(id<<1)-i]:(mx-i);
我就是个**…
附本题代码
-----------------------------------------.
1 | //能AC的OMRailgun的代码 |
2017-01-08 23:01:19 Tabris_ 阅读数:237
博客爬取于2020-06-14 22:42:23
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54237933
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068
---------------------------------------------------------.
最长回文
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18924 Accepted Submission(s): 6934
Problem Description
给出一个只由小写英文字符a,b,c…y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c…y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
abab
Sample Output
4
3
-------------------------------------------------------.
解题思路:
就是Manacher入门题目
Manacher 是一个能在的复杂度内解决字符串中最长回文子串的问题
1 | # include <bits/stdc++.h> |
2017-01-08 15:18:59 Tabris_ 阅读数:268
博客爬取于2020-06-14 22:42:25
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54234049
题目链接:http://www.spoj.com/problems/MINSUB/
---------------------------------------------------------------------------------------.
MINSUB - Largest Submatrix
no tags
You are given an matrix M (consisting of nonnegative integers) and an integer K. For any submatrix of M’ of M define min(M’) to be the minimum value of all the entries of M’. Now your task is simple: find the maximum value of min(M’) where M’ is a submatrix of M of area at least K (where the area of a submatrix is equal to the number of rows times the number of columns it has).
Input
The first line contains a single integer T (T ≤ 10) denoting the number of test cases, T test cases follow. Each test case starts with a line containing three integers, R (R ≤ 1000), C (C ≤ 1000) and K (K ≤ R * C) which represent the number of rows, columns of the matrix and the parameter K. Then follow R lines each containing C nonnegative integers, representing the elements of the matrix M. Each element of M is ≤ 10^9
Output
For each test case output two integers: the maximum value of min(M’), where M’ is a submatrix of M of area at least K, and the maximum area of a submatrix which attains the maximum value of min(M’). Output a single space between the two integers.
Example
Input:
2
2 2 2
1 1
1 1
3 3 2
1 2 3
4 5 6
7 8 9
Output:
1 4
8 2
------------------------------------------------------------------------------------------.
题目大意:问你找到一个面积大于K的子矩阵中的最小值,在保证最小值最大的情况下计算面积的最大值
解题思路:
首先最小值最大这种就想到了二分,甚至都想到了每次将的值用一表示,其他用0表示,然后枚举子矩阵的左上角和右下角二维树状数组计算值,这样的话总复杂度就到了
然后就不会了
看了wannaflyunion的题解才知道用一个叫做单调栈的东西能在的复杂度中解决求子矩阵的最大值
想法也同样是每次将的值用一表示,其他用0表示.增加的是在这个过程中处理了每个点向左的1的个数,然后通过维护每一列的时候向上有几个不小于这个值的向下有几个不小于这个值的. 这个过程通过单调栈能做到 ,然后判断的是列的 所以总复杂度最后只到了
因为二分的不同写法 注意下1e9这个值就好了,
附本题代码
-----------------------------------------------------.
1 | 再次抄袭wannaflyunion的代码.. |
2017-01-07 01:11:20 Tabris_ 阅读数:412
博客爬取于2020-06-14 22:42:26
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54150706
题目链接:http://poj.org/problem?id=2796
----------------------------------------------------------------------------------------------------.
Feel Good
Time Limit: 3000MSMemory Limit: 65536K
Total Submissions: 13624Accepted: 3807
Case Time Limit: 1000MSSpecial Judge
Description
Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated to studying how good or bad days influent people’s memories about some period of life.
A new idea Bill has recently developed assigns a non-negative integer value to each day of human life.
Bill calls this value the emotional value of the day. The greater the emotional value is, the better the daywas. Bill suggests that the value of some period of human life is proportional to the sum of the emotional values of the days in the given period, multiplied by the smallest emotional value of the day in it. This schema reflects that good on average period can be greatly spoiled by one very bad day.
Now Bill is planning to investigate his own life and find the period of his life that had the greatest value. Help him to do so.
Input
The first line of the input contains n - the number of days of Bill’s life he is planning to investigate(1 <= n <= 100 000). The rest of the file contains n integer numbers a1, a2, … an ranging from 0 to 106 - the emotional values of the days. Numbers are separated by spaces and/or line breaks.
Output
Print the greatest value of some period of Bill’s life in the first line. And on the second line print two numbers l and r such that the period from l-th to r-th day of Bill’s life(inclusive) has the greatest possible value. If there are multiple periods with the greatest possible value,then print any one of them.
Sample Input
6
3 1 6 4 5 2
Sample Output
60
3 5
Source
Northeastern Europe 2005
----------------------------------------------------------------------------------------------------.
题目大意:
给定一个序列,让你求[]的最大值。
解题思路:
如果暴力求解的话很明显需要来解决,但是更明显的就是会超时.
于是换一种想法,由于我是找的单调栈类型题,所以,就没有想算法…
至于单调栈怎么维护,其实很简单了,
于其类似的有单调队列,
单调,单调,所以栈中所有元素都是递增的,
那么我们在维护一个单调栈的时候要将所有的于即将进栈的元素不单调的元素出栈,这样下去就能维护一个单调栈了.
维护单调栈的好处也很明显,能够快速的维护一个区间内的最小值.
这样下来在进行统计的时候就能减少很多不必要的计算.
首先区间和用一个前缀和来表示,将求取区间和的部分降到,在每一次维护一个元素的时候,采用一个结构体,
1 | struct node |
在每一次出栈操作的时候维护一下所需要计算的结果就行.
并不是很难想,但是注意元素全部为0的时候,初始化ans需要<0
附本题代码
1 | //#include <bits/stdc++.h> |
2017-01-05 22:17:18 Tabris_ 阅读数:399
博客爬取于2020-06-14 22:42:27
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/54098779
题目连接:http://www.spoj.com/problems/KAOS/
基本都是借(chao)鉴(xi)WannaflyUnion
------------------------------------------------------.
KAOS - Kaos
kaos
Little Lovro likes to play games with words. During the last few weeks he realized that some words don’t like each other.
The words A and B don’t like each other if the word A is lexicographically before the word B, but the word B’ is lexicographically before the word A’, where X’ stands for the word X reversed (if X = “kamen”, then X’ = “nemak”). For example, the words “lova” and “novac” like each other, but the words “aron” and “sunce” don’t like each other.
Given some set of the words, we define the degree of chaos of the set as the number of pairs of different words that don’t like each other.
Write a program that, given a set of words, finds the chaos degree for the set.
input data
The first line of input contains an integer N, 2 ≤ N ≤ 100 000.
Each of the following N lines contains one word – a sequence of at most 10 lowercase letters of the English alphabet (‘a’ – ‘z’). There will be no two identical words in the set.
output data
The first and only line of output should contain a single integer – the chaos degree of the given set of words.
Note: use 64-bit signed integer type (int64 in Pascal, long long in C/C++)
examples
|||||
|-|-|-|
|input | input | input|
|2 | 4 | 14|
|lopta | lova | branimir|
|kugla | novac | vladimir|
| | aron | tom|
|output | sunce | kruz|
|0 | | bred|
| | output | pit|
|| 3 | zemlja|
|| | nije|
|| | ravna|
| | | ploca|
|| | ko|
| | | je|
| | | zapalio|
| | | zito|
| | | output|
| | | 48|
------------------------------------------------------.
题目大意:
就是给你一堆字符串,问你有多少对满足,正序时字典序a>b且逆序时字典序b>a的对数
解题思路:
很容易想到先对字符串按照字典序排序一遍,然后问题就能简化为仅仅判断逆序时字典序的对数就好了.
但是对于如何统计这个没有什么好的思路,最后看了WannaFlyUnion的题解才想到用Trie就好了…(不会字符串的渣渣根本没有向这方面想)
然后才惊人的发现,Trie树居然也可以用静态数组来实现,…
然后学习了… 这样就成了简单的Trie入门题了…
以下借(chao)鉴(xi)WannaflyUnion的题解代码
----------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-12-31 03:54:03 Tabris_ 阅读数:620
博客爬取于2020-06-14 22:42:28
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53949605
今天2016/12/31日,大二上倒数第3天,距离下一赛季网选还有大概8个月。
先总结一下过去的一年半所做所为。
大一上:
听说了学院有一个叫做ACM的组织,然后来了3天,初步接触了C语言。第一次选拔赛很荣幸的没有被选拔上,然后经历了20多天的堕落(期间除了上网玩,没碰过一次键盘),后来参加了第三次院内选拔赛,发挥比第一次强了一丢丢但是还是不太好。最后和学长一顿好说,终于算是同意我加入ACM了。然后的每天平时除了上课和在寝室睡觉,其他时间都在实验室,当初所认知的有限,完全不知道算法都有什么,于是就整天刷校OJ。在听了最近的几次培训内容,在学长们的帮助下也算是了解了一些算法,但是对于当时简单的算法还是不能很好掌握。日子一天天过去,迎来了第一次相对正式的ACM比赛,是院内举行的个人赛,很荣幸当时发挥不错得到了rank5。后来又与C和Z组队参加了校团队赛,虽然名次不是很理想,但是毕竟才刚大一,时间还很多,还可以努力。于是一个学期就这么过去了。第一学期对文化课比较重视,题目又简单,再加上英语老师又那么美丽,没有挂科。
大一寒假:
以前中学班任经常说的一句话,假期是一个很好的超过别人的机会,可是当时我并没有珍惜。记得是42天的假期,除了ACM学长们组织的训练之外,自己做的题目少的可怜,刷题时间加起来不足20小时。一个假期就这么荒废了过去。
大一下:
新学期开学,提前就知道这学期比较忙,有蓝桥杯、校个人、省选和省赛,期间几乎每周都有训练/比赛。首先蓝桥杯还是做了一些准备了,幸运的是取了省1=,获得了北京的参赛资格。去北京呆了四天,逛了逛故宫、圆明园,然后没啥准备就去了PKU比赛了,然后一道水题没有做对,一道计算几何没有模板。心态还是比较炸的。获得了3=的rank10+,说不定多得一分就能拿2=的O(T_T)O。其次是校个人赛,虽然英文题面有一道前几天做过的题没有出比较遗憾,但是最终校内rank16还是比较开心的。最后是省选+省赛,省选一共两场,从组队开始队伍配合就有着严重的问题,再加上那时候胃不好总打嗝影响了队友,导致队友输出削弱。还好最终还是通过省选拿到省赛参赛资格。省赛就非常惨淡了,热身赛就开始懵逼,看着对面HIT金大爷队两个一血气球,顿时感到自己菜的一逼。决赛也只做出了两道简单的签到题,一道建边四层for能过的题目我硬是要降到线性,然后GG。第二学期虽然不重视文化课了,但是靠前突击加上linlinsong学神的帮助下索性没有挂科(在此鸣谢linlinsong)。
大一暑假:
估计这段时间是我目前为止人生中最宝贵的一段时光了吧?
因为假期ACM暑期集训的缘故,假期时间并没有回家(因为家在同城还是回家取被子待了几个小时的)。因为之前的留校申请没有写所以最终无奈和队友们在学校附近租的房子住了一个月。
七月份跟着NULL等巨巨挂的训练题目。穿插着多校训练(根本作不动,完全就是被虐的说)。回去没事打一打BC/CF,然后补补番+上网溜达溜达。七月份就过去了。
八月份,因为上层联系到HIT,所以ACM一堆人都去参加了HIT的暑期训练营,虽然去了那里基本跟不上那里的进度,但还是见到了好多HIT的dalao(可惜生的晚了一年没有亲眼见到xiaodao)学到了不少东西,至少知道了之前所没听说过、没学过的算法,尤其是通过HIT才学会了数位DP(一直以来的痛,这个在网选上贡献很大,如果最后一场网选鄙队没有AC拿到数位DP的话可能连被发配到杭州的资格也没有了)。最后由于鄙校与HIT开学时间不一样,无奈没有坚持到最后一天。
中间因为有着CCPC的网选,所以回西区打了网选,题目思路还好,就是因为一个变量没有用64位长整型,坑了一波队友。虽然在校内rank4,但是远远达不到取得现场赛名额的水平,归根结底还是菜的一逼。
这个暑假是目前为止最为充实的一段时间了,基本每一天都在进步,每一天都能了解到新的东西。
大二上:
大二开学就是2016赛季的开始了,同时也是鄙院ACM吸收新鲜血液的时候,那时候真的是很忙得,但还是很开心的,有好多16级同学过来学习编程。由于受到学长抬举,在ACM给了一个能说上几句话的职位,平时就是没事安排人给新生出/挂点题就好了,最后算是选拔了一些人来加入到ACM的学习中(但很讽刺的是根本没几个人来学习竞赛的内容)。9月中上旬,有着多场网选,不幸的是鄙队没有一次发挥差不多的,校内排名最坏达到了11,好在长老向东北赛的举办方要来的几个名额加上学长打下来的正好是11个,艰难的获得了东北地区赛的名额。在最后一场网选中,在多队没有AC的情况下AC了一道数位DP排名上升了两名,所幸获得了被发配到杭州参赛的资格(至于杭州的悲惨遭遇在渣渣的CSDN博客上有,可以百度【Tabris】第三个应该就是我的博客, 然后去博客左侧所搜【杭州】就出来了)。东北赛和省赛类似都是最后的几个小时我在写题,不一样的是省赛时的思路可能就是错的(因为题目没有OJ公布所以一直没法补题)东北赛的题目思路确实是正解了,但由于本渣渣弱鸡一般的代码能力,一直没有调试好代码,造成鄙队最终只出了3个签到题。然后基本除了带带新生就没有什么大事了。直到2016年的院赛,因为之前与老师沟通,这次院赛的题目命题工作被我和我的一名队友(mengxiang000)接下来了,为了出这套题也是费了一些功夫,为了保密,只能偷偷的在实验室包了4次宿,为了有防止AK的情况,mengxiang000还在高年租中加入了一道邀请Tommy巨巨出的一道防AK题目。但由于个人实力水平有限,在个人负责的两个题目中由于考虑不够周全,数据不强,导致有人水过,一定程度的影响了一些参赛选手的成绩。然后就是校赛了,热身是16年上半年的个人赛题目,和队友无聊的水了三个一血。歇了一会二,就开始正式赛了,发挥还不错(主要是很多人都为了拿奖金没有3人组队参赛),最后凭着手速拿了rank2,但也发现了和rank1的差距,差了两道题目(怪不得人家regional能拿金,我们在CCPC只能拿铁233)。这一学期,由于自己对文化课的不重视,还不知道最后会挂几科。训练也不积极,真的是最咸鱼的一学期了。
=====================分割线================================
明明说好了是说自己大学来的所作所为,写着写着就变成了类似退役贴的东西??!。但是除了竞赛我也确实没有什么好说的了,大学除了吃喝玩就是在睡觉,剩下点的时间就泡在实验室里咸鱼。以致于造成现在这样一事无成的状况,文化课什么都不是,投入一些精力的竞赛还是啥也不是。细数数自己倒了大学妹子也没有,学习还不好,竞赛也只是个菜鸡,玩的也不开心。一天天我到底在干什么?!学习?不,上课要么睡觉、要么玩手机。训练?不,好好训练也不至于现在这么菜。撩妹?no,现在还没有这个精力。
仔细想想这一天真的纯是混日子啊,无所事事。学习不好,安慰自己把精力投入到竞赛上了;竞赛不好,安慰自己还需要上课而没有充分的时间来训练。但是反思一下,在教室是看竞赛方面的东西多还是玩游戏、睡觉多?显然是后者。典型的主观不努力,客观找原因的行为。还整天在抱怨ACM集训队实验室没有训练氛围(但也确实是,除了偶尔几个大一的能刷几个题,真的没谁实在搞竞赛了,剩下的整日不是做项目,就是学文化课,再不就是****)。但还是自己作为ACM集训队的fhz,没有将实验室训练氛围带动起来的原因。
今天和队友算了一下日子,距离2017赛季大概也就是仅仅的8个月了,然而现在鄙队的竞赛水平还是菜的一逼,运气好了能在区域赛垫底拿一个牌子回来,运气不好就还是打铁,回顾一下这一学期,真的是没什么收获,水平依然还是停留在哪个菜鸡的水平上,作为一个三流大学四流院系N流队伍中第三队员的我真的不知到应该用什么样的语言来训斥我了。自己不努力,还妄想着要怎样怎样,简直痴人说梦。
在此立下几个flag(行了队友知道就行了,说出去大家会笑话的)。希望今年能完成这些中的大部分。在一个是距离下一个赛季仅有8个月左右的时间了,确实应该闭关修炼一波了。想想8个月之后,我也应该退役了吧?时间过得真快,如果真的退役了,也不知道以后到底能去做什么。顺气自然吧,先把这8个月过好,对得起自己最后的一点点青春。
=========语文不好,如果真有人赏脸给面子看了这点牢骚,原谅我这搓逼的语文==========
最后附上两张巨巨的语录提醒自己应该干什么,少水群啊,多做题!!!。
]]>2016-12-28 19:13:06 Tabris_ 阅读数:264
博客爬取于2020-06-14 22:42:29
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53912212
题目链接:http://poj.org/problem?id=3667
---------------------------------------------------------------------------------.
Hotel
Time Limit: 3000MSMemory Limit: 65536K
Total Submissions: 16674Accepted: 7234
Description
The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).
The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r…r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.
Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi …Xi +Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.
Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.
Input
Output
Sample Input
10 6
1 3
1 3
1 3
1 3
2 5 5
1 6
Sample Output
1
4
7
0
5
Source
USACO 2008 February Gold
--------------------------------------------------------------------------------.
题目大意:
就是在这个区间.
有两种操作
解题思路:
还是基本的想到了线段树的区间更新.
不一样的就是这次要查找的是连续的x个长度,
这点想了好久,最后还是想到在节点上增加两个值,来代表区间中最左边有多少个连续的,最右边代表有多少个连续的,原本的值来代表区间内最大的连续的长度是多少.然后维护一下就行了.
思路构建的很容易 ,但是最后代码实现的时候发现好麻烦啊,因为一个rr写成了ll 硬是调试了2个小时有没有啊…
跟普通的区间更新差别也就是在pushup和pushdown两个操作上面.
pushup
1 | /* |
pushdown
1 | /* |
附本题代码
1 | //#include <bits/stdc++.h> |
2016-12-09 17:08:59 Tabris_ 阅读数:233
博客爬取于2020-06-14 22:42:30
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53541831
题目链接:http://poj.org/problem?id=1436
-------------------------------------------------------------------------.
Horizontally Visible Segments
Time Limit: 5000MSMemory Limit: 65536K
Total Submissions: 5262Accepted: 1932
Description
There is a number of disjoint vertical line segments in the plane. We say that two segments are horizontally visible if they can be connected by a horizontal line segment that does not have any common points with other vertical segments. Three different vertical segments are said to form a triangle of segments if each two of them are horizontally visible. How many triangles can be found in a given set of vertical segments?
Task
Write a program which for each data set:
reads the description of a set of vertical segments,
computes the number of triangles in this set,
writes the result.
Input
The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 20. The data sets follow.
The first line of each data set contains exactly one integer n, 1 <= n <= 8 000, equal to the number of vertical line segments.
Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:
yi’, yi’‘, xi - y-coordinate of the beginning of a segment, y-coordinate of its end and its x-coordinate, respectively. The coordinates satisfy 0 <= yi’ < yi’’ <= 8 000, 0 <= xi <= 8 000. The segments are disjoint.
Output
The output should consist of exactly d lines, one line for each data set. Line i should contain exactly one integer equal to the number of triangles in the i-th data set.
Sample Input
1
5
0 4 4
0 3 1
3 4 2
0 2 2
0 2 3
Sample Output
1
Source
Central Europe 2001
---------------------------------------------------------------------------.
题目大意:
就是在二维平面上有n个平行于Y轴的线段,问你两两能用水平线(平行于X轴)直接连接在一起的三元组有多少个。
大概就这意思吧
解题思路:
遇到知道题目的做法一定是考虑怎么判断两个线段是不是能够直接连接在一起的,其实只要维护一个线段树从左向右或者从右向左扫一遍就行了,对于每个线段每个都染色,维护最左或最右边的颜色就行了,只要先查询,后更新就能判断出当前的线段和之前出现过的几个线段能够直接相连接的了。
但是要注意的是,在维护线段树的时候不能直接用(y1,y2)来更新。因为会在(1,4,1)(1,2,2)(3,4,2)(1,4,3)这样的情况下出现第四条线段查询的时候查询不到第一条,所以维护的室友要用(y12,y22)来维护,这样的话。就能空出来一个5,这样就能够查询到了。
期间两个边的链接关系用一个bool型的二维数组就可以了,这样不会MLE了
最后统计结果的时候因为时间给的很宽只要三层for中间剪下枝就能怼过去了。
※数据不保证一定是从左到右的 一定要排序啊.
附本题代码
--------------------------------------------------------------------------------------------.
1 | //#include <bits/stdc++.h> |
2016-12-07 21:39:16 Tabris_ 阅读数:636
博客爬取于2020-06-14 22:42:31
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53510746
题目连接:http://gdutcode.sinaapp.com/problem.php?cid=1051&pid=7
-----------------------------------------.
《为什么会变成这样呢》
Problem Description:
“第一次有了喜欢的人,还得到了一生的挚友,两份喜悦互相重叠,这双重的喜悦又带来了更多更多的喜悦,本应已经得到了梦幻一般的幸福时光,然而,为什么,会变成这样呢?”双重的喜悦感却无法带来更多的幸福,现在,雪菜在很多喜悦感之中只想要得到两份不重叠的喜悦感(其他的喜悦感都是重叠的),你能帮她找出这两份不同的喜悦感是多少吗?
Input:
第一行一个整数T,代表数据的组数(1<=T<=10),接下来T组数据,每组数据的第一行是一个整数n(1<=n<=1000000),第二行是n个整数ai(0 <= ai <= 1000000000)代表喜悦感,每两个整数之间有一个空格,题目保证有且仅有两个不同的整数出现一次,其他的整数都是出现两次。
Output:
对于每组数据,输出两个整数,分别代表两份不同的喜悦感,中间有一个空格,并且喜悦感较小的先输出。
Sample input:
2
6
2 2 1 1 3 4
4
1 1 3 4
Sample output:
3 4
3 4
-------------------------------------------------------.
题意:中文题 不解释,
解题思路:
遇到这个题目 大家应该都能想出来的做法,只要先排个序 ,然后找在扫一遍就行了. 但是这题的时限只有1000ms,所以就TLE了
正解是采用位运算 用的做法
首先考虑,除了要求的两个数之外,其他的数都有2个 那么 对于所有的数异或的话,结果就是目标两个数的异或和,
因为这两个数不同,所以异或的结果一定>0
这时候考虑,异或的结果在某二进制上的某一个1 一定是目标数的其中一个贡献的,那么只要讲之间的在同二进制位下为1/0的分成两部分分别求异或和,结果一定是目标数.
输出的时候判断下大小就好了
附本题代码
----------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-30 20:30:18 Tabris_ 阅读数:488
博客爬取于2020-06-14 22:42:32
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53413365
大二选手做新生题目,最后累死累活做了8道(3H) ,剩下的待补。。。
还是太菜 ,继续努力
----------------------------------------------------------------------------------------------------------------------.
Save the Princess
题目大意 :就是有两个人要去九公主 ,一共有N个人 公主在第K个位置,两人轮流杀强盗,杀完最后一个强盗的人赢
解题思路:
没什么好说的,把题读明白就行了。
就是判断n的奇偶性。
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
巴比伦花园
这题我不会 ,待补。。
----------------------------------------------------------------------------------------------------------------------.
极差
题目:中文题
解题思路:
水题,只要扫一遍,维护个最大最小值,然后想减即可.
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
圣杯战争
还没有做这道题 ,做了也出不了…
----------------------------------------------------------------------------------------------------------------------.
校庆
题意 : 中文题
解题思路:直接暴力模拟,
(和2016hrbust校个人赛相似 ,就xjb搞就行
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
牛吃草
题意 : 中文题
解题思路:
直接对牛能吃草的面积二分答案即可
check部分用相交圆面积计算即可;
不知道相交圆面积如何求的戳这里
二分范围即
(如果不考虑牛在园内 ,这样的话绝对会WA
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
众数
题意 : 中文题
解题思路:
水题,还是扫一遍就行了;
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
KI的斐波那契
题意 : 中文题
解题思路:
首先考虑 ,字符串的变化规律和斐波那契是相同的规律的
那么我们可以将一个大的数依次减去斐波那契数列变成一个很小的值,这样的话我们就直接能求出来了.
(其实这样看的话 我的代码还是能优化很多的,直接让fibo数变成0or1 的话 根本不用写这么长…
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
萌新吃果果
题意 : 中文题
阶梯思路:
就是一个模拟题 ,按要求直接来就行了.(不懂看代码
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
萌新的旅行
这题 没想明白 .待补…
----------------------------------------------------------------------------------------------------------------------.
KI的目标
题意 :中文题
解题思路:
这题就是在一个树上去掉一些子树,问最后剩下多少节点 ,
那么根据题意:
我们只要在遍历树的时候不遍历删掉的子树就行了,然后统计一下遍历了多少节点即可.
因为点很多 ,所以采用邻接表存储图.
1 | //#include <bits/stdc++.h> |
----------------------------------------------------------------------------------------------------------------------.
]]>2016-11-29 21:58:33 Tabris_ 阅读数:476
博客爬取于2020-06-14 22:42:33
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53400832
首先作为大二选手,做新生的题目就很尴尬了,然后3个小时单挑(6)加补题(2),最后也只能8个题也是菜的可以。
外加膜拜一发rank1的新生队伍,Orz。。
从(0,0)走到(n,m)很好办 直接dp一下就能计算出来
因为不能路过强盗的位置和强盗一步就能走到的位置.所以这几个位置要特殊判断一下即可.
转移方程
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
这道题首先看到了最小的最大值,我就想二分答案做,但是check部分想了好久也写不出来,于是放弃这个思路.
想了一下最暴力的思路
要枚举三个位置——两个传送阵+1个折中点的位置
在枚举过程中维护的就是几个距离的最大值即可
1)min_dis(1,n)
2)min_dis(1,折中点)
3)min_dis(1,折中点左边的位置) (通过传送阵之后的)
维护过程我们可以先处理个前缀和 这样的话就能维护了.
然而发现的复杂度根本不可行
然后我们发现我们需要的距离一定是从到其他点的 ,那么我们可以确定,其中一个传送阵一定要放在位置上,否则的话最小的最大长度就是就会多了dis(1,左边的传送阵).
这样的话复杂度就降到了
但是发现还是不够用
首先我们能够确定的是 一定要枚举一个值,
那么我们考虑是枚举第二个传送阵还是枚举折中的点…
发现如果开始就枚举折中的点的话,那么不好找传送阵.
于是决定枚举传送阵.
发现,如果枚举传送阵,那么我能能够利用双指针法的方式确定折中点.
这样的话复杂度就降到了
问题就解决了…
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
这道题个人对最终的结果的证明是不太够的,但是也怼过去了…
其实就是来判断3个情况,
1.行和列的和是不是相等,不是的话那么一定不可能.
2.然后判断的是行的最大值和列上的非0值能不能对上,如果对不上的话那么也是不可能的.
3.同上,就是把行列交换一下,
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
这道题目粗看很难 但是想一想其实还是能做的
首先对于 还是非常好求的
我们想到将N按照算数基本定理展开变成
这时候我们有N的因子个数为 = $\prod_{i=1}^{k}(a_i+1) $
这时候我考虑某一个N的因子也就是将变成
那么最终N的所有因子的因子个数和就是
= $\prod_{i=1}^{k}\frac{(1+a_i+1)(a_i+1)}{2} $
但是说了半天我们计算的只是的值
那么我对于该如何求解呢
首先我们知道这样三个数列的前n项和
$ 1^3+ 2^3+ 3^3+ …+ n^3 = {(\frac{(1+n)n}{2})}^2$
…
证明过程从略.(方法好像叫列项相消…
然后我们发现其中两项很相像,
通过观察法发现,与题目要求的有很强的对应关系,那么结论也会有很强的对应关系,
所以得出结论 , 我们只要求出即可,事实发现可行,于是AC…
但是我们需要怎么才能证明得出呢?
考虑到N只有一个素因子的时候,那么他的因子的因子个数和就是
=>
那么对于N有2个素因子的时候他的因子的因子个数和就是
=>
然后采用数学归纳法,即可得出对于N有多个素因子的时候
=>
最后一句 ,以后再也不想证明数学题了,尼玛墨迹死了,还这么绕….
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
这道题目其实和HDU1430是一样的
这里有我HDU1430的题解.传送阵
本题问的是从1~9这个原序列到达其他序列的最少旋转次数,那么翻过来也就是从给定的某一个序列到达1~9这个原序列的最少旋转次数。因为 我们只要预处理出所有的情况就行了。
这道题目要求得最少次数,很容易想到BFS
然后根据题目的1~9的全排列,显然就是康拓展开。
利用康拓展开值来确定一个序列。
每一次BFS的过程中,向其旋转一个2*2后的序列一遍一遍的搜索就行了。(!!!注意的是 从当前序列到原序列是顺时针旋转的,那么从原序列过来就是逆时针的 ,否则 虽然还是能过掉挺多数据,那也是WA啊。。别问我怎么知道能过掉很多数据的 /哭笑)
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
不会…
---------------------------------------------------------------------------------.
这道题 据说不知道什么是后序遍历的16级同学暴力就过了
但是我这里真不知道怎么暴力 ,于是就模拟了一下题意,建了一颗二叉树,然后后序遍历了一下.(话树写的好糙啊但最后也怼过去了
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
没有想好怎么hash 待补题…
---------------------------------------------------------------------------------.
水题一个,没有什么好说的,随便做就行了
可以双端队列,
但是时效性最好的还是用数组做,用一个"指针"维护一下就好了
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
这题不会。
---------------------------------------------------------------------------------.
简单模拟,没有什么好说的
1 | //#include <bits/stdc++.h> |
---------------------------------------------------------------------------------.
]]>2016-11-16 19:09:12 Tabris_ 阅读数:292
博客爬取于2020-06-14 22:42:34
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53190165
题目链接:http://poj.org/problem?id=2528
-------------------------------------------.
Mayor’s posters
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 60379Accepted: 17492
Description
The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules:
Every candidate can place exactly one poster on the wall.
All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown).
The wall is divided into segments and the width of each segment is one byte.
Each poster must completely cover a contiguous number of wall segments.
They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections.
Your task is to find the number of visible posters when all the posters are placed given the information about posters’ size, their place and order of placement on the electoral wall.
Input
The first line of input contains a number c giving the number of cases that follow. The first line of data for a single case contains number 1 <= n <= 10000. The subsequent n lines describe the posters in the order in which they were placed. The i-th line among the n lines contains two integer numbers li and ri which are the number of the wall segment occupied by the left end and the right end of the i-th poster, respectively. We know that for each 1 <= i <= n, 1 <= li <= ri <= 10000000. After the i-th poster is placed, it entirely covers all wall segments numbered li, li+1 ,… , ri.
Output
For each input data set print the number of visible posters after all the posters are placed.
The picture below illustrates the case of the sample input.
Sample Input
1
5
1 4
2 6
8 10
3 4
7 10
Sample Output
4
Source
Alberta Collegiate Programming Contest 2003.10.18
------------------------------------------.
题目大意:
就是给一个连续的区间,在上面的n个子区间(可覆盖)刷上n种颜色,问你最后漏出来的有几种颜色.
解题思路:
就是用线段树来维护每一个区间覆盖上颜色,最后计算叶子上的节点有几种颜色即可.
但是注意到范围有这么大 但是n只有
所以能够离散化一下计算.
注意的是离散化后的区间应该是 不然RE
附本题代码
--------------------------------.
1 | /* |
2016-11-15 20:30:35 Tabris_ 阅读数:198
博客爬取于2020-06-14 22:42:35
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53176786
题目链接:http://poj.org/problem?id=2886
------------------------------------.
Who Gets the Most Candies?
Time Limit: 5000MSMemory Limit: 131072K
Total Submissions: 13899Accepted: 4397
Case Time Limit: 2000MS
Description
N children are sitting in a circle to play a game.
The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (−A)-th child to the right.
The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p. Who gets the most candies?
Input
There are several test cases in the input. Each test case starts with two integers N (0 < N ≤ 500,000) and K (1 ≤ K ≤ N) on the first line. The next N lines contains the names of the children (consisting of at most 10 letters) and the integers (non-zero with magnitudes within 108) on their cards in increasing order of the children’s numbers, a name and an integer separated by a single space in a line with no leading or trailing spaces.
Output
Output one line for each test case containing the name of the luckiest child and the number of candies he/she gets. If ties occur, always choose the child who jumps out of the circle first.
Sample Input
4 2
Tom 2
Jack 4
Mary -1
Sam 1
Sample Output
Sam 3
Source
POJ Monthly–2006.07.30, Sempr
-----------------------------------.
题目大意:
就是有n个人围城一圈,第一次第k个人离开,接下来离开的人是上一次离开的人的位置相对手上的数字相对位置上的人。
如果正的就是顺时针,负的就是逆时针
然后输出的是获得糖果最多的人。这个人获得的糖果数是第p个离开。是p的因子个数。
解题思路:
首先对于n个人来说,获得的最多的糖果个数和其是第几个离开的已经是确定的了,就是一个反素数,这个只要打个表就行了。
那么我们的任务就只剩下了 怎么找第K个离开的人。
每一次我们能够知道的离开的编号是哪一个,所以我们只要一个个的找就行了,但是直接暴力的找的话复杂度是,n又很大 一定会超时。
所以我们采取的就是用线段树维护的方法,每次离开的人放到树上,然后找下一个人,这样的话复杂度就降到了.
维护的方法就是在树上的节点存储这个区间中剩下的没有离开的人的个数,然后更新的时候减掉1就行了.
这个与POJ2828一样 详情戳这里
附本题代码
----------------------------.
1 | # include <stdio.h> |
2016-11-14 19:49:32 Tabris_ 阅读数:252
博客爬取于2020-06-14 22:42:37
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53163302
题目链接:http://poj.org/problem?id=2828
-------------------------------------------------------.
Buy Tickets
Time Limit: 4000MSMemory Limit: 65536K
Total Submissions: 18998Accepted: 9435
Description
Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue…
The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he had to travel by train to Mianyang, Sichuan Province for the winter camp selection of the national team of Olympiad in Informatics.
It was one o’clock a.m. and dark outside. Chill wind from the northwest did not scare off the people in the queue. The cold night gave the Little Cat a shiver. Why not find a problem to think about? That was none the less better than freezing to death!
People kept jumping the queue. Since it was too dark around, such moves would not be discovered even by the people adjacent to the queue-jumpers. “If every person in the queue is assigned an integral value and all the information about those who have jumped the queue and where they stand after queue-jumping is given, can I find out the final order of people in the queue?” Thought the Little Cat.
Input
There will be several test cases in the input. Each test case consists of N + 1 lines where N (1 ≤ N ≤ 200,000) is given in the first line of the test case. The next N lines contain the pairs of values Posi and Vali in the increasing order of i (1 ≤ i ≤ N). For each i, the ranges and meanings of Posi and Vali are as follows:
Posi ∈ [0, i − 1] — The i-th person came to the queue and stood right behind the Posi-th person in the queue. The booking office was considered the 0th person and the person at the front of the queue was considered the first person in the queue.
Vali ∈ [0, 32767] — The i-th person was assigned the value Vali.
There no blank lines between test cases. Proceed to the end of input.
Output
For each test cases, output a single line of space-separated integers which are the values of people in the order they stand in the queue.
Sample Input
4
0 77
1 51
1 33
2 69
4
0 20523
1 19243
1 3890
0 31492
Sample Output
77 33 69 51
31492 20523 3890 19243
Hint
The figure below shows how the Little Cat found out the final order of people in the queue described in the first test case of the sample input.
Source
POJ Monthly–2006.05.28, Zhu, Zeyuan
------------------------------------------------------.
题目大意:
就是一堆人排队去买票 ,然后每一次有一个人插在某一个位置上,现在问你,最后买票的顺序
解题思路:
首先要明确的是一定要逆序进行维护,逆序的话在插队的时候才能够确定他的最终位置
以第一组样例来说的话,
逆序看 那么一定能够确定
69在第2个位置上
33在第1个位置上
77在第0个位置上
这个是一定的 .
那么这时候在想51应该排在哪里,
写出这个的话可能更好理解一些
77
77 51
77 33 51
77 33 69 51
把这个想像成一个树的话 那么逆序插入的话 就能直接判断元素所在的位置了, 如果正序插入的话 还会涉及遍历后续所有元素,太耗时了.
那么这时候怎么判断之前在这个位置的元素应该放到什么位置呢?
想到这点的人真的是太机智了(现在越来越感觉自己的智商不够用了
用线段树的节点来存储这个节点所包含的区间 还有几个位置,
这样的话只要在每一次找到树中还剩下的第x个位置插入进去就行了
明白了这个就不难实现了
如果不太理解的话可以看下代码的注释
附本题代码
---------------------------------------.
1 | //#include <bits/stdc++.h> |
2016-11-13 16:27:43 Tabris_ 阅读数:237
博客爬取于2020-06-14 22:42:38
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53149713
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394
--------------------------------------------------.
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18798 Accepted Submission(s): 11367
Problem Description
The inversion number of a given number sequence a1, a2, …, an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.
For a given sequence of numbers a1, a2, …, an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:
a1, a2, …, an-1, an (where m = 0 - the initial seqence)
a2, a3, …, an, a1 (where m = 1)
a3, a4, …, an, a1, a2 (where m = 2)
…
an, a1, a2, …, an-1 (where m = n-1)
You are asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
Author
CHEN, Gaoli
Source
ZOJ Monthly, January 2003
---------------------------------------------------.
题目大意:
就是有一个序列 ,这个序列可以循环,变成下列这么些个序列。
a1, a2, …, an-1, an (m = 0 - the initial seqence)
a2, a3, …, an, a1 (m = 1)
a3, a4, …, an, a1, a2 (m = 2)
…
an, a1, a2, …, an-1 (m = n-1)
然后对于每种序列 计算逆序对数
然后输出逆序对数最小的值
解题思路:
首先对于最初的序列求解逆序对数 ,只需要线段树or树状数组就行了
这里采取的是线段树维护
在每次把数据挂到树上之前 可以区间查询的方式计算这个值的逆序数 然后O()遍历一遍就能知道整个序列的逆序数了
总复杂度是O()
然后他要求的序列一共有n个那样的话不能O() 这样复杂度实在太高了
然后想最后发现了有一个规律;
因为序列中的数就是0~n-1且新的序列是从旧的序列移过来的。
那么逆序数就会相应减少个 同时就增加了个
这样的话就能够O()处理了
附本题代码
------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-10 19:53:10 Tabris_ 阅读数:228
博客爬取于2020-06-14 22:42:39
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53120130
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556
-------------------------------------------------.
Color the ball
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17629 Accepted Submission(s): 8823
Problem Description
N个气球排成一排,从左到右依次编号为1,2,3…N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
Input
每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
当N = 0,输入结束。
Output
每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
Sample Input
3
1 1
2 2
3 3
3
1 1
1 2
1 3
0
Sample Output
1 1 1
3 2 1
Author
8600
Source
HDU 2006-12 Programming Contest
----------------------------------------------------.
题目大意: 。。。
解题思路:
题目给的很清楚了是区间更新,所以思考。
每次区间的每一个值都+1,那么考虑数据结构中的线段树和树状数组,
这里采用树状数组的做法。
这里只要直接根据树状数组的意义直接做就行了 ,
因为树状数组无非也就是一个动态的前缀和而且 。
这样的话没更新一个值,那么后面的所有值也相当于更新了;
所以更新区间就可以只单点更新两次就行了
对于区间(a,b)
只要给a更新+1,给b更新-1就行了;
附本题代码
-------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-10 16:24:18 Tabris_ 阅读数:269
博客爬取于2020-06-14 22:42:40
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53116979
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2836
----------------------------------------------------------------------------------.
Traversal
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 891 Accepted Submission(s): 348
Problem Description
I arrive at a big lake and I have to cross it. Luckily, I’m a very good jumper, but the lake is too big to be crossed in one jump. On the shore, I find N boxes of different heights, set in a certain order. If I throw a box into the lake, it will float and it will have the same height as on the shore. This is good, because I intend to throw some boxes into the lake and get from one shore to the other by jumping from box to box. The only things to consider are:
The lake is big, so I must throw at least 2 boxes, which means that in order to cross the lake I have to make at least 3 jumps.
Not all the boxes have to be thrown; some of them may be ignored.
The boxes can be thrown into the lake only in the order they are found on the shore and I have to jump on them in this order.
The height difference between two consecutive boxes I use must be at most H meters, because I can jump a lot in length, but I have some problems with jumping in height.The height of a box doesn’t change when I jump on it.
I’m always able to jump from the shore to a box and from a box to the shore, no matter what the height of the box is.
Facing so many possibilities that respect the above conditions, I begin counting the number of possibilities that I have, instead of actually crossing the lake. I quickly find the answer and I wonder whether you can also find it as fast as I did.
Task
Write a program that determines the number of possibilities to cross the lake in the above conditions. Since the number can be quite big, you only have to output the remainder of this number, when divided by 9901.
Input
There are multiple test cases. Each test case contains two integers N and H, separated by a space, representing the number of boxes and the maximum height difference between two consecutive boxes thrown into the lake. The following N lines contain the heights of the boxes, in the order the boxes are set on the shore. The (i+1)th line contains the height of the ith box.
Output
For each test case you should output a single line, containing the number of possibilities modulo 9901.
Constraints
1 < N < 100 001
0 < H < 100 000 001
The height of any box is a strictly positive integer and does not exceed 100 000 000
Sample Input
4 2
1
3
7
5
Sample Output
4
Hint
Explanation
There are 4 possibilities:
1 3
1 3 5
3 5
7 5
Source
2009 Multi-University Training Contest 3 - Host by WHU
------------------------------------------------------------------------------------.
题目大意:
就是给你一个序列,至少选出两个元素的序列中使得相邻元素之间的差≤h 的方案数。
解题思路:
首先不看数据范围的话,很好想了 ,就是一个dp,
dp[i]为以i为结尾的方案数
转移就是
dp[i]=sigma{dp[j] | abs(a[i]-a[j])<=H}+1
复杂度为O(n^2) ,所以不可行,
然后观察了一下,由于转移的过程中正好是一个连续的和,所以想到前缀和优化,又因为是动态的 ,所以采用了树状数组优化.
在选取连续区间的时候我们用另一个数组来存储 ,然后排个序,去个重,用来二分查询位置.
二分的就是3个
最后注意下代码细节 就可以了。
其实想到了如何DP这道题目就并不难了,奈何我个DP废。。。
附本题代码
-----------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-09 21:26:29 Tabris_ 阅读数:312
博客爬取于2020-06-14 22:42:41
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53106292
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2642
-----------------------------------------------------------------------------------------.
Stars
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 1675 Accepted Submission(s): 706
Problem Description
Yifenfei is a romantic guy and he likes to count the stars in the sky.
To make the problem easier,we considerate the sky is a two-dimension plane.Sometimes the star will be bright and sometimes the star will be dim.At first,there is no bright star in the sky,then some information will be given as “B x y” where ‘B’ represent bright and x represent the X coordinate and y represent the Y coordinate means the star at (x,y) is bright,And the ‘D’ in “D x y” mean the star at(x,y) is dim.When get a query as “Q X1 X2 Y1 Y2”,you should tell Yifenfei how many bright stars there are in the region correspond X1,X2,Y1,Y2.
There is only one case.
Input
The first line contain a M(M <= 100000), then M line followed.
each line start with a operational character.
if the character is B or D,then two integer X,Y (0 <=X,Y<= 1000)followed.
if the character is Q then four integer X1,X2,Y1,Y2(0 <=X1,X2,Y1,Y2<= 1000) followed.
Output
For each query,output the number of bright stars in one line.
Sample Input
5
B 581 145
B 581 145
Q 0 600 0 200
D 581 145
Q 0 600 0 200
Sample Output
1
0
Author
teddy
Source
百万秦关终属楚
-----------------------------------------------------------------------------------------.
题目大意:
就是一共有M个操作
操作一共有3种
1)B x y (x,y)位置上出现星星
2)D x y (x,y)位置的星星消失了
3)Q x1 x2 y1 y1 查询矩形范围内的星星有多少个
解题思路:
思路上没有什么可说的,因为是动态的 所以必须是二维树状数组,维护即可
注意的是 ,同一坐标下最多只能有一个星星,删除的话这个坐标就没有星星了
注意 做题的时候注意下坐标的范围 ,因为是从0开始那么计算的时候所有坐标都要加1 否则的话会无限TLE
附本题代码
---------------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-09 20:47:06 Tabris_ 阅读数:262
博客爬取于2020-06-14 22:42:42
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53105883
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2852
-----------------------------------------------------------.
KiKi’s K-Number
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3865 Accepted Submission(s): 1716
Problem Description
For the k-th number, we all should be very familiar with it. Of course,to kiki it is also simple. Now Kiki meets a very similar problem, kiki wants to design a container, the container is to support the three operations.
Push: Push a given element e to container
Pop: Pop element of a given e from container
Query: Given two elements a and k, query the kth larger number which greater than a in container;
Although Kiki is very intelligent, she can not think of how to do it, can you help her to solve this problem?
Input
Input some groups of test data ,each test data the first number is an integer m (1 <= m <100000), means that the number of operation to do. The next m lines, each line will be an integer p at the beginning, p which has three values:
If p is 0, then there will be an integer e (0 < e <100000), means press element e into Container.
If p is 1, then there will be an integer e (0 < e <100000), indicated that delete the element e from the container
If p is 2, then there will be two integers a and k (0 < a <100000, 0 < k <10000),means the inquiries, the element is greater than a, and the k-th larger number.
Output
For each deletion, if you want to delete the element which does not exist, the output “No Elment!”. For each query, output the suitable answers in line .if the number does not exist, the output “Not Find!”.
Sample Input
5
0 5
1 2
0 6
2 3 2
2 8 1
7
0 2
0 2
0 4
2 1 1
2 1 2
2 1 3
2 1 4
Sample Output
No Elment!
6
Not Find!
2
2
4
Not Find!
Source
2009 Multi-University Training Contest 4 - Host by HDU
-----------------------------------------------------------.
题目大意:
就是有N个操作 ,操作一共有3种
1) 0 的时候 就是在集合中加上一个e
2) 1 的时候 就是在集合中删除一个e
3) 2 的时候 就是找到在集合中比a大的第K个数
解题思路:
因为数一直是在1e6以内的 所以我们只要将其放在一个树状数组中就行了
这样的话对于 1,2操作就非常好处理了 ,利用桶的思想,记录一下就行了
但是对于3操作的话 就不行了,因为直接暴力的话会TLE啊 ,
所以我们只要二分一下答案 就可以了;
还是很简单啊 。
附本题代码
---------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-09 15:09:25 Tabris_ 阅读数:265
博客爬取于2020-06-14 22:42:43
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53100103
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1559
---------------------------------------------------------------------------------------------.
最大子矩阵
Time Limit: 30000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4361 Accepted Submission(s): 2273
Problem Description
给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。
Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为四个正整数m,n,x,y(0< m,n<1000 AND 0< x<=m AND 0< y<=n),表示给定的矩形有m行n列。接下来这个矩阵,有m行,每行有n个不大于1000的正整数。
Output
对于每组数据,输出一个整数,表示子矩阵的最大和。
Sample Input
1
4 5 2 2
3 361 649 676 588
992 762 156 993 169
662 34 638 89 543
525 165 254 809 280
Sample Output
2474
Author
lwg
Source
HDU 2006-12 Programming Contest
---------------------------------------------------------------------------------------------.
题目大意:中文题
解题思路 :
根据这个时限 目测暴力都能过去 ,但是为了练习树状数组 还是用二维的树状数组过得
最最最最裸的二维树状数组 没什么可说的
附本题代码
----------------------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-08 21:46:00 Tabris_ 阅读数:238
博客爬取于2020-06-14 22:42:44
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53088871
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838
----------------------------------------------------.
Cow Sorting
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3275 Accepted Submission(s): 1102
Problem Description
Sherlock’s N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique “grumpiness” level in the range 1…100,000. Since grumpy cows are more likely to damage Sherlock’s milking equipment, Sherlock would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes Sherlock a total of X + Y units of time to exchange two cows whose grumpiness levels are X and Y.
Please help Sherlock calculate the minimal time required to reorder the cows.
Input
Line 1: A single integer: N
Lines 2…N + 1: Each line contains a single integer: line i + 1 describes the grumpiness of cow i.
Output
Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.
Sample Input
3
2
3
1
Sample Output
7
Hint
Input Details
Three cows are standing in line with respective grumpiness levels 2, 3, and 1.
Output Details
2 3 1 : Initial order.
2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4).
1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).
Source
2009 Multi-University Training Contest 3 - Host by WHU
----------------------------------------------------.
题目大意:
主要看hint就能知道了
其实还是一个冒泡排序 只不过求得是总花费 每次花费为交换的两个值得和
解题思路:
首先用树状数组对每个数求一下他出现之前逆序对数
对于每个数来说 它对结果的贡献就是
他之前的逆序对数*a_i+与他逆序的数的总和
这里直接采取了维护两个树状数组的暴力思路:
一个维护逆序对个数
一个维护逆序数的和
注意要用I64 否则溢出了…
附本题代码
------------------------------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-08 21:03:47 Tabris_ 阅读数:233
博客爬取于2020-06-14 22:42:45
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53088409
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5775
----------------------------------------------------------.
Bubble Sort
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1241 Accepted Submission(s): 683
Problem Description
P is a permutation of the integers from 1 to N(index starting from 1).
Here is the code of Bubble Sort in C++.
for(int i=1;i<=N;++i)
for(int j=N,t;j>i;—j)
if(P[j-1] > P[j])
t=P[j],P[j]=P[j-1],P[j-1]=t;
After the sort, the array is in increasing order. ?? wants to know the absolute values of difference of rightmost place and leftmost place for every number it reached.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each consists of one line with one integer N, followed by another line with a permutation of the integers from 1 to N, inclusive.
limits
T <= 20
1 <= N <= 100000
N is larger than 10000 in only one case.
Output
For each test case output “Case #x: y1 y2 … yN” (without quotes), where x is the test case number (starting from 1), and yi is the difference of rightmost place and leftmost place of number i.
Sample Input
2
3
3 1 2
3
1 2 3
Sample Output
Case #1: 1 1 2
Case #2: 0 0 0
Hint
In first case, (3, 1, 2) -> (3, 1, 2) -> (1, 3, 2) -> (1, 2, 3)
the leftmost place and rightmost place of 1 is 1 and 2, 2 is 2 and 3, 3 is 1 and 3
In second case, the array has already in increasing order. So the answer of every number is 0.
Author
FZU
Source
2016 Multi-University Training Contest 4
-----------------------------------------------------------.
题目大意:
就是求每个数字在冒泡排序的过程中位置的区间大小
解题思路:
用手写了写 发现结果就是
max(前面有几个比a_i大,后面有几个比a_i小);
其实也很好想 根据冒泡排序的交换规则
很容易的计算每一个数字左移数和右移数
至于结果为什么是二者的最大值 也很好想,
因为两者的差就是a_i-i,画图演示的话就是
其他情况得跟这个差不多 不再赘述/
然后用树状数组维护两遍就行了
附本题代码
---------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-08 20:10:00 Tabris_ 阅读数:265
博客爬取于2020-06-14 22:42:46
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53086898
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2689
-------------------------------------------------------------------------------------.
Sort it
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4140 Accepted Submission(s): 2945
Problem Description
You want to processe a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. Then how many times it need.
For example, 1 2 3 5 4, we only need one operation : swap 5 and 4.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 1000); the next line contains a permutation of the n integers from 1 to n.
Output
For each case, output the minimum times need to sort it in ascending order on a single line.
Sample Input
3
1 2 3
4
4 3 2 1
Sample Output
0
6
Author
WhereIsHeroFrom
Source
ZJFC 2009-3 Programming Contest
-------------------------------------------------------------------------------------.
题目大意:
就是问这个序列冒泡排序的话 需要交换多少次
解题思路:
明确题意之后就非常好理解了
对于每个数字来说交换了多少次 也就是在这个数出现之前有几个比他大的数字。累加即可。
这里维护一个树状数组,每次把a[i]的值更新为1,这样的话查询的时候1~a[i]的和就是这个数出现之前比他大的数字的个数。
处理不难 。
附本题代码
----------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-08 19:45:07 Tabris_ 阅读数:269
博客爬取于2020-06-14 22:42:47
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53086391
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4046
---------------------------------------------------------------.
Panda
Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3439 Accepted Submission(s): 1113
Problem Description
When I wrote down this letter, you may have been on the airplane to U.S.
We have known for 15 years, which has exceeded one-fifth of my whole life. I still remember the first time we went to the movies, the first time we went for a walk together. I still remember the smiling face you wore when you were dressing in front of the mirror. I love your smile and your shining eyes. When you are with me, every second is wonderful.
The more expectation I had, the more disappointment I got. You said you would like to go to U.S.I know what you really meant. I respect your decision. Gravitation is not responsible for people falling in love. I will always be your best friend. I know the way is difficult. Every minute thinking of giving up, thinking of the reason why you have held on for so long, just keep going on. Whenever you’re having a bad day, remember this: I LOVE YOU.
I will keep waiting, until you come back. Look into my eyes and you will see what you mean to me.
There are two most fortunate stories in my life: one is finally the time I love you exhausted. the other is that long time ago on a particular day I met you.
Saerdna.
It comes back to several years ago. I still remember your immature face.
The yellowed picture under the table might evoke the countless memory. The boy will keep the last appointment with the girl, miss the heavy rain in those years, miss the love in those years. Having tried to conquer the world, only to find that in the end, you are the world. I want to tell you I didn’t forget. Starry night, I will hold you tightly.
Saerdna loves Panda so much, and also you know that Panda has two colors, black and white.
Saerdna wants to share his love with Panda, so he writes a love letter by just black and white.
The love letter is too long and Panda has not that much time to see the whole letter.
But it’s easy to read the letter, because Saerdna hides his love in the letter by using the three continuous key words that are white, black and white.
But Panda doesn’t know how many Saerdna’s love there are in the letter.
Can you help Panda?
Input
An integer T means the number of test cases T<=100
For each test case:
First line is two integers n, m
n means the length of the letter, m means the query of the Panda. n<=50000,m<=10000
The next line has n characters ‘b’ or ‘w’, ‘b’ means black, ‘w’ means white.
The next m lines
Each line has two type
Type 0: answer how many love between L and R. (0<=L<=R< n)
Type 1: change the kth character to ch(0<=k< n and ch is ‘b’ or ‘w’)
Output
For each test case, output the case number first.
The answer of the question.
Sample Input
2
5 2
bwbwb
0 0 4
0 1 3
5 5
wbwbw
0 0 4
0 0 2
0 2 4
1 2 b
0 0 4
Sample Output
Case 1:
1
1
Case 2:
2
1
1
0
Source
The 36th ACM/ICPC Asia Regional Beijing Site —— Online Contest
---------------------------------------------------------------.
题目大意:
就是最开始有一个n这么长的串 有m次操作
操作0,L,R,询问L~R中内包含"wbw"的个数。
操作1,k,ch,将第k个字符更换为ch。
解题思路:
就是用树状数组维护一下 ,在“wbw”中以左边为界放到树状数组中就行了。
然后在更换字符的时候
枚举一下几种情况就行了
附本题代码
-----------------------------------------.
1 | # include <bits/stdc++.h> |
2016-11-07 21:24:45 Tabris_ 阅读数:404
博客爬取于2020-06-14 22:42:49
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53072003
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541
-----------------------.
Stars
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8916 Accepted Submission(s): 3547
Problem Description
Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers want to know the distribution of the levels of the stars.
For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it’s formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.
You are to write a program that will count the amounts of the stars of each level on a given map.
Input
The first line of the input file contains a number of stars N (1<=N<=15000). The following N lines describe coordinates of stars (two integers X and Y per line separated by a space, 0<=X,Y<=32000). There can be only one star at one point of the plane. Stars are listed in ascending order of Y coordinate. Stars with equal Y coordinates are listed in ascending order of X coordinate.
Output
The output should contain N lines, one number per line. The first line contains amount of stars of the level 0, the second does amount of stars of the level 1 and so on, the last line contains amount of stars of the level N-1.
Sample Input
5
1 1
5 1
7 1
3 3
5 5
Sample Output
1
2
1
1
0
Source
Ural Collegiate Programming Contest 1999
------------------------------------------------------------.
题目大意 :
就是求左下角有多少个星星的星星的个数
解题思路 :
就是一个基本的数据结构
树状数组和线段树都可做
我用的树状数组AC的 闲来无事复习一下也是有收获的 维护的时候i<=maxn 而不是树状数组的长度 。。 很强势 也怪当初没有好好学习树状数组就去搞线段树了。。然后做了几天就放弃数据结构了 看来这的要好好学习数据结构了。。。
仔细读题 发现y是递增的 这样的话 y值就没什么用了 我们只要维护x就可以了 维护前用桶记录一下就可以了;;
附本题代码
---------------------------.
1 | # include <bits/stdc++.h> |
2016-11-05 16:48:35 Tabris_ 阅读数:574
博客爬取于2020-06-14 22:42:50
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53046282
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430
---------------------------------------------.
魔板
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2968 Accepted Submission(s): 672
Problem Description
在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:
1 2 3 4
8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
Input
每组测试数据包括两行,分别代表魔板的初态与目态。
Output
对每组测试数据输出满足题意的变换步骤。
Sample Input
12345678
17245368
12345678
82754631
Sample Output
C
AC
Author
LL
---------------------------------------------.
题目大意 :中文题 自己读。。。。
解题思路:
首先可以明确的是 这个字符串改变之前和改变之后的关系是一定有的 那么原串和终串无论是什么 只要讲原串和终串映射回“12345678”这样的话 就能够计算了
那样的话 所有的解都可以变成 “12345678” 这个串的变化 ;
由于 8!=40320 状态数目非常少 变化也只有三种 那么我们只要用BFS就可以了 利用广度优先的特性 求出的解也是最优的
那么首先BFS预处理结果一下就行了 串的变化模拟就可以了
后来计算的时候 把原串和终串处理一下 变成"12345678"与"balabala"的样子 然后输出结果就行了
但是在标记的时候 想到用康托展开的值来标记 而不是用map映射(但是想想map映射 也没什么毛病吧)。
这个代码确实是AC的 只是win7 CB13.2 运行会渣掉 找了1天BUG还是没有找到 最后提交上去想保存一下代码的时候 发现居然AC了!! AC了!
附本题代码
----------------------------.
1 | # include <bits/stdc++.h> |
----------------------------.
]]>2016-11-04 16:16:54 Tabris_ 阅读数:240
博客爬取于2020-06-14 22:42:51
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53036273
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1027
--------------------------------------------.
Ignatius and the Princess II
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7182 Accepted Submission(s): 4264
Problem Description
Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5166 says, “I have three question for you, if you can work them out, I will release the Princess, or you will be my dinner, too.” Ignatius says confidently, “OK, at last, I will save the Princess.”
“Now I will show you the first problem.” feng5166 says, “Given a sequence of number 1 to N, we define that 1,2,3…N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it’s easy to see the second smallest sequence is 1,2,3…N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It’s easy, isn’t is? Hahahahaha…”
Can you help Ignatius to solve this problem?
Input
The input contains several test cases. Each test case consists of two numbers, N and M(1<=N<=1000, 1<=M<=10000). You may assume that there is always a sequence satisfied the BEelzebub’s demand. The input is terminated by the end of file.
Output
For each test case, you only have to output the sequence satisfied the BEelzebub’s demand. When output a sequence, you should print a space between two numbers, but do not output any spaces after the last number.
Sample Input
6 4
11 8
Sample Output
1 2 3 5 6 4
1 2 3 4 5 6 7 9 8 11 10
Author
Ignatius.L
--------------------------------------------.
题目大意:
就是求有n个数的第m个排列
解题思路:
由于m≤1e5 但是不知道数据量到底是多大 所以不应该采取暴力的做法 正解应该是康托逆展开
但是这时候考虑n比较大 到了1000,这时候如果直接康托逆展开的话 阶乘会爆掉 所以不可取
这时候看了一下m值只有1e5 那么就能知道变化的序列里面也只有后面几位而已
这时候暴力跑一下 发现 只有后8位的顺序有变化
这时候我们只要单独把8位逆展开就可以了
注意的是n小于8的时候 不要算多就可以了
展开过程比较水 随便写写就好了 如果不是特别了解康拓展开 可以戳这里<-目录里面有
附本题AC代码
--------------------------------------------------------------------------------------.
1 | # include <stdio.h> |
----------------------------------------------------------------------------------------.
]]>2016-11-04 13:22:06 Tabris_ 阅读数:385
博客爬取于2020-06-14 22:42:52
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53033813
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=139
---------------------------------------------.
我排第几个
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的?
输入
第一行有一个整数n(0 < n<=10000);
随后有n行,每行是一个排列;
输出
输出一个整数m,占一行,m表示排列是第几位;
样例输入
3
abcdefghijkl
hgebkflacdji
gfkedhjblcia
样例输出
1
302715242
260726926
----------------------------------------------.
解题思路:
本题就是一道康拓展开的入门练习题目
找到这个字符串在字典序中排在第几就行了
求出展开值+1就是了
康拓展开现见这里<-翻目录
附本题代码
-----------------------------------.
1 | # include <stdio.h> |
------------------------------------.
]]>2016-11-03 13:13:07 Tabris_ 阅读数:193
博客爬取于2020-06-14 22:42:53
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53020524
题目链接:http://codeforces.com/contest/525/problem/D
--------------------------------------.
D. Arthur and Walls
time limit per test2 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
Finally it is a day when Arthur has enough money for buying an apartment. He found a great option close to the center of the city with a nice price.
Plan of the apartment found by Arthur looks like a rectangle n × m consisting of squares of size 1 × 1. Each of those squares contains either a wall (such square is denoted by a symbol “*” on the plan) or a free space (such square is denoted on the plan by a symbol “.”).
Room in an apartment is a maximal connected area consisting of free squares. Squares are considered adjacent if they share a common side.
The old Arthur dream is to live in an apartment where all rooms are rectangles. He asks you to calculate minimum number of walls you need to remove in order to achieve this goal. After removing a wall from a square it becomes a free square. While removing the walls it is possible that some rooms unite into a single one.
Input
The first line of the input contains two integers n, m (1 ≤ n, m ≤ 2000) denoting the size of the Arthur apartments.
Following n lines each contain m symbols — the plan of the apartment.
If the cell is denoted by a symbol “*” then it contains a wall.
If the cell is denoted by a symbol “.” then it this cell is free from walls and also this cell is contained in some of the rooms.
Output
Output n rows each consisting of m symbols that show how the Arthur apartment plan should look like after deleting the minimum number of walls in order to make each room (maximum connected area free from walls) be a rectangle.
If there are several possible answers, output any of them.
Examples
1 | input |
--------------------------------------.
题目大意 :
就是给你一个nm的矩阵 里面‘’代表着墙 ‘.’代表空地
现在让你尽可能少的移开墙 然后使每一片联通的空地都成为一个矩形
解题思路:
最开始看到这题的想法就是搜索 判断联通快然后让这一部分所在的最小矩形全部变成‘.’ 然后发现不行 有可能 操作之后的两个矩形又连到一起了,这样的话所有操作都需要再从新来一下,图还特别大 所以一定会超时
然后左想右想 还是不明白
最后看了 别人的代码 明白了
只需要看每一个2*2的部分就行了
对于连不连通 也非常好判断了
而判断用不用移走墙 就更好想了 对于每一个22内 只有一个‘’号的时候一定要移走 其他情况就不用
想明白这句话 这道题就可以解决了
最后处理的时候用一个队列 维护一下坐标即可
每个点最多也只是遍历一遍,这样就不会超时了 而且操作也更简单
详情看代码就好
附本题代码
--------------------------------.
1 | # include<bits/stdc++.h> |
--------------------------------.
]]>2016-11-02 14:14:50 Tabris_ 阅读数:236
博客爬取于2020-06-14 22:42:54
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/53007513
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3415
-------------------------------------.
Max Sum of Max-K-sub-sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7522 Accepted Submission(s): 2776
Problem Description
Given a circle sequence A[1],A[2],A[3]…A[n]. Circle sequence means the left neighbour of A[1] is A[n] , and the right neighbour of A[n] is A[1].
Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases.
Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
Output
For each test case, you should output a line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.
Sample Input
4
6 3
6 -1 2 -6 5 -5
6 4
6 -1 2 -6 5 -5
6 3
-1 2 -6 5 -5 6
6 6
-1 -1 -1 -1 -1 -1
Sample Output
7 1 3
7 1 3
7 6 2
-1 1 1
Author
shǎ崽@HDU
Source
HDOJ Monthly Contest – 2010.06.05
--------------------------------------.
题目大意:
给你一个成环的数列,让你寻找其中区间长度不大于k的区间最大和与 区间的起始位置和结束位置。
解题思路:
因为做的题目就是单调队列的专题 就没想算法
然后考虑成环的 所以要把区间变成2倍的 这样就有环了,,,
然后因为要取区间的和 而维护单调队列的时候也只是维护区间的左界 为了方便计算区间的值 所以把数组变成前缀和的形式
然后在维护的时候个人维护的是左界限的左一位的值 计算区间和比较容易
总的来说就是
枚举右界限 维护一下每次最优的左界线 然后把不符合结果的出队列就好了
附本题代码
--------------------------------------.
1 |
|
2016-10-31 17:37:05 Tabris_ 阅读数:227
博客爬取于2020-06-14 22:42:55
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52984325
题目链接:http://poj.org/problem?id=2823
--------------------------------.
Sliding Window
Time Limit: 12000MSMemory Limit: 65536K
Total Submissions: 55854Accepted: 16062
Case Time Limit: 5000MS
Description
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. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window positionMinimum valueMaximum value
: | : | : |
---|---|---|
Window position | Minimum value | Maximum value |
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position. |
Input
The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.
Output
There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
Sample Input
8 3
1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7
-----------------------------------.
题目大意:
就是求长度为n的数列中长度为k的邻近区间的最大值和最小值;
解题思路:
这道题就是单调队列的入门题目
但是据说线段树也可以过 但是不仅代码量大 而且复杂度也不是最优的。
以为这个求得区间与区间之间存在邻近的关系 所以想到用单调队列优化的思路这样的话可以把复杂度降到O(n)
维护的时候只要维护一下下标就行了
单调队列的数组实现其实和尺追法差不多,觉得不好写的话用手过几遍数据强化一下就行.
附本题代码
----------------------.
1 | # include <iostream> |
2016-10-30 21:38:33 Tabris_ 阅读数:270
博客爬取于2020-06-14 22:42:56
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52974565
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5945
------------------------------------.
问题描述
青年理论计算机科学家Fxx给的学生设计了一款数字游戏。
一开始你将会得到一个数:XX,每次游戏将给定两个参数:k,tk,t, 任意时刻你可以对你的数执行下面两个步骤之一:
1.:X = X - i(1 <= i <= t)1.X=X−i(1<=i<=t)。
2.:2.若:X:X为:k:k的倍数,X = X / kX=X/k。
现在Fxx想要你告诉他最少的运行步骤,使:X:X变成:11。
输入描述
第一行一个整数:T(1\leq T\leq20):T(1≤T≤20)表示数据组数。
接下来:T:T行,每行三个数:X,k,t(0\leq t\leq10^6,1\leq X,k\leq10^6)X,k,t(0≤t≤10^ 6 ,1≤X,k≤10^ 6 )
数据保证有解。
输出描述
输出共:T:T行。
每行一个整数表示答案。
输入样例
2
9 2 1
11 3 3
输出样例
4
3
---------------------------------------.
题目大意:中文题 不解释.
解题思路:
很容易先到是一个sbDP
状态转移方程就是
if(0==i%k)dp[i]=min(dp[i],dp[i/k]+1);
dp[i]=min(dp[i],min{dp[i+1],dp[i+2],,dp[i+t]}+1);,dp[i+t]}这个操作如果暴力求解的话复杂度是O(xt) 很不现实 ,所以要优化 。
上述转移方程很好设计 但是因为数据很大 所以min{dp[i+1],dp[i+2],
首先想到的是挂到线段树上 每次更新一个点+查询一个区间最小值 这样的话复杂度就降到O(x*logt) 然后发现还是会超时 ,于是乎就GG了
最后结束之后发现这是一个叫做单调队列优化的东西 于是借鉴巨巨们的博客http://blog.csdn.net/guhaiteng/article/details/52972757
学习到了
单调队列 其实就是一个通过维护下标在O(1)内知道区间最小值的东西
其实有点模拟数组的思想
然后根据题意
确定一下值的范围 ,删去无用值 ,每次操作都是线性的。
这样下来 总的时间复杂度就是O(n)
好高端的东西 现在理解的还不是那么特别透 。。。。继续努力。
然后
附本题代码
------------------------------.
1 | # include <bits/stdc++.h> |
2016-10-27 21:56:49 Tabris_ 阅读数:349
博客爬取于2020-06-14 22:42:57
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52950443
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1524
-------------------------------.
A Chess Game
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2133 Accepted Submission(s): 954
Problem Description
Let’s design a new chess game. There are N positions to hold M chesses in this game. Multiple chesses can be located in the same position. The positions are constituted as a topological graph, i.e. there are directed edges connecting some positions, and no cycle exists. Two players you and I move chesses alternately. In each turn the player should move only one chess from the current position to one of its out-positions along an edge. The game does not end, until one of the players cannot move chess any more. If you cannot move any chess in your turn, you lose. Otherwise, if the misfortune falls on me… I will disturb the chesses and play it again.
Do you want to challenge me? Just write your program to show your qualification!
Input
Input contains multiple test cases. Each test case starts with a number N (1 <= N <= 1000) in one line. Then the following N lines describe the out-positions of each position. Each line starts with an integer Xi that is the number of out-positions for the position i. Then Xi integers following specify the out-positions. Positions are indexed from 0 to N-1. Then multiple queries follow. Each query occupies only one line. The line starts with a number M (1 <= M <= 10), and then come M integers, which are the initial positions of chesses. A line with number 0 ends the test case.
Output
There is one line for each query, which contains a string “WIN” or “LOSE”. “WIN” means that the player taking the first turn can win the game according to a clever strategy; otherwise “LOSE” should be printed.
Sample Input
4
2 1 2
0
1 3
0
1 0
2 0 2
0
4
1 1
1 2
0
0
2 0 1
2 1 1
3 0 1 3
0
Sample Output
WIN
WIN
WIN
LOSE
WIN
Source
PKU Monthly
--------------------------------------.
题目大意:
这题就是给你一个有向图 最后不能移动的人就输了 问你先手输赢的情况
这题的输入比较乱 反正我是看了半天才明白;
就是先输入一个n代表有n个点
然后又n行 分别表示的是0~n-1这几个点指向的节点
第一个数x是指向几个节点,然后的x个数表示节点
然后有q次询问
接下来有q行
每行第一个数表示有x个起始位置 接下来的是x个其实位置的值
然后让你判断先手的输赢
解题思路:
这题就是最最最最裸的SG函数了
恰恰就是sg函数的定义:把问题抽象成一个有向无环图
并没有什么可说的 只要dfs一下就行了 当然for也可以
然而特别要注意的是,mex操作中的标记数组声明在外面就不能过 在函数里面声明就AC
这都是玄学。。。
附本题代码
-------------------------------.
1 |
|
2016-10-27 16:17:26 Tabris_ 阅读数:239
博客爬取于2020-06-14 22:42:58
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52946902
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1517
-------------------------------.
A Multiplication Game
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5345 Accepted Submission(s): 3048
Problem Description
Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p = 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, they draw an integer 1 < n < 4294967295 and the winner is who first reaches p >= n.
Input
Each line of input contains one integer number n.
Output
For each line of input output one line either
Stan wins.
or
Ollie wins.
assuming that both of them play perfectly.
Sample Input
162
17
34012226
Sample Output
Stan wins.
Ollie wins.
Stan wins.
Source
University of Waterloo Local Contest 2001.09.22
Recommend
LL
-------------------------------.
题目大意:就是给你数n 两个人轮流对x(初始为1)乘上一个[2,9]之间的一个数字 最先得到x≥n的人获胜
解题思路:
这种题 很显然是博弈 但是又不是几个常见的模型
所以找一下其中的必胜态和必败态
首先对于[n,+∞]一定是必胜态 ,没有问题 ;
那么能够一步到达这里的一定是必败态
那就是[ceil(n/9),n-1];
然后不管怎么样一步只能到达必败态的位置一定是必胜态;
那就是[ceil(n/2),n-1];
之后这样的话我们就可以暴力的枚举到最后 看一看1这个位置是必胜态还是必败态就好了
附本题代码
-------------------------.
1 | # include <bits/stdc++.h> |
2016-10-25 19:37:29 Tabris_ 阅读数:758
博客爬取于2020-06-14 22:42:59
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52926338
题目链接:http://vjudge.net/contest/137260#problem/W
-----------------------------------.
Sum of Consecutive Integers
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Description
Given an integer N, you have to find the number of ways you can express N as sum of consecutive integers. You have to use at least two integers.
For example, N = 15 has three solutions, (1+2+3+4+5), (4+5+6), (7+8).
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing an integer N (1 ≤ N ≤ 1014).
Output
For each case, print the case number and the number of ways to express N as sum of consecutive integers.
Sample Input
5
10
15
12
36
828495
Sample Output
Case 1: 1
Case 2: 3
Case 3: 1
Case 4: 2
Case 5: 47
-------------------------------------.
题目大意 :
给你一个数N ,然后问你 一些连续的数和 等于N的种类数
解题思路:
首先
N=a+(a+1)+(a+2)+(a+3)+…+(a+k-1)
=(a+a+k-1)k/2 =(2a+k-1)*k/2
然后把式子转换一下
得到这样的结果
2N/K-K=2a-1
我们能够知道2a-1是奇数 所以2N/K与K之间一定是一个奇数一个偶数的
那么这时候只要求有多少种K的值能够满足 这个式子 就可以了
1)K为奇数 2N/K为偶数
2)K为偶数 2N/K为奇数
这时候2N/K和/K都是2N的奇因子 其中上述两种情况在计算中不会出现重叠的时候 所以计算两者加和就行了也就是N*2的奇因子,
综上所述 :N的奇数因子的个数即为解。
然后只要求N得奇质因子的个数就行了
根据算数基本定理讲N展开
N=p1^a1p2^a2p2^a2*…*pn^an
然后根据因子个数的公式 ∏ i_n (ai+1)
由于我们求的是奇质因子的个数 所有质因子为偶数的时候就不用计算了 当然质因子中只有2一个是偶数
附本题代码
------------------------.
1 | //#include <bits/stdc++.h> |
2016-10-24 22:00:16 Tabris_ 阅读数:11191
博客爬取于2020-06-14 22:43:01
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52916166
2016-10-22 16:58:05 Tabris_ 阅读数:316
博客爬取于2020-06-14 22:43:02
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52893406
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1692
----------------------------------------.
Problem 1692 Key problem
Accept: 197 Submit: 865
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Whenever rxw meets Coral, he requires her to give him the laboratory key. Coral does not want to give him the key, so Coral ask him one question. if rxw can solve the problem, she will give him the key, otherwise do not give him. rxw turns to you for help now,can you help him?
N children form a circle, numbered 0,1,2, … …, n-1,with Clockwise. Initially the ith child has Ai apples. Each round game, the ith child will obtain ( LA(i+n-1)%n+RA(i+1)%n ) apples. After m rounds game, Coral would like to know the number of apples each child has. Because the final figure may be very large, so output the number model M.
Input
The first line of input is an integer T representing the number of test cases to follow. Each case consists of two lines of input: the first line contains five integers n,m,L,R and M . the second line contains n integers A0, A1, A2 … An-1. (0 <= Ai <= 1000,3 <= n <= 100,0 <= L, R <= 1000,1 <= M <= 10 ^ 6,0 <=m < = 10 ^ 9). After m rounds game, output the number model M of apples each child has.
Output
Each case separated by a space. See sample.
Sample Input
1
3 2 3 4 10000
1 2 3
Sample Output
120 133 131
Source
FOJ月赛-2009年3月— Coral
----------------------------------------.
题目大意:就是每个人初始有a[i]个苹果,每一轮能得到左边L倍+右边R倍的苹果,问你M轮之后每个人有多少个苹果.
解题思路:
很明显的矩阵快速幂.构造矩阵非常简单
但是要注意下n≤100 所以n^3会超时,所以要优化一下,
根据矩阵我们能够发现
[1 L 0 0 R]
[R 1 L 0 0]
[0 R 1 L 0]
[0 0 R 1 L]
[L 0 0 R 1]
这是一个很明显的循环矩阵
根据循环矩阵的n次幂还是循环矩阵的这个性质我们每次求解的时候只需要求解一行或一列就可以了,这样的话就能把n^3优化到n^2了
这样就不会超时了
附本题代码
---------------------------------。
1 | //#include <bits/stdc++.h> |
2016-10-22 00:30:09 Tabris_ 阅读数:986
博客爬取于2020-06-14 22:43:03
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52888634
首先感谢学校把这次机会给了网赛打的那么差的我们队。
然后说一下杭州之旅,因为在东北,要是坐火车的话,要坐31个小时的火车,于是我们决定自己多出一点坐3个小时的飞机去杭州。于是提早半个多月买了4折的往返机票。等到机场的时候,由于我们没有老师,学长带队,还都第一次坐飞机,于是天真的以为等飞机起飞前几分钟去飞机上就好了,于是愉快的第一次就误机了。。由于买的打折机票,于是不能改签,不能退。于是查了一下航班,准备订更晚点的另一班飞机去,然后也不知道怎么了估计是队友着急了,手快的订了26号的航班。。。然而当天是16号。。。也是醉了 ,然后退票,由于又是打折机票,所以每张票只退了50…于是半个小时,2000软妹币直接变成150、、、还好我们订的机票早了一天,连忙又订了第二天晚上22:05的机票,这才能在比赛开始前及时报道,。。
热身赛,由于比赛环境是hdoj,还有熟悉的CB所以,并没有测试什么乱遭的东西。。。于是直接开始做题。。。A题开始刚看题目,,,感觉很简单 ,直接对半非就行了。刚写完,队友说错了,有组样例过不去,然后出了几个数据都是分成最大,最小的在一个集合,剩下的在另一个集合,然后提交WA。最后队友说枚举断点,然后交了,又是WA、、、(赛后听说这是正解。。)。然后队友做B。。。一道sb搜索题,,队友RE了一发,,然后改了一下bug。AC了 ,然后调A ,结果最后结束也没有A。。。
正式赛、比赛开始先读题目,不到5分钟清华的队伍就FB了A 于是我们就去翻译A,然后以我渣比的英语和马虎的翻译加上队友成功把题意翻译错了,题目要求是只能对相邻的两个进行操作,然而我们当成了任意的,,,于是乎无论怎么贪心,就是有问题,,于是队友看F题。。上来WA一发,然后找到一个没考虑到的情况AC了,,然后看身边的队伍ABCF都过了。。。开始看BC,,,,C题思路秒想出,直接从后面的开始扫,然后可以了,因为一个队友再改A我又看了B,然后B题队友也在想,我想计算几何方向,队友想图论方向,队友说这个只要缩下点,建一个有向图用个XX算法就行了(本人不会图论名字也说不明白),然后我觉得很可行,起码比计算几何靠谱多了,,于是这两题的思路就没有改变,等队友ACA题。。但是队友还是没A,于是我另一个队友先去写了C,不幸WA了,,这个时候我重读了一下A题然后发现了读题失误,,然后把C的代码打印下来找BUG,我回去敲A然后果断的TLE了,,然后我蒙蔽了,明明是线性的算法数据量并不是非常大,怎么能TLE呢。。于是换队友敲了一发,又TLE了。。。 最后每个人都敲了一发还是TLE,,然后改C题。。C题的思路很明确 并不会有错,,然后我又去写了一发,还是错,,这时候队友上厕所了,我换个姿势写了一下A,,结果就这么AC了, ,,,于是回头看C,C还是没想到为什么会WA,,这时候应该说一下之前队友写了一发B然而在刚把B的代码写完的时候电脑突然断电了,,,于是本就很炸的队友这回直接就临近崩溃了,,重新开机,发现代码果然已经没有了。。。于是有重敲了一发B,,然后提交WA.。。然后队友重新考虑了一下,,,有个点没有考虑到,,,给了给。。还是没有AC….
这时候比赛还剩40分钟,我就改了一下C 。。提交还是WA,,,这时候早已经怀疑人生,,,剩下的时间一直在不停的交B和C题 但是最后还是没有过,,,
最后2题滚粗,,,,拿了人生首次铁牌,,也感受到了高中OI爷的可怕,比赛时坐我们后面的福州三中拿了rank3的牛逼成绩%%%%%。。其他rank2也是安师大附中的淼焱轟队伍,其他OI爷队伍也都非常牛逼,,%%%%
赛后问了群里发现B,C题目的思路都没有错,C题是因为被卡了精度,然后有人用分数过的,有人用EPS过的,由于比赛期间根本没考虑精度这个问题,所以C题GG,B题的思路一样估计还是队友因为电脑断电加上心态爆炸代码写炸了,,
虽然这次打铁了,杭州一路也比较坎坷,但是也是非常有意义的,首先比赛的经验就收获了很多,还见到了众多大佬,,很后悔没有向jls,cls,dls要签名,,,赛后5分钟终于在杭州首次见到了学校的老师。老师也在安慰,,还好拿到了一些纪念品杭州也没算白来,,,由于误机+打铁后心情不是很好杭州的游玩时间就没有了,最后也没有去西湖看一看就回去了,。。。虽然来之前就知道南方的奖不好拿,,但是也还是不甘心,首先A题这个最水的签到题居然犯下一个又一个的失误,直接打乱了队内的节奏,,其他两道题也并不是不会,但是没有AC否则4题的话还是能够稳铜的。。还是做题太少经验不足,作为队长,这是我的失责,,在这里向我的两个队友表示歉意。。
接下来还是要好好努力,争取明年一定要拿一个铜甚至银,,虽然是弱校,弱队,没有老师,但是要知道靠谁不如靠自己,,不管以后结果如何,都要对得起自己。。
不忘初心,方得始终。
人生成就:
第一次误机 get√
第一次坐飞机 get√
第一次去南方 get√
第一次打全国性比赛 get√
第一次打铁 get√
2016-10-10 21:41:07 Tabris_ 阅读数:1168
博客爬取于2020-06-14 22:43:04
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52782106
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5925
---------------------------------.
Coconuts
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 343 Accepted Submission(s): 110
Problem Description
TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams about eating. One day, TanBig dreams of a field of coconuts, and the field looks like a large chessboard which has R rows and C columns. In every cell of the field, there is one coconut. Unfortunately, some of the coconuts have gone bad. For sake of his health, TanBig will eat the coconuts following the rule that he can only eat good coconuts and can only eat a connected component of good coconuts one time(you can consider the bad coconuts as barriers, and the good coconuts are 4-connected, which means one coconut in cell (x, y) is connected to (x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1).
Now TanBig wants to know how many times he needs to eat all the good coconuts in the field, and how many coconuts he would eat each time(the area of each 4-connected component).
Input
The first line contains apositiveinteger T(T≤10) which denotes the test cases. T test cases begin from the second line. In every test case, the first line contains two integers R and C, 0< R,C ≤109 the second line contains an integer n, the number of bad coconuts, 0≤n≤200 from the third line, there comes n lines, each line contains two integers, xi and yi, which means in cell(xi,yi), there is a bad coconut.
It is guaranteed that in the input data, the first row and the last row will not have bad coconuts at the same time, the first column and the last column will not have bad coconuts at the same time.
Output
For each test case, output “Case #x:” in the first line, where x denotes the number of test case, one integer k in the second line, denoting the number of times TanBig needs, in the third line, k integers denoting the number of coconuts he would eat each time, you should output them in increasing order.
Sample Input
2
3 3
2
1 2
2 1
3 3
1
2 2
Sample Output
Case #1:
2
1 6
Case #2:
1
8
--------------------------------------------------.
题目大意:
就是有rc的方阵,代表每个房间,每个房间上有一个糖 ,其中有n个坏的 。
然后一个人吃糖,只能上下左右的房间是连着的,然后不能去糖坏了的房间,
问你一共需要进入几次 ,每次能吃多少糖。
/**************/
上述表达不清晰
下面换一种说法
就是有rc的方阵 上面都是白的 其中有n个黑色的点 ,问你黑色的点把白色的点分成了几个部分,每个部分的点有多少。
解题思路:
正常的思想就应该是搜索了,但是奈何图太大 ,会超时;
所以得换个思路想问题 ,
图虽然很大 ,但是黑色的点只有200个,
所以突破点应该就在这里。
最终想出用离散化的方法解决这个问题,;
图很大的时候每个点之间的距离很大,只要把这一部分离散化就好了,离散化后 图最坏也只是400*400,这样的话搜索就不会超时了。
离散化的时候很简单 对于x,y坐标分别离散化一下就行了,然后映射到图上就是二维的离散化了。
注意的是 挨着的坐标在离散化后也是挨着的,不挨着的坐标,在离散化后也是不挨着的。然后开个数组存储下离散化后,每个x,y应该是多少,然后直接dfs/bfs均可,在搜索的时候就能统计值了。
知道怎样离散化,然后写写代码就好了。
注意:题目数据量大 要用LL
当时在赛场上,上个厕所的功夫终于想出了离散化的正解 ,然后我那渣比的代码能力 +队友搅屎,调了2h没有调好。。。
附本题代码
-------------------------.
1 | # include <bits/stdc++.h> |
2016-10-05 19:28:29 Tabris_ 阅读数:282
博客爬取于2020-06-14 22:43:05
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52740134
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4790
------------------------------.
Just Random
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2782 Accepted Submission(s): 850
Problem Description
Coach Pang and Uncle Yang both love numbers. Every morning they play a game with number together. In each game the following will be done:
1. Coach Pang randomly choose a integer x in [a, b] with equal probability.
2. Uncle Yang randomly choose a integer y in [c, d] with equal probability.
3. If (x + y) mod p = m, they will go out and have a nice day together.
4. Otherwise, they will do homework that day.
For given a, b, c, d, p and m, Coach Pang wants to know the probability that they will go out.
Input
The first line of the input contains an integer T denoting the number of test cases.
For each test case, there is one line containing six integers a, b, c, d, p and m(0 <= a <= b <= 109, 0 <=c <= d <= 109, 0 <= m < p <= 109).
Output
For each test case output a single line “Case #x: y”. x is the case number and y is a fraction with numerator and denominator separated by a slash (‘/’) as the probability that they will go out. The fraction should be presented in the simplest form (with the smallest denominator), but always with a denominator (even if it is the unit).
Sample Input
4
0 5 0 5 3 0
0 999999 0 999999 1000000 0
0 3 0 3 8 7
3 3 4 4 7 0
Sample Output
Case #1: 1/3
Case #2: 1/1000000
Case #3: 0/1
Case #4: 1/1
Source
2013 Asia Chengdu Regional Contest
-----------------------------.
题目大意:
给你两个区间[a,b][c,d]
求分别从两个区间中取出x,y. 使得(x+y)mod p==m的概率
解题思路 :
概率就是
可行的组数/所有的组数
所有的组数就是(b-a+1)*(d-c+1)
问题就是怎么求解可行的组数
如果暴力的话 最坏是O(10^18) 一定会超时
如果把区间对p取模 存在数组里然后在选取 时空复杂度均为O(10^9) 还是不可行
于是 就改变一下思路
他要求的是(x+y)mod p==m 那么x+y的区间就是
[a+c,b+d]
这样的话 会发现 [a+c,b+d]中每个数出现的次数虽然不相等但是有非常严谨的规律 如下图
明确这些就很好算了
只有分别对这三个区间进行统计就行了
但是为了方便计算这里讲[c,d]区间变成了[c+p-m,d+p-m]
这样的话选出来的数就相当于(x+y)mod p==0
统计的时候就方便多了
统计的时候
每一个区间只要找到最大和最小的满足mod p==0的数的位置
然后用高斯公式就能直接计算了 ::(首项+末项)*项数/2
为了避免重复统计 鄙渣做了2点改动
1.判断的区间为[A1,A2] (A2,A3) [A3,A4]
2.特判了一下(a==b&&c==d)的情况 否则按照我的思路就会多统计一遍
1 | if(a==b&&c==d) |
附本题代码
---------------------------.
1 | # include <bits/stdc++.h> |
2016-10-04 18:34:39 Tabris_ 阅读数:313
博客爬取于2020-06-14 22:43:06
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52734843
题目链接:http://codeforces.com/contest/723/problem/C
------------------------------------.
C. Polycarp at the Radio
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Polycarp is a music editor at the radio station. He received a playlist for tomorrow, that can be represented as a sequence a1, a2, …, an, where ai is a band, which performs the i-th song. Polycarp likes bands with the numbers from 1 to m, but he doesn’t really like others.
We define as bj the number of songs the group j is going to perform tomorrow. Polycarp wants to change the playlist in such a way that the minimum among the numbers b1, b2, …, bm will be as large as possible.
Find this maximum possible value of the minimum among the bj (1 ≤ j ≤ m), and the minimum number of changes in the playlist Polycarp needs to make to achieve it. One change in the playlist is a replacement of the performer of the i-th song with any other group.
Input
The first line of the input contains two integers n and m (1 ≤ m ≤ n ≤ 2000).
The second line contains n integers a1, a2, …, an (1 ≤ ai ≤ 109), where ai is the performer of the i-th song.
Output
In the first line print two integers: the maximum possible value of the minimum among the bj (1 ≤ j ≤ m), where bj is the number of songs in the changed playlist performed by the j-th band, and the minimum number of changes in the playlist Polycarp needs to make.
In the second line print the changed playlist.
If there are multiple answers, print any of them.
Examples
input
4 2
1 2 3 2
output
2 1
1 2 1 2
input
7 3
1 3 2 2 2 2 1
output
2 1
1 3 3 2 2 2 1
input
4 4
1000000000 100 7 1000000000
output
1 4
1 2 3 4
Note
In the first sample, after Polycarp’s changes the first band performs two songs (b1 = 2), and the second band also performs two songs (b2 = 2). Thus, the minimum of these values equals to 2. It is impossible to achieve a higher minimum value by any changes in the playlist.
In the second sample, after Polycarp’s changes the first band performs two songs (b1 = 2), the second band performs three songs (b2 = 3), and the third band also performs two songs (b3 = 2). Thus, the best minimum value is 2.
------------------------------------------.
题目大意 :
给定 n 个数,让把某一些变成 1-m之间的数,要改变最少,使得1-m中每个数中出现次数最少的尽量大。
解题思路:
就是模拟这个过程就行了
首先明确的是要想1-m之间的数中出现次数最少的尽量大那就是n/m个 (说白了就是匀乎匀乎。。。)
先记录一下1~m中每个数出现的次数 最后跟n/m比一下
然后就知道了 需要把改动多少个数了
我这里用另一个数组存储下改动的数
改动的 时候首先先把大于m的数给改成1~m个数
如果最后还有数需要改动就 在遍历一下数组 先统计下每个数的出现次数 只有出现次数==n/m之后才能改动这个数 这样才能保证1~m中每个数最少出现n/m个 然后注意下细节就能AC了、、
附本题代码
---------------------------.
1 | # include<bits/stdc++.h> |
2016-10-04 17:34:41 Tabris_ 阅读数:400
博客爬取于2020-06-14 22:43:07
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52734656
题目链接:http://codeforces.com/contest/723/problem/D
----------------------------------------.
D. Lakes in Berland
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cell is either land or water. The map is surrounded by the ocean.
Lakes are the maximal regions of water cells, connected by sides, which are not connected with the ocean. Formally, lake is a set of water cells, such that it’s possible to get from any cell of the set to any other without leaving the set and moving only to cells adjacent by the side, none of them is located on the border of the rectangle, and it’s impossible to add one more water cell to the set such that it will be connected with any other cell.
You task is to fill up with the earth the minimum number of water cells so that there will be exactly k lakes in Berland. Note that the initial number of lakes on the map is not less than k.
Input
The first line of the input contains three integers n, m and k (1 ≤ n, m ≤ 50, 0 ≤ k ≤ 50) — the sizes of the map and the number of lakes which should be left on the map.
The next n lines contain m characters each — the description of the map. Each of the characters is either ‘.’ (it means that the corresponding cell is water) or ‘*’ (it means that the corresponding cell is land).
It is guaranteed that the map contain at least k lakes.
Output
In the first line print the minimum number of cells which should be transformed from water to land.
In the next n lines print m symbols — the map after the changes. The format must strictly follow the format of the map in the input data (there is no need to print the size of the map). If there are several answers, print any of them.
It is guaranteed that the answer exists on the given data.
Examples
1 | input |
Note
In the first example there are only two lakes — the first consists of the cells (2, 2) and (2, 3), the second consists of the cell (4, 3). It is profitable to cover the second lake because it is smaller. Pay attention that the area of water in the lower left corner is not a lake because this area share a border with the ocean.
------------------------.
题目大意:
就是 “.”代表水 “*”代表土
被土圈上的水是湖 没被圈上的水是海
现在只需要K个湖 所以要填上一些湖 问最小花费(填一格花费1)
解题思路:
就是无脑DFS
先把海搜索一遍 然后开始搜索湖 并染色 (染色拿vis数组染色就行)
拿一个结构体记录每个颜色的湖的大小 按照湖的大小从小到大排下序 最小的开始填湖 就能得到最小花费了
/**************************/
打CF的时候无脑WA7 过后重敲一发 居然1发就AC了。。。思路一模一样。。。。 GG。。
附本题代码
--------------------------.
1 | # include<bits/stdc++.h> |
2016-09-30 13:43:05 Tabris_ 阅读数:312
博客爬取于2020-06-14 22:43:08
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52710814
题目链接:http://codeforces.com/contest/344/problem/E
--------------------------------------------.
E. Read Time
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Mad scientist Mike does not use slow hard disks. His modification of a hard drive has not one, but n different heads that can read data in parallel.
When viewed from the side, Mike’s hard drive is an endless array of tracks. The tracks of the array are numbered from left to right with integers, starting with 1. In the initial state the i-th reading head is above the track number hi. For each of the reading heads, the hard drive’s firmware can move the head exactly one track to the right or to the left, or leave it on the current track. During the operation each head’s movement does not affect the movement of the other heads: the heads can change their relative order; there can be multiple reading heads above any of the tracks. A track is considered read if at least one head has visited this track. In particular, all of the tracks numbered h1, h2, …, hn have been read at the beginning of the operation.
Mike needs to read the data on m distinct tracks with numbers p1, p2, …, pm. Determine the minimum time the hard drive firmware needs to move the heads and read all the given tracks. Note that an arbitrary number of other tracks can also be read.
Input
The first line of the input contains two space-separated integers n, m (1 ≤ n, m ≤ 105) — the number of disk heads and the number of tracks to read, accordingly. The second line contains n distinct integers hi in ascending order (1 ≤ hi ≤ 1010, hi < hi + 1) — the initial positions of the heads. The third line contains m distinct integers pi in ascending order (1 ≤ pi ≤ 1010, pi < pi + 1) - the numbers of tracks to read.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is recommended to use the cin, cout streams or the %I64d specifier.
Output
Print a single number — the minimum time required, in seconds, to read all the needed tracks.
Examples
input
3 4
2 5 6
1 3 6 8
output
2
input
3 3
1 2 3
1 2 3
output
0
input
1 2
165
142 200
output
81
Note
The first test coincides with the figure. In this case the given tracks can be read in 2 seconds in the following way:
during the first second move the 1-st head to the left and let it stay there;
move the second head to the left twice;
move the third head to the right twice (note that the 6-th track has already been read at the beginning).
One cannot read the tracks in 1 second as the 3-rd head is at distance 2 from the 8-th track.
--------------------------------------------.
题目大意:
就是有N个磁头 和M个要读取的位置
磁头每移动一格耗时1秒
问你最短多长时间 能够将这M个位置读取
解题思路:
首先二分答案
然后判断这个答案能不能满足
然后慢慢缩小区间 最后答案就出来了
判断的时候要采取贪心的策略
因为在判断的时候我们默认二分出来的就是答案
然后贪心 看一看在二分出来的那个答案中能不能满足题意
只要判断每个磁头走移动这些步最多能都读取几个位置
然后判断这些位置能不能被走完
走完就是成立了
判断的时候就是让每个磁头尽可能的像右走 (前提是想把左边需要读取的点都读取完毕)
详细的请看代码注释…
附本题代码
----------.
1 | # include <bits/stdc++.h> |
2016-09-27 15:33:17 Tabris_ 阅读数:785
博客爬取于2020-06-14 22:39:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52681216
1 | inline int read(){ |
printf("%*d",length+1,a[i][j]); //其中*号是位数 对应length是对应位数的数据 +1是数值之前的空格占一位
利用斯特林公式,LL a = 0.5 * log10(2.0 * Pi * n) + n * log10(n * 1.0 / E) + 1;
Wiki链接
1 | int sum[N]; |
1 | # include <iostream> |
1.单调队列:在一个双端对列中维护最后解的方法;
一般适用于:
在一个动态的范围内 对于一个限定长度的子区间进行处理最优解的过程
[解决浮动窗口的最优解]
注意: 顾名思义 一定要保证队列中元素的单调性
1 | int deq[] ;//队列实体 |
练习题目:NYOJ 139
>康托展开的公式是 X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a21!+a10! 其中,ai为当前未出现的元素中是排在第几个(从0开始)。
>这个公式可能看着让人头大,最好举个例子来说明一下。例如,有一个数组 s = [“A”, “B”, “C”, “D”],它的一个排列 s1 = [“D”, “B”, “A”, “C”],现在要把 s1 映射成 X。n 指的是数组的长度,也就是4,所以
X(s1) = a43! + a32! + a21! + a10!
关键问题是 a4、a3、a2 和 a1 等于啥?
a4 = “D” 这个元素在子数组 [“D”, “B”, “A”, “C”] 中是第几大的元素。"A"是第0大的元素,"B"是第1大的元素,“C” 是第2大的元素,"D"是第3大的元素,所以 a4 = 3。
a3 = “B” 这个元素在子数组 [“B”, “A”, “C”] 中是第几大的元素。"A"是第0大的元素,"B"是第1大的元素,“C” 是第2大的元素,所以 a3 = 1。
a2 = “A” 这个元素在子数组 [“A”, “C”] 中是第几大的元素。"A"是第0大的元素,"C"是第1大的元素,所以 a2 = 0。
a1 = “C” 这个元素在子数组 [“C”] 中是第几大的元素。“C” 是第0大的元素,所以 a1 = 0。(因为子数组只有1个元素,所以a1总是为0)
所以,X(s1) = 33! + 12! + 01! + 00! = 20
A B C | 0
A C B | 1
B A C | 2
B C A | 3
C A B | 4
C B A | 5
练习题目:HDU 1027
如果已知 s = [“A”, “B”, “C”, “D”],X(s1) = 20,能否推出 s1 = [“D”, “B”, “A”, “C”] 呢?
因为已知 X(s1) = a43! + a32! + a21! + a10! = 20,所以问题变成由 20 能否唯一地映射出一组 a4、a3、a2、a1?如果不考虑 ai 的取值范围,有
33! + 12! + 01! + 00! = 20
23! + 42! + 01! + 00! = 20
13! + 72! + 01! + 00! = 20
03! + 102! + 01! + 00! = 20
03! + 02! + 201! + 00! = 20
等等。但是满足 0 <= ai <= n-1 的只有第一组。可以使用辗转相除的方法得到 ai,如下图所示:
知道了a4、a3、a2、a1的值,就可以知道s1[0] 是子数组[“A”, “B”, “C”, “D”]中第3大的元素 “D”,s1[1] 是子数组 [“A”, “B”, “C”] 中第1大的元素"B",s1[2] 是子数组 [“A”, “C”] 中第0大的元素"A",s[3] 是子数组 [“C”] 中第0大的元素"C",所以s1 = [“D”, “B”, “A”, “C”]。
这样我们就能写出一个函数 Permutation3(),它可以返回 s 的第 m 个排列。
1 | # include<iostream> |
算法介绍
http://blog.csdn.net/zchahaha/article/details/51058738
http://www.mamicode.com/info-detail-523965.html
1 | int dp[N][N]; //dp[i][j]为i点到1点,再从1点到j点的最短距离, |
基:在线性代数中,基(也称为基底)是描述、刻画向量空间的基本工具。向量空间的基是它的一个特殊的子集,基的元素称为基向量。向量空间中任意一个元素,都可以唯一地表示成基向量的线性组合。如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数。
同样的,线性基是一种特殊的基,它通常会在异或运算中出现,它的意义是:通过原集合S的某一个最小子集S1使得S1内元素相互异或得到的值域与原集合S相互异或得到的值域相同。
性质
求线性基.
1 | void Guass(){ |
中心思想就是用两个栈来维护,一个用来存储符号,另一个用来存储数值.
1 | /*** |
后缀表达式也叫逆波兰表达式
1 | # include<iostream> |
对于两个多项式,求多项式的gcd,要求首项次数为1,多项式中的运算都%n
1 | # include <bits/stdc++.h> |
2016-09-26 19:21:33 Tabris_ 阅读数:375
博客爬取于2020-06-14 22:43:09
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52673118
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3292
-----------------------------------------------------------.
No more tricks, Mr Nanguo
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 378 Accepted Submission(s): 250
Problem Description
Now Sailormoon girls want to tell you a ancient idiom story named “be there just to make up the number”. The story can be described by the following words.
In the period of the Warring States (475-221 BC), there was a state called Qi. The king of Qi was so fond of the yu, a wind instrument, that he had a band of many musicians play for him every afternoon. The number of musicians is just a square number.Beacuse a square formation is very good-looking.Each row and each column have X musicians.
The king was most satisfied with the band and the harmonies they performed. Little did the king know that a member of the band, Nan Guo, was not even a musician. In fact, Nan Guo knew nothing about the yu. But he somehow managed to pass himself off as a yu player by sitting right at the back, pretending to play the instrument. The king was none the wiser. But Nan Guo’s charade came to an end when the king’s son succeeded him. The new king, unlike his father, he decided to divide the musicians of band into some equal small parts. He also wants the number of each part is square number. Of course, Nan Guo soon realized his foolish would expose, and he found himself without a band to hide in anymore.So he run away soon.
After he leave,the number of band is Satisfactory. Because the number of band now would be divided into some equal parts,and the number of each part is also a square number.Each row and each column all have Y musicians.
Input
There are multiple test cases. Each case contains a positive integer N ( 2 <= N < 29). It means the band was divided into N equal parts. The folloing number is also a positive integer K ( K < 10^9).
Output
There may have many positive integers X,Y can meet such conditions.But you should calculate the Kth smaller answer of X. The Kth smaller answer means there are K – 1 answers are smaller than them. Beacuse the answer may be very large.So print the value of X % 8191.If there is no answers can meet such conditions,print “No answers can meet such conditions”.
Sample Input
2 999888
3 1000001
4 8373
Sample Output
7181
600
No answers can meet such conditions
Author
B.A.C
Source
2010 “HDU-Sailormoon” Programming Contest
----------------------------------------.
题目大意:
南郭先生的故事想必大家都知道
就是最开始有X*X人
后来南郭走了
变成了N个Y*Y
之后题目给你一个N 和K
让你求满足题意的第K大的X值是多少。。。
解题思路:
题目显然能够得到下面的方程
XX=1+NYY
转化一下就是
XX-NYY=1
这就是标准的佩尔方程了 不知道佩尔方程的话可以先去百度下.
首先N很小 所以可以先暴力的跑出特解 然后用迭代的方式求得第K大的解
X(n)=X(n-1)X(1)+N*Y(n-1)Y(1)
Y(n)=X(n-1)Y(1)+Y(n-1)X(1)
因为K很大 所以要用矩阵优化一下
矩阵略
附本题代码
---------------------------------.
1 | # include <iostream> |
2016-09-21 21:39:52 Tabris_ 阅读数:300
博客爬取于2020-06-14 22:43:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52613712
题目链接:http://poj.org/problem?id=1305
-------------------------------.
Fermat vs. Pythagoras
Time Limit: 2000MSMemory Limit: 10000K
Total Submissions: 1561Accepted: 913
Description
Computer generated and assisted proofs and verification occupy a small niche in the realm of Computer Science. The first proof of the four-color problem was completed with the assistance of a computer program and current efforts in verification have succeeded in verifying the translation of high-level code down to the chip level.
This problem deals with computing quantities relating to part of Fermat’s Last Theorem: that there are no integer solutions of a^n + b^n = c^n for n > 2.
Given a positive integer N, you are to write a program that computes two quantities regarding the solution of x^2 + y^2 = z^2, where x, y, and z are constrained to be positive integers less than or equal to N. You are to compute the number of triples (x,y,z) such that x < y < z, and they are relatively prime, i.e., have no common divisor larger than 1. You are also to compute the number of values 0 < p <= N such that p is not part of any triple (not just relatively prime triples).
Input
The input consists of a sequence of positive integers, one per line. Each integer in the input file will be less than or equal to 1,000,000. Input is terminated by end-of-file
Output
For each integer N in the input file print two integers separated by a space. The first integer is the number of relatively prime triples (such that each component of the triple is <=N). The second number is the number of positive integers <=N that are not part of any triple whose components are all <=N. There should be one output line for each input line.
Sample Input
10
25
100
Sample Output
1 4
4 9
16 27
----------------------------.
题目大意 :
就是问你在小于N中选取三个元素能构成多少个本源毕达哥拉斯不等式与其中不能形成毕达哥拉斯不等式的元素有多少个
解题思路:
毕达哥拉斯不等式
x^2 + y^2 = z^2 (其实就是勾股定理)
本源毕达哥拉斯不等式就是满足gcd(x,y,z)==1时的毕格拉斯不等式;
毕达哥拉斯不等式有下列特点
x=m^2-n^2;
y=2mn;
z=m^2+n^2;
其中m+n为奇数
在本源毕达哥拉斯不等式中满足gcd(m,n)==1;
本题数据量很小 所以只需要枚举一下m,n就行了
附本题代码
----------------------------.
1 | # include<stdio.h> |
2016-09-21 20:04:19 Tabris_ 阅读数:375
博客爬取于2020-06-14 22:43:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52612567
题目链接:http://poj.org/problem?id=1091
---------------------------------.
1 | 跳蚤 |
------------------------------------.
题目大意:略
解题思路:
很明显的题目需要求解这么一个方程的解a[1]*x1+a[2]*x2+a[3]*x3+…+a[n]*xn+a[n+1]*m=1 (0<=a[i]<=m)
显然 满足方程式的解需要只需要满足
gcd(a[1],a[2],a[3]…a[n+1])==1 就行了
然后求解的过程就容易多了
就只求解M^N-gcd!=1 的方案数就行了
之后只要把M质因子分解 容斥一下就行了
引用这里
许多博客都举了这么一个例子:
例如:n=2,m=360
360=3^22^35 所有不满足条件的数列,最大公约数是360质因子的乘积,只要将这些组合去掉,就是要求的答案(不懂的慢慢揣摩)
那么就要先求出m的所有质因子,然后求出总的排列组合的个数,即题目中说的M^N,最后根据鸽巢原理求得最后答案。
公式为:ans=M^N-(有奇数个公因数的n元组)+(有偶数个公因数的n元组)。拿上面的例子来说就是
ans=m^n-( 有公因数2的n元组)- (有公因数3的n元组)- (有公因数5的n元组)+ (有公因数2,3的n元组) +(有公因数2,5的n元组)+ (有公因数3,5的n元组)- (有公因数2,3,5的n元组).
有公因数d的n元组,每个位置上有 (m/d)个选择(1 ~ m里面有m/d个d的倍数),根据乘法原理,可以得出有公因数d的n元组有 (m/d)^n 个.
附本题代码
------------------------.
1 | # include<stdio.h> |
2016-09-21 18:29:01 Tabris_ 阅读数:237
博客爬取于2020-06-14 22:43:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52611426
题目链接:http://poj.org/problem?id=2429
-----------------------------.
GCD & LCM Inverse
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 13908Accepted: 2572
Description
Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b. But what about the inverse? That is: given GCD and LCM, finding a and b.
Input
The input contains multiple test cases, each of which contains two positive integers, the GCD and the LCM. You can assume that these two numbers are both less than 2^63.
Output
For each test case, output a and b in ascending order. If there are multiple solutions, output the pair with smallest a + b.
Sample Input
3 60
Sample Output
12 15
---------------------------------------------.
题目大意:
就是给你两个数的GCD和LCM值 让你求出和最小的这两个数
解题思路:
lcm=a/gcdb;
lcm/gcd=a/gcdb/gcd;
然后把lcm/gcd 这个结果质因子分解一下就行了
然后DFS求解和最小的值…
附本题代码
--------------------------------.
1 | /*******************Miller_Rabin素数测试&&Pollard_rho整数分解**************************/ |
2016-09-20 17:32:57 Tabris_ 阅读数:653
博客爬取于2020-06-14 22:43:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52598186
算法原理:https://en.wikipedia.org/wiki/Prime-counting_function
这是一篇对素数问题描述非常详细的一篇博客了
代码一:
复杂度大概O(n^(3/4))
1 | # include <bits/stdc++.h> |
代码二:
复杂度大概O(n^(2/3))
1 | # include<cstdio> |
代码一:
复杂度大概O(n^(3/4))
1 | # include <bits/stdc++.h> |
代码二:
复杂度大概O(n^(2/3))
1 | # include <cstring> |
2016-09-19 20:02:35 Tabris_ 阅读数:454
博客爬取于2020-06-14 22:43:15
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52588817
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895
------------------------.
Mathematician QSC
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 222 Accepted Submission(s): 109
Problem Description
QSC dream of becoming a mathematician, he believes that everything in this world has a mathematical law.
Through unremitting efforts, one day he finally found the QSC sequence, it is a very magical sequence, can be calculated by a series of calculations to predict the results of a course of a semester of a student.
This sequence is such like that, first of all,f(0)=0,f(1)=1,f(n)=f(n−2)+2∗f(n−1)(n≥2)Then the definition of the QSC sequence is g(n)=∑ni=0f(i)^2. If we know the birthday of the student is n, the year at the beginning of the semester is y, the course number x and the course total score s, then the forecast mark is x^g(n∗y)%(s+1).
QSC sequence published caused a sensation, after a number of students to find out the results of the prediction is very accurate, the shortcoming is the complex calculation. As clever as you are, can you write a program to predict the mark?
Input
First line is an integer T(1≤T≤1000).
The next T lines were given n, y, x, s, respectively.
n、x is 8 bits decimal integer, for example, 00001234.
y is 4 bits decimal integer, for example, 1234.
n、x、y are not negetive.
1≤s≤100000000
Output
For each test case the output is only one integer number ans in a line.
Sample Input
2
20160830 2016 12345678 666
20101010 2014 03030303 333
Sample Output
1
317
Source
2016 ACM/ICPC Asia Regional Shenyang Online
------------------------.
题目大意:
就是给你四个数n,y,x,s,
让你求x^g(n∗y)%(s+1).
其中g(n)=∑(i->n)f(i)^2;
f(0)=0,f(1)=1,f(n)=f(n−2)+2∗f(n−1)(n≥2)
解题思路:
对于x的指数g(n) 是一个很大的数 所以需要想办法把它改成我们能计算的 就是欧拉降幂
然后只要求解g(n)就行了
很容易的想到g(n)=f(n)*f(n+1)/2 其中f(n)只用一个矩阵加速就能很快地求解
但是随后发现这样并不行 因为f(n)已经是对Phi(s+1)取模之后的数了 在/2之后之就会出错 然后想到求逆元的办法解决 但是随后发现虽然2是一个质数但是并不能满足gcd(2,s+1)==1 因为s+1%2可能等于0 于是这个思路就GG了。。。
最后还是看了ICPCCamp的题解 才知道解法
最终还是一个矩阵快速幂
(f[n]^2,f[n+1]^2,f[n]*f[n+1],g[n])
↑这是左矩阵
[0,1,0,0]
[1,4,2,1]
[0,4,1,0]
[0,0,0,1] ←这是右矩阵
是这么解释的
相信你已经看懂了
//
就是思维太局限了 首先欧拉降幂不知道
再后来矩阵不会构造 导致这场的GG。。
//
附本题代码
--------------------------------------.
1 | # include<bits/stdc++.h> |
2016-09-18 22:01:52 Tabris_ 阅读数:316
博客爬取于2020-06-14 22:43:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52578407
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5898
-----------------------------------------------------------.
odd-even number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 125 Accepted Submission(s): 66
Problem Description
For a number,if the length of continuous odd digits is even and the length of continuous even digits is odd,we call it odd-even number.Now we want to know the amount of odd-even number between L,R(1<=L<=R<= 9*10^18).
Input
First line a t,then t cases.every line contains two integers L and R.
Output
Print the output for each case on one line in the format as shown below.
Sample Input
2
1 100
110 220
Sample Output
Case #1: 29
Case #2: 36
Source
2016 ACM/ICPC Asia Regional Shenyang Online
--------------------------------------.
题目大意:
就是统计区间内满足连续奇数个数为偶数且连续偶数为奇数的数的个数
解题思路 :
很明显一道数位DP
鄙人用的是记忆化搜索
开了4维数组
LL dp[30][3][30][3];
分别是位数 奇偶 正在判断的连续奇偶的长度 满不满足的状态
LL dfs(int pos,int pre,int x,int limit,int status,int lengh)
分别是位数/上一位的数字/上一位数字的奇偶性/数位的限制/满不满足的状态/正在判断的连续奇偶的长度
然后转移的时候注意的就是前导0的情况不要当成偶的数字给统计了 否则数会多
数位DP无非就三点
数组怎么开
记忆化搜索的参数
转移的过程
↑上面3点都解决了 相信数位DP的题目就解决了。
平时为了验证数位DP的正确性 在小数据的时候把记忆化注释掉了 交题的时候没改回来 就这样TLE了一发。。。GG
但也终于在比赛中AC了一道数位DP 也算是小进步
附本题代码
--------------------------------.
1 | # include <stdio.h> |
2016-09-16 17:15:30 Tabris_ 阅读数:1428
博客爬取于2020-06-14 22:43:17
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52556618
题目链接:http://poj.org/problem?id=2142
--------------------------------------------.
The Balance
Time Limit: 5000MSMemory Limit: 65536K
Total Submissions: 5998Accepted: 2610
Description
Ms. Iyo Kiffa-Australis has a balance and only two kinds of weights to measure a dose of medicine. For example, to measure 200mg of aspirin using 300mg weights and 700mg weights, she can put one 700mg weight on the side of the medicine and three 300mg weights on the opposite side (Figure 1). Although she could put four 300mg weights on the medicine side and two 700mg weights on the other (Figure 2), she would not choose this solution because it is less convenient to use more weights.
You are asked to help her by calculating how many weights are required.
Input
The input is a sequence of datasets. A dataset is a line containing three positive integers a, b, and d separated by a space. The following relations hold: a != b, a <= 10000, b <= 10000, and d <= 50000. You may assume that it is possible to measure d mg using a combination of a mg and b mg weights. In other words, you need not consider “no solution” cases.
The end of the input is indicated by a line containing three zeros separated by a space. It is not a dataset.
Output
The output should be composed of lines, each corresponding to an input dataset (a, b, d). An output line should contain two nonnegative integers x and y separated by a space. They should satisfy the following three conditions.
You can measure dmg using x many amg weights and y many bmg weights.
The total number of weights (x + y) is the smallest among those pairs of nonnegative integers satisfying the previous condition.
The total mass of weights (ax + by) is the smallest among those pairs of nonnegative integers satisfying the previous two conditions.
No extra characters (e.g. extra spaces) should appear in the output.
Sample Input
700 300 200
500 200 300
500 200 500
275 110 330
275 110 385
648 375 4002
3 1 10000
0 0 0
Sample Output
1 3
1 1
1 0
0 3
1 1
49 74
3333 1
Source
--------------------------.
题目大意 :
就是有一个天平 现在你要称N质量的物体
你只有a,b两种质量的砝码若干
问你最少需要每种砝码多少个才能称出N质量的物体
(要求在个数相同的时候选取砝码质量和最少的组合)
解题思路:
这道题目其实很简单 打眼一瞅就知道是一个扩展欧几里得
但是对于怎么输出最小的解得组合 这点就不太容易了
其实呢也不难 稍加分析就能得到结果了
首先呢
运用扩展欧几里得能够求出x,y的任意一组解
这样的话 假如求x或y的最小正整数解释非常容易的
只要x=(x%a+a)%a y=(x%b+b)%b这样就行了
然后想 要求出|x|+|y|的最小值怎么办呢
其实无非是两种
一种是在x为最小正整数解的时候
另一种是在y为最小正整数解的时候
证明略(取数是稍微想一想就知道了)
知道这个就好了
最后把两种的结果一比较 就能得出符合题意的解了
附本题代码
------------------.
1 | # include <stdio.h> |
2016-09-16 14:01:15 Tabris_ 阅读数:677
博客爬取于2020-06-14 22:43:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52555267
题目链接:http://poj.org/problem?id=2689
-------------------------.
Prime Distance
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 16728Accepted: 4450
Description
The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no proper factors (it is only evenly divisible by 1 and itself). The first prime numbers are 2,3,5,7 but they quickly become less frequent. One of the interesting questions is how dense they are in various ranges. Adjacent primes are two numbers that are both primes, but there are no other prime numbers between the adjacent primes. For example, 2,3 are the only adjacent primes that are also adjacent numbers.
Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).
Input
Each line of input will contain two positive integers, L and U, with L < U. The difference between L and U will not exceed 1,000,000.
Output
For each L and U, the output will either be the statement that there are no adjacent primes (because there are less than two primes between the two given numbers) or a line giving the two pairs of adjacent primes.
Sample Input
2 17
14 17
Sample Output
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
---------------------------------------.
题目大意:
就是给定一个区间L,U∈[1,2147483647] U-L∈[1 000 000] 让你求出这个区间内距离最近和距离最远的两个素数对
解题思路 :
看似不难的题目因为给了[1,2147483647] 这么一个数据范围变得似乎不可解了
其实并不难 至少出题人还给了区间范围≤1 000 000 这么人性化的一个设定
我们考虑的事求出区间内的素数
其实也就是求出区间内的合数 剩下的就是素数了
这道题目显然不能用朴素的素数测试了 然后想到筛法 但是筛法并不能筛[1,2147483647] 这么大范围的素数
这时候根据朴素测试想到选取素数只需要选取其根号下的范围即可
这样范围就缩小到[1,(1<<16)] 这么小的范围了 然后筛法就行了
最后要确定的是[L,U]区间内的素数个数 同样 我们只要晒出合数就行了
筛的代码也很好实现
1 | for(LL i=0; i<k; i++) |
上述代码应该很好理解 就是找[1,(1<<16)] 范围内质数的倍数 也就是[L,U]范围内的合数 其实就是筛法选素数 一样的
然后遍历一下 把[L,U]内的素数记录下来
最后在遍历一下 找一下符合题意的素数对就行了
当然上述两行是可以在一次遍历中实现的 有兴趣的话 可以自己实现一下
附本题代码
--------------------------.
1 | # include <stdio.h> |
2016-09-14 14:25:00 Tabris_ 阅读数:700
博客爬取于2020-06-14 22:43:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52537683
题目链接:http://codeforces.com/contest/714/problem/C
-------------------------------------.
C. Sonya and Queries
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Today Sonya learned about long integers and invited all her friends to share the fun. Sonya has an initially empty multiset with integers. Friends give her t queries, each of one of the following type:
Input
The first line of the input contains an integer t (1 ≤ t ≤ 100 000) — the number of operation Sonya has to perform.
Next t lines provide the descriptions of the queries in order they appear in the input file. The i-th row starts with a character ci — the type of the corresponding operation. If ci is equal to ‘+’ or ‘-’ then it’s followed by a space and an integer ai (0 ≤ ai < 1018) given without leading zeroes (unless it’s 0). If ci equals ‘?’ then it’s followed by a space and a sequence of zeroes and onse, giving the pattern of length no more than 18.
It’s guaranteed that there will be at least one query of type ‘?’.
It’s guaranteed that any time some integer is removed from the multiset, there will be at least one occurrence of this integer in it.
Output
For each query of the third type print the number of integers matching the given pattern. Each integer is counted as many times, as it appears in the multiset at this moment of time.
Examples
input
12
1 and 241.
361.
101 and 361.
361.
4000.
-----------------------------------.
题目大意:(懂不懂题目的我眼泪掉下来~~~)
就是有一个multiset 这么一个容器
有三种操作
解题思路 :
就是维护一个map
映射的事这个状态下的个数
然后就能在O(18n)的复杂度中求解出来了
附本题代码
----------------------------.
1 | # include <bits/stdc++.h> |
2016-09-13 17:00:13 Tabris_ 阅读数:278
博客爬取于2020-06-14 22:43:20
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52527503
题目链接 : http://poj.org/problem?id=3233
-----------------------------------------.
Matrix Power Series
Time Limit: 3000MSMemory Limit: 131072K
Total Submissions: 20930Accepted: 8760
Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4
0 1
1 1
Sample Output
1 2
2 3
Source
------------------------------------------.
题目大意:
不用解释了吧 就是求Sn
Sn = A + A^2 + A^3 + … + A^k.
解题思路:
这种题目一定想到矩阵快速幂
然后就是怎么构造矩阵了
[A O] 乘 [A E] 等 [A^2 S1]
[O O] 号 [O E]号 [O S0]
矩阵大致就是这么构造出来的
然后注意的事E只有主对角线是1 剩下的都是0 (Sb的我全写成E然后WA的都怀疑人生了)
附本题代码
-----------------------------------.
1 | # include <stdio.h> |
2016-09-13 12:29:47 Tabris_ 阅读数:405
博客爬取于2020-06-14 22:43:21
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52524819
题目链接:http://poj.org/problem?id=2115
----------------------------------.
C Looooops
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 24028Accepted: 6658
Description
A Compiler Mystery: We are given a C-language style for loop of type
for (variable = A; variable != B; variable += C)
statement;
I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2k) modulo 2k.
Input
The input consists of several instances. Each instance is described by a single line with four integers A, B, C, k separated by a single space. The integer k (1 <= k <= 32) is the number of bits of the control variable of the loop and A, B, C (0 <= A, B, C < 2k) are the parameters of the loop.
The input is finished by a line containing four zeros.
Output
The output consists of several lines corresponding to the instances on the input. The i-th line contains either the number of executions of the statement in the i-th instance (a single integer number) or the word FOREVER if the loop does not terminate.
Sample Input
3 3 2 16
3 7 2 16
7 3 2 16
3 4 2 16
0 0 0 0
Sample Output
0
2
32766
FOREVER
Source
CTU Open 2004
------------------------------------------------------.
题目大意 :
就是 给你a,b,c,k
问你这个循环 能不能被跳出 能的话跳出所需的最小循环次数是多少
for (variable = A; variable != B; variable += C)
其实稍转化下就是这个了
在方程a+xc≡b(mod 2^k)中求取x的最小正整数解
解题思路 :
根据题意很明显的知道
a+xc=b+y(2^k)
然后移项 就得到了这么一个标准的二元一次不定方程
b-a=xc-y(2^k)
最后扩展欧几里得求解一下就行了
求解出来的数应该是这样
(c,2^k)=xc-y(2^k)
设(c,2^k) = d;
然后原式就改成了这样
(b-a)/dxc-(b-a)/ry*(2^k)=b-a
结果就是
x = (b-a)/d*x;
最后去一下最小整数解
x = (x%(2^k)+(2^k))%(2^k);
如果是最小正整数解得话 还得
if(x==0) x=2^k;
!!!最最重要的是POJ交G++要用I64 然而VJ上告诉的是lld WA了无数发 还是最后看了代码才知道5555555555555
附本题代码
----------------------------------.
1 | # include <stdio.h> |
2016-09-12 00:25:33 Tabris_ 阅读数:290
博客爬取于2020-06-14 22:43:22
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52509493
题目连接:http://poj.org/problem?id=2769
-------------------------------.
Reduced ID Numbers
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 9927Accepted: 3960
Description
T. Chur teaches various groups of students at university U. Every U-student has a unique Student Identification Number (SIN). A SIN s is an integer in the range 0 ≤ s ≤ MaxSIN with MaxSIN = 106-1. T. Chur finds this range of SINs too large for identification within her groups. For each group, she wants to find the smallest positive integer m, such that within the group all SINs reduced modulo m are unique.
Input
On the first line of the input is a single positive integer N, telling the number of test cases (groups) to follow. Each case starts with one line containing the integer G (1 ≤ G ≤ 300): the number of students in the group. The following G lines each contain one SIN. The SINs within a group are distinct, though not necessarily sorted.
Output
For each test case, output one line containing the smallest modulus m, such that all SINs reduced modulo m are distinct.
Sample Input
2
1
124866
3
124866
111111
987651
Sample Output
1
8
Source
Northwestern Europe 2005
--------------------------------------.
题目大意:
就是给你N个数(ni<1e6) 找一个数使得这N个数都不同于这个数 输出最小的这个数
解题思路:
开始一顿推公式 推啊推 然后发现根本推不出来 ;
然后看了一下数据范围 发现N*1e6 时间给的就是2S 暴力就行了啊
然后就这样水过去了。。。。
从1开始枚举就行了 然后判断下所有数对其求余的值 然后hash记录一下 就能判断行不行了 行了就直接输出 不行就接着枚举 因为数值最大只有1e6 所以最后肯定有一个数能满足题意。。。。
最讨厌做这种暴力题目了 说难真不难 但是我这种ZZ根本不想搞暴力 结果就各种GG
其实还是思维定式太重了 想问题 越来越极限。。。
附本题代码
-----------------------------------------。
1 | # include <stdio.h> |
2016-09-11 17:03:47 Tabris_ 阅读数:366
博客爬取于2020-06-14 22:43:23
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52504739
题目链接:http://vjudge.net/contest/132006#problem/I
------------------------------------------.
I - X问题
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit
Status
Description
求在小于等于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 < a[i] <= 10)。
Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。
Output
对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。
Sample Input
3
10 3
1 2 3
0 1 2
100 7
3 4 5 6 7 8 9
1 2 3 4 5 6 7
10000 10
1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9
Sample Output
1
0
3
--------------------------.
题目大意:中文题 不解释
解题思路 :
裸的解一元线性同余方程组
不同于中国剩余定理 因为a[i]不互质
不懂如何解一元线性同余方程组的可以看这篇博客 http://m.blog.csdn.net/article/details?id=50887445
其实还是很好懂的 明白了如何处理3个式子 就明白了
但注意的是最后的结果问的是(0,N]之间有多少个满足的X值的个数而不是X的值 Ps:正整数 不能算0…
附本题代码
-------------------------------;
1 | # include <bits/stdc++.h> |
2016-09-11 13:36:33 Tabris_ 阅读数:475
博客爬取于2020-06-14 22:43:25
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52503620
题目链接:http://codeforces.com/contest/712/problem/C
--------------------------.
C. Memory and De-Evolution
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Memory is now interested in the de-evolution of objects, specifically triangles. He starts with an equilateral triangle of side length x, and he wishes to perform operations to obtain an equilateral triangle of side length y.
In a single second, he can modify the length of a single side of the current triangle such that it remains a non-degenerate triangle (triangle of positive area). At any moment of time, the length of each side should be integer.
What is the minimum number of seconds required for Memory to obtain the equilateral triangle of side length y?
Input
The first and only line contains two integers x and y (3 ≤ y < x ≤ 100 000) — the starting and ending equilateral triangle side lengths respectively.
Output
Print a single integer — the minimum number of seconds required for Memory to obtain the equilateral triangle of side length y if he starts with the equilateral triangle of side length x.
Examples
input
6 3
output
4
input
8 5
output
3
input
22 4
output
6
Note
In the first sample test, Memory starts with an equilateral triangle of side length 6 and wants one of side length 3. Denote a triangle with sides a, b, and c as (a, b, c). Then, Memory can do .
In the second sample test, Memory can do .
In the third sample test, Memory can do:
-----------------------------------------------.
题目大意 : 就是给你两个数 一大一小 分别是两个正三角形 问你把大的正三角形变成小的三角形的最少操作次数
操作的要求如下
1.每次只能对三角形的一条边操作
2.每次操作后的三条边都能构成三角形
解题思路 :
开始正着想 只能过样例
后来在队友的提示下 采取逆向思维
题目不是从大的变到小的么
我们求从小的变到大的的最小操作次数 反过来操作就是大的变小的了
然后就是每次把最小的那一条边 变成 其他两边和-1 (-1是因为要构成三角形)
然后暴力就行了
附本题代码
-----------------------------.
1 | # include <bits/stdc++.h> |
2016-09-10 19:53:11 Tabris_ 阅读数:1446
博客爬取于2020-06-14 22:43:26
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52496677
题目连接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5874
---------------------------------------.
Friends and Enemies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 26 Accepted Submission(s): 14
Problem Description
On an isolated island, lived some dwarves. A king (not a dwarf) ruled the island and the seas nearby, there are abundant cobblestones of varying colors on the island. Every two dwarves on the island are either friends or enemies. One day, the king demanded that each dwarf on the island (not including the king himself, of course) wear a stone necklace according to the following rules:
For any two dwarves, if they are friends, at least one of the stones from each of their necklaces are of the same color; and if they are enemies, any two stones from each of their necklaces should be of different colors. Note that a necklace can be empty.
Now, given the population and the number of colors of stones on the island, you are going to judge if it’s possible for each dwarf to prepare himself a necklace.
Input
Multiple test cases, process till end of the input.
For each test case, the one and only line contains 2 positive integers M,N (M,N<231) representing the total number of dwarves (not including the king) and the number of colors of stones on the island.
Output
For each test case, The one and only line of output should contain a character indicating if it is possible to finish the king’s assignment. Output T" (without quotes) if possible,
F" (without quotes) otherwise.
Sample Input
20 100
Sample Output
T
Source
2016 ACM/ICPC Asia Regional Dalian Online
-------------------------------------------------------------.
题目大意:
就是有M个人N种颜色的石头 M个人中每两个人 不是朋友就是敌人
现在他们每个人要用石头要串一条项链 要求是
1.朋友之间的项链至少有一个相同颜色的石头
2.敌人之间没有颜色相同的石头
3.项链可以使空的 就是不串石头
问N种颜色的石头能不能满足这M个人
解题思路:
比赛的时候队友说是二分图 然后让我毫不犹豫的给否定了 然后就GG了.. 谁能告诉我这是一种什么样的体验.. 网络赛再次坑了队友一波.. O(T_T)O
看题吧 问能不能满足 肯定是要和最坏的情况比较 也就是求最坏的情况下需要多少种颜色的石子
根据两个人的关系只有朋友和敌人这点 就可以相像成一个二分图了 分别在两侧的人是朋友 (比赛的时候居然想成了同侧的是朋友 就这样吧队友坑了) 这样的话 就是求一个完全二分图的边数有多少就行了
因为M个人 想要边数最多 所以尽量均分 左右两边个一般就行了
这样的话 边数就是m/2*(m-m/2);
之后跟N比一下就好了 。。
这么水的题目 。。。
我。、
附本题代码
-------------------------------。
1 | # include <bits/stdc++.h> |
2016-09-09 13:07:02 Tabris_ 阅读数:345
博客爬取于2020-06-14 22:43:27
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52486102
题目链接:http://codeforces.com/contest/552/problem/C
--------------------------------------.
C. Vanya and Scales
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vanya has a scales for weighing loads and weights of masses w0, w1, w2, …, w100 grams where w is some integer not less than 2 (exactly one weight of each nominal value). Vanya wonders whether he can weight an item with mass m using the given weights, if the weights can be put on both pans of the scales. Formally speaking, your task is to determine whether it is possible to place an item of mass m and some weights on the left pan of the scales, and some weights on the right pan of the scales so that the pans of the scales were in balance.
Input
The first line contains two integers w, m (2 ≤ w ≤ 109, 1 ≤ m ≤ 109) — the number defining the masses of the weights and the mass of the item.
Output
Print word ‘YES’ if the item can be weighted and ‘NO’ if it cannot.
Examples
input
3 7
output
YES
input
100 99
output
YES
input
100 50
output
NO
Note
Note to the first sample test. One pan can have an item of mass 7 and a weight of mass 3, and the second pan can have two weights of masses 9 and 1, correspondingly. Then 7 + 3 = 9 + 1.
Note to the second sample test. One pan of the scales can have an item of mass 99 and the weight of mass 1, and the second pan can have the weight of mass 100.
Note to the third sample test. It is impossible to measure the weight of the item in the manner described in the input.
---------------------------------------------------------------.
题目大意 :
就是有w^0,w^1,W^2…w^100 ,这么些个砝码 每种砝码各一个 问用这些砝码能不能称出m质量
解题思路:
就是正常使用天平 模拟下就好了
注意的是砝码可以放到天平的右边 且每种砝码只有一个
这样的话 只要判断是不是有那种砝码使用超过1次就行了
判断的时候其实就是把m写成w进制数就好了
每一数位上的数字就是对应的砝码用了多少次 所以只可能为 0 or 1 or w-1;
0和1 很好理解
为啥好友w-1呢
其实这么想 就是w^i 和w^(i+1)组成的 就是这两个放在的两边而已
所以只要这么判断就行了
1 | for(int i=0; i<k; i++) |
附本题代码
------------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-09-07 19:32:43 Tabris_ 阅读数:530
博客爬取于2020-06-14 22:43:28
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52462508
题目链接:http://codeforces.com/contest/354/problem/A
-----------------------------------------------.
A. Vasya and Robot
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya has n items lying in a line. The items are consecutively numbered by numbers from 1 to n in such a way that the leftmost item has number 1, the rightmost item has number n. Each item has a weight, the i-th item weights wi kilograms.
Vasya needs to collect all these items, however he won’t do it by himself. He uses his brand new robot. The robot has two different arms — the left one and the right one. The robot can consecutively perform the following actions:
Take the leftmost item with the left hand and spend wi · l energy units (wi is a weight of the leftmost item, l is some parameter). If the previous action was the same (left-hand), then the robot spends extra Ql energy units;
Take the rightmost item with the right hand and spend wj · r energy units (wj is a weight of the rightmost item, r is some parameter). If the previous action was the same (right-hand), then the robot spends extra Qr energy units;
Naturally, Vasya wants to program the robot in a way that the robot spends as little energy as possible. He asked you to solve this problem. Your task is to find the minimum number of energy units robot spends to collect all items.
Input
The first line contains five integers n, l, r, Ql, Qr (1 ≤ n ≤ 105; 1 ≤ l, r ≤ 100; 1 ≤ Ql, Qr ≤ 104).
The second line contains n integers w1, w2, …, wn (1 ≤ wi ≤ 100).
Output
In the single line print a single number — the answer to the problem.
Examples
input
3 4 4 19 1
42 3 99
output
576
input
4 7 2 3 9
1 2 3 4
output
34
Note
Consider the first sample. As l = r, we can take an item in turns: first from the left side, then from the right one and last item from the left. In total the robot spends 4·42 + 4·99 + 4·3 = 576 energy units.
The second sample. The optimal solution is to take one item from the right, then one item from the left and two items from the right. In total the robot spends (2·4) + (7·1) + (2·3) + (2·2 + 9) = 34 energy units.
-----------------------------------------.
题目大意 :
就是有一排N个东西 从左到友质量分别是w1.w2。。。wn
有一个机器人搬 这个机器人有两只手 左手和右手的油耗分别是l,r ;
这个机器人正常情况下只能一只手搬一个东西之后另一只手搬 搬一个东西左手的损耗是wi* l 右手是wi*r ;
如果不换手的情况下左右手分别需要多耗油Ql,Qr ;
问搬完这么多东西最少花费是多少?
解题思路:
这道题目首先想到的是DP但是最后发现我渣不知道怎么转移
于是乎我就换了个思路 在纸上模拟了一下过程 最后发现 最后这些东西一定会有一个断点 断点的左边就是左手拿的 断点的右边就是右手拿的 这样在多想一下就发现 只要看左手拿的和右手拿的个数的差就能知道多耗费的油的个数有多少了
比如说:
7
1 2 3 4 5 6 7
比如说从某处断开
1 2 | 3 4 5 6 7
这时候左边的就是左手拿的 右边的就是右手拿的 过程可以是7 1 6 2 5 4 3 这样的话就多花费的就是 4 3 的这两个
当然你也可以 1 7 2 6 5 4 3 但这样的话多花费的就是5 4 3 这三个了 很明显不如前者好
从中也能够看出左右两边差<=1的时候是没有多的花费的
为了让多余的花费最少 所以我只要吧左右两边的错开 就能够最省了 最终多余花费也只有一边才有 另一边是不存在多余花费的
而每次都能够错开 每次多话费的也就是 两边之差-1
综上所述 这道题目就能够解了
附本题代码
-----------------------------------.
1 | # include <bits/stdc++.h> |
2016-09-07 13:38:21 Tabris_ 阅读数:699
博客爬取于2020-06-14 22:43:29
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52458744
题目链接:http://codeforces.com/problemset/problem/594/A
--------------------------------------------.
A. Warrior and Archer
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
In the official contest this problem has a different statement, for which jury’s solution was working incorrectly, and for this reason it was excluded from the contest. This mistake have been fixed and the current given problem statement and model solution corresponds to what jury wanted it to be during the contest.
Vova and Lesha are friends. They often meet at Vova’s place and compete against each other in a computer game named The Ancient Papyri: Swordsink. Vova always chooses a warrior as his fighter and Leshac chooses an archer. After that they should choose initial positions for their characters and start the fight. A warrior is good at melee combat, so Vova will try to make the distance between fighters as small as possible. An archer prefers to keep the enemy at a distance, so Lesha will try to make the initial distance as large as possible.
There are n (n is always even) possible starting positions for characters marked along the Ox axis. The positions are given by their distinct coordinates x1, x2, …, xn, two characters cannot end up at the same position.
Vova and Lesha take turns banning available positions, Vova moves first. During each turn one of the guys bans exactly one of the remaining positions. Banned positions cannot be used by both Vova and Lesha. They continue to make moves until there are only two possible positions remaining (thus, the total number of moves will be n - 2). After that Vova’s character takes the position with the lesser coordinate and Lesha’s character takes the position with the bigger coordinate and the guys start fighting.
Vova and Lesha are already tired by the game of choosing positions, as they need to play it before every fight, so they asked you (the developer of the The Ancient Papyri: Swordsink) to write a module that would automatically determine the distance at which the warrior and the archer will start fighting if both Vova and Lesha play optimally.
Input
The first line on the input contains a single integer n (2 ≤ n ≤ 200 000, n is even) — the number of positions available initially. The second line contains n distinct integers x1, x2, …, xn (0 ≤ xi ≤ 109), giving the coordinates of the corresponding positions.
Output
Print the distance between the warrior and the archer at the beginning of the fight, provided that both Vova and Lesha play optimally.
Examples
input
6
0 1 3 7 15 31
output
7
input
2
73 37
output
36
Note
In the first sample one of the optimum behavior of the players looks like that:
Vova bans the position at coordinate 15;
Lesha bans the position at coordinate 3;
Vova bans the position at coordinate 31;
Lesha bans the position at coordinate 1.
After these actions only positions 0 and 7 will remain, and the distance between them is equal to 7.
In the second sample there are only two possible positions, so there will be no bans.
--------------------------------------------.
题目大意 :
大概就是在一个坐标轴上 有N个点 然后有两个人 他们轮流去掉一个点 知道最后剩下两个点为止
其中呢 先手 是希望最后剩下的两个点距离最大
后手 是希望最后剩下的两个点距离最小
问的是 最后剩下的两个点距离最小是多少
解题思路:
做这道题的时候只想到可能是博弈其他的一点想法都没有 最后还是去查了题解 发现这种问题属于对称博弈
对称博弈大概就是有两个个体无角色区分的人且有着相同的运动区间 大致就这样
然后分析下这道题
转自这里
我们假设最后留下来的位置是l和r。
接下来我们要证明l和r之间的距离一定是n/2 - 1!
首先我们证明距离不会大于n/2 - 1。
假设距离 > n/2 - 1,那么显然Warrior肯定在其中选了一个位置。但是如果Warrior这么做,他完全可以放弃这个位置,去选L或者R,这样就能缩短最终距离。所以这种情况不可能。
既然如此,那么距离肯定是 <= n/2 - 1。Archer只能努力让距离保持在n/2 - 1。
Warrior的最优选择肯定是选择最左端或者最右端的空,Archer总是选 剩下能选择的空里的 中间那个空,所以到最后[L, R]之间Archer肯定能选择n/2 - 1步,也就是距离肯定是 n/2 - 1。
所以最终R - L = n / 2
于是乎 这道题就能解了。。。
附本题代码
-------------------------------.
1 | # include <bits/stdc++.h> |
2016-09-06 11:25:15 Tabris_ 阅读数:208
博客爬取于2020-06-14 22:43:30
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52448350
题目链接:http://codeforces.com/contest/344/problem/C
--------------------------------------------------.
C. Rational Resistance
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Mad scientist Mike is building a time machine in his spare time. To finish the work, he needs a resistor with a certain resistance value.
However, all Mike has is lots of identical resistors with unit resistance R0 = 1. Elements with other resistance can be constructed from these resistors. In this problem, we will consider the following as elements:
one resistor;
an element and one resistor plugged in sequence;
an element and one resistor plugged in parallel.
With the consecutive connection the resistance of the new element equals R = Re + R0. With the parallel connection the resistance of the new element equals . In this case Re equals the resistance of the element being connected.
Mike needs to assemble an element with a resistance equal to the fraction . Determine the smallest possible number of resistors he needs to make such an element.
Input
The single input line contains two space-separated integers a and b (1 ≤ a, b ≤ 1018). It is guaranteed that the fraction is irreducible. It is guaranteed that a solution always exists.
Output
Print a single number — the answer to the problem.
Please do not use the %lld specifier to read or write 64-bit integers in С++. It is recommended to use the cin, cout streams or the %I64d specifier.
Examples
input
1 1
output
1
input
3 2
output
3
input
199 200
output
200
Note
In the first sample, one resistor is enough.
In the second sample one can connect the resistors in parallel, take the resulting element and connect it to a third resistor consecutively. Then, we get an element with resistance . We cannot make this element using two resistors.
------------------------.
题目大意: 就是有N个阻值为1的电阻 可以串联 可以并联 问最受用多少个电阻 能组成a/b这么个阻值
解题思路:
很好想 主要就是考虑串并联的公式 如果a/b>1的话 写成代分数 形式的话 前面整数部分用串联的方式一定会是最少的 然后接下来剩下的假分数的阻值 把它掉过来 接着这么运算就行了 直到最后分数变成了整数为止
上述就是思路了 聪明的你是不是也发现了 上述过程其实就是一个简单的辗转相除法 只要在其中加上一个记录[a/b]的过程就行了
附本题代码
---------------.
1 | # include<bits/stdc++.h> |
2016-09-05 17:17:27 Tabris_ 阅读数:346
博客爬取于2020-06-14 22:43:31
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52441909
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1799
------------------------.
1799: 小Z的黑白棋
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 17 Solved: 9
[Submit][Status][Web Board]
Description
小Z有一些黑白棋,他觉得黑白混杂在一起极具美感,所以他总喜欢将这些棋子排成一排序列S1,但是小Y就喜欢跟小Z作对,她会趁小Z不注意偷偷将小Z最右边的棋子拿走,往他棋子序列的最左边添加一个白色的棋子形成一个新的序列S2来破坏小Z的美感。
S2(1~n) = 白棋+S1(i=1~n-1)
小Z总相信第一感,他认为他自己最初排好的序列S1是最完美的,新的序列S2会造成一定的破坏美感指数 = damage(S1) = S1与S2有多少个位置黑色与白色互不对应
Exp:
令白棋为a,黑棋为b :S1 = ababa S2=aabab damage(S1)=4
因为小Z有很多种摆放序列的方式,现在他希望让你帮他求所有摆放序列的方式会造成的damage(S1)的平均值
Input
多组数据输入输出
每组数据输入一个整数n和m表示白棋和黑棋的数量 0<=n , m<=1000,000,000 , 保证n+m>=1
Output
每组输出一个平均值答案,用最简分数表示,如果可以化简到整数,就用整数表示
Sample Input
1 1
Sample Output
3/2
---------------------------.
题目大意: 中文 不解释;
题解 :
本题因为数据比较大 显然不能暴力
根据是n种白棋m种黑棋 先到组合数学的思路
n个白棋和m个黑棋有C(m+n,n)种排列。
然后就一直在想怎么才能直接组合出结果呢 半天后发现我根本就想不到啊
然后换了一种思路
求每个点对结果的贡献 最后累加就行了
就是这个位置对结果贡献1的排列有多少种就行了 这是能够排列组合出来的
分为下面两种情况
1,第一个点为黑棋的有C(m+n-1,n)种 因为后来变成了白棋 那么这就是第1个位置对结果的贡献
C(m+n-1,n)
2,第i(i=1,2,3…m+n-1)个棋子和第i+1个棋子颜色不同的 有2C(m+n-2,n-1)种 因为后来会发生错位的情况 那么这就是第i个位置对结果的贡献
2C(m+n-2,n-1)(m+n-1)=2n*C(m+n-1,n)
最后一推倒 就出来了这么一个公式
(1+2*n)C(m+n-1,n)/C(m+n,n)
=(1+2n)*m/(m+n)
贡献式思维主要就是求每个位置能对最后的结果贡献了多少 最后累加就行了
附本题代码
----------------------.
1 | # include<bits/stdc++.h> |
2016-09-01 15:54:48 Tabris_ 阅读数:491
博客爬取于2020-06-14 22:43:32
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52400477
题目链接:http://codeforces.com/problemset/problem/664/B
---------------------------------.
B. Rebus
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a rebus of form ? + ? - ? + ? = n, consisting of only question marks, separated by arithmetic operation ‘+’ and ‘-’, equality and positive integer n. The goal is to replace each question mark with some positive integer from 1 to n, such that equality holds.
Input
The only line of the input contains a rebus. It’s guaranteed that it contains no more than 100 question marks, integer n is positive and doesn’t exceed 1 000 000, all letters and integers are separated by spaces, arithmetic operations are located only between question marks.
Output
The first line of the output should contain “Possible” (without quotes) if rebus has a solution and “Impossible” (without quotes) otherwise.
If the answer exists, the second line should contain any valid rebus with question marks replaced by integers from 1 to n. Follow the format given in the samples.
Examples
input
? + ? - ? + ? + ? = 42
output
Possible
9 + 13 - 39 + 28 + 31 = 42
input
? - ? = 1
output
Impossible
input
? = 1000000
output
Possible
1000000 = 1000000
------------------------------------------.
题目大意 :
就是把问好(?)的数用1~n填上 如果存在等式能够成立的情况就输出Possible 和这个等式 (有SPJ)
否则输出Impossible
题目分析:
先把加上的数有几个 减去的数有几个统计一下
然后把每个数都附上1
接着把差的数匀乎匀乎就行了
附本题代码
----------------------------------.
1 | # include<bits/stdc++.h> |
2016-09-01 14:02:59 Tabris_ 阅读数:1031
博客爬取于2020-06-14 22:43:33
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52399129
题目链接 : 太长了_传送阵<<–
------------------------------------.
A cellular automaton is a collection of cells on a grid of specified shape that evolves through a number
of discrete time steps according to a set of rules that describe the new state of a cell based on the states
of neighboring cells. The order of the cellular automaton is the number of cells it contains. Cells of the
automaton of order n are numbered from 1 to n.
The order of the cell is the number of different values it may contain. Usually, values of a cell of
order m are considered to be integer numbers from 0 to m − 1.
One of the most fundamental properties of a cellular automaton is the type of grid on which it
is computed. In this problem we examine the special kind of cellular automaton — circular cellular
automaton of order n with cells of order m. We will denote such kind of cellular automaton as n, m −
automaton.
A distance between cells i and j in n, m-automaton is defined as min(|i − j|, n − |i − j|). A denvironment
of a cell is the set of cells at a distance not greater than d.
On each d-step values of all cells are simultaneously replaced by new values. The new value of cell i
after d-step is computed as a sum of values of cells belonging to the d-enviroment of the cell i modulo
m.
The following picture shows 1-step of the 5,3-automaton.
The problem is to calculate the state of the n, m-automaton after k d-steps.
Input
The input file contains several test cases, each of them consists of two lines, as described below.
The first line of the input contains four integer numbers n, m, d, and k (1 ≤ n ≤ 500, 1 ≤ m ≤
1000000, 0 ≤ d < n
2
, 1 ≤ k ≤ 10000000). The second line contains n integer numbers from 0 to m − 1
— initial values of the automaton’s cells.
Output
For each test case, write to the output, on a line by itself, the values of the n, m-automaton’s cells after
k d-steps.
Sample Input
5 3 1 1
1 2 2 1 2
5 3 1 10
1 2 2 1 2
Sample Output
2 2 2 2 1
2 0 0 2 2
------------------------------------------------.
题目大意 :
就是有一个N这么大的环 现在有这样的操作每次选取每个数及其左右d个距离内的所有数的和 对m取模之后作为这个数的新值 问你K次操作后 每个数都是多少
解题思路 :
首先根据题中的 图片 观察了一下 发现这道题用矩阵快速幂能够解决
以题目图片为例 能构造出如下的矩阵
[1 1 0 0 1] 这 [1] = [2]
[1 1 1 0 0] 里 [2] = [2]
[0 1 1 1 0] 是 [2] = [2]
[0 0 1 1 1] 乘 [1] = [2]
[1 0 0 1 1] 号 [2] = [1]
然后写了一发矩阵快速幂
写完了 发现程序根本运行不了
找了N久BUG 最后在Q巨的指导下才知道 因为数组太大500*500 导致爆栈了
然后把 函数改成引用 就能运行了 但是还是不能A掉题
然后又找了N久的BUG 换了下思路 发现越来越乱
最后看了一波题解 才知道(如下)这玩意叫做循环矩阵
[1 1 0 0 1]
[1 1 1 0 0]
[0 1 1 1 0]
[0 0 1 1 1]
[1 0 0 1 1]
它的性质可以看着篇文章 后面的部分 目录里找矩阵快速幂就行了
http://blog.csdn.net/qq_33184171/article/details/51488462
然后终于优化到了N^2
结果最后的结果 莫名的PE PE PE!!! PE 了5 发我也是醉了 最醉了的是 到最后我也没明白为什么PE
然后找了一发大神的代码 直接AC了。。。
格式没问题啊,,,
然后就没有然后了 这题 做的太闹心了 在群里问问题的时候还被 菊菊们讽刺了一波。。。
算了 最后附上本题代码
-------------------------.
1 | # include <iostream> |
2016-08-31 15:57:33 Tabris_ 阅读数:227
博客爬取于2020-06-14 22:43:34
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52385951
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2109
--------------------------------.
Problem 2109 Mountain Number
Accept: 231 Submit: 592
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
One integer number x is called “Mountain Number” if:
(1) x>0 and x is an integer;
(2) Assume x=a[0]a[1]…a[len-2]a[len-1](0≤a[i]≤9, a[0] is positive). Any a[2i+1] is larger or equal to a[2i] and a[2i+2](if exists).
For example, 111, 132, 893, 7 are “Mountain Number” while 123, 10, 76889 are not “Mountain Number”.
Now you are given L and R, how many “Mountain Number” can be found between L and R (inclusive) ?
Input
The first line of the input contains an integer T (T≤100), indicating the number of test cases.
Then T cases, for any case, only two integers L and R (1≤L≤R≤1,000,000,000).
Output
For each test case, output the number of “Mountain Number” between L and R in a single line.
Sample Input
3
1 10
1 100
1 1000
Sample Output
9
54
384
Source
“高教社杯”第三届福建省大学生程序设计竞赛
---------------------------------------------------------------.
题目大意:
就是给你一个区间[l,r]
问你在这个区间内满足从高位起偶数位的数字要**>=**两边的数字 这样的有多少个
解题思路:
标准的数位DP
dp[第多少位][上一位的数字][奇数位or偶数位];
开这样一个数组 然后DP就行了
我用的记忆华搜索
dfs(int pos,int weishu,int pre,int limit)
dfs(第多少位,位数,上一位的数字,限制);
决策的时候
1 | for(int i=0; i<=endi; i++) |
如果觉得还是wrong的注意下输出是%lld 还是%I64d
%lld 就会返回wrong answer
还有就是FZU不支持 #include < bits/stdc++.h>
附本题代码
------------------------------------------------.
1 | # include <iostream> |
2016-08-27 17:33:29 Tabris_ 阅读数:380
博客爬取于2020-06-14 22:43:35
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52336164
题目链接:http://acm.nyist.edu.cn/JudgeOnline/status.php?pid=737
-------------------------------.
石子合并(一)
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
输入
有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
输出
输出总代价的最小值,占单独的一行
样例输入
3
1 2 3
7
13 7 8 16 21 4 18
样例输出
9
239
------------------------------------.
解题思路:
题目要求必须是相邻的两堆才能合并 所以不能用优先队列处理
想到区间dp
dp[i][j] 表示i~j区间内的最小花费
每次维护区间合并的最小值 即可
但要注意 花费的问题是累加的 所以每一次区间的维护中应该加上区间内所有的和 用前缀和处理
状态转移方程是
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
当然本题也可以采用平行四边形优化 跑的能跟快一点
方法是 用另外一个数组记录最有分割点 也就是枚举的K
附本题代码
--------------------------.
1 | //#include <bits/stdc++.h> |
2016-08-27 14:49:48 Tabris_ 阅读数:420
博客爬取于2020-06-14 22:43:37
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52335175
题目链接: http://poj.org/problem?id=2955
---------------------------------.
Brackets
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 6430Accepted: 3443
Description
We give the following inductive definition of a “regular brackets” sequence:
the empty sequence is a regular brackets sequence,
if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
if a and b are regular brackets sequences, then ab is a regular brackets sequence.
no other sequence is a regular brackets sequence
For instance, all of the following character sequences are regular brackets sequences:
(), [], (()), ()[], ()[()]
while the following character sequences are not:
(, ], )(, ([)], ([(]
Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1, i2, …, im where 1 ≤ i1 < i2 < … < im ≤ n, ai1ai2 … aim is a regular brackets sequence.
Given the initial sequence ([([]])], the longest regular brackets subsequence is [([])].
Input
The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters (, ), [, and ]; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.
Output
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
Sample Input
((()))
()()()
([]])
)[)(
([][][)
end
Sample Output
6
6
4
0
6
题目大意:就是问你 整个区间内 不连续的能匹配上的括号的总数
解题思路:
区间DP
dp[i][j] = i~j 区间内能够匹配的括号的个数
很简单 详见代码吧
附本题代码
----------------------------------------.
1 | //#include <bits/stdc++.h> |
2016-08-26 23:24:05 Tabris_ 阅读数:1697
博客爬取于2020-06-14 22:43:38
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52332586
题目连接 : http://codeforces.com/problemset/problem/55/D
-------------------------------.
D. Beautiful numbers
time limit per test4 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.
Input
The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·10^18).
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).
Output
Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).
Examples
input
1
1 9
output
9
input
1
12 15
output
2
---------------------------------.
题目大意 :
就是求区间内能被所有位上的数字(!0)整除的数的个数
解题思路 :
困了 明天再写吧,,
首先这很明显是一个数位DP
满足被所有位上的数字(!0)整除的数 其实就是满足被这些位数的lcm整除
然后就是怎么处理一个数在不断变化中 还要对lcm{xi}取模呢
这时候就要仔细思索其中的奥妙 也是本题最重要的一点.
首先lcm{1~9}=2520;
想到每个数都是1~9中某些数字的lcm 所以他们一定能整除2520
因为 若a≡b(mod m) 且d|m 则a≡b(mod d);
转化一下设b已经是对m取完模的了
于是得到 若a % m=b%m 且d|m 则a % d = b%d;
因为 **b=b%m ** 所以 b=b%m=b%d
所以 b%m%m=b%d%m
所以 b%m=b%d(km)%m
所以可以得到下 x%km%m<=>x%m
综上所述 x%2520%lcm{xi}==0 ; 是满足条件
而x%2520 是可以确定的 和大数取模类似
mod = (mod*10+本位数字)%2520 ;
所以我们开数组的时候要有x%2520 和lcm{xi}这两项 再加上位数 所以 数组应该这么开
dp[位数][x%2520][lcm{xi}];
但是这么开的话是这样的 dp[19][2520][2520] 1925202520 = 120657600 即使CF提供的256M的内存也会炸的不要不要的
所以得想办法优化一下
然后就想啊想 终于~~
想到每个数只能是1~9的最小公倍数 所以计算了下 所有的lcm一共有48种可 能 如下:
1 2 3 4 5 6 7 8 9 10 12 14 15 18 20 21 24 28 30 35 36 40 42 45 56 60 63 70 72 84 90 105 120 126 140 168 180 210 252 280 315 360 420 504 630 840 1260 2520
共计48种
然后就可以离散化一下 这样 dp[19][2520][2520]–>dp[19][2520][48]; 降低了空间复杂度 就可以AC了;
其实还可以继续优化 因为上面的结论 所以 %2520 <=>%252的 所以最后的数组可以优化到dp[19][252][48];
这样的时空复杂度均能得到下降
大家可以自己试一试
附本题代码
------------------------------------.
1 | # include <bits/stdc++.h> |
2016-08-25 23:11:27 Tabris_ 阅读数:323
博客爬取于2020-06-14 22:43:39
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52319408
题目连接:http://poj.org/problem?id=3252
-----------------------------.
Round Numbers
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 12190Accepted: 4629
Description
The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone’ (also known as ‘Rock, Paper, Scissors’, ‘Ro, Sham, Bo’, and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can’t even flip a coin because it’s so hard to toss using hooves.
They have thus resorted to “round number” matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both “round numbers”, the first cow wins,
otherwise the second cow wins.
A positive integer N is said to be a “round number” if the binary representation of N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus, 9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.
Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many “round numbers” are in a given range.
Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤ Start < Finish ≤ 2,000,000,000).
Input
Line 1: Two space-separated integers, respectively Start and Finish.
Output
Line 1: A single integer that is the count of round numbers in the inclusive range Start…Finish
Sample Input
2 12
Sample Output
6
Source
USACO 2006 November Silver
---------------------------.
题目大意 :
就是计算出区间[first,end]之间 二进制下 不含前导0且0的个数比1的个数多少的数的个数
解题思路:
跟人用的数位DP
后来看网上的题解 有用组合数学 解决的 有兴趣的话 可以去看一下 .
数位DP 就没什么好解释的了 分别记录下0和1的个数 然后DP就行了
DP[当前位数][1的个数][0的个数];;;
dfs(当前位数,被没被放过,1的个数,0的个数,数字限制);
但是在DP中鄙人出现了一个大的BUG 那就是如下的代码(问题已解决)
1 | /*在for循环的时候 鄙人最开始使用下面注释掉的方式写的代码 |
上面的问题 主要是tji,tou值的初始化有问题
改成这样就行了
1 | { |
我那样的话值会错误的非常离谱因为判断的时候判断的就是ji,ou加不加1 的问题 而我渣忽略了没有操作的情况 导致值变成了0 最终造成结果错误 …
/真TMZZ/
附本题代码
-------------------------------.
1 | //#include <bits/stdc++.h> |
2016-08-25 20:07:46 Tabris_ 阅读数:286
博客爬取于2020-06-14 22:43:40
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52317803
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3709
------------------------------.
Balanced Number
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 4621 Accepted Submission(s): 2169
Problem Description
A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the number, the distance from a digit to the pivot is the offset between it and the pivot. Then the torques of left part and right part can be calculated. It is balanced if they are the same. A balanced number must be balanced with the pivot at some of its digits. For example, 4139 is a balanced number with pivot fixed at 3. The torqueses are 42 + 11 = 9 and 9*1 = 9, for left part and right part, respectively. It’s your job
to calculate the number of balanced numbers in a given range [x, y].
Input
The input contains multiple test cases. The first line is the total number of cases T (0 < T ≤ 30). For each case, there are two integers separated by a space in a line, x and y. (0 ≤ x ≤ y ≤ 1018).
Output
For each case, print the number of balanced numbers in the range [x, y] in a line.
Sample Input
2
0 9
7604 24324
Sample Output
10
897
Author
GAO, Yuan
Source
2010 Asia Chengdu Regional Contest
--------------------------.
题目大意:
就是求[m,n]区间内的平衡数有多少
平衡数的定义为
在一个数中 找一个确定一位数字为"支点" 然后两边的每位数字的值乘上力矩(就是这位到支点的距离)的和相等 这样的数被的定义为平衡数;
解题思路:
还是标准的数位DP
只是要明确的一点是 同一个数 如果为平衡数的话 那么它的支点有且仅有一个 就是说两个数不能被计算两次;
所以在进行DP的时候只要枚举支点即可
还有就是两边的和相等 可以转化为两边的和为0 (只要规定了力矩的方向就能完成)
比如说1234321 支点很明显是4 然后13+22+31+3(-1)+2*(-2)+1*(-3)==0;
上述明白了就可以DP了 鄙某用的是记忆化搜索的形式写的
dp[位数][力矩总和][支点的位数];
dfs(当前位数,支点,力矩总和,数位的限制);
附本题代码
------------------------.
1 | # include <bits/stdc++.h> |
2016-08-25 15:54:39 Tabris_ 阅读数:386
博客爬取于2020-06-14 22:43:41
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52315342
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1140
------------------------------------.
D - How Many Zeroes?
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Description
Jimmy writes down the decimal representations of all natural numbers between and including m and n, (m ≤ n). How many zeroes will he write down?
Input
Input starts with an integer T (≤ 11000), denoting the number of test cases.
Each case contains two unsigned 32-bit integers m and n, (m ≤ n).
Output
For each case, print the case number and the number of zeroes written down by Jimmy.
Sample Input
5
10 11
100 200
0 500
1234567890 2345678901
0 4294967295
Sample Output
Case 1: 1
Case 2: 22
Case 3: 92
Case 4: 987654304
Case 5: 3825876150
-----------------------------------------.
题目大意 :就是求区间[m,n]之间的所有数中 0的个数是多少 ?
解题思路 : 、
标准的数位DP
dp[位数][0~9][0的个数];
然后记忆化搜索的时候
dfs(第几位,前面有没有非0的数,取数的限制,0的个数);
大概这样就能AC了 然后注意下细节就好了…
附本题代码
----------------------------.
1 | # include <bits/stdc++.h> |
2016-08-24 17:32:54 Tabris_ 阅读数:695
博客爬取于2020-06-14 22:43:42
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52302558
题目链接:http://codeforces.com/problemset/problem/710/D
--------------------------.
D. Two Arithmetic Progressions
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such that L ≤ x ≤ R and x = a1k’ + b1 = a2l’ + b2, for some integers k’, l’ ≥ 0.
Input
The only line contains six integers a1, b1, a2, b2, L, R (0 < a1, a2 ≤ 2·109, - 2·109 ≤ b1, b2, L, R ≤ 2·109, L ≤ R).
Output
Print the desired number of integers x.
Examples
input
2 0 3 3 5 21
output
3
input
2 4 3 0 6 17
output
2
-----------------------------.
题目大意 :
就是给你a1, b1, a2, b2, L, R 在区间L~R找一个x 使得a1k’ + b1 = a2l’ + b2 问能找到的x的个数
解题思路 :
根据题意 很明显的同余方程
x= b1 (mod a1);
x= b2 (mod a2);
然后解得x的最小正整数解之后 每次加上 lcm(a1,a2) 一直从l到r 这部分直接计算就能够得出
值得注意的是l与 b1,b2 的大小有关 在计算的时候l应取三者最大值;
Ps:题目很坑的是有负数的情况 也是赛后看了题解才知道。。
附本题代码
-----------------------------------.
1 | # include <bits/stdc++.h> |
2016-08-23 21:02:49 Tabris_ 阅读数:367
博客爬取于2020-06-14 22:43:43
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52294422
题目链接 : http://codeforces.com/problemset/problem/710/C
-----------------------------------.
C. Magic Odd Square
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Find an n × n matrix with different numbers from 1 to n2, so the sum in each row, column and both main diagonals are odd.
Input
The only line contains odd integer n (1 ≤ n ≤ 49).
Output
Print n lines with n integers. All the integers should be different and from 1 to n2. The sum in each row, column and both main diagonals should be odd.
Examples
input
1
output
1
input
3
output
2 1 4
3 5 7
6 9 8
-----------------------------------------.
题目大意: 就是给你一个奇 数N 让你把1~ N^2 填到N*N的 矩阵中 使得每行每列主对角线的和为奇数
解题思路:
附本题代码
---------------------------.
1 | # include<stdio.h> |
2016-08-23 12:49:21 Tabris_ 阅读数:585
博客爬取于2020-06-14 22:43:44
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52289905
题目链接:http://codeforces.com/problemset/problem/710/E
-------------------------------------------------.
E. Generate a String
time limit per test2 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
zscoder wants to generate an input file for some programming competition problem.
His input is a string consisting of n letters ‘a’. He is too lazy to write a generator so he will manually generate the input in a text editor.
Initially, the text editor is empty. It takes him x seconds to insert or delete a letter ‘a’ from the text file and y seconds to copy the contents of the entire text file, and duplicate it.
zscoder wants to find the minimum amount of time needed for him to create the input file of exactly n letters ‘a’. Help him to determine the amount of time needed to generate the input.
Input
The only line contains three integers n, x and y (1 ≤ n ≤ 107, 1 ≤ x, y ≤ 109) — the number of letters ‘a’ in the input file and the parameters from the problem statement.
Output
Print the only integer t — the minimum amount of time needed to generate the input file.
Examples
input
8 1 1
output
4
input
8 1 10
output
8
--------------------------------------.
题目大意 :
就是从0开始 每次可以+1或-1或*2 ±操作花费x *2操作花费y 问你达到n的最小花费是多少?
解题思路 :
就是DP
DP 的时候只要从0遍历到n即可 因为题目的数据范围是1e7 所以并不会超时
转移的时候一共决策三种状态 就是
1.由i-1 转移过来的
2.由i/2 转移过来的 这时候要区分下奇数还是偶数
——— 偶数很简单了 只要决策i 与 i/2 的状态就行了
——— 奇数的话 那么一定是前一个数2+1或者2-1达到的状态 由于遍历的时候已经判断了+1的情况 所以 这里只需考虑-1的情况就行 所以决策的事i 与 i/2+1
然后输出下结果就好了
附本题代码
-------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-08-22 20:34:43 Tabris_ 阅读数:366
博客爬取于2020-06-14 22:43:45
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52280031
题目链接 :HDU最近比较炸 不贴链接了、、
------------------.
Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 15374 Accepted Submission(s): 5565
Problem Description
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence “49”, the power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
Input
The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.
The input terminates by end of file marker.
Output
For each test case, output an integer indicating the final points of the power.
Sample Input
3
1
50
500
Sample Output
0
1
15
Hint
From 1 to 500, the numbers that include the sub-sequence “49” are “49”,“149”,“249”,“349”,“449”,“490”,“491”,“492”,“493”,“494”,“495”,“496”,“497”,“498”,“499”,
so the answer is 15.
----------------------------------.
题目大意 : 就是问你从1~m 里 有49的数的个数
解题思路 :
最最基础的数位DP
附本题代码
------------------------------------------------------.
1 |
|
2016-08-21 14:51:58 Tabris_ 阅读数:219
博客爬取于2020-06-14 22:43:46
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52267286
题目链接:http://codeforces.com/contest/707/problem/B
--------------------------------------.
B. Bakery
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Masha wants to open her own bakery and bake muffins in one of the n cities numbered from 1 to n. There are m bidirectional roads, each of whose connects some pair of cities.
To bake muffins in her bakery, Masha needs to establish flour supply from some storage. There are only k storages, located in different cities numbered a1, a2, …, ak.
Unforunately the law of the country Masha lives in prohibits opening bakery in any of the cities which has storage located in it. She can open it only in one of another n - k cities, and, of course, flour delivery should be paid — for every kilometer of path between storage and bakery Masha should pay 1 ruble.
Formally, Masha will pay x roubles, if she will open the bakery in some city b (ai ≠ b for every 1 ≤ i ≤ k) and choose a storage in some city s (s = aj for some 1 ≤ j ≤ k) and b and s are connected by some path of roads of summary length x (if there are more than one path, Masha is able to choose which of them should be used).
Masha is very thrifty and rational. She is interested in a city, where she can open her bakery (and choose one of k storages and one of the paths between city with bakery and city with storage) and pay minimum possible amount of rubles for flour delivery. Please help Masha find this amount.
Input
The first line of the input contains three integers n, m and k (1 ≤ n, m ≤ 105, 0 ≤ k ≤ n) — the number of cities in country Masha lives in, the number of roads between them and the number of flour storages respectively.
Then m lines follow. Each of them contains three integers u, v and l (1 ≤ u, v ≤ n, 1 ≤ l ≤ 109, u ≠ v) meaning that there is a road between cities u and v of length of l kilometers .
If k > 0, then the last line of the input contains k distinct integers a1, a2, …, ak (1 ≤ ai ≤ n) — the number of cities having flour storage located in. If k = 0 then this line is not presented in the input.
Output
Print the minimum possible amount of rubles Masha should pay for flour delivery in the only line.
If the bakery can not be opened (while satisfying conditions) in any of the n cities, print - 1 in the only line.
Examples
input
5 4 2
1 2 5
1 2 3
2 3 4
1 4 10
1 5
output
3
input
3 1 1
1 2 3
3
output
-1
Note
Image illustrates the first sample case. Cities with storage located in and the road representing the answer are darkened.
----------------------------------.
题意:
有n个城市 m条双向边 k各仓库分别在a1…ak城市
现在要 找一个没有仓库的城市里找一个城市,使得它到其中一个仓库的距离最短,求这个仓库的距离。
注:-1的情况包括,没有仓库或者全是仓库。
题解:
主要就是不能用矩阵来存储图就行了 鄙人用的vector
代码
--------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-08-19 16:04:23 Tabris_ 阅读数:504
博客爬取于2020-06-14 22:43:47
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52251839
题目连接 : 就当前HDU的情况 就先不给了
--------------------------------------------------------------------.
Hard problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 195 Accepted Submission(s): 148
Problem Description
cjj is fun with math problem. One day he found a Olympic Mathematics problem for primary school students. It is too difficult for cjj. Can you solve it?
Give you the side length of the square L, you need to calculate the shaded area in the picture.
The full circle is the inscribed circle of the square, and the center of two quarter circle is the vertex of square, and its radius is the length of the square.
Input
The first line contains a integer T(1<=T<=10000), means the number of the test case. Each case contains one line with integer l(1<=l<=10000).
Output
For each test case, print one line, the shade area in the picture. The answer is round to two digit.
Sample Input
1
1
Sample Output
0.29
----------------------------------------------.
题目大意 : 就是正方形边长为n时 求阴影面积 保留小数后两位
题目分析 :
当天不想做多校 然后队友给看了这题 说是小学奥数题目 所以就一直割补法 然后 GG
今天偶然看了看过去整理的模板 猛然看到一个叫做相交圆面积的东西 然后就想到了这道题目。。
然后大致是这样的。
小的圆是蓝的 打的圆是红的 绿色部分是相交的面积 (红色+蓝色==绿色?就当是对的了:不可能错)
然后根据相交圆面积求绿色部分 最后拿小圆的面积减去它 最后在乘个二就行了。。。
之后做题的时候只求一次边长为1的阴影部分面价就好了 因为平面图形 等比放大N倍 面积就是原来的n*n倍
就是这么水 然而被第一句话误导了 一直在寻找巧妙的办法…
什么小学奥数题目。。。 小学能学这个??!!!
附本题代码
-----------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-08-15 09:35:35 Tabris_ 阅读数:309
博客爬取于2020-06-14 22:43:49
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52208349
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5833
-------------------------------.
Zhu and 772002
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 446 Accepted Submission(s): 147
Problem Description
Zhu and 772002 are both good at math. One day, Zhu wants to test the ability of 772002, so he asks 772002 to solve a math problem.
But 772002 has a appointment with his girl friend. So 772002 gives this problem to you.
There are n numbers a1,a2,…,an. The value of the prime factors of each number does not exceed 2000, you can choose at least one number and multiply them, then you can get a number b.
How many different ways of choices can make b is a perfect square number. The answer maybe too large, so you should output the answer modulo by 1000000007.
Input
First line is a positive integer T , represents there are T test cases.
For each test case:
First line includes a number n(1≤n≤300),next line there are n numbers a1,a2,…,an,(1≤ai≤1018).
Output
For the i-th test case , first output Case #i: in a single line.
Then output the answer of i-th test case modulo by 1000000007.
Sample Input
2
3
3 3 4
3
2 2 2
Sample Output
Case #1:
3
Case #2:
3
Author
UESTC
Source
2016中国大学生程序设计竞赛 - 网络选拔赛
----------------------------------------------.
题目大意: 就是有n这么长的序列 然后从中选至少一个数 让这些数的乘积为完全平方数 问有多少种选法
题目分析:
首先注意题目说的 a[i]的最大质因子不会超过2000 这也是在提示你要质因子分解 分解就简单处理一下分解就行了 怎么分都行
这里首先想到的就应该是算数基本定理
A=p1^a1p2^a2p3^a3*…pn^an (pn是质数)
然后分解的时候怎么怎么存储数据?,怎么操作呢?
首先要想这个问题
几个数相乘的结果如果是完全平方数 有什么特点呢?
说白了就是开方后能得到一个整数
比如说B=a1a2; B,a1,a2都为整数 且a1==a2
那么a1和a2 他们质因子分解后是完全一样的
那么B的算是基本定理展开就等于a1的算是基本定理展开乘上a2的算是基本定理展开
那么可以肯定的是B的算是基本定理展开 an一定是偶数的 所以就能拆成两个a1 a2
那么反过来说只要B的算是基本定理展开 an都是偶数 就一定是完全平方数
那么在判断的时候就只要判断an的值的奇偶性就可以了
于是我们就开了这样的数组factor[n+10][333] (2000以内的质数只有303个)
把每个数转化为了一个2进制数
我们可以把题目转化成求n个数中的k个数数异或为0的情况数。使用x1—xn表示最终第i堆石子到底取不取(1取,0不取),将每堆石子数画成2进制的形式,列成303个方程来求自由变元数,最后由于自由变元能取1、0两种状态
然后直接高斯消元就可以了
最后的结果就是 2^(自由元)-1
注: 最终结果减去的那个一 减去的是1个都不选则情况下的0
附本题代码
-----------------------------------.
1 |
|
2016-08-12 13:42:04 Tabris_ 阅读数:192
博客爬取于2020-06-14 22:43:50
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52190898
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3389
----------------------.
Game
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 610 Accepted Submission(s): 426
Problem Description
Bob and Alice are playing a new game. There are n boxes which have been numbered from 1 to n. Each box is either empty or contains several cards. Bob and Alice move the cards in turn. In each turn the corresponding player should choose a non-empty box A and choose another box B that B < A && (A+B)%2=1 && (A+B)%3=0. Then, take an arbitrary number (but not zero) of cards from box A to box B. The last one who can do a legal move wins. Alice is the first player. Please predict who will win the game.
Input
The first line contains an integer T (T<=100) indicating the number of test cases. The first line of each test case contains an integer n (1<=n<=10000). The second line has n integers which will not be bigger than 100. The i-th integer indicates the number of cards in the i-th box.
Output
For each test case, print the case number and the winner’s name in a single line. Follow the format of the sample output.
Sample Input
2
2
1 2
7
1 3 3 2 2 1 2
Sample Output
Case 1: Alice
Case 2: Bob
---------------------------------------------.
题目大意 就是把右边盒子里的的给左边盒子 但要求B < A && (A+B)%2=1 && (A+B)%3=0
谁不能移牌 谁就输了
题目分析 :
就是 博弈么 找规律 就好 了
根据上面的很容易分析到
1.最后一定会放到 1 3 4这3个盒子里
2.右边最终能移到1 3 4中的哪一个也是能够求的
3.右边的移到左边的步数是偶数个还是奇数个也是可求的 只要经过偶数步数才能到达的 都是必败点
分析每一个的时候可以把其他的盒子当成空的
这样就是N个游戏组合到了一起 然后作为NIM取一下异或值就行了
总的来说就是分情况讨论一下
奇数: %3 == 0 偶数步骤后到达盒子3
%3 == 1 偶数步骤后到达盒子1
%3 == 2 ji步骤后到达盒子2
偶数: %3 == 0 奇数步骤后到达盒子3
%3 == 1 偶数步骤后到达盒子1
%3 == 2 奇数步骤后到达盒子4
之后操作就好了
附本题代码
------------------------------------.
1 | # include<bits/stdc++.h> |
2016-08-11 20:25:10 Tabris_ 阅读数:457
博客爬取于2020-06-14 22:43:51
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52186214
题目连接 : 传送阵
-------------------------.
GCD
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1734 Accepted Submission(s): 852
Problem Description
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to a and b,For example,(1,2)=1,(12,18)=6.
(a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.
Input
The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (2<=N<=1000000000, 1<=M<=N), representing a test case.
Output
For each test case,output the answer on a single line.
Sample Input
3
1 1
10 2
10000 72
Sample Output
1
6
260
-----------------------------------------.
题目大意 :不用解释了吧 …
解题思路:
这道题所需要的算法主要为欧拉函数的运用和一点点的GCD知识。
问题所要求的是 gcd( x , n ) > m ,由gcd( x , n )本身可知,gcd求出来的是 x 和n的最大公约数(设为a),即有式子gcd( x ,n )=a , 进一步进行化简可变为gcd( x/a , n/a )=1 , 到了此处这个式子又有了另一层含义——x/a与n/a互素 。在联想到欧拉函数的功能——对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目。于是将欧拉函数里的n换成n/a,不就正好能求出x/a的个数了吗?x/a的个数不就是我们所要求的x的个数了吗?
转自这里
附本题代码
-------------------------------------.
1 | # include <stdio.h> |
2016-08-11 20:13:29 Tabris_ 阅读数:224
博客爬取于2020-06-14 22:43:52
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52186122
题目连接:传送门
------------------------------.
Unknown Treasure
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2196 Accepted Submission(s): 814
Problem Description
On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a combination lock and some numbers on it. After quite a research, the mathematician found out that the correct combination to the lock would be obtained by calculating how many ways are there to pick m different apples among n of them and modulo it with M. M is the product of several different primes.
Input
On the first line there is an integer T(T≤20) representing the number of test cases.
Each test case starts with three integers n,m,k(1≤m≤n≤10^18,1≤k≤10) on a line where k is the number of primes. Following on the next line are k different primes p1,…,pk. It is guaranteed that M=p1⋅p2⋅⋅⋅pk≤10^18 and pi≤10^5 for every i∈{1,…,k}.
Output
For each test case output the correct combination on a line.
Sample Input
1
9 5 2
3 5
Sample Output
6
------------------------------.
题目大意:
就是求C(n,m)%M ,M= p1p2p3p4…*pn;
题目解释:
大组合数就是用lucas定理求解
而lucas要求是对质数取模的时候才成立
所以分别对p[i] 进行求解 然后构成了一个同余方程组
用中国剩余定理求解就行了
注意大数乘法的时候可能会爆longlong 所以要用快速乘
附本题代码
------------------------------.
1 | # include <stdio.h> |
2016-08-11 19:59:34 Tabris_ 阅读数:238
博客爬取于2020-06-14 22:43:53
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52186000
题目连接: 传送阵
------------------------------.
Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3902 Accepted Submission(s): 1536
Problem Description
Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.
Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
Input
The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 1015) and (1 <=N <= 109).
Output
For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
Sample Input
2
1 10 2
3 15 5
Sample Output
Case #1: 5
Case #2: 10
Hint
In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
------------------------------------.
题目大意: 就是求a~b区间内与n互质的数的个数
解题思路:与n互质的数的个数也就是gcd(x,n)==1.但是数据量非常大 所以暴力不可解
于是换个思路 就是求gcd(x,n)!=1的数的个数 然后区间总数减一下 就能得到结果
gcd(x,n)!=1就简单了
只要求出[1~a-1][1~b]这两个区间内的与n有约数(非1)的数的个数
想到把n质因子分解 然后容斥定理求解即可
附本题代码
----------------------------------.
1 | # include <stdio.h> |
2016-08-11 17:19:07 Tabris_ 阅读数:317
博客爬取于2020-06-14 22:43:54
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52184669
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2604
--------------------.
Queuing
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4713 Accepted Submission(s): 2083
Problem Description
Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time.
Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue.
Your task is to calculate the number of E-queues mod M with length L by writing a program.
Input
Input a length L (0 <= L <= 10 6) and M.
Output
Output K mod M(1 <= M <= 30) where K is the number of E-queues with length L.
Sample Input
3 8
4 7
4 8
Sample Output
6
2
1
Author
WhereIsHeroFrom
-----------------------------------.
题目大意 :就是问子串中没有fmf fff的串有多少个
题解 : 我是暴力打表找的规律
所以不解释
这是打表代码
-------------------.
1 | # include <cstdio> |
附本题AC代码
------------------------------------.
1 | # include<bits/stdc++.h> |
2016-08-11 11:48:04 Tabris_ 阅读数:345
博客爬取于2020-06-14 22:43:55
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52181264
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2588
-------------------------.
GCD
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1700 Accepted Submission(s): 829
Problem Description
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to a and b,For example,(1,2)=1,(12,18)=6.
(a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.
Input
The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (2<=N<=1000000000, 1<=M<=N), representing a test case.
Output
For each test case,output the answer on a single line.
Sample Input
3
1 1
10 2
10000 72
Sample Output
1
6
260
-------------------------.
题目大意 : 不解释
题解:
首先明确的是,要求的成立
那么我们只要知道结果为N的每一个约数时的个数就行了,
gcd(a,b)>=c 可以转化成gcd(a/c,b/c)=1;
那么
那么就是求
最后答案就是
题目所求的欧拉函数也同理
最后O(sqrt(n)^(3/2))可解决
附本题代码
-----------------------.
1 | # include <stdio.h> |
2016-08-10 15:19:05 Tabris_ 阅读数:556
博客爬取于2020-06-14 22:43:56
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52171819
题目连接 : http://codeforces.com/problemset/problem/704/A
--------------------------------------.
A. Thor
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Thor is getting used to the Earth. As a gift Loki gave him a smartphone. There are n applications on this phone. Thor is fascinated by this phone. He has only one minor issue: he can’t count the number of unread notifications generated by those applications (maybe Loki put a curse on it so he can’t).
q events are about to happen (in chronological order). They are of three types:
Application x generates a notification (this new notification is unread).
Thor reads all notifications generated so far by application x (he may re-read some notifications).
Thor reads the first t notifications generated by phone applications (notifications generated in first t events of the first type). It’s guaranteed that there were at least t events of the first type before this event. Please note that he doesn’t read first t unread notifications, he just reads the very first t notifications generated on his phone and he may re-read some of them in this operation.
Please help Thor and tell him the number of unread notifications after each event. You may assume that initially there are no notifications in the phone.
Input
The first line of input contains two integers n and q (1 ≤ n, q ≤ 300 000) — the number of applications and the number of events to happen.
The next q lines contain the events. The i-th of these lines starts with an integer typei — type of the i-th event. If typei = 1 or typei = 2 then it is followed by an integer xi. Otherwise it is followed by an integer ti (1 ≤ typei ≤ 3, 1 ≤ xi ≤ n, 1 ≤ ti ≤ q).
Output
Print the number of unread notifications after each event.
Examples
input
3 4
1 3
1 1
1 2
2 3
output
1
2
3
2
input
4 6
1 2
1 4
1 2
3 3
1 3
1 3
output
1
2
3
0
1
2
Note
In the first sample:
Application 3 generates a notification (there is 1 unread notification).
Application 1 generates a notification (there are 2 unread notifications).
Application 2 generates a notification (there are 3 unread notifications).
Thor reads the notification generated by application 3, there are 2 unread notifications left.
In the second sample test:
Application 2 generates a notification (there is 1 unread notification).
Application 4 generates a notification (there are 2 unread notifications).
Application 2 generates a notification (there are 3 unread notifications).
Thor reads first three notifications and since there are only three of them so far, there will be no unread notification left.
Application 3 generates a notification (there is 1 unread notification).
Application 3 generates a notification (there are 2 unread notifications).
----------------------------------.
题目大意 :
就是你有一个手机 有三种操作
1,x软件收到一个信息
2,看了所有x软件的信息
3,看了第1~第x次收到的信息 (被看过的也算)
每次都输出一下当前手机里的未读信息的个数
题解 :
首先把信息编号
用一个vector 和set 维护下就好了
vector有n个 代表n个软件 每次向n[x]中加入新的信息编号
set存储所有的信息
维护的时候
对于1 操作 把信息编号加入vector 和set
对于2 操作 对应n[x]遍历一遍 从set中删除
对于3 操作 遍历1~x 从set中删除 (这里注意每次的x要记录一下 然后下一次遍历的时候只要遍历这个x到下一个x的区间就行了 之前被删除的不用再删除一遍 否则会TLE)
每次输出set的大小就行了
这样总体复杂度是O(2n)
/**************** 这些shi牢骚
这道题是赛后补得 并且看了网上的题解
当时 想到了思路 当时没有做主要是怕TLE 在一个不太会用set (我是小白) 当时想到的是对数组二分查找整个区间 然后删除 当对判断数据的统计这一块只想到了线段树(赛前几天才学习数据结构,做什么题都想用线段树) 然后旁边队友 风骚的A了这道题后 告诉用STL做 然而对于不会STL的我老说 根本没法搞。 So我就不做了。。。
仔细想来 根本不用那么麻烦 多熟练下vector map set 这东西其实是能秒的。。
****************/
附本题代码
-------------------------.
1 | # include<bits/stdc++.h> |
2016-08-10 10:57:04 Tabris_ 阅读数:222
博客爬取于2020-06-14 22:43:57
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52169407
题目连接 : 传送阵
----------------------------------------------.
Colored Sticks
Time Limit: 5000MSMemory Limit: 128000K
Total Submissions: 35437Accepted: 9287
Description
You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?
Input
Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.
Output
If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.
Sample Input
blue red
red violet
cyan blue
blue magenta
magenta cyan
Sample Output
Possible
Hint
Huge input,scanf is recommended.
Source
The UofA Local 2000.10.14
--------------------------------------.
题目大意 就是有多个木棍 两头有颜色 对于不同的木棍 相同颜色的一段能连接到一块 问你所有的棍能不能接成一根棍子
解题思路:
应该想到如果颜色是用数字表示的就非常好解决了 只要判断一下这些每个颜色的度就能解决 注意!! 生成的图可能是个森林 所以要用并查集判断下 是否生成的是一个树(应该是环)
现在想的问题就只剩下字符串怎么转化成数字了 用map转化的话不可行 所以想到用tire树来解决 这样才不会爆内存
对于学会tire树的你相信不是个问题 注意的是 把每个串插入到树中的时候只要把最后一个字符所在的节点+1 就行了 再在tire中加上一个index(索引)的元素 记录这个串的编号 (查询操作是没用的)
刚学字符串10days 纯属个人解法 如有错误 请一定要指正
附本题代码
---------------------------------------------.
1 | # include <bits/stdc++.h> |
2016-08-08 13:20:00 Tabris_ 阅读数:845
博客爬取于2020-06-14 22:39:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52151010
#KMP
算法介绍文章:http://blog.csdn.net/u011564456/article/details/20862555?utm_source=tuicool&utm_medium=referral
1 | char s1[N],s2[N]; |
指针动态实现
1 | //#include <bits/stdc++.h> |
数组静态实现
(Double Arrays Trie-DAT)
用两个数组来实现
其实本质来看,就和模拟数组差不多少的东西,每次将元素放到尾部。
再用另一个二位数组来表示接下来的索引就行了。
1 | const int N = 100000+7; |
指针动态存储
1 | # include<iostream> |
1 |
|
Manacher 是一个能在的复杂度内解决字符串中最长回文子串的问题
1 | /*** |
SA[i] = j表示为按照从小到大排名为i的后缀 是以j(下标)开头的后缀
rank[i] = j 表示为按照从小到大排名 以i为下标开始的后缀 排名为j
RANK表示你排第几 SA表示排第几的是谁 (记住这个就行)
height[i] 表示 sa[i] 与 sa[i-1] 的最长公共前缀(LCP)
1 | const int MAXN=400010; |
2016-08-08 08:35:28 Tabris_ 阅读数:765
博客爬取于2020-06-14 22:39:15
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52148588
##并查集
1 | 不需要模板 |
1 | int pre[N]; |
可以明确的是,对于一个并查集来说,合并操作是不可逆的,即两个元素处在同一个集合下,那么就不能将两者拆开否则会产生错误.那么问题来了
问:如果一个节点的关系发生改变了怎么办呢?
答:如果要改变节点a的关系重新创建一个节点p表示节点a,原先的节点a就不要了,通过一个映射,映射过去就行了(map[a]=p)
1 | int pre[N],h[N],hh; |
可持久化数据结构就是可以访问历史版本的数据结构,能修改之后还能查询之前的状态就是可持久化。
现在还没有学明白,会更新上的。
详解戳这里<<—
这里有最详细的树状数组各种操作的模板
注意:一定要仔细看数据范围 如果是从0开始的 那么在树状数组中一定要加上1然后在操作 因为求和的时候有-1操作 所以不这样就会无限TLE…
1.前缀和
2.[1,n]的最大最小值 ,换句话就还是前缀的东西.
3.区间覆盖的问题 (仅限对区间进行增改值的,更新还是一样查询的时候注意只要getSum(id)就行了)
1 | //切记 在多组数据的题上要清空数组 |
原理和一维的一模一样
1 | const int N = 1000+5; |
/*
二维区间更新
1.update(x,y,val);
2.update(x,Y+1,-val);
3.update(X+1,y,-val);
4.update(X+1,Y+1,val);
*/
详解戳这里
线段树维护区间和。
---------------------------------------.
1 | /* |
所谓线性变换,就是我们的线段树能处理ax+b这种操作。现在线段树的常用操作有add,mul,set无论是哪种我们都可以使用线性变换得到。
add v: 1x+v
mul v:vx+0
set v: 0*x+v
主席树(函数式线段树,可持久化线段树)其实就是维护多颗线段树,
每更新一个元素,那么就根据它的上一状态新建一颗线段树,然后就是线段树的操作了,
一般来维护(区间第K大,区间不同元素个数(在线做法))
每次新建一颗线段树,都只是开的节点,
然后指向前一状态的其他不需要更新的节点,这样的话大大降低了总空间复杂度
主席树的具体维护要看不同情况而定,需要怎么维护就怎么维护即可
主席树一般可以看做维护树与树的前缀和,
1 | int rt[N*20]; //表示更新当前元素所形成的不同线段树的树根, |
预处理出ST表 实现查询区间最大/小值的算法.(即RMQ问题)
要求数组是静态的(就是不会有元素更改,删除等操作)
ST表其实就是通过倍增的思想,先将一段一段的区间最大/小值处理出来,然后通过O(1)的计算的出所要求的解.
形象一点就是
表示第i个位置开始长度为的最大最小值,
在预处理的时候我们就能够倍增的求出每个位置的st[][]的值,那么这时候每次查询的就是 因为倍增过来的都是长度的.那么就可以找到两个同样长度的区间一个是从开始包含向后的区间,另一个是从开始包含向前的区间.取二者的就可以了.
最后一点就是开数组的时候一定是不要后者容易超时.
代码实现
1 | int st[n][17]; |
其实就是从根节点进行搜索,
然后向下dfs遍历树,依次进行编号,
同时能保证子树的编号一定大于父节点的编号,
同时借用两个数组,$L[_],R[_] u\big(L[u],R[u]\big),开区间$ 内。
这样在进行对子树 进行的操作的时候 可以借助数据结构 对区间进行查找,
1 | vector<int >G[N]; |
树链剖分是一种将树形结构转化为线性结构的算法
通过两次树的遍历,将树剖分成一个个的[重链],
且对每个节点进行编号,确保一条链上的节点编号连续
这样一来,我们就能通过一个维护区间关系的数据结构来维护树上,属同一个链上的元素
在维护两个节点(u,v)的时候即:维护两个节点(u,v)间的元素,
我么从深度大的不断向上维护,最后遍历的位置,两个节点一定在一条链上(且深度小的就是LCA(u,v))
1 | int dep[N]; //每个节点的深度 |
本质还是一个二叉查找树,但是根据树的旋转,能将一些在某种情况下树退化为单链的时候重新旋转为树
这是最好实现的平衡树了,能够实现求区间翻转,前驱,后继,第K大,查找值,插入,删除,合并,分离 等其他二叉查找树能够做到的功能 and so on
学习SPLAY最终要的是先要理解二叉查找树,然后就要理解好伸展,旋转操作就行了,其他操作原理上和普通二叉查找树是一样的
附下个人的SPLAY模板(Bate 1)
SPLAY操作可以在优化,旋转操作可以在优化,各种功能还没有写
1 | int ch[N][2]; //ch[][0] lson ch[][1] rson |
由于SPLAY比较长 所以单独开了一贴
]]>2016-08-05 13:33:21 Tabris_ 阅读数:1044
博客爬取于2020-06-14 22:43:58
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52128243
今天解除了一下线段树 据自己理解手撸了发建树与查询的操作 的模板
1 | # include <iostream> |
2016-08-04 21:56:25 Tabris_ 阅读数:589
博客爬取于2020-06-14 22:43:59
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52123533
题目连接 : http://acm.hdu.edu.cn/showproblem.php?pid=5795
-----------------------------------------------------------.
A Simple Nim
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 170 Accepted Submission(s): 111
Problem Description
Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On each turn they can pick any number of candies which come from the same heap(picking no candy is not allowed).To make the game more interesting,players can separate one heap into three smaller heaps(no empty heaps)instead of the picking operation.Please find out which player will win the game if each of them never make mistakes.
Input
Intput contains multiple test cases. The first line is an integer 1≤T≤100, the number of test cases. Each case begins with an integer n, indicating the number of the heaps, the next line contains N integers s[0],s[1],…,s[n−1], representing heaps with s[0],s[1],…,s[n−1] objects respectively.(1≤n≤106,1≤s[i]≤109)
Output
For each test case,output a line whick contains either"First player wins.“or"Second player wins”.
Sample Input
2
2
4 4
3
1 2 4
Sample Output
Second player wins.
First player wins.
-------------------------------------------.
题目大意 : 有n堆糖果 两个人 轮班来从一堆中取任意不为0个石子或者把其中某一堆分成三堆(这时候不能取石子) 拿走最后一个石子的人赢 问 先手赢还是后手赢
解题思路:
//////////////***********************//////////////////
其实本次博客并不是写题解的 只是用来发泄一下弱鸡的自己 (淡然后面肯定有题解...)
做题的时候 首先看到s[i]<1e9 就放弃了用SG函数的思想来解决此问题 更没想打表 更更没想到打表找规律这种事情 于是 各种姿势各种WA 最后看到题解的我眼泪掉下来 明明很简单的 但还是GG了 其实还是对知识点的不了解 之前学习SG函数的时候就没讲SG函数吃透 才会整场只A了1001 还是在队友优化了题目之后才解决的 1002也和本题一样 想到了Lucas定理+容斥原理 可硬是没写出来 还是对容斥原理的理解不够 甚至还想用某图论算法来解决它
说白了就是菜 但这也终于发挥了多校的作用 毕竟300买的账号。。 对于算法了解多了固然好 但是每一个都要吃透 否则就是 明明应该AC的题目却WA … 行了 不发牢骚了
----------------------------------------------.
心情实在压抑 直接贴的网上大神代码
打表的代码
1 | int g[100]; |
根据输出很容易看到 sg[x%8==0]=x-1;sg[x%8==7]=x+1;
最终的AC代码
1 | int main(){ |
2016-08-03 13:38:04 Tabris_ 阅读数:219
博客爬取于2020-06-14 22:44:01
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52102801
题目链接 : http://poj.org/problem?id=3254
---------------------------------------------------.
Corn Fields
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 12927Accepted: 6766
Description
Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can’t be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.
Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.
Input
Line 1: Two space-separated integers: M and N
Lines 2…M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)
Output
Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000.
Sample Input
2 3
1 1 1
0 1 0
Sample Output
9
Hint
Number the squares as follows:
1 2 3
4
There are four ways to plant only on one squares (1, 2, 3, or 4), three ways to plant on two squares (13, 14, or 34), 1 way to plant on three squares (134), and one way to plant on no squares. 4+3+1+1=9.
---------------------------------------------------.
题目大意 : 就是一个n*m的地方 1代表有草 0 代表没草
现在要往这里放一些牛 牛只能放在有草的地方 而且 两个牛不能相邻 问有多少种方法
解题思路 : n*m不大的这种一猜就是状压(一般<=20) 然后每一行与每一行有着状态的转移 于是想到DP 解决
首先吧每一行的草的状态用一个数存起来 就是这样
1 | int x; |
有了这些状态好办了 直接DP
DP 的时候主要判断的就是3项
1.左右有没有挨着的 status&(status<<1)
2.是不是只在有草的地方放牛 (草地的状态&想放牛的状态)==想放牛的状态
3.判断相邻两行的状态有没有相邻的(这时候相邻就是上下相邻) 直接 上&下 就行了
然后就是DP一下就好了 本人做这题的时候也是刚学DP 博客写的很…挫…
附本题代码
------------------------------------------.
1 | # include<cstdio> |
2016-07-30 16:38:04 Tabris_ 阅读数:406
博客爬取于2020-06-14 22:44:02
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52073496
题目连接 :http://acm.hdu.edu.cn/showproblem.php?pid=1536
------------------------------------------.
S-Nim
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6629 Accepted Submission(s): 2802
Problem Description
Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim is played as follows:
The starting position has a number of heaps, all containing some, not necessarily equal, number of beads.
The players take turns chosing a heap and removing a positive number of beads from it.
The first player not able to make a move, loses.
Arthur and Caroll really enjoyed playing this simple game until they recently learned an easy way to always be able to find the best move:
Xor the number of beads in the heaps in the current position (i.e. if we have 2, 4 and 7 the xor-sum will be 1 as 2 xor 4 xor 7 = 1).
If the xor-sum is 0, too bad, you will lose.
Otherwise, move such that the xor-sum becomes 0. This is always possible.
It is quite easy to convince oneself that this works. Consider these facts:
The player that takes the last bead wins.
After the winning player’s last move the xor-sum will be 0.
The xor-sum will change after every move.
Which means that if you make sure that the xor-sum always is 0 when you have made your move, your opponent will never be able to win, and, thus, you will win.
Understandibly it is no fun to play a game when both players know how to play perfectly (ignorance is bliss). Fourtunately, Arthur and Caroll soon came up with a similar game, S-Nim, that seemed to solve this problem. Each player is now only allowed to remove a number of beads in some predefined set S, e.g. if we have S =(2, 5) each player is only allowed to remove 2 or 5 beads. Now it is not always possible to make the xor-sum 0 and, thus, the strategy above is useless. Or is it?
your job is to write a program that determines if a position of S-Nim is a losing or a winning position. A position is a winning position if there is at least one move to a losing position. A position is a losing position if there are no moves to a losing position. This means, as expected, that a position with no legal moves is a losing position.
Input
Input consists of a number of test cases. For each test case: The first line contains a number k (0 < k ≤ 100 describing the size of S, followed by k numbers si (0 < si ≤ 10000) describing S. The second line contains a number m (0 < m ≤ 100) describing the number of positions to evaluate. The next m lines each contain a number l (0 < l ≤ 100) describing the number of heaps and l numbers hi (0 ≤ hi ≤ 10000) describing the number of beads in the heaps. The last test case is followed by a 0 on a line of its own.
Output
For each position: If the described position is a winning position print a ‘W’.If the described position is a losing position print an ‘L’. Print a newline after each test case.
Sample Input
2 2 5
3
2 5 12
3 2 4 7
4 2 3 7 12
5 1 2 3 4 5
3
2 5 12
3 2 4 7
4 2 3 7 12
0
Sample Output
LWW
WWL
Source
Norgesmesterskapet 2004
-------------------------------------------------------.
题目大意 :
就是多个 有多个堆的取石子游戏,只有N种取法 ,问先手输或者赢。
解题思路 : 很明显的SG函数问题 通过每次给你的N种取法 把SG值求出来然后看最后异或值是否为0就行了额
!!!!!!!!!!注意的是
计算sg函数的时候 最开始我h[]数组开的是10008,这样的结果就是无限的TLE
后来发现 取法有N种 那么i-s[]最多也只有N种 那么我h[]只要开 N 这么大就完全够了 以前怎么也想不明白 但是现在想明白了。。 只有这样才不会在 预处理的时候发生超时
附本题代码
-----------------------.
1 | # include<bits/stdc++.h> |
2016-07-29 17:50:50 Tabris_ 阅读数:388
博客爬取于2020-06-14 22:44:03
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52067386
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5015
-------------------------------------------.
233 Matrix
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1817 Accepted Submission(s): 1075
Problem Description
In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 … in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be 233, 2333, 23333… (it means a0,1 = 233,a0,2 = 2333,a0,3 = 23333…) Besides, in 233 matrix, we got ai,j = ai-1,j +ai,j-1( i,j ≠ 0). Now you have known a1,0,a2,0,…,an,0, could you tell me an,m in the 233 matrix?
Input
There are multiple test cases. Please process till EOF.
For each case, the first line contains two postive integers n,m(n ≤ 10,m ≤ 109). The second line contains n integers, a1,0,a2,0,…,an,0(0 ≤ ai,0 < 231).
Output
For each case, output an,m mod 10000007.
Sample Input
1 1
1
2 2
0 0
3 7
23 47 16
Sample Output
234
2799
72937
Hint
-----------------------------------------------------.
题目大意 : 这道题 很好读懂 不需要翻译
解题思路:
就是构造矩阵 然后计算a[n][m]的值
我的思路就是
先把a[i][0]都为0的时候a[n][m]的值计算出来
再把a[0][i]都当成0的时候a[n][m]的值计算出来
把两者相加就是最终的结果了
所以我们就把这个问题分成两个子问题做就是了
一、
我先求的是a[0][i]都当成0的时候的a[n][m]值
这个其实很好求 先手写了一下发现有个规律
为了能明确的表达这个规律
在这里我们定义Sni为n个a[i][0]项和 SSni为Sni的前n项和 依此类推
未来了避免书写SSSSni的情况用mSni表示
例如3Sni就是SSSni; 这时候m=0就表示a[i][0]的值
我们通过手写能够知道a[n][m]的值为
(n-1)Smi+(n-2)Smi+…+(n-n)Smi;
而找这些值就很好处理了 只要构造一个上三角矩阵就行了
初始化a[i][j] 使每行都为a[i][0] 在乘上 上三角矩阵的k-1次幂就行了 切记a*上三角 不能反过来 因为矩阵只有结合律没有交换律
这样a[0][i]都当成0的时候的a[n][m]值就求出来了
二、
计算a[i][0]都为0的时候a[n][m]的值计算出来
计算这个的时候就容易多了 用我们要的结果就是计算数列的前n项和的前n项和的前n项和 至于有多少层就看n的值 n是几就是几层
这个矩阵就明显复杂一点
10 0 10 10 10 10 10 10 10 10 10 10
1 1 1 1 1 1 1 1 1 1 1 1
0 0 1 1 1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 1
这是我构造出来的b矩阵
还有a矩阵 是
233 3 233 233 233 233 233 233 233 233 233 233
下面的值不重要
a矩阵每项的值分别是
a[n] 3(a[n+1]-a[n]*10) 剩下的就是从1层前n项和到10层前n项和
上面解释过
最后n是几就选择第几层的前n项和
这样就把a[i][0]都为0的时候a[n][m]的值计算出来
最后两者相加就出现结果了
//因为分成两遍做得 第二次初始化错误 导致模拟赛后1分54秒才调好 虽然1发ac了但是很不爽啊
附本题代码
-------------------------------------.
1 | # include <iostream> |
2016-07-28 20:39:58 Tabris_ 阅读数:592
博客爬取于2020-06-14 22:44:04
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52058872
题目连接 :http://codeforces.com/problemset/problem/700/B
CF 的题目 可以去VJ上 挂
---------------------------------------------------------.
Connecting Universities
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Treeland is a country in which there are n towns connected by n - 1 two-way road such that it’s possible to get from any town to any other town.
In Treeland there are 2k universities which are located in different towns.
Recently, the president signed the decree to connect universities by high-speed network.The Ministry of Education understood the decree in its own way and decided that it was enough to connect each university with another one by using a cable. Formally, the decree will be done!
To have the maximum sum in the budget, the Ministry decided to divide universities into pairs so that the total length of the required cable will be maximum. In other words, the total distance between universities in k pairs should be as large as possible.
Help the Ministry to find the maximum total distance. Of course, each university should be present in only one pair. Consider that all roads have the same length which is equal to 1.
Input
The first line of the input contains two integers n and k (2 ≤ n ≤ 200 000, 1 ≤ k ≤ n / 2) — the number of towns in Treeland and the number of university pairs. Consider that towns are numbered from 1 to n.
The second line contains 2k distinct integers u1, u2, …, u2k (1 ≤ ui ≤ n) — indices of towns in which universities are located.
The next n - 1 line contains the description of roads. Each line contains the pair of integers xj and yj (1 ≤ xj, yj ≤ n), which means that the j-th road connects towns xj and yj. All of them are two-way roads. You can move from any town to any other using only these roads.
Output
Print the maximum possible sum of distances in the division of universities into k pairs.
Examples
input
7 2
1 5 6 2
1 3
3 2
4 5
3 7
4 3
4 6
output
6
input
9 3
3 2 1 6 5 9
8 9
3 2
2 7
3 4
7 6
4 5
2 1
2 8
output
9
Note
The figure below shows one of possible division into pairs in the first test. If you connect universities number 1 and 6 (marked in red) and universities number 2 and 5 (marked in blue) by using the cable, the total distance will equal 6 which will be the maximum sum in this example.
---------------------------------------------------------.
题目大意 :就是让你找在K*2个点中找到K条路 使得和最大
解题思路
其实把每条路都求出来在加和的话 一定会超时 所以要换一种思路 看了一下node 发现总是有那么多的边被很多路经过
所以就求出来每条边被多少路经过就行了呗
而求被多少条路经过就简单多了 只有求出这条路径左边有多少个k2里的点右边边有多少个k2里的点 取小的那一个值就行了
这是必然的 想让路最长对于每一条边来说 一定是让左右两边的点尽可能的连上
最终记录下来每条边对总结过的贡献就行了 总复杂度O(N)
这种贡献式思维 很常用 也很好用 能大大降低时间复杂度 而且在很多时候比直接求解的代码 算法上的难度要小 而且小很多
附本题代码
-----------------------------------------------------.
1 | # include <iostream> |
2016-07-26 23:49:05 Tabris_ 阅读数:779
博客爬取于2020-06-14 22:39:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52040812
ACM进阶计划
ACM队不是为了一场比赛而存在的,为的是队员的整体提高。
大学期间,ACM队队员必须要学好的课程有:
lC/C++两种语言
l高等数学
l线性代数
l数据结构
l离散数学
l数据库原理
l操作系统原理
l计算机组成原理
l人工智能
l编译原理
l算法设计与分析
除此之外,我希望你们能掌握一些其它的知识,因为知识都是相互联系,触类旁通的。
以下学习计划每学期中的内容不分先后顺序,虽说是为立志于学习ACM的同学列的知识清单,但内容不限于ACM的知识。英语之类与专业相距较远的课程请自行分配时间,这里不再列举。
大一上学期:
必学:
1.C语言基础语法必须全部学会
a)推荐“语言入门”分类20道题以上
b)提前完成C语言课程设计
2.简单数学题(推荐“数学”分类20道以上)
需要掌握以下基本算法:
a)欧几里德算法求最大公约数
b)筛法求素数
c)康托展开
d)逆康托展开
e)同余定理
f)次方求模
3.计算几何初步
a)三角形面积
b)三点顺序
4.学会简单计算程序的时间复杂度与空间复杂度
5.二分查找法
6.简单的排序算法
a)冒泡排序法
b)插入排序法
7.贪心算法经典题目
8.高等数学
以下为选修:
9.学会使用简单的DOS命令(较重要)
a)color/dir/copy/shutdown/mkdir(md)/rmdir(rd)/attrib/cd/
b)知道什么是绝对路径与相对路径
c)学会使用C语言调用DOS命令
d)学会在命令提示符下调用你自己用C语言编写的程序,并使用命令行参数给自己的程序传参(比如自己制作一个copyfile.exe实现与copy命令基本功能一致的功能)
e)学会编写bat批处理文件
10.学会Windows系统的一些小知识,如设置隐藏文件,autoRun.inf的设置等。
11.学会编辑注册表(包括使用注册表编辑器regedit和使用DOS命令编辑注册表)
12.学会使用组策略管理器管理(gpedit.msc)组策略。
大一下学期:
1.掌握C++部分语法,如引用类型,函数重载等,基本明白什么是类。
2.学会BFS与DFS
a)迷宫求解(最少步数)
b)水池数目(NYOJ27)
c)图像有用区域(NYOJ92)
d)树的前序中序后序遍历
3.动态规划(15题以上),要学会使用循环的方法写动态规划,同时也要学会使用记忆化搜索的方法。
a)最大子串和
b)最长公共子序列
c)最长单调递增子序列(O(n)与O(nlogn)算法都需要掌握)
d)01背包
e)RMQ算法
4.学会分析与计算复杂程序的时间复杂度
5.学会使用栈与队列等线性存储结构
6.学会分治策略
7.排序算法
a)归并排序
b)快速排序
c)计数排序
8.数论
a)扩展欧几里德算法
b)求逆元
c)同余方程
d)中国剩余定理
9.博弈论
a)博弈问题与SG函数的定义
b)多个博弈问题SG值的合并
10.图论:
a)图的邻接矩阵与邻接表两种常见存储方式
b)欧拉路的判定
c)单最短路bellman-ford算法dijkstra算法。
d)最小生成树的kruskal算法与prim算法。
11.学会使用C语言进行网络编程与多线程编程
12.高等数学
13.线性代数
a)明确线性代数的重要性,首先是课本必须学好
b)编写一个Matrix类,进行矩阵的各种操作,并求编写程序解线性方程组。
c)推荐做一两道“矩阵运算”分类下的题目。
以下为选修,随便选一两个学学即可:
14.(较重要)使用C语言或C++编写简单程序来调用一些简单的windowsAPI,或者在linux下进行linux系统调用,其目的是明白什么是API(应用程序接口)。
15.网页设计
a)学习静态网页技术(html+css+javascript)
b)较具有艺术细胞的可以试试Photoshop
c)php或其它动态网页技术
16.学习matlab,如果想参加数学建模大赛的话,需要学这个软件。
大一假期(如果留校集训)
1.掌握C++语法,并熟练使用STL
2.试着实现STL的一些基本容器和函数,使自己基本能看懂STL源码
3.图论
a)使用优先队列优化Dijkstra和Prim
b)单源最短路径之SPFA
c)差分约束系统
d)多源多点最短路径之FloydWarshall算法
e)求欧拉路(圈套圈算法)
4.进行复杂模拟题训练
5.拓扑排序
6.动态规划进阶
a)完全背包、多重背包等各种背包问题(参见背包九讲)
b)POJ上完成一定数目的动态规划题目
c)状态压缩动态规划
d)树形动态规划
7.搜索
a)回溯法熟练应用
b)复杂的搜索题目练习
c)双向广度优先搜索
d)启发式搜索(包括A*算法,如八数码问题)
8.计算几何
a)判断点是否在线段上
b)判断线段相交
c)判断矩形是否包含点
d)判断圆与矩形关系
e)判断点是否在多边形内
f)判断点到线段的最近点
g)计算两个圆的公切线
h)求矩形的并的面积
i)求多边形面积
j)求多边形重心
k)求凸包
选修
9.可以学习一种C++的开发框架来编写一些窗体程序玩玩(如MFC,Qt等)。
10.学习使用C或C++连接数据库。
大二一整年:
1.数据结构
a)单调队列
b)堆
c)并查集
d)树状数组
e)哈希表
f)线段树
g)字典树
2.图论
a)强连通分量
b)双连通分量(求割点,桥)
c)强连通分量与双连通分量缩点
d)LCA、LCA与RMQ的转化
e)二分图匹配
i.二分图最大匹配
ii.最小点集覆盖
iii.最小路径覆盖
iv.二分图最优匹配
v.二分图多重匹配
f)网络流
i.最大流的基本SAP
ii.最大流的ISAP或者Dinic等高效算法(任一)
iii.最小费用最大流
iv.最大流最小割定理
3.动态规划多做题提高(10道难题以上)
4.数论
a)积性函数的应用
b)欧拉定理
c)费马小定理
d)威乐逊定理
5.组合数学
a)群论基础
b)Polya定理与计数问题
c)Catalan数
6.计算几何
a)各种旋转卡壳相关算法
b)三维计算几何算法
7.理解数据库原理,学会SQL语句
8.学好计算机组成原理
9.学习Transact-SQL语言,学会使用触发器,存储过程,学会数据库事务等。
10.图论二
a)网络流的各种构图训练(重要)
b)最小割与最小点权覆盖等的关系(详见《最小割模型在信息学竞赛中的应用》一文)
c)次小生成树
d)第k短路
e)最小比率生成树
11.线性规划
12.动态规划更高级进阶
13.KMP算法
14.AC自动机理论与实现
15.博弈论之Alpha-beta剪枝
选修,有相关兴趣的可以学一下:
16.自学C#或Java做一个项目,比如C++/C#/Java考试系统之类的。
17.先做一些小游戏玩玩,然后可以学一下DirectX或者OpenGL,或者可以试试XNA游戏框架。
18.了解一下游戏引擎相关的知识
其中的寒假假期最好:
1.自学完离散数学
2.自学概率论的部分章节
3.自学操作系统部分章节
大三、
1.巩固之前的知识,进行一遍大复习。
2.一些如蚁群算法,遗传算法,模拟退火算法等人工智能方面应用较广的随机性算法。
3.把编译原理上学的东西应用到编程中:如DFA,NFA,还有语法分析的各种方法等。
当你按上面那些一步步走过来时你已经是牛人了,后面要学的东西,就是由牛人自己来发掘的了。
2016-07-26 10:43:44 Tabris_ 阅读数:378
博客爬取于2020-06-14 22:44:05
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52033548
题目连接 :http://acm.hdu.edu.cn/showproblem.php?pid=3240
-----------------------------------------------------------------------------.
Counting Binary Trees
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 739 Accepted Submission(s): 256
Problem Description
There are 5 distinct binary trees of 3 nodes:
Let T(n) be the number of distinct non-empty binary trees of no more than n nodes, your task is to calculate T(n) mod m.
Input
The input contains at most 10 test cases. Each case contains two integers n and m (1 <= n <= 100,000, 1 <= m <= 109) on a single line. The input ends with n = m = 0.
Output
For each test case, print T(n) mod m.
Sample Input
3 100
4 10
0 0
Sample Output
8
2
Source
2009 “NIT Cup” National Invitational Contest
------------------------------------------.
题目大意 : 就是让你求 卡特兰数对M取模的结果
题解 :
卡特兰数主要有两种
一般式 :
另类递归式: h(n)=((4*n-2)/(n+1))*h(n-1);
在这里我们用的是递归式求解卡特兰数
注意我们求解的是卡特兰数的前N项和 h(1)=1 h(2)=2 h(3)=5 h(4)=14
根据递归式很容易想到(4*n-2)/(n+1) 求它的值然后不断乘起来就行 首先想到分子可以直接累乘 分母每一步计算一下乘上逆元即可
但是求逆元的要求就是分子分母互质 所以我们想到分解下m 的质因子 然后最分式上下约分处理 这个时候就可以用一个数组来存储分式中M的每个素因子个数 分子的就加一 分母的就减一
最后计算就行了
附本题代码
--------------------------------------------.
1 | # include <stdio.h> |
2016-07-24 16:57:43 Tabris_ 阅读数:385
博客爬取于2020-06-14 22:44:06
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52014844
题目连接:http://poj.org/problem?id=2653
------------------------------------------------------------------------.
Pick-up sticks
Time Limit: 3000MSMemory Limit: 65536K
Total Submissions: 12353Accepted: 4660
Description
Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed that the last thrown stick is always on top but he wants to know all the sticks that are on top. Stan sticks are very, very thin such that their thickness can be neglected.
Input
Input consists of a number of cases. The data for each case start with 1 <= n <= 100000, the number of sticks for this case. The following n lines contain four numbers each, these numbers are the planar coordinates of the endpoints of one stick. The sticks are listed in the order in which Stan has thrown them. You may assume that there are no more than 1000 top sticks. The input is ended by the case with n=0. This case should not be processed.
Output
For each input case, print one line of output listing the top sticks in the format given in the sample. The top sticks should be listed in order in which they were thrown.
The picture to the right below illustrates the first case from input.
Sample Input
5
1 1 4 2
2 3 3 1
1 -2.0 8 4
1 4 8 2
3 3 6 -2.0
3
0 0 1 1
1 0 2 1
2 0 3 1
0
Sample Output
Top sticks: 2, 4, 5.
Top sticks: 1, 2, 3.
Hint
Huge input,scanf is recommended.
------------------------------------------------------.
题目大意 : 就是依次向平面上扔几根棍 ,问最后没被其他木棍压住的木棍有哪些
题解: 水题 判断从每个棍向后来的棍 判断线段相交 有没有交上的 没有就是所要求的 记录下来 最后输出一下就醒了
时间够长 能够小 n^2 就行
附本题代码
------------------------------------.
1 | # include<iostream> |
2016-07-23 23:14:02 Tabris_ 阅读数:871
博客爬取于2020-06-14 22:44:07
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52008038
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5750
-----------------------------------------.
Dertouzos Accepts: 76 Submissions: 1357
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
问题描述
正整数称为的positive proper divisor, 当且仅当并且. 例如, 1, 2, 和3是6的positive proper divisor, 但是6不是.
Peter给你两个正整数和. 他想要知道有多少小于的整数, 满足他们的最大positive proper divisor恰好是.
输入描述
输入包含多组数据, 第一行包含一个整数表示测试数据组数. 对于每组数据:
第一行包含两个整数和$ (2 \le n, d \le 10^9)$
输出描述
对于每组数据, 输出一个整数.
输入样例
9
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
100 13
输出样例
1
2
1
0
0
0
0
0
4
----------------------------------------------------.
题目大意: 自己看
解题思路:
首先要明确的是 NM的最大因子为N的时候只有M为素数 且M<=N的最小素因子的时候 ;
试想 $N=p_1^{a_1}p_2^{a_2}p_3^{a_3}p_4^{a_4} …… p_n^{a_n} ; (p[i] < p[i+1]) $
如果M不是素数那么M=XY,NM的因子中 就多了NX和NY 均比N大 所以不成立
如果M>p1 (假设所有的ai均为1)那么N*M的因子中 就多了 一定大于 所以也不成立 至于某个的时候同理
也不行
所以先打出sqrt(1e9)内的所有素数
然后暴力找即可
1 | for(int i=0;i<k;i++) |
k值不到1e4 加上题目3500ms 就能过了
附上本题代码
----------------------------------------------------------.
1 | # include <iostream> |
2016-07-23 11:33:07 Tabris_ 阅读数:872
博客爬取于2020-06-14 22:44:08
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52003317
题目连接 :http://codeforces.com/problemset/problem/701/C
-----------------------------------.
C. They Are Everywhere
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Sergei B., the young coach of Pokemons, has found the big house which consists of n flats ordered in a row from left to right. It is possible to enter each flat from the street. It is possible to go out from each flat. Also, each flat is connected with the flat to the left and the flat to the right. Flat number 1 is only connected with the flat number 2 and the flat number n is only connected with the flat number n - 1.
There is exactly one Pokemon of some type in each of these flats. Sergei B. asked residents of the house to let him enter their flats in order to catch Pokemons. After consulting the residents of the house decided to let Sergei B. enter one flat from the street, visit several flats and then go out from some flat. But they won’t let him visit the same flat more than once.
Sergei B. was very pleased, and now he wants to visit as few flats as possible in order to collect Pokemons of all types that appear in this house. Your task is to help him and determine this minimum number of flats he has to visit.
Input
The first line contains the integer n (1 ≤ n ≤ 100 000) — the number of flats in the house.
The second line contains the row s with the length n, it consists of uppercase and lowercase letters of English alphabet, the i-th letter equals the type of Pokemon, which is in the flat number i.
Output
Print the minimum number of flats which Sergei B. should visit in order to catch Pokemons of all types which there are in the house.
Examples
input
3
AaA
output
2
input
7
bcAAcbc
output
3
input
6
aaBCCe
output
5
Note
In the first test Sergei B. can begin, for example, from the flat number 1 and end in the flat number 2.
In the second test Sergei B. can begin, for example, from the flat number 4 and end in the flat number 6.
In the third test Sergei B. must begin from the flat number 2 and end in the flat number 6.
-----------------------------------------------------------------------------.
题目大意 :有N个公寓里面住着口袋妖怪 ,下面给了N个公寓中每个公寓里的口袋妖怪的是哪一种 (分别用大小写字母表示 共52种) 你只能从其中的任意一个公寓进去,然后出去,然而呢 邻近的公寓与公寓之间是相通的 你可以从左边的公寓不出去就走到右边的公寓 问你如果一个人想要收集全所有出现过得所有种的口袋妖怪最少要经过多少个公寓,每种口袋妖怪有一个即可。。
解题思路:根据题意 ,N比较大 所以暴力三层for 会TLE 之后仔细看了下题 很明显的尺追法
维护两个指针 代表区间的左右界
按要求不断维护 更新最值即可
/********/ 换一种画风来描述这个问题
如果子串(i,j)包含了所有种个不同的字符,那么子串(i,k),(j < 9 < length)也包含了至少个不同字符。
因此对于每一个左边界,只要找到最小的满足条件的右边界,就能找到以这个左边界开始的符合条件的子串的长度的最小值。
寻找这个右边界,是经典的追赶法(尺取法,双指针法)问题。维护两个指针(数组下标),轮流更新左右边界,更新最值即可。复杂度 O(N)。
详情看代码注释吧
1 | # include <iostream> |
2016-07-23 11:07:59 Tabris_ 阅读数:442
博客爬取于2020-06-14 22:44:09
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52003146
题目连接 :http://codeforces.com/problemset/problem/701/B
------------------------------------------------.
B. Cells Not Under Attack
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya has the square chessboard of size n × n and m rooks. Initially the chessboard is empty. Vasya will consequently put the rooks on the board one after another.
The cell of the field is under rook’s attack, if there is at least one rook located in the same row or in the same column with this cell. If there is a rook located in the cell, this cell is also under attack.
You are given the positions of the board where Vasya will put rooks. For each rook you have to determine the number of cells which are not under attack after Vasya puts it on the board.
Input
The first line of the input contains two integers n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ min(100 000, n2)) — the size of the board and the number of rooks.
Each of the next m lines contains integers xi and yi (1 ≤ xi, yi ≤ n) — the number of the row and the number of the column where Vasya will put the i-th rook. Vasya puts rooks on the board in the order they appear in the input. It is guaranteed that any cell will contain no more than one rook.
Output
Print m integer, the i-th of them should be equal to the number of cells that are not under attack after first i rooks are put.
Examples
input
3 3
1 1
3 1
2 2
output
4 2 0
input
5 2
1 5
5 1
output
16 9
input
100000 1
300 400
output
9999800001
Note
On the picture below show the state of the board after put each of the three rooks. The cells which painted with grey color is not under the attack.
-----------------------------------------------------.
题目大意: 就是在N*N的方格内 放入M个 “車” 这样 这个"車"所在的行列都是不安全的了 问 一次放入这些“車”后 还有多少安全的位置
(自己大概意淫出来的正确的题意)
题解 : N,M 的数据量太大了,不能暴力求解 。 xjb画了画 发现 每次安全的位置个数都是NN-N(x+y)+xy; (x表示有多少行上有车,y同理)最后再加上x和y减重的那部分xy;既是正解;
操作的时候要用两个数组记录下这行有没有車,这列有没有車 如果没有x,y就++;有了就不加了
附本体代码
------------------------------------------.
1 | int xx[101010],yy[101010]; |
2016-07-22 18:15:39 Tabris_ 阅读数:431
博客爬取于2020-06-14 22:44:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51997347
-------------------------------------------------------------.
hdu 5572
1 | # include <iostream> |
2016-07-17 16:12:39 Tabris_ 阅读数:405
博客爬取于2020-06-14 22:39:17
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51932828
1 | struct Matrix |
1 | # include<stdio.h> |
1 | # include<stdio.h> |
2016-07-17 12:56:31 Tabris_ 阅读数:295
博客爬取于2020-06-14 22:44:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51931853
题目连接 : http://poj.org/problem?id=3233
Matrix Power Series
Time Limit: 3000MSMemory Limit: 131072K
Total Submissions: 20125Accepted: 8449
Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4
0 1
1 1
Sample Output
1 2
2 3
题目大意 : 就是求S %m;
题解 : 其实很容易知道A^k 之后只需加和就行了
但是直接加和还是不行 k的范围是在太大 会超时 所以就构造一个矩阵
因为S可以看成S=A(I+A(I+A(I+…A(I+A)))) (I是单位矩阵)
拿k=3举例S=A(I+A(I+A))
那么我们想,可不可以构造一个矩阵T使得TT(因为是k次幂)这样乘下去每次可以得到A(A+I)
那么肯定T有个两个元素就是A与I
那么假设:T={A I }
I I
那么T=TT={AA+II AI+II}
AI+II II+II
这样存在一个I(A+I)的式子 ,当T再乘以T的时候会出现A(A+I)
这个时候我们可以简化将T={A I}
0 I
这样可以简化很多计算TT={AA AI+II}
0 I
那么容易得到T^(K+1)={A^(K+1) I+A+A^2+A^3+…+A^K}
0 I
这样我们只需要算T的k+1次幂就可以了
上文摘自 http://blog.csdn.net/yihuikang/article/details/7722765
实在懒得写这些 其实就是简单的等比矩阵求和 学过线性代数 就应该能构造出来矩阵的
错将输入 n,k,m 当成的 n,m,k 错了一上午 。。汗2333333333
附本提代码
1 | # include <iostream> |
2016-07-17 09:37:27 Tabris_ 阅读数:261
博客爬取于2020-06-14 22:44:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51930813
题目连接 : http://poj.org/problem?id=3070
Fibonacci
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 12738Accepted: 9065
Description
In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …
An alternative formula for the Fibonacci sequence is
.
Given an integer n, your goal is to compute the last 4 digits of Fn.
Input
The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.
Output
For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).
Sample Input
0
9
999999999
1000000000
-1
Sample Output
0
34
626
6875
Hint
As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by
.
Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:
.
题目大意 : 这个的大意应该不用说了吧
题解 : 这个题目大意里已经说得很清楚了吧 。。
就是裸的矩阵快速幂 没什么难度 主要是用来熟悉下 矩阵快速么的代码实现 并顺手撸了一发模板
1 | const int M = 2; |
直接附本题代码吧
1 | # include <iostream> |
2016-07-16 19:16:49 Tabris_ 阅读数:164
博客爬取于2020-06-14 22:44:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51925879
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5317
RGCDQ
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2667 Accepted Submission(s): 1060
Problem Description
Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more interesting things about GCD. Today He comes up with Range Greatest Common Divisor Query (RGCDQ). What’s RGCDQ? Please let me explain it to you gradually. For a positive integer x, F(x) indicates the number of kind of prime factor of x. For example F(2)=1. F(10)=2, because 10=25. F(12)=2, because 12=22*3, there are two kinds of prime factor. For each query, we will get an interval [L, R], Hdu wants to know maxGCD(F(i),F(j)) (L≤i< j≤R)
Input
There are multiple queries. In the first line of the input file there is an integer T indicates the number of queries.
In the next T lines, each line contains L, R which is mentioned above.
All input items are integers.
1<= T <= 1000000
2<=L < R<=1000000
Output
For each query,output the answer in a single line.
See the sample for more details.
Sample Input
2
2 3
3 5
Sample Output
1
1
题目大意 : 就是在1~1e6 这个范围内 f[i]表示i的质因子的种类数 (8=2^3 f[8]=1 ( 仅有2 )) 让你求的是l~r区间内 GCD(F(i),F(j)) (L ≤ i < j ≤ R) 的最大值
题解 : 这道题目看起来很难 ,其实很好想。首先1~1e6 这个范围内f[i]的最大值也只有7 。举例2357111317=510510 这已经是f[i]=7最小的数了 其次小的就是4849845已经大于1e6 很多了 所以至于f[i]=8的数就不用考虑了
知道了上述这些 就很好处理了 只要预先打表 先用筛法将f[1~1e6]计算出来 在用前缀和的形式 分别吧f[i]=1,=2,…=7的数记录出来 开的数组就是has[1e6][10] 并不会超内存
最后就能记录下来l~r范围内 f[i]=1,=2,…=7 的个数 这样的话再求MAXgcd就方便多了
总时间复杂度就是 O(7e6+7T)
7e6 = nlogn + n
附本题代码
Ps至于最后判断gcd是几的50+代码 是因为写短的 WA了5发 而且是在找不到别的错误 就枚举了一下maxgcd 还好AC了。。。
1 | # include <stdio.h> |
2016-07-03 16:45:29 Tabris_ 阅读数:369
博客爬取于2020-06-14 22:44:15
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51815810
题目链接 :http://acm.hust.edu.cn/vjudge/contest/view.action?cid=120197#problem/Y
Trailing Zeroes (II)
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit Status Practice LightOJ 1090
Description
Find the number of trailing zeroes for the following function:
***C(n,r) x p^q ***
where n, r, p, q are given. For example, if n = 10, r = 4, p = 1, q = 1, then the number is 210 so, number of trailing zeroes is 1.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case contains four integers: n, r, p, q (1 ≤ n, r, p, q ≤ 106, r ≤ n).
Output
For each test case, print the case number and the number of trailing zeroes.
Sample Input
2
10 4 1 1
100 5 40 5
Sample Output
Case 1: 1
Case 2: 6
题目大意 : 就是求***C(n,r) x p^q *** 末尾有几个 0
题解 : 求末尾有几个0 就将其展开成(2^n) * (5^m) * k 然后输出min(n,m) 即可。。
但是数据量特别大 所以需要先预处理
用 five[N],two[N]出 N!中n,m的值(值的含义如上所述) 然后 稍加操作即可求出C(n,m)中n,m的值 (这里并不难,看代码就明白了)
剩下的p^q 就更好办了 p=(2^n) * (5^m) * k
求出的n,m的值在乘上q
最后加上C(n,m)中n,m的值 就是方程里n,m的值
总复杂度 O(1e6*(log(2,1e6)+log(5,1e6))+T *(log(2,p)+log(5,p)))
附本题代码
1 | # include <stdio.h> |
2016-07-02 16:42:00 Tabris_ 阅读数:328
博客爬取于2020-06-14 22:44:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51811570
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=120197#problem/H
The problem statement is very easy. Given a number n you have to determine the largest power of m,
not necessarily prime, that divides n!.
Input
The input file consists of several test cases. The first line in the file is the number of cases to handle.
The following lines are the cases each of which contains two integers m (1 < m < 5000) and n
(0 < n < 10000). The integers are separated by an space. There will be no invalid cases given and
there are not more that 500 test cases.
Output
For each case in the input, print the case number and result in separate lines. The result is either an
integer if m divides n! or a line ‘Impossible to divide’ (without the quotes). Check the sample input
and output format.
Sample Input
2
2 10
2 100
Sample Output
Case 1:
8
Case 2:
97
题目大意 : 就是N!%m^k=0; 给你n和m 求最大的k;
题解 : 其实很简单 就是把N!与M 质因子分解后
Pi表示第i个质数的贡献是多少
像这样
8 = 2^3 ,Pi=3;
N! ~~ Pn1…Pn2…Pn3…Pn4…Pn5…
M ~~ Pm1…Pm2…Pm3…Pm4…Pm5…
然后找出Pni/Pmi 的最小值 就是我们要求的答案了
附本题代码 170ms
1 | # include <stdio.h> |
2016-06-30 15:54:37 Tabris_ 阅读数:241
博客爬取于2020-06-14 22:44:17
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51791054
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=120197#problem/U
Digits of Factorial
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit
Status
Description
Factorial of an integer is defined by the following function
f(0) = 1
f(n) = f(n - 1) * n, if(n > 0)
So, factorial of 5 is 120. But in different bases, the factorial may be different. For example, factorial of 5 in base 8 is 170.
In this problem, you have to find the number of digit(s) of the factorial of an integer in a certain base.
Input
Input starts with an integer T (≤ 50000), denoting the number of test cases.
Each case begins with two integers n (0 ≤ n ≤ 106) and base (2 ≤ base ≤ 1000). Both of these integers will be given in decimal.
Output
For each case of input you have to print the case number and the digit(s) of factorial n in the given base.
Sample Input
5
5 10
8 10
22 3
1000000 2
0 100
Sample Output
Case 1: 3
Case 2: 5
Case 3: 45
Case 4: 18488885
Case 5: 1
题目大意 : 就是求n!在base进制下表示 不算前导0的话 有多少位
多少位的话 直接取log即可
但是n大了 long long 会爆 所以
拆成
log(n!)=log(n)+log(n-1)+ … (以上底数为base).
因为计算机中只有底数为十的对数函数 所以 表示成lg(n!)/lg(base) 就行
最后n==0 的时候要特判一下.
上面就是题解了
但是 我做的时候出现了 迷之RE+迷之WA
RE : printf(“Case %d: %.0llf\n”,++p,f[n]/log(base)+0.5);
这么输出居然是RE
于是又换了一种
WA:printf(“Case %d: %d\n”,++p,(int)(f[n]/log(1.0*base)+0.5));
这样居然是WA ?我就不明白了
最后还是看别人代码 用的ceil() 才过的 但这到底是为什么啊啊啊啊啊啊啊啊啊
最终过得姿势 ::: printf(“Case %d: %d\n”,++p,(int)ceil(f[n]/log(1.0*base)))
附本题代码
–
1 | # include <stdio.h> |
2016-06-29 16:32:35 Tabris_ 阅读数:305
博客爬取于2020-06-14 22:44:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51783994
题目链接:LightOJ 1035 Intelligent Factorial Factorization
Intelligent Factorial Factorization
Time Limit:500MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit
Status
Description
Given an integer N, you have to prime factorize N! (factorial N).
Input
Input starts with an integer T (≤ 125), denoting the number of test cases.
Each case contains an integer N (2 ≤ N ≤ 100).
Output
For each case, print the case number and the factorization of the factorial in the following format as given in samples.
Case x: N = p1 (power of p1) * p2 (power of p2) * …
Here x is the case number, p1, p2 … are primes in ascending order.
Sample Input
3
2
3
6
Sample Output
Case 1: 2 = 2 (1)
Case 2: 3 = 2 (1) * 3 (1)
Case 3: 6 = 2 (4) * 3 (2) * 5 (1)
题目大意 就是把N! 质因子分解一下
题解: 因为数据量很小 所以预处理一下所有N! 的质因子个数即可
这种办法 应该可以做到n<=1000
n<10000的时候用容器存一下 而且时间在大一丢丢 应该还是能做的
因为数据量太小 所有算法都是最最最最最暴力的
附本题代码
1 | # include <stdio.h> |
2016-06-29 15:13:15 Tabris_ 阅读数:415
博客爬取于2020-06-14 22:44:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51783218
题目链接 : http://acm.hust.edu.cn/vjudge/contest/view.action?cid=120197#problem/Q
–
Ifter Party
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit
Status
Description
I have an Ifter party at the 5th day of Ramadan for the contestants. For this reason I have invited C contestants and arranged P piaju’s (some kind of food, specially made for Ifter). Each contestant ate Q piaju’s and L piaju’s were left (L < Q).
Now you have to find the number of piaju’s each contestant ate.
Input
Input starts with an integer T (≤ 325), denoting the number of test cases.
Each case contains two non-negative integers P and L (0 ≤ L < P < 231).
Output
For each case, print the case number and the number of possible integers in ascending order. If no such integer is found print ‘impossible’.
Sample Input
4
10 0
13 2
300 98
1000 997
Sample Output
Case 1: 1 2 5 10
Case 2: 11
Case 3: 101 202
Case 4: impossible
题目大意 : 就是有P个单位的食物 有未知人数的人来吃 剩下L个单位的食物 其中没人吃的是一样多的 问每个人吃了多少食物 把每种可能都列举出来(任何一种可能均大于L)
如果没有任何一种可能就输出 impassbale
题解 : 设 n=P-L 其实就是吧n的所有因子中大于L 的数输出
T只有325个 所以暴力求解即可
for(LL i=1;i*i<=n;i++)
{
if(p%i==0)
{
if(i>l)
a[num++]=i;
if(p/i>l&&p/i!=i) //注意这里 能被开平方的话数就重了 在这wrong 5发 汗!
a[num++]=p/i;
}
}
附本题代码
1 | # include <stdio.h> |
2016-06-28 21:47:05 Tabris_ 阅读数:244
博客爬取于2020-06-14 22:44:20
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51779048
Apart from the novice programmers, all others know that you can’t exactly represent numbers raised
to some high power. For example, the C function pow(125456, 455) can be represented in double data
type format, but you won’t get all the digits of the result. However we can get at least some satisfaction
if we could know few of the leading and trailing digits. This is the requirement of this problem.
Input
The first line of input will be an integer T < 1001, where T represents the number of test cases. Each
of the next T lines contains two positive integers, n and k. n will fit in 32 bit integer and k will be less
than 10000001.
Output
For each line of input there will be one line of output. It will be of the format LLL . . . T T T, where
LLL represents the first three digits of n
k and T T T represents the last three digits of n
k
. You are
assured that n
k will contain at least 6 digits.
Sample Input
2
123456 1
123456 2
Sample Output
123…456
152…936
题目大意 就是求 n^k 的前三位和后三位
题解 :
后三位很好处理了 直接快速幂取模就好了
前三位就比较复杂了
n^k=A 同时取log
klog(n)=log(A) => A=10^(klog(n))
在这里我们知道k*log(10) =a.b (a是整数部分,b是小数部分)
在这里 a对A 的贡献就是一堆0 所以并没有什么用
所以A=10^(b)
因为要取 A 的前三位 所以A= 10^(2+b) 即可
还有一个坑点 就是后三位数如果是 12 的话 要输出012 就是前导0要有 wrong 了无数发
附本题代码
1 | # include <stdio.h> |
2016-06-28 21:36:41 Tabris_ 阅读数:674
博客爬取于2020-06-14 22:44:21
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51778975
Mathematically Hard
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit
Status
Description
Mathematically some problems look hard. But with the help of the computer, some problems can be easily solvable.
In this problem, you will be given two integers a and b. You have to find the summation of the scores of the numbers from a to b (inclusive). The score of a number is defined as the following function.
score (x) = n2, where n is the number of relatively prime numbers with x, which are smaller than x
For example,
For 6, the relatively prime numbers with 6 are 1 and 5. So, score (6) = 22 = 4.
For 8, the relatively prime numbers with 8 are 1, 3, 5 and 7. So, score (8) = 42 = 16.
Now you have to solve this task.
Input
Input starts with an integer T (≤ 105), denoting the number of test cases.
Each case will contain two integers a and b(2 ≤ a ≤ b ≤ 5 * 106).
Output
For each case, print the case number and the summation of all the scores from a to b.
Sample Input
3
6 6
8 8
2 20
Sample Output
Case 1: 4
Case 2: 16
Case 3: 1237
题目大意 就是求a~b的所有数的欧拉函数的和
题解:数据量5e6 预处理一下 将所有欧拉函数的平方求出 在处理一下前缀和 即可 因为后面的大数会爆long long 所以要用unsign long long
附本题代码
1 | # include <stdio.h> |
2016-06-26 19:17:17 Tabris_ 阅读数:497
博客爬取于2020-06-14 22:44:22
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51763961
题目链接:这里是传送阵。。
Tom and Jerry are very fond of cat and mice games, which might be rather obvious to you. Today they
are playing a very complicated game. The goals are simple as usual though, Jerry would be running
and Tom would have to catch Jerry.
However, today Jerry is running on a perfect circular
path with radius R meters, at a constant speed of
V m/s. Initially Tom is sitting at the very center of
the circle. He wants to catch Jerry as soon as possible,
but we all know, Tom is not very intelligent. Instead
of calculating an optimal direction to catch Jerry, he is
just running towards Jerry.
As Jerry is also moving, the path Tom has taken
start to look like a curve (see picture above). At any
given moment, Tom’s position is between Jerry’s current
position and the center of the circle. Tom is also
moving at a constant speed of V m/s, same speed as
Jerry. Find the time (in seconds) Tom would need to
catch Jerry.
Input
Input file has T (T ≤ 10000) test cases, each case consists of two integer R and V . Here, 0 < R, V ≤
10000.
Output
For each test case, print the case number and the time Tom will need to catch Jerry. Floating point
rounding error lower than 10−5 will be ignored by the judge.
Sample Input
4
45 100
5 1547
1000 10000
5668 5467
Sample Output
Case 1: 0.70685835
Case 2: 0.00507691
Case 3: 0.15707963
Case 4: 1.62854830
题目大意 : 就是 Jerry在半径为R的圆上 Tom在圆心 Tom面向Jerry追 Jerry和Tom的速度都是V 问多长时间Tom能追上Jerry
既然Tom 总是面向Jerry 追的 所以Tom的路径就是一个半径为R/2 的半圆 Jerry的路径就是一个半径为R的四分之一圆 时间就可求了
t=2 * PI * r/4 / v;
附本题代码
1 | # include <stdio.h> |
2016-06-07 10:37:00 Tabris_ 阅读数:477
博客爬取于2020-06-14 22:44:23
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51596858
本帖研究的是小数化分数与分数化小数
小数化分数 :http://acm.hdu.edu.cn/showproblem.php?pid=1717
分数化小数 : http://nanti.jisuanke.com/t/42
这里的小数包括循环小数 循环部分用"()" 括起来 For Example 1/3 = 0.(3) 。。。
小数化分数的性质如下 :
1、有限小数的话把小数点后面的数除以10(一位数).100(两位数).1000(三位数)等,
2、如果是无限循环小数那就把循环的数除以9、99、999(同上)
3、如果是混循环小数,循环数字为两位情况下不循环的数字一位则除以990,两位则9900,并加上不循环小数数值乘以990或者9900。
即:分子=不循环部分和循环部分连起来-不循环部分。分母=99…(循环位数)0…(不循环位数)
小数化分数就是
0.abcd(efghij)
(abcdefghij-abcd)/9999990000 (没有约分)
在代码处理中 应该用字符串输入 ;
还有即使pow函数要慎用。。。
附代码。
1 | # include <cstring> |
这个暂时还没弄明白 ,,莫着急、、、
分数化小数代码
1 |
2016-05-31 13:10:56 Tabris_ 阅读数:532
博客爬取于2020-06-14 22:44:25
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51544872
题目链接:http://codeforces.com/problemset/problem/676/C
C. Vasya and String
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
High school student Vasya got a string of length n as a birthday present. This string consists of letters ‘a’ and ‘b’ only. Vasya denotes beauty of the string as the maximum length of a substring (consecutive subsequence) consisting of equal letters.
Vasya can change no more than k characters of the original string. What is the maximum beauty of the string he can achieve?
Input
The first line of the input contains two integers n and k (1 ≤ n ≤ 100 000, 0 ≤ k ≤ n) — the length of the string and the maximum number of characters to change.
The second line contains the string, consisting of letters ‘a’ and ‘b’ only.
Output
Print the only integer — the maximum beauty of the string Vasya can achieve by changing no more than k characters.
Examples
input
4 2
abba
output
4
input
8 1
aabaabaa
output
5
Note
In the first sample, Vasya can obtain both strings “aaaa” and “bbbb”.
In the second sample, the optimal answer is obtained with the string “aaaaabaa” or with the string “aabaaaaa”.
题目大意 :
给你一个长度为n且只有a和b构成的字符串,你可以改变k个字母 ,即a变b b变a。。
问在你操作后 的最长子串的长度是多少。。
子串要求只有一种字母构成 ;
解题思路 :
分别计算一下 全是a的子串与全是b的自创最长能多长 ,取两个最大值即可;
我就是给字符串标一下号 ,并记录他们的位置 然后找到中间存在
举个栗子:(对的不是很齐 , 表格的话有太影响观看,最后就只能这样了)
aabaabaa
求a的子串的时候记录b的位置
-aabaabaa-
1–2–3–4 <–这是序号
-1 2 5 8 <–这是位置
求b的子串的时候记录a的位置
-aabaabaa-
123-45-678 <–这是序号
-1 0 1 3 4 6 7 8 <–这是位置
然后找中间有m个的区间 求一下开区间内的长度即可
附本题代码
1 | # include<iostream> |
2016-05-24 10:54:37 Tabris_ 阅读数:1852
博客爬取于2020-06-14 22:39:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51488462
#这里是数论入门题目了 很全面<<-- 戳这里
欧拉降幂
O(1)解决快速乘取膜
1 | LLu qmodx(LLu a,LLu b,LLu c) |
n = p1^a1p2^a2p3^a3*…*pk^ak 约束和s = (p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^ak)
lucas 定理 快速求大组合数 (省内存&省时间)
组合数求模
组合数求模
1 | # include <iostream> |
计算 其中b能整除a
如果b与c互素,则
如果b与c不互素,则
对于b与c互素和不互素都有成立
这里是扩展欧几里德入门的题目了 做完这些我觉得才明白了扩展欧几里德的应用 传送阵<<—
1 | # include <iostream> |
定义:,称x为a关于m的逆元
对于方程 我们可以转化为求
由于恒成立,所以除法取模就可以将被除数转化为乘上被除数的逆元即可.
1 | void exgcd(int a,int b,int &d,int &x,int &y){ |
费马小定理 :.
可以转化为.所以就是a关于p的逆元(!!!p必须为素数)
1 | int qmod(int a,int b){ |
还是用 babystep_gaintstep算法求解。但是这题并不能用POJ_2417的算法,直接套该
算法,下面简要说明一下不能用的原因。首先我们有必要归纳一下用babystep算法解题
的步骤:
(1) 求M = ceil( sqrt© ) ;
(2) for(i=0;i< M;i++) hash( i , A^i ) ;
(3) 求D = A^M%C;
(4) r = 1 ; for( i = 0 ; i < M ; i++ ) ex_gcd(r , C , x , y ) ; res = x * B % C ; jj = find( res)
如果找到了这时候的jj,则答案就是iM+jj,如果没有找到,则res = res * D % C,继续循
环查找,如果最终都没有找到,则输出无解。 在上述的步骤中,如果题目中没有告诉我们
gcd(A , C) = 1,则我们上述的方法是错误的,原因就在于第4步,求res的时候。因为如果
我们无法保证gcd(A , C) = 1 ,也就不能保证gcd(r ,C) = 1(因为D=A^M, r = D^i),所有在
用 扩展欧几里得求出rx + Cy = gcd(r,C ) 的一个解x0之后,原方程:rx+Cy = B的解
x = x0 * B / gcd(r,C) + iC / gcd(r,C) ,但是我们这个时候并不能计算出gcd(r,C),因为此时
的r本来就是经过取余之后得出的,并不能直接用来求gcd,因此我们上述的普通babystep
算法就会出错了。
这样我们就要换一种处理的方法了,这里介绍一种AC大牛博客上的一种“消因子”的方法,
具体内容请看这里:AC大牛。经过上面的分析我们很清楚接下去的处理应该从哪方面着
手,就是应该从不能求出gcd(r , C)入手。一种思想就是既然无法求, 那我每次只要保证
gcd(r, C) = 1那样就可以想普通babystep一样求解了,既然要保证gcd(r,C) =1 ,而
r = (A^M)^i,因此归根到底还是要求gcd( A , C ) = 1。下面就是从AC大牛博客上参考的“消因子”
法了,每次我们 都消去A,C的一个因子,然后对B,C, D进行如下的处理:B/=tmp;C/=tmp ;
D = D* A/tmp%C ,这样经过b轮的消因子之后,gcd(A,C) = 1, 接下去我们就可以用普通
的babystep求解出方程:A^x = B’( mod C’ ) 的解 res1, 原方程的解就是 res = res1 + b。
下面给出这种方法正确的简要证明;一开始我们要求的方程是:A^x = B( mod C ),也就是
求一个最小的x,使得A^x + Cy = B,通过消因子, 我们不断在方程两遍消去gcd(A,C),这
样方程就可以变成 DA^x1 + C’y1 = B’,很简单就可以证明上式中 x = x1 + b ; y = y1 的(只要
在方程的两边分别将消去的因子乘回去等式还是保持不变的)。这样我们的问题就转化为了
求x1和y1,即DA^x1 = B’( mod C’ ),此时gcd( A , C’) = 1,这样我们就可以用普通的babystep
求出上述式子的解x1,同时也就求出了x,这样本题就解决了。
但是上述的方法还是有一个bug的,也就是说,我们用babystep求出的x1>=0,所以上述的
方法只能求出x >= b的解,这样我们自然就会想到如果有一个解x < b怎么办,上述方法就会出
先错误了,因此我们这里还需要改进。考虑b的最大值是多少,考虑每次我们消去的因子数都
最小也就是2,这样我们就可以得到b的最大值就是log©,这样我们只要保证每次log©之内的
解都特判一下, 就不会出现我们刚才的问题了, 所以我们要在进行上述处理之前进行一次for
循环 ,特判0 - log©直接的x是否能成为解,接下去再用上述的“消因子”算法。
最后不得不佩服发明这种算法的人的神奇,将O©复杂度的判断,分两级判断将复杂度降低
到O( sqrt© ),所以就是为什么叫" babystep_gaintstep "了, 哈哈。
1 |
|
1 | int prime[20000],kp=0; |
普通的素数测试我们有O(√ n)的试除算法。事实上,我们有O(slog³n)的算法。
定理一:假如p是质数,且(a,p)=1,那么a^(p-1)≡1(mod p)。即假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1。(费马小定理)
该定理的逆命题是不一定成立的,但是令人可喜的是大多数情况是成立的。
于是我们就得到了一个定理的直接应用,对于待验证的数p,我们不断取a∈[1,p-1]且a∈Z,验证a^(p-1) mod p是否等于1,不是则p果断不是素数,共取s次。其中a^(p-1) mod p可以通过把p-1写成二进制,由(a*b)mod c=(a mod c)*b mod c,可以在t=log(p-1)的时间内计算出解,如考虑整数相乘的复杂度,则一次计算的总复杂度为log³(p-1)。这个方法叫快速幂取模。
为了提高算法的准确性,我们又有一个可以利用的定理。
定理二:对于0 < x < p,x^2 mod p =1 => x=1或p-1。
我们令p-1=(2^t)*u,即p-1为u二进制表示后面跟t个0。我们先计算出x[0]=a^u mod p ,再平方t次并在每一次模p,每一次的结果记为x[i],最后也可以计算出a^(p-1) mod p。若发现x[i]=1而x[i-1]不等于1也不等于p-1,则发现p果断不是素数。
可以证明,使用以上两个定理以后,检验s次出错的概率至多为2^(-s),所以这个算法是很可靠的。
需要注意的是,为了防止溢出(特别大的数据),a*b mod c 也应用类似快速幂取模的方法计算。当然,数据不是很大就可以免了。
下面是我的程序。
1 | //**************************************************************** |
1 |
|
对于任意一个我们可以写成
我们求解的时候只要先讲素数筛出来,然后直接一个个的除就行了,这样的理想复杂度是
但是注意一种情况,可能展开的数N就是一个很大的素数,比如,这样的数如果有个的话就不能简单快速的展开了.于是我们可以在判定数是否为素数的数组中在开一维记录其为第几个素数.这样一来复杂度就会降低很多
1 | int prime[N],kp; |
--------------------------.
1 | void phi_table() //欧拉函数。。。 |
1 | struct Matrix |
1 |
|
用于快速求卷积
卷积可以类比两个多项式相乘
正常暴力求卷积的复杂度是 ,但是通过FFT加速 求卷积的复杂度能降到
算法学习笔记
FFT模板
1 | struct Complex{ |
NTT
1 | const int Maxn=50000; |
下面这种方法可以很有效地求出根号a的近似值:首先随便猜一个近似值x,然后不断令x等于x和a/x的平均数,迭代个六七次后x的值就已经相当精确了。
( 4 + 2/ 4 ) / 2 = 2.25
( 2.25 + 2/ 2.25 ) / 2 = 1.56944…
( 1.56944…+ 2/1.56944…) / 2 = 1.42189…
( 1.42189…+ 2/1.42189…) / 2 = 1.41423…
这种算法的原理很简单,我们仅仅是不断用(x,f(x))的切线来逼近方程x^2-a=0的根。根号a实际上就是x^2-a=0的一个正实根,这个函数的导数是2x。也就是说,函数上任一点(x,f(x))处的切线斜率是2x。那么,x-f(x)/(2x)就是一个比x更接近的近似值。代入f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。
1 | const float EPS = 1e-5; |
1 | /** |
预处理逆元
1 | 方法一 i的逆元 |
不赘述
定义:设,,使得成立的最小的,称为对模的阶,记为。
定理:如果模有原根,那么它一共有个原根。
定理:若,,则。
定理:如果为素数,那么素数一定存在原根,并且模的原根的个数为。
定理:设是正整数,是整数,若模的阶等于,则称为模的一个原根。
假设一个数对于模来说是原根,那么的结果两两不同,且有,那么可以称为是模的一个原根,归根到底就是当且仅当指数为的时候成立。(这里是素数)
模有原根的充要条件:,其中是奇素数。
求模素数原根的方法:对素因子分解,即是的标准分解式,若恒有
成立,则就是的原根。(对于合数求原根,只需把换成即可)
求解原根的完整代码
1 | 如果mod 为素数 |
2016-05-22 18:11:12 Tabris_ 阅读数:1482
博客爬取于2020-06-14 22:39:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51476199
//转自:http://www.oschina.net/code/snippet_203297_11313
组合数求模
组合数求模
问题:求解组合数C(n,m),即从n个相同物品中取出m个的方案数,由于结果可能非常大,对结果模10007即可。
方案1: 暴力求解,C(n,m)=n*(n-1)…(n-m+1)/m!,n<=15
方案2: 打表,C(n,m)=C(n-1,m-1)+C(n-1,m),n<=1,000
方案3: 质因数分解,C(n,m)=n!/(m!*(n-m)!),C(n,m)=p1a1-b1-c1p2a2-b2-c2…pkak-bk-ck,n<=10,000,000
方案4: Lucas定理,将m,n化为p进制,有:C(n,m)=C(n0,m0)*C(n1,m1)…(mod p),算一个不是很大的C(n,m)%p,p为素数,化为线性同余方程,用扩展的欧几里德定理求解,n在int范围内,修改一下可以满足long long范围内。
1 | int Combination(int n, int m) |
1 | const int M = 10007; |
1 | //用筛法生成素数 |
1 | # include <stdio.h> |
1 |
|
莫比乌斯反演公式
莫比乌斯函数
$ \mu(n) = \left{\begin{array}{rcl} 1 && ,n=1\ (-1)^r && ,n=p_1p_2…*p_r \0 && ,other \end{array}\right.$
莫比乌斯函数是一个乘性函数
莫比乌斯函数的和函数 满足
$ F(n) = \sum_{d|n}\mu(d) = \left{\begin{array}{rcl} 1 && ,n=1 \0 && ,n>1 \end{array}\right.$
莫比乌斯反演公式
对于
形式一:
形式二:
注意有这样的两种形式,
1 | int mobius(int n){ |
就是从(0,0)到(n,0)中 只能向左/左上/左下走的方案数
(x,y)其中y>0
两种公式
2016-05-22 18:08:16 Tabris_ 阅读数:543
博客爬取于2020-06-14 22:44:26
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51476184
传送阵:http://acm.hdu.edu.cn/showproblem.php?pid=5698
瞬间移动
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 128 Accepted Submission(s): 61
Problem Description
有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m列的格子有几种方案,答案对1000000007取模。
Input
多组测试数据。
两个整数n,m(2≤n,m≤100000)
Output
一个整数表示答案
Sample Input
4 5
Sample Output
10
Source
2016"百度之星" - 初赛(Astar Round2B)
其实写了写就是一个杨辉三角,只不过行变换了一下
杨辉三角是一个由数字排列成的三角形数表,一般形式如下:
1 n=0
1 1 n=1
1 2 1 n=2
1 3 3 1 n=3
1 4 6 4 1 n=4
1 5 10 10 5 1 n=5
1 6 15 20 15 6 1 n=6
……
特征
与二项式定理的关系:杨辉三角的第n行就是二项式 展开式的系数列.
对称性:杨辉三角中的数字左、右对称,对称轴是杨辉三角形底边上的“高”.
结构特征:杨辉三角除斜边上1以外的各数,都等于它“肩上”的两数之和.
这些数排列的形状像等腰三角形,两腰上的数都是1.
从右往左斜着看,从左往右斜着看,和前面的看法一样,这个数列是左右对称的.
上面两个数之和就是下面的一行的数.
这行数是第几行,就是第二个数加一.
而在本题中 是这样的、
1 1 1 1 1 1 1
1 2 3 4 5 6
1 3 6 10 15
1 4 10 20
1 5 15
1 6
1
看了看其实就是行变了 列并没有变
把它改一下 行变成行加列-1 即可;
最后的最后直接贴上求组合数的模板AC…
附本题AC 代码
方案1 187ms
1 | # include <iostream> |
方案 2 31ms
1 | # include <iostream> |
2016-05-18 21:59:54 Tabris_ 阅读数:531
博客爬取于2020-06-14 22:44:27
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51447994
题目链接:
A :http://codeforces.com/problemset/problem/675/A
B :http://codeforces.com/problemset/problem/675/B
C :http://codeforces.com/problemset/problem/675/C
A. Infinite Sequence
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya likes everything infinite. Now he is studying the properties of a sequence s, such that its first element is equal to a (s1 = a), and the difference between any two neighbouring elements is equal to c (si - si - 1 = c). In particular, Vasya wonders if his favourite integer b appears in this sequence, that is, there exists a positive integer i, such that si = b. Of course, you are the person he asks for a help.
Input
The first line of the input contain three integers a, b and c ( - 109 ≤ a, b, c ≤ 109) — the first element of the sequence, Vasya’s favorite number and the difference between any two neighbouring elements of the sequence, respectively.
Output
If b appears in the sequence s print “YES” (without quotes), otherwise print “NO” (without quotes).
Examples
input
1 7 3
output
YES
input
10 10 0
output
YES
input
1 -4 5
output
NO
input
0 60 50
output
NO
Note
In the first sample, the sequence starts from integers 1, 4, 7, so 7 is its element.
In the second sample, the favorite integer of Vasya is equal to the first element of the sequence.
In the third sample all elements of the sequence are greater than Vasya’s favorite integer.
In the fourth sample, the sequence starts from 0, 50, 100, and all the following elements are greater than Vasya’s favorite integer.
题目大意 : 就是有一个等差数列 给你首元素与公差 再给你一个数 判断其在不在等差数列上
题目很简单
判断(b-a)mod C == 0 ?
注意的是C<0 与C = 0 的情况稍加判断即可
直接上代码
1 | # include <stdio.h> |
B. Restoring Painting
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya works as a watchman in the gallery. Unfortunately, one of the most expensive paintings was stolen while he was on duty. He doesn’t want to be fired, so he has to quickly restore the painting. He remembers some facts about it.
The painting is a square 3 × 3, each cell contains a single integer from 1 to n, and different cells may contain either different or equal integers.
The sum of integers in each of four squares 2 × 2 is equal to the sum of integers in the top left square 2 × 2.
Four elements a, b, c and d are known and are located as shown on the picture below.
Help Vasya find out the number of distinct squares the satisfy all the conditions above. Note, that this number may be equal to 0, meaning Vasya remembers something wrong.
Two squares are considered to be different, if there exists a cell that contains two different integers in different squares.
Input
The first line of the input contains five integers n, a, b, c and d (1 ≤ n ≤ 100 000, 1 ≤ a, b, c, d ≤ n) — maximum possible value of an integer in the cell and four integers that Vasya remembers.
Output
Print one integer — the number of distinct valid squares.
Examples
input
2 1 1 1 2
output
2
input
3 3 1 2 3
output
6
Note
Below are all the possible paintings for the first sample.
In the second sample, only paintings displayed below satisfy all the rules.
题目大意 : 给你一个九宫格 其中四个角和中间的数是未知的
给定你一个数 n 和其他四个数a,b,c,d
问在四个角和中间的格子上填上1~n中的数 (可以重复填入)
使得四个2x2的格子数的和相等的填法有多少种
解题思路 :
Tables | Are | Cool |
---|---|---|
x1 | a | x2 |
b | ?? | c |
x3 | d | x4 |
2x2的情况为
1: x1+a+b+??
2: x2+a+c+??
3: x3+d+b+??
4: x4+c+d+??
显然中间的?? 填什么多可以 即有n中填法
同时也能得到
当任意x值确定的时候 其他值也就确定了
假定当 x1,x2,x3,x4满足题意的时候
x1+1,x2+1,x3+1,x4+1 也满足题意 (当中最大值<=n)
这个时候我们只要枚举一下
a+b, b+d,d+c,a+c的最大值 这时候其对应的x值为1
结果即为
count(maxX~n) * n;
附本题代码
1 | # include <stdio.h> |
C. Money Transfers
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
There are n banks in the city where Vasya lives, they are located in a circle, such that any two banks are neighbouring if their indices differ by no more than 1. Also, bank 1 and bank n are neighbours if n > 1. No bank is a neighbour of itself.
Vasya has an account in each bank. Its balance may be negative, meaning Vasya owes some money to this bank.
There is only one type of operations available: transfer some amount of money from any bank to account in any neighbouring bank. There are no restrictions on the size of the sum being transferred or balance requirements to perform this operation.
Vasya doesn’t like to deal with large numbers, so he asks you to determine the minimum number of operations required to change the balance of each bank account to zero. It’s guaranteed, that this is possible to achieve, that is, the total balance of Vasya in all banks is equal to zero.
Input
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of banks.
The second line contains n integers ai ( - 109 ≤ ai ≤ 109), the i-th of them is equal to the initial balance of the account in the i-th bank. It’s guaranteed that the sum of all ai is equal to 0.
Output
Print the minimum number of operations required to change balance in each bank to zero.
Examples
input
3
5 0 -5
output
1
input
4
-1 0 1 0
output
2
input
4
1 2 3 -6
output
3
Note
In the first sample, Vasya may transfer 5 from the first bank to the third.
In the second sample, Vasya may first transfer 1 from the third bank to the second, and then 1 from the second to the first.
In the third sample, the following sequence provides the optimal answer:
transfer 1 from the first bank to the second bank;
transfer 3 from the second bank to the third;
transfer 6 from the third bank to the fourth.
题目大意 : 就是一圈银行 有的银行缺钱 有的银行的钱有富余 你要把富余出来的前取走 存到缺钱的银行里 银行是围城一个圈的
问你身上揣钱的走过的路有多少
两个邻近的银行中有一条道
(略带意淫的翻译)
解题思路:
借鉴:http://blog.csdn.net/yukizzz/article/details/51437984
把这些分成尽可能多的和为0的区间
每个区间走过的路即为区间元素个数-1;
这里用了map 否则数组开不了那么大
(区间和为0的充要条件是区间两端点的前缀和相等即mp[si] == mp[sj])那么这道题就做出来了
附本题代码
1 | # include <stdio.h> |
2016-05-16 17:15:07 Tabris_ 阅读数:246
博客爬取于2020-06-14 22:44:28
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51426587
题目链接:
GTW likes gt Accepts: 54 Submissions: 782
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
问题描述
从前,有只萌萌的GT,他们分成了两组在一起玩游戏。他们会排列成一排,第只GT会随机得到一个能力值。在第秒的时候,第只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT。
为了使游戏更加有趣,GT的首领GTW会发功次,第次发功的时间为,则在第$c_i b_1,b_2,…,b_{c_i}$ 都会增加1。
现在,GTW想知道在第秒之后,会有几只GT存活下来。
输入描述
第一行只有一个整数,表示测试数据组数。
第二行有两个整数。表示GT的个数和GTW发功的次数。
第三到行,每行有两个整数,表示第ii只GT在哪个组和他的能力值$ (0\leq a[i]\leq 1,1\leq b[i]\leq 10^6)n+3n+m+2c_i$ ,表示GTW第ii次发功的时间。
输出描述
总共行,第行表示第组数据中,GT存活的个数。
输入样例
1
4 3
0 3
1 2
0 3
1 1
1
3
4
输出样例
3
HINT
第1秒后 能力值为4 2 3 1
第2秒后 能力值为4 2 3 1
第3秒后 能力值为5 3 4 1,第2只GT被第3只GT消灭掉了
第4秒后 能力值为6 4 5 2
c[i] 并不是有序的
题目大意 : 详见中闻题面
题解:
本题求解的是最后还剩下多少 , 也就是求有多少被灭了;
在第i秒的时候i能把编号0~i-1的小于他的全灭了
如果每次到第i秒的时候在从前向后遍历一遍的话 必定会超时
所以换个角度
如果编号i被灭了 也就是说后面有比他大且是另外一组的
所以从后面遍历即可
根据c[i]的遍历就能计算出b[i]在i秒时的值 这时候看后面有没有比他大的且是另外一组的
所以
倒序遍历 维护两个最大值即可
附本题代码
1 | # include <stdio.h> |
2016-04-29 21:34:59 Tabris_ 阅读数:291
博客爬取于2020-06-14 22:44:29
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51284402
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=5606
tree Accepts: 143 Submissions: 807
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
问题描述
有一个树(nn个点, n-1n−1条边的联通图),点标号从11~nn,树的边权是00或11.求离每个点最近的点个数(包括自己).
输入描述
第一行一个数字TT,表示TT组数据.
对于每组数据,第一行是一个nn,表示点个数,接下来n-1n−1,每行三个整数u,v,wu,v,w,表示一条边连接的两个点和边权.
T = 50,1 <= n <= 100000, 1 <= u,v <=n,0 <= w <= 1T=50,1≤n≤100000,1≤u,v≤n,0≤w≤1.
输出描述
对于每组数据,输出答案.
考虑到输出规模过大,设ans_ians
i
表示第ii个点的答案.你只需输出ans_1 ^ ans_2 ^ ans_3^ans_nans
1
xor ans
2
xor ans
3
… xor ans
n
即可.
输入样例
1
3
1 2 0
2 3 1
输出样例
1
Hint
ans_1 = 2ans
1
=2
ans_2 = 2ans
2
=2
ans_3 = 1ans
3
=1
2 \ xor \ 2 \ xor \ 1=12 xor 2 xor 1=1, 因此输出11.
题目大意 : 如题 中文体面。。。。
解题思路 : 题目说 找到每个点离自己最近的点的个数 而且还包括自己 自己与自己的距离 就是0 没有疑议
所以就找到与自己距离为0的点的个数即可
但是数据达到了10^6 如果两层for的话必定会超时 所以不可以暴力解
这时思考 一个点与其距离为0的点的个数和 是对每一个点都成立的
比如说 点1 点2 点3 互相距离为0
所以ans1=3 ans2=3 ans3=3;
就是有几个点 他们有的ans值都相同
这样之求解出这些点的一个的ans值就行
然后在求解出ans个ans的自身异或 值
Ps: ans个ans的自身异或 值
很简单 只要判断ans的奇偶即可 ans为偶数 那么异或的结果为0 ans为奇数 异或值即为ans本身
在这里 我求解这些互相距离为0的点 采用的是并查集 把距离相同且为0 的点归为统一集合
之后在遍历一遍 记录每个集合的个数(即ans)即可 、
然后再把这些ans值互相异或即可
附本题代码
1 | # include <iostream> |
2016-04-29 14:45:29 Tabris_ 阅读数:375
博客爬取于2020-06-14 22:44:30
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51281788
ACMer与Coder的交流分享地
POJ2635-The Embarrassed Cryptographer
转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1309305108
大致题意:
给定一个大数K,K是两个大素数的乘积的值。
再给定一个int内的数L
问这两个大素数中最小的一个是否小于L,如果小于则输出这个素数。
解题思路:
首先对题目的插图表示无语。。。
高精度求模+同余模定理
1、 Char格式读入K。把K转成千进制Kt,同时变为int型。
把数字往大进制转换能够加快运算效率。若用十进制则耗费很多时间,会TLE。
千进制的性质与十进制相似。
例如,把K=1234567890转成千进制,就变成了:Kt=[ 1][234][567][890]。
为了方便处理,我的程序是按“局部有序,全局倒序”模式存放Kt
即Kt=[890][567][234][1 ] (一个中括号代表一个数组元素)
2、 素数打表,把10^6内的素数全部预打表,在求模时则枚举到小于L为止。
注意打表不能只打到100W,要保证素数表中最大的素数必须大于10^6,否则当L=100W且K为GOOD时,会因为数组越界而RE,这是因为越界后prime都是负无穷的数,枚举的while(prime[pMin]<L)循环会陷入死循环
3、 高精度求模。
主要利用Kt数组和同余模定理。
例如要验证123是否被3整除,只需求模124%3
但当123是一个大数时,就不能直接求,只能通过同余模定理对大数“分块”间接求模
具体做法是:
先求1%3 = 1
再求(1*10+2)%3 = 0
再求 (0*10+4)% 3 = 1
那么就间接得到124%3=1,这是显然正确的
而且不难发现, (1*10+2)*10+4 = 124
这是在10进制下的做法,千进制也同理,10改为1000就可以了
Source修正:
Nordic 2005
按 Ctrl+C 复制代码
1 | //Memory Time |
按 Ctrl+C 复制代码
Sample Input
143 10
143 20
667 20
667 30
2573 30
2573 40
4 2
6 3
6 3
15 3
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 2
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 3
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 999981
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 999982
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 999983
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 999984
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999536689 999985
9936798836621706335903766366605021199756127575438907144689843371764114998372849970522970722679648297 1000000
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999924165887 1000000
9999999999999999997709341477512928270733515750111494296807693217401592660013176273247584305454312971 1000000
9999999999988881245087379264540384030358544520360773252628174690915590034078934845096473005364364269 1000000
9999999999999999999999999999999999999999999999999999999999999999999997947710886296926452585995644787 1000000
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998743929569 1000000
9999999999999999999999999999999999999999999999999999999999999999999999996406876316697599258447653751 1000000
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995271511 1000000
9999664515006205757944572422495695942633452678405393581216966782816097132509526872495414067984894021 1000000
0 0
Sample Output
GOOD
BAD 11
GOOD
BAD 23
GOOD
BAD 31
GOOD
BAD 2
BAD 2
GOOD
GOOD
GOOD
GOOD
GOOD
GOOD
BAD 999983
BAD 999983
BAD 587
BAD 100043
GOOD
GOOD
GOOD
GOOD
GOOD
BAD 16603
BAD 9103
2016-04-19 00:23:29 Tabris_ 阅读数:530
博客爬取于2020-06-14 22:44:31
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51184895
题目链接 : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3872
Beauty of Array
Time Limit: 2 Seconds Memory Limit: 65536 KB
Edward has an array A with N integers. He defines the beauty of an array as the summation of all distinct integers in the array. Now Edward wants to know the summation of the beauty of all contiguous subarray of the array A.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer N (1 <= N <= 100000), which indicates the size of the array. The next line contains N positive integers separated by spaces. Every integer is no larger than 1000000.
Output
For each case, print the answer in one line.
Sample Input
3
5
1 2 3 4 5
3
2 3 3
4
2 3 3 2
Sample Output
105
21
38
题目大意 :
给出一个N大小的数组,寻找一些这个数组的子集的和,
举个例子吧
1 2 3 4 5
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
_ 2
_ 2 3
_ 2 3 4
_ 2 3 4 5
_ _ 3
_ _ 3 4
_ _ 3 4 5
_ _ _ 4
_ _ _ 4 5
_ _ _ _ 5
举例子的话 很形象了 就不再解释了
计算这些数组的和 (包括最开始输入的几个数)
如果 在每一个子集 中如果有重复出现的数则只加一遍;
数据非常大 10^6 暴力一定会超时
本题的主要思路就是 输入一个数 就把这个数包括之前的数新产生的符合题意的子集的和加入
如
输入1时 1
子集为
1
输入2时 1 2
新增子集为
1 2
_ 2
输入3时 1 2 3
新增子集为
1 2 3
_ 2 3
_ _ 3
输入4时 1 2 3 4
新增子集为
1 2 3 4
_ 2 3 4
_ _ 3 4
_ _ _ 4
输入5时 1 2 3 4 5
新增子集为
1 2 3 4 5
_ 2 3 4 5
_ _ 3 4 5
_ _ _ 4 5
_ _ _ _ 5
综合一下就是
1 2 3 4 5
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
_ 2
_ 2 3
_ 2 3 4
_ 2 3 4 5
_ _ 3
_ _ 3 4
_ _ 3 4 5
_ _ _ 4
_ _ _ 4 5
_ _ _ _ 5
以上是没有出现重复的情况
每次新增子集为前一种情况的每个新增子集加入这个元素
用一个数存上这些数的和即可
出现重复情况其实也很好理解
假定此时已经输入 1 2 3 4
在输入3时
新增子集为
1 2 3 4 3
_ 2 3 4 3
_ _ 3 4 3
_ _ _ 4 3
_ _ _ _ 3
因为之前已经出现过 3 所以新加入的子集中3就不需要再重复的加了;
而怎么判断子集中有没有与新输入元素重复的元素呢
观察
1 2 3 4 3
_ 2 3 4 3
_ _ 3 4 3
_ _ _ 4 3
_ _ _ _ 3
不难发现前三个新增子集已经有过3
但是后两个子集并没有3
其实想一想,如果输入顺序为1 3 2 4 3的话
新增子集为
1 3 2 4 3
_ 3 2 4 3
_ _ 2 4 3
_ _ _ 4 3
_ _ _ _ 3
这时前2个新增子集有过3
后3个子集并没有3
如果在换个顺序 又会发生变化 ;
而我们计算的时候把新增子集的和记录下来
之后再把多加的数值减去就行
不难发现只要与新加入元素相同的元素 在第几次输入 就会有几个子集存在元素重复
这是用一个数组吧这个数存在的位置记录一下就行
但是如果有多个重复的情况呢;
即输入为3 2 3 4 3
这时新增子集为
3 2 3 4 3
_ 2 3 4 3
_ _ 3 4 3
_ _ _ 4 3
_ _ _ _ 3
发现重复总是以除新输入元素之外最后输入的相同元素判断的;
所以每次更新一下元素出现位置即可;
用sum来存储总共的和
用ans来存储新增子集的和
这是如果出现相同时
ans- = 输入元素 * 未更新的位置;
就是新增元素的和
综上所述
本题的思路就完全出来了
看似本文叙述非常多,其实都是思维的过程,实际操作起来非常快的。
1 | # include <iostream> |
2016-04-18 22:51:32 Tabris_ 阅读数:611
博客爬取于2020-06-14 22:44:32
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51183322
题目链接 :http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3870
Team Formation
Time Limit: 3 Seconds Memory Limit: 131072 KB
For an upcoming programming contest, Edward, the headmaster of Marjar University, is forming a two-man team from N students of his university.
Edward knows the skill level of each student. He has found that if two students with skill level A and B form a team, the skill level of the team will be A ⊕ B, where ⊕ means bitwise exclusive or. A team will play well if and only if the skill level of the team is greater than the skill level of each team member (i.e. A ⊕ B > max{A, B}).
Edward wants to form a team that will play well in the contest. Please tell him the possible number of such teams. Two teams are considered different if there is at least one different team member.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer N (2 <= N <= 100000), which indicates the number of student. The next line contains N positive integers separated by spaces. The ith integer denotes the skill level of ith student. Every integer will not exceed 109.
Output
For each case, print the answer in one line.
Sample Input
2
3
1 2 3
5
1 2 3 4 5
Sample Output
1
6
题目大意 : 就是给你N个数,找寻其中的两个数使得这两个数的异或值大于这两个数中的任意一个的情况数。
解题思路 :
正常的时候应该两两计算异或值判断,复杂度为O(n^2),但是因为题目的数据量比较大为10^6,会超时所以不可行。
那怎么办呢,。
既然题目说的是异或,那么就是位运算,那么就在二进制上思考。
题目要的又是异或的值大于这两个值的每一个 也就是满足大于这两个数中大的一个即可 , 那么就想一想仅在二进制下,两个数怎么比较大小。
我们知道二进制下的值 换算成10进制就是 2的整数次幂加和的形式
example:
x = 100001110(2) = 2^8+2^3+2^2+2^1;
y = 100011010(2) = 2^8+2^4+2^3+2^1;
看等式右边很容易就能得出 x < y;
从最高位开始比较 如果相同就比较下一位,直到出现不同的情况 ,如果不同即一为0一为1 , 则这位为1的大,这时候后面的位数怎样都不重要了,变化的这一位在数值上已经比后面的位数最大的情况还要大了,所以不需要考虑;
知道这些在异或
二进制下 同位运算 相异为1 (0^1/1^0) 相同为0 (1^1/0^0)
一个数在异或运算之后要比本身大,需要的是其与其异或运算的数在最高位(不计算前导0)的位上为0;
解释一下:
100001110 想要得到一个比它大的一个数只需要在它为0的任意1位上变为1即可(这时需要在这位的前面的任何一位都不改变,而后面的值则无所谓,前文已经解释)
所以另1个数的最高位在这个数为0的位上即可
明白了以上几点,本题就可以做了,
首先要把每个数的二进制上的为0的位数都记录下来(前导0不算)
在把每个数在二进制上的最高位的1(必为1)记录下来
比如说在二进制上的某一位 存在在这位上为0的数为n个,存在最高位在这位上的数为m个
则满足题目的结果就为n*m个;
而题目的数据为最大10^9 那么在二进制上就不超过int整型 既是32位;
所以只需要计算这32位的的情况的和即可
把每位的情况分别用两个数组来存就行
看下代码吧 很短 很好理解
1 | # include<stdio.h> |
2016-04-17 19:51:34 Tabris_ 阅读数:298
博客爬取于2020-06-14 22:44:33
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51174895
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=1233
还是畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 37241 Accepted Submission(s): 16762
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
Hint
Hint
Huge input, scanf is recommended.
最简单的最小生成树 入门
就不赘述了
直接上代码
kruskal
1 | # include <iostream> |
prim
1 | # include <iostream> |
2016-04-12 14:03:33 Tabris_ 阅读数:505
博客爬取于2020-06-14 22:44:34
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51132938
题目链接 :http://poj.org/problem?id=2954
Triangle
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 5661Accepted: 2439
Description
A lattice point is an ordered pair (x, y) where x and y are both integers. Given the coordinates of the vertices of a triangle (which happen to be lattice points), you are to count the number of lattice points which lie completely inside of the triangle (points on the edges or vertices of the triangle do not count).
Input
The input test file will contain multiple test cases. Each input test case consists of six integers x1, y1, x2, y2, x3, and y3, where (x1, y1), (x2, y2), and (x3, y3) are the coordinates of vertices of the triangle. All triangles in the input will be non-degenerate (will have positive area), and −15000 ≤ x1, y1, x2, y2, x3, y3 ≤ 15000. The end-of-file is marked by a test case with x1 = y1 = x2 = y2 = x3 = y3 = 0 and should not be processed.
Output
For each input case, the program should print the number of internal lattice points on a single line.
Sample Input
0 0 1 0 0 1
0 0 5 0 0 5
0 0 0 0 0 0
Sample Output
0
6
题目大意 :
在一个网格上有三个点,求这三个点围城的三角形内部有几个格点(恰好在三角形的边上的格点不算)。
题目思路:
涉及到格点了,很容易先到是PICK公式——S=a/2+b-1。
(Ps :不知道什么是PICK公式的点这里->这里T_T这里)
这是一个PICK公式的逆运用来求b。
转换一下公式即可=>b=(2S-a)/2+1。
本题中要先把每条边上的格点数求出来,其实很简单运用GCD(辗转相除法)即可。设每条边的向量为(x,y)->GCD(x,y)就是这条边上的格点个数-1,很好理解,求得的结果是排除这条边的一个端点的. 而最大公约数实几就证明有几个格点在边上.也就是这个方向的向量中满足两端均在格点上的向量为(x,y)/GCD(x,y),那么GCD(x,y)为几就说明有几个这样的 “单位” 向量.
明白了以上代码实心就好了,
附本题代码
1 | # include<iostream> |
2016-04-11 19:32:06 Tabris_ 阅读数:1617
博客爬取于2020-06-14 22:39:20
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51124611
相当全的计算几何模板
http://paste.ubuntu.com/24458430/
Ps:尽量不要用除法,三角函数,强制类型转换等操作,否则精度损失比较大
const double PI = acos(-1.0);
const double EPS = 1e-8;
任何double的比较运算都要用eps
我们想将向量 以为轴点逆时针旋转,且旋转角为 $\alpha \left[\begin{array}{cc}\ x’ \ y’ \end{array}\right]=\left[\begin{array}{cc}\ \cos(\alpha) &&-\sin(\alpha) \ \sin(\alpha) && \cos(\alpha) \end{array}\right] \times \left[\begin{array}{cc}\ x \ y \end{array}\right]$
1 | double mul(Point p1,Point p2,Point p0){ |
1 | double dis(Point p1,Point p2){ |
1 | struct point{ |
1 | point xmult(point u,point v){ |
1 | double dmult(point u,point v){ |
1 | point subt(point u,point v){ |
1 | point pvec(plane s){ |
1 | double dis(point p1,point p2){ |
1 | double vlen(point p){ |
1 | bool judge(point a,point b,point c,point d){ |
1 | double ptoplane(point p,point s1,point s2,point s3){ |
1 | double Area_triangle(point a,point b,point c){ |
1 | bool dy(double x,double y) { return x > y + eps;} // x > y |
复杂度寻求凸包
1 |
1 | const int maxN=50000; |
1 | bool IsIntersected(point s1,point e1,point s2,point e2)//两个线段相交 |
1 | point intersection(point &A,point &B,point &C,point &D) |
1 | struct Round { |
可以由4个点构成3个向量,3个向量共面的充要条件是向量为a,b,c,存在实数x,y,z不全为零,使得xa+yb+zc=0。转化为线性代数的3个向量线性相关的行列式为0。
1 | double is_coplanar(point a, point b, point c, point d){ |
2016-04-10 19:26:51 Tabris_ 阅读数:3490
博客爬取于2020-06-14 22:39:21
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51114511
#计算几何模板总结 :
尽量不要用除法,三角函数,强制类型转换(尤其是double转int)等操作,否则精度损失比较大 。
const double PI = acos(-1.0);
const double EPS = 1e-8;
对小数点后1位 取整 的方法为 ±1 (+1位进位 -1为退位)
eg:8(double)=7.9999999999…;
8(int)=8;
int(8(double))=7; !!!
这样精度损失就大了~~~~
1.在用1e-n判断相等的时候不是n越大越好 要选择合适的 ,一般为6/8/9/10
2.判断两条线段距离大小关系的时候有平方倍进行比较。
3.未完待续。。。
首先明确点与直线的位置关系只有两种:
1.点在直线上
2.点不在直线上
在这里只要用叉积判断就可以了
以上图为例只需满足向量即可
如果叉积等于0 则说明两向量共线 所以点在直线上
如果叉积不为0 则说明点不在直线上
知道了如何判断点与直线的位置关系在来判断点与线段的位置关系就容易多了
跟直线类似点与线段也只有两种位置关系:
1.点在线段上
2.点不在线段上
如果点在线段上则需满足以下两种情况:
1.点在线段所在的直线上。
2.点在以线段为对角线的矩形内。
前者很好理解,而后者则确保点不在线段的两端延长线上。
所以除了判断叉积还要判断坐标关系
以下图为例
很容易得出
应满足以下结论
c.x> min(a.x,b.x);
c.x< max(a.x,b.x);
c.y> min(a.y,b.y);
c.y< max(a.y,b.y);
这样就满足了点在矩形内
当然不能忘记用叉积判断;;;
先要说明,当点在三角形边上的时候视为点在三角形的内部
在这里我们运用面积关系来判断点在三角形的内外
观察S△dab+S△dbc+S△dac与S△abc的大小关系
观察上两图不难发现当点在三角形内是S△dab+S△dbc+S△dac是相等于S△abc的
而点在三角线外的时候
S△dab+S△dbc+S△dac是大于S△abc的
所以只要计算出两式的大小关系即可
Ps:这里求面积运用的为叉乘,就是 延伸出去的平行四边形的面积
;
判断大小关系的时候不用除以2 直接判断即可 且更加精确
判断两个线段是否相交,要先想一下两条线段之间都有什么样的位置关系。
1.相离
2.相交
3.重合
4.平行
观察了上面4个图片 可以明显的观察到 相交与其他3种的不同
一条线段的两个端点分别在另一条线段的两边
了解了这些加上叉乘就可以进行计算了
Ps:如果不了解叉乘的话必须先了解下叉乘,但我相信能做到求线段相交的人一定对叉乘有了全方位的了解
首先我们知道如果两个点在在一条线段两侧 那么对于线段两端与这两个点分别做叉乘计算取得的积一定是小于0的
可以得到以下结论
其实想也很好想
如果两个线段不想交那么势必存在一条线段的两个端点在另一条线段同侧,上述式子就不能满足。
所以通过计算上述式子也就能知道两线段是不是相交了。
但是在实际计算中如果数据量非常大的话那么我们总是计算4遍叉乘的话会很麻烦
所以要考虑更简单的判断两条线不相交的办法来排除一些情况,当然也只能排除一些情况而已,但即使这样也能使整个程序运行的快一些。
我们可以通过判断这两条线段的四个点的关系来淘汰很多点:
(这部分证明并没有什么意义,大家想想即可明白,在此就不赘述了,支架以代码形式给出)
max(s1.x,e1.x) < min(s2.x,e2.x)
max(s2.x,e2.x) < min(s1.x,e1.x)
max(s1.y,e1.y) < min(s2.y,e2.y)
max(s2.y,e2.y) < min(s1.y,e1.y)
这4中情况都是不相交的
======
上述已经介绍了如何判断线段相交,该上代码了
1 | double multi(Point p1,Point p2,Point p0){ |
两个圆的位置一共有五种情况
1.内含 2.内切 3.相交 4.外切 5.外离
在计算几何中 内含与内切 可以当做同一种情况 外切与外离 可以当做同一种情况
Ps:如果有疑问可以自己画一画图 就会明白了
所以在计算几何中只要分成3种情况就行了
先定义 d为两圆圆心距离
1.外离
外离
这种情况下d>=r1+r2
两圆间没有相交的部分
所以相交面积是0
2.内含
内含
这种情况下 大圆把小圆全部覆盖
相交的面积就是校园的面积 PI * r1 * r1
此情况下 d<=r大-r小
写成代码就是d <= fabs(r1 - r2)
3.相交
相交
相交的部分可以分成 大小两个圆上弧ab与直线ab围成的图形
即可看作
S扇形abc1-S△abc1+S扇形abc2-S△abc2<=>
S扇形abc1+S扇形abc2-S□ac1bc2;
根据中学学的扇形的面积公式可以推到如下
$ang2 = acos(\dfrac{r2 * r2 + d * d - r1 * r1}{2.0r2d}) S扇形_{abc1}=ang1 * r1 * r1 S扇形_{abc2}=ang2 * r2 * r2 S□ac1bc2=d * r1 * sin(ang1)$
======
上述已经介绍了如何计算两圆相交面积,该上代码了
1 | double solve(Round a, Round b) |
2016-04-10 18:36:31 Tabris_ 阅读数:549
博客爬取于2020-06-14 22:44:35
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51114254
题目链接 :http://poj.org/problem?id=1066
Treasure Hunt
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 6260Accepted: 2598
Description
Archeologists from the Antiquities and Curios Museum (ACM) have flown to Egypt to examine the great pyramid of Key-Ops. Using state-of-the-art technology they are able to determine that the lower floor of the pyramid is constructed from a series of straightline walls, which intersect to form numerous enclosed chambers. Currently, no doors exist to allow access to any chamber. This state-of-the-art technology has also pinpointed the location of the treasure room. What these dedicated (and greedy) archeologists want to do is blast doors through the walls to get to the treasure room. However, to minimize the damage to the artwork in the intervening chambers (and stay under their government grant for dynamite) they want to blast through the minimum number of doors. For structural integrity purposes, doors should only be blasted at the midpoint of the wall of the room being entered. You are to write a program which determines this minimum number of doors.
An example is shown below:
Input
The input will consist of one case. The first line will be an integer n (0 <= n <= 30) specifying number of interior walls, followed by n lines containing integer endpoints of each wall x1 y1 x2 y2 . The 4 enclosing walls of the pyramid have fixed endpoints at (0,0); (0,100); (100,100) and (100,0) and are not included in the list of walls. The interior walls always span from one exterior wall to another exterior wall and are arranged such that no more than two walls intersect at any point. You may assume that no two given walls coincide. After the listing of the interior walls there will be one final line containing the floating point coordinates of the treasure in the treasure room (guaranteed not to lie on a wall).
Output
Print a single line listing the minimum number of doors which need to be created, in the format shown below.
Sample Input
7
20 0 37 100
40 0 76 100
85 0 0 75
100 90 0 90
0 71 100 61
0 14 100 38
100 47 47 100
54.5 55.4
Sample Output
Number of doors = 2
题目大意 :
有一个100*100大的封闭,有着一堆墙,墙的两端都在封闭空间的边上,在封闭空间内有一出宝藏,问你至少要打穿多少墙才能取得宝藏。
解题思路 :
在外围进入里面打多少墙就是计算从这堆墙的两端与宝藏处所连成的线段总共穿过了几道墙(其实想一想也能明白,两点之间直线最短,所以在这样的条件下穿过的墙数最少,就是最少的了),也就是判断一下线段相交,因为数据量并不是很大,所以暴力的枚举就好。
这里应用到了判断线段相交的方法
如果对此不是怎么了解的话可以看下这里:
华丽丽的传送阵:http://blog.csdn.net/qq_33184171/article/details/51114511
提示:
1.计算结果要加1,因为从封闭空间也是用墙封上的。
2.0的时候要特判下,这时结果为1。
附本题代码
1 | # include <iostream> |
2016-04-08 22:01:36 Tabris_ 阅读数:566
博客爬取于2020-06-14 22:44:37
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51100211
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=3264
Open-air shopping malls
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2314 Accepted Submission(s): 859
Problem Description
The city of M is a famous shopping city and its open-air shopping malls are extremely attractive. During the tourist seasons, thousands of people crowded into these shopping malls and enjoy the vary-different shopping.
Unfortunately, the climate has changed little by little and now rainy days seriously affected the operation of open-air shopping malls—it’s obvious that nobody will have a good mood when shopping in the rain. In order to change this situation, the manager of these open-air shopping malls would like to build a giant umbrella to solve this problem.
These shopping malls can be considered as different circles. It is guaranteed that these circles will not intersect with each other and no circles will be contained in another one. The giant umbrella is also a circle. Due to some technical reasons, the center of the umbrella must coincide with the center of a shopping mall. Furthermore, a fine survey shows that for any mall, covering half of its area is enough for people to seek shelter from the rain, so the task is to decide the minimum radius of the giant umbrella so that for every shopping mall, the umbrella can cover at least half area of the mall.
Input
The input consists of multiple test cases.
The first line of the input contains one integer T (1<=T<=10), which is the number of test cases.
For each test case, there is one integer N (1<=N<=20) in the first line, representing the number of shopping malls.
The following N lines each contain three integers X,Y,R, representing that the mall has a shape of a circle with radius R and its center is positioned at (X,Y). X and Y are in the range of [-10000,10000] and R is a positive integer less than 2000.
Output
For each test case, output one line contains a real number rounded to 4 decimal places, representing the minimum radius of the giant umbrella that meets the demands.
Sample Input
1
2
0 0 1
2 0 1
Sample Output
2.0822
题目大意 :
就是给你一堆圆 选一个圆的圆心给定一个半径 使得这个圆能够覆盖其他圆面积的一半以上 输出最小的这种圆的面积
解题思路 :
枚举每个点,用二分的方法寻找半径
二分区间为[0,完整覆盖一个圆的半径长度]
然后二分就好
二分判定为 覆盖一个圆面积一半
其中涉及计算相交圆面积
可以先看一看这道题 POJ 2546
详细题解加相交圆面积的算法 可以看这里
http://blog.csdn.net/qq_33184171/article/details/51100090
提示 :
本题数据较少 一个个的枚举即可 不用担心超时的问题
计算几何这种问题相对来说涉及的数学公式非常多
其中反映到编译语言上就会非常复杂
所以多整理模板
参加竞赛时会省很多事
附本题代码
1 | # include <iostream> |
2016-04-08 21:48:50 Tabris_ 阅读数:1281
博客爬取于2020-06-14 22:44:38
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51100090
题目链接:http://poj.org/problem?id=2546
Circular Area
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 5662Accepted: 2215
Description
Your task is to write a program, which, given two circles, calculates the area of their intersection with the accuracy of three digits after decimal point.
Input
In the single line of input file there are space-separated real numbers x1 y1 r1 x2 y2 r2. They represent center coordinates and radii of two circles.
Output
The output file must contain single real number - the area.
Sample Input
20.0 30.0 15.0 40.0 30.0 30.0
Sample Output
608.366
题目大意:
就是求两个圆的相交部分的面积
解题思路:
就是简单的几何题目。
两个圆的位置一共有五种情况
1.内含 2.内切 3.相交 4.外切 5.外离
在计算几何中 内含与内切 可以当做同一种情况 外切与外离 可以当做同一种情况
Ps:如果有疑问可以自己画一画图 就会明白了
所以在计算几何中只要分成3种情况就行了
先定义 d为两圆圆心距离
1.外离
这种情况下d>=r1+r2
两圆间没有相交的部分
所以相交面积是0
2.内含
这种情况下 大圆把小圆全部覆盖
相交的面积就是校园的面积 PI * r1 * r1
此情况下 d<=r大-r小
写成代码就是d <= fabs(r1 - r2)
3.相交
相交的部分可以分成 大小两个圆上弧ab与直线ab围成的图形
即可看作
S扇形abc1-S△abc1+S扇形abc2-S△abc2<=>
S扇形abc1+S扇形abc2-S□ac1bc2;
根据中学学的扇形的面积公式可以推到如下
ang1 = acos((r1 * r1 + d * d - r2 * r2) / 2. / r1 / d)
ang2 = acos((r2 * r2 + d * d - r1 * r1) / 2. / r2 / d)
S扇形abc1=ang1 * r1 * r1
S扇形abc2=ang2 * r2 * r2
S□ac1bc2=d * r1 * sin(ang1)
S = ang1 * r1 * r1+ang2 * r2 * r2 - d * r1 * sin(ang1)
附本题代码
1 | # include <iostream> |
2016-04-05 20:44:34 Tabris_ 阅读数:383
博客爬取于2020-06-14 22:44:39
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51068008
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1007
Quoit Design
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 43752 Accepted Submission(s): 11379
Problem Description
Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.
Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.
Input
The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.
Output
For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places.
Sample Input
2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0
题目大意 :
给你N个点 求最小距离点对
解决方案 :
因为数据过多 达到了100000 而且时间只给了1s 如果两两对比的话 一定会超时 所以想到用分治的思想解决 但第一次提交居然WA了一发 之后才想到 光分治还不行 还要对坐标排下序 我采取的是从大到小排x坐标与y坐标和 的方式 点的距离就能分布均匀
然后AC 但是跑了702ms 不开心 #_#~~
看到有人跑了0ms 差距啊 …
但是并不想在优化了
所以开始贴代码了
1 | # include <iostream> |
2016-04-05 17:31:08 Tabris_ 阅读数:2158
博客爬取于2020-06-14 22:44:40
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51066516
题目链接 http://poj.org/problem?id=3304
Segments
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 11920 Accepted: 3757
Description
Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common.
Input
Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing a positive integer n ≤ 100 showing the number of segments. After that, n lines containing four real numbers x1 y1 x2 y2 follow, in which (x1, y1) and (x2, y2) are the coordinates of the two endpoints for one of the segments.
Output
For each test case, your program must output “Yes!”, if a line with desired property exists and must output “No!” otherwise. You must assume that two floating point numbers a and b are equal if |a - b| < 10-8.
Sample Input
3
2
1.0 2.0 3.0 4.0
4.0 5.0 6.0 7.0
3
0.0 0.0 0.0 1.0
0.0 1.0 0.0 2.0
1.0 1.0 2.0 1.0
3
0.0 0.0 0.0 1.0
0.0 2.0 0.0 3.0
1.0 1.0 2.0 1.0
Sample Output
Yes!
Yes!
No!
Source
Amirkabir University of Technology Local Contest 2006
题目大意 :
就是给你一堆线段 问你是否存在这样一条直线 使得所有线段在直线上的投影均有公共部分 有输出Yes 没有输出No
解题方法 :
投影直线上有公共点的话就是说这条直线存在一个垂线经过所有线段 就是与所有线段均相交
只要枚举这些线段端点所确定的直线 是否存在一条与所有线段均相交即可
判断线段相交用的是叉乘 首先用两点p1,p2确定了一条直线 在用p1,p2分别与计算线段两个端点计算叉乘即可
叉乘之积>0就说明线段两端点在直线的同侧 也就是直线不经过此线段
注意 :
本题是double类型
判断是否有重点 重点定义为坐标非常接近的两点 <1e-8即可
判断叉乘之积时 只要<1e-8 即可
附本题代码
这是引用网上与我代码非常接近的大神的代码 能Ac 但我的不知为什么就是不行 ~>_<~ 但也在下面贴出来了 如果有人找到BUG 了 一定要回复我 不胜感激
1 | # include <iostream> |
我那错误的代码>_<
1 |
|
2016-04-05 14:42:26 Tabris_ 阅读数:350
博客爬取于2020-06-14 22:44:41
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51064675
题目链接:http://poj.org/problem?id=2398
Toy Storage
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 4962 Accepted: 2950
Description
Mom and dad have a problem: their child, Reza, never puts his toys away when he is finished playing with them. They gave Reza a rectangular box to put his toys in. Unfortunately, Reza is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for Reza to find his favorite toys anymore.
Reza’s parents came up with the following idea. They put cardboard partitions into the box. Even if Reza keeps throwing his toys into the box, at least toys that get thrown into different partitions stay separate. The box looks like this from the top:
We want for each positive integer t, such that there exists a partition with t toys, determine how many partitions have t, toys.
Input
The input consists of a number of cases. The first line consists of six integers n, m, x1, y1, x2, y2. The number of cardboards to form the partitions is n (0 < n <= 1000) and the number of toys is given in m (0 < m <= 1000). The coordinates of the upper-left corner and the lower-right corner of the box are (x1, y1) and (x2, y2), respectively. The following n lines each consists of two integers Ui Li, indicating that the ends of the ith cardboard is at the coordinates (Ui, y1) and (Li, y2). You may assume that the cardboards do not intersect with each other. The next m lines each consists of two integers Xi Yi specifying where the ith toy has landed in the box. You may assume that no toy will land on a cardboard.
A line consisting of a single 0 terminates the input.
Output
For each box, first provide a header stating “Box” on a line of its own. After that, there will be one line of output per count (t > 0) of toys in a partition. The value t will be followed by a colon and a space, followed the number of partitions containing t toys. Output will be sorted in ascending order of t for each box.
Sample Input
4 10 0 10 100 0
20 20
80 80
60 60
40 40
5 10
15 10
95 10
25 10
65 10
75 10
35 10
45 10
55 10
85 10
5 6 0 10 60 0
4 3
15 30
3 1
6 8
10 10
2 1
2 8
1 5
5 5
40 10
7 9
0
Sample Output
Box
2: 5
Box
1: 4
2: 1
没做过poj 2318的建议先做一下 跟本题是差不多的 但稍微简单些 http://poj.org/problem?id=2398
题目大意: 有一个方盒子 有N个板隔开 分成N+1个区域
又给了M个玩具的坐标 问你有N个玩具(忽略玩具体积)的区域(不能恰好在区域内)有几个
解题思路: 每相邻的两个板看成两个向量 分别求其与其中一点和玩具坐标的叉积 如果两叉积的乘积<0 就说明这个玩具坐标点在一个板的右边 一个板的左边
因为数据量比较大 可以把板和方盒的两边记录下来 然后二分 道理是一样的
上述就能记录下来每个区域有几个玩具
所以有N个玩具的区域有几个 就不用赘述了…
附本题代码
1 | # include <iostream> |
2016-04-05 13:59:34 Tabris_ 阅读数:555
博客爬取于2020-06-14 22:44:42
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51064266
题目链接:http://poj.org/problem?id=2318
TOYS
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 13008 Accepted: 6269
Description
Calculate the number of toys that land in each bin of a partitioned toy box.
Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys in, but John is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for John to find his favorite toys.
John’s parents came up with the following idea. They put cardboard partitions into the box. Even if John keeps throwing his toys into the box, at least toys that get thrown into different bins stay separated. The following diagram shows a top view of an example toy box.
For this problem, you are asked to determine how many toys fall into each partition as John throws them into the toy box.
Input
The input file contains one or more problems. The first line of a problem consists of six integers, n m x1 y1 x2 y2. The number of cardboard partitions is n (0 < n <= 5000) and the number of toys is m (0 < m <= 5000). The coordinates of the upper-left corner and the lower-right corner of the box are (x1,y1) and (x2,y2), respectively. The following n lines contain two integers per line, Ui Li, indicating that the ends of the i-th cardboard partition is at the coordinates (Ui,y1) and (Li,y2). You may assume that the cardboard partitions do not intersect each other and that they are specified in sorted order from left to right. The next m lines contain two integers per line, Xj Yj specifying where the j-th toy has landed in the box. The order of the toy locations is random. You may assume that no toy will land exactly on a cardboard partition or outside the boundary of the box. The input is terminated by a line consisting of a single 0.
Output
The output for each problem will be one line for each separate bin in the toy box. For each bin, print its bin number, followed by a colon and one space, followed by the number of toys thrown into that bin. Bins are numbered from 0 (the leftmost bin) to n (the rightmost bin). Separate the output of different problems by a single blank line.
Sample Input
5 6 0 10 60 0
3 1
4 3
6 8
10 10
15 30
1 5
2 1
2 8
5 5
40 10
7 9
4 10 0 10 100 0
20 20
40 40
60 60
80 80
5 10
15 10
25 10
35 10
45 10
55 10
65 10
75 10
85 10
95 10
0
Sample Output
0: 2
1: 1
2: 1
3: 1
4: 0
5: 1
0: 2
1: 2
2: 2
3: 2
4: 2
Hint
As the example illustrates, toys that fall on the boundary of the box are “in” the box.
题目大意: 有一个方盒子 有N个板隔开 分成N+1个区域
又给了M个玩具的坐标 问你每个区域内(不能恰好在区域内)的玩具有几个(忽略玩具体积)
解题思路: 每相邻的两个板看成两个向量 分别求其与其中一点和玩具坐标的叉积 如果两叉积的乘积<0 就说明这个玩具坐标点在一个板的右边 一个板的左边
因为数据量比较大 可以把板和方盒的两边记录下来 然后二分 道理是一样的
附本题代码
1 | # include <iostream> |
2016-04-01 13:54:06 Tabris_ 阅读数:795
博客爬取于2020-06-14 22:44:43
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/51036352
题目链接—> 点此传送阵
Area
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 17766Accepted: 4925
Description
You are going to compute the area of a special kind of polygon. One vertex of the polygon is the origin of the orthogonal coordinate system. From this vertex, you may go step by step to the following vertexes of the polygon until back to the initial vertex. For each step you may go North, West, South or East with step length of 1 unit, or go Northwest, Northeast, Southwest or Southeast with step length of square root of 2.
For example, this is a legal polygon to be computed and its area is 2.5:
Input
The first line of input is an integer t (1 <= t <= 20), the number of the test polygons. Each of the following lines contains a string composed of digits 1-9 describing how the polygon is formed by walking from the origin. Here 8, 2, 6 and 4 represent North, South, East and West, while 9, 7, 3 and 1 denote Northeast, Northwest, Southeast and Southwest respectively. Number 5 only appears at the end of the sequence indicating the stop of walking. You may assume that the input polygon is valid which means that the endpoint is always the start point and the sides of the polygon are not cross to each other.Each line may contain up to 1000000 digits.
Output
For each polygon, print its area on a single line.
Sample Input
4
5
825
6725
6244865
Sample Output
0
0
0.5
2
题目大意: 有一个直角坐标系 初始位置在(0,0) 给你一个字符串,其中1,2,3,4,6,7,8,9分别对应向8个方向 最后走回来 确保 数据最后能走回原点 问行走路线所圈成的多边形面积。。
最开是就想到了要用外积的几何意义来做 但是题目不能确保所走过的路线能是一个凸包 所以不敢用 然后就一直没有别的思路 最后按照样例 画了画 发现 外积的几何意义成立 于是有画了个凹包 发现也成立 于是敲了敲代码 就Ac了。。
外积的几何意义:
外积也称叉积或向量积
几何意义就是两个向量所构成的平行四边形面积就是外积
三角形的话就是外积的一半
如上图所示
Sabcd=αxβ;
SΔabc=αxβ;
本题就是把除原点外的相邻两个点与原点组成的三角形的面积加和就行
用外积求面积是会遇到结果为负的情况 是正常的 ,这样最后得到的和就会把多加上去的消掉 ,
注意 最终结果为正
注意 double的精度不好控制 用long long int 比较好控制
附本题代码
1 | # include <iostream> |
2016-03-22 15:28:27 Tabris_ 阅读数:7313
博客爬取于2020-06-14 22:44:44
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50955548
暂时标准答案没有出来 个别题目 不好现在就写出来 先将就看 过后会补上
煤球数目
有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
…
如果一共有100层,共有多少个煤球?
请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
本题 就是签到题
每层 为上面所有层之和
然后求100层 共有多少个煤球
答案是171700
1 | # include <iostream> |
生日蜡烛
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
本题就是暴力求解
把1到1000岁都试一遍 (其实到100岁就行 毕竟人活不到那岁数啊)
答案是26与236 毕竟活不到236 所以 答案是26
1 | # include <iostream> |
凑算式
B DEF
A + — + ------- = 10
C GHI
(如果显示有问题,可以参见【图1.jpg】)
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
本题 也是暴力求解 挨个试 满足了 +1 之后输出总和就好了
我没有采用9层for 用的是全排列 代码能简洁一点
答案是29
1 | # include <iostream> |
快速排序
排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。
其思想是:先选一个“标尺”,
用它把整个队列过一遍筛子,
以保证:其左边的元素都不大于它,其右边的元素都不小于它。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
下面的代码是一种实现,请分析并填写划线部分缺少的代码。
1 | # include <stdio.h> |
注意:只填写缺少的内容,不要书写任何题面已有代码或说明性文字。
本题就是一个基础的快速排序
仔细观察了一下 就是缺少将“标尺”这个数交换到分好的数中间的操作 所以加上swap(a,p,j)
这个代码填空吧 关于后面有没有分号这个问题 我认为 既然横线后面给你分号了 就不用写了 但是 这个分号加与不加 对整体代码都是一样的 即使加了 也不能算错
抽签
X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。
…
那么最终派往W星的观察团会有多少种国别的不同组合呢?
下面的程序解决了这个问题。
数组a[] 中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
…
(以下省略,总共101行)
1 | # include <stdio.h> |
仔细阅读代码,填写划线部分缺少的内容。
注意:不要填写任何已有内容或说明性文字。
本题就是一个简单的深搜
观察到(k==N) 就能知道 每次k应该加1
在观察 b[M-m+j] = k+‘A’; 就能判断出 应该是m-j
当然 在这个代码中 i==j 所以
f(a,k+1,m-j,b)
f(a,k+1,m-i,b)
是一样的 哪个都对 。
方格填数
如下的10个格子
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
本题如果用二维数组做 其实就是和数独差不多 判断一圈就可以了
本题我用的也是全排列 毕竟方便 然后判断可不可行 可行就加1
最后答案为1580
1 | # include <iostream> |
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
个人用的深搜 得出的答案为124 与网上的其他题解有出入 先不放题解了
最后看来正解应该是116
---------------------update------------------------
我的方法是在int a[]={0,0,0,0,0,0,0,1,1,1,1,1};的全排列中找5个1联通的个数.
1 | int b[10][10]; |
四平方和
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开
例如,输入:
5
则程序应该输出:
0 0 1 2
再例如,输入:
12
则程序应该输出:
0 2 2 2
再例如,输入:
773535
则程序应该输出:
1 1 267 838
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include
提交时,注意选择所期望的编译器类型。
这题比赛时没有优化只用了 4层for 加剪枝 运行了一下4888888 秒出 所以就没有优化 但是用三层for完全可以解决 哎 不知能不能超时 都怪蓝桥杯 前面各种小暴力 最后都忘记优化了
话不多说 直接上代码 上三层for的吧 毕竟 这个肯定更稳妥
1 | # include <iostream> |
交换瓶子
有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
例如,输入:
5
3 1 2 5 4
程序应该输出:
3
再例如,输入:
5
5 4 3 2 1
程序应该输出:
2
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include
提交时,注意选择所期望的编译器类型。
本题鄙人有两种解法
一、
比赛时用的是并查集解决的,主要是观察过后发现一个很神奇的现象,如果N个数在这N个数,本来的位置的集合中相互混乱,那么只需操作N-1步,就能换回来。
比如说 5-3 1 2 5 4
其中 3 1 2 本应在1 2 3 的位置 但是他们相互乱序 但只要先把1和3换过来 变成1 3 2 在换3和2 这样就变回了1 2 3 这样的顺序 ,5 4也一样 交换一步就可以了 。
但是这个方法并不知道对不对
但比赛是我用的就是这种
采用并查集的方法 把相互乱序的放在一个集合中 然后只要计算每个集合的元素数-1的和 这样就可以了
比赛时测试样例 并没有什么出入 但有了下一种解法就总感觉会有错 哎 等结果下来吧 看看成绩怎么样就知道了
1 | 怕误人子弟 代码就暂时不贴了 |
二、
这是比赛之后发现校oj里有的一道题 但比较复杂 稍加修改 就成了这道题 算是直接模拟两两交换就行了
1 | # include<stdio.h> |
最大比例
X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式:
第一行为数字N,表示接下的一行包含N个正整数
第二行N个正整数Xi(Xi<1 000 000 000 000),用空格分开。每个整数表示调查到的某人的奖金数额
要求输出:
一个形如A/B的分数,要求A、B互质。表示可能的最大比例系数
测试数据保证了输入格式正确,并且最大比例是存在的。
例如,输入:
3
1250 200 32
程序应该输出:
25/4
再例如,输入:
4
3125 32 32 200
程序应该输出:
5/2
再例如,输入:
3
549755813888 524288 2
程序应该输出:
4/1
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include
提交时,注意选择所期望的编译器类型。
这道题 本渣并不会 所以 嘿嘿 你懂得…
2016-03-17 12:39:13 Tabris_ 阅读数:2585
博客爬取于2020-06-14 22:44:45
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50912690
一个串的子串是指该串的一个连续的局部。如果不要求连续,则可称为它的子序列。
比如对串: “abcdefg” 而言,“ab”,“abd”,“bdef” 等都是它的子序列。
特别地,一个串本身,以及空串也是它的子序列。
对两个串而言,可以有许多的共同的子序列,我们关心的是:它们所共同拥有的长度最大的子序列是多长。以下代码实现了这个问题的求解。请填写划线部分缺失的代码。
注意:只填写划线部分缺少的内容,不要填写任何多余的符号或注释、说明等。例如,不要填写已经给出的小括号。
1 | // tag==1 && *p!=' ' |
1/1 + 1/2 + 1/3 + 1/4 + … 在数学上称为调和级数。
它是发散的,也就是说,只要加上足够多的项,就可以得到任意大的数字。
但是,它发散的很慢:
前1项和达到 1.0
前4项和才超过 2.0
前83项的和才超过 5.0
那么,请你计算一下,要加多少项,才能使得和达到或超过 15.0 呢?
请填写这个整数。
注意:只需要填写一个整数,不要填写任何多余的内容。比如说明文字。
1 | # include <stdio.h> |
如果x的x次幂结果为10(参见【图1.png】),你能计算出x的近似值吗?
显然,这个值是介于2和3之间的一个数字。
请把x的值计算到小数后6位(四舍五入),并填写这个小数值。
注意:只填写一个小数,不要写任何多余的符号或说明。
1 | //手动二分 |
今有7对数字:两个1,两个2,两个3,…两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:
17126425374635
当然,如果把它倒过来,也是符合要求的。
请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。
注意:只填写这个14位的整数,不能填写任何多余的内容,比如说明注释等。
1 | # include <stdio.h> |
勾股定理,西方称为毕达哥拉斯定理,它所对应的三角形现在称为:直角三角形。
已知直角三角形的斜边是某个整数,并且要求另外两条边也必须是整数。
求满足这个条件的不同直角三角形的个数。
【数据格式】
输入一个整数 n (0 < n < 10000000) 表示直角三角形斜边的长度。
要求输出一个整数,表示满足条件的直角三角形个数。
例如,输入:
5
程序应该输出:
1
再例如,输入:
100
程序应该输出:
2
再例如,输入:
3
程序应该输出:
0
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include
提交时,注意选择所期望的编译器类型。
1 | # include <stdio.h> |
你一定听说过“数独”游戏。
如【图1.png】,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复。
数独的答案都是唯一的,所以,多个解也称为无解。
本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目。但对会使用计算机编程的你来说,恐怕易如反掌了。
本题的要求就是输入数独题目,程序输出数独的唯一解。我们保证所有已知数据的格式都是合法的,并且题目有唯一的解。
格式要求:
输入9行,每行9个数字,0代表未知,其它数字为已知。
输出9行,每行9个数字表示数独的解。
例如:
输入(即图中题目):
005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700
程序应该输出:
145327698
839654127
672918543
496185372
218473956
753296481
367542819
984761235
521839764
再例如,输入:
800000000
003600000
070090200
050007000
000045700
000100030
001000068
008500010
090000400
程序应该输出:
812753649
943682175
675491283
154237896
369845721
287169534
521974368
438526917
796318452
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include
提交时,注意选择所期望的编译器类型。
1 | # include <cstdio> |
2016-03-15 20:42:54 Tabris_ 阅读数:1566
博客爬取于2020-06-14 22:44:46
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50899795
蓝桥杯2014第五题
打印图形:
小明在X星球的城堡了发现了如下图形和文字:
Rank=3
Rank=4
Rank=5
题目是填空题 但是代码是自己写的 博客最下面有原代码
分形问题最主要的是找到图形的最基本的点
如POJ 2083 的那个X 基本构成 就是在九个方格里 左上,左下,中间,右上,右下,这5个位置 都有X 而数字每加一个 就把每一个X替换成这个基本的构成
POJ :http://poj.org/problem?id=2083
这道题个基本构成就不是这么简单 不是每个三角形上的每个点 而是三角形上的一个顶点 其实了解过分形的 看到这句就能解决了 之后就一遍又一遍的递归就好了 但千万注意 你递归的只是三角形的一个顶点(选择这个图形选择上顶点会方便一些) 在打印图形的时候 要把基本三角形的8个点 都打印上
具体如下 数字表示递归操作的层级
画圈的就是所说的基本点 递归应从这里开始
然后找下一级图形的基本点
其实每个上级的基本点都是被递归多次的 毕竟分形就是大的图形中套用小的图形 一直套 直到分形处理结束 这时候就开始赋值了(也就是打印图形的过程)
详情请看代码注释 很详细的哦
1 | # include<stdio.h> |
精简版代码
1 | # include<stdio.h> |
蓝桥杯的代码(为填空)
其答案为 f(a,rank-1,row,col+w/2)
他的想法和我稍有偏差 但是道理都一样的 这里就不在过多阐述了
但是他的这个代码还是值得读一读的
1 | # define N 70 |
2016-03-14 17:44:24 Tabris_ 阅读数:426
博客爬取于2020-06-14 22:44:47
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50888426
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 49(25 users)Total Accepted: 23(19 users)Rating: Special Judge: No
Description
Leyni有一种神秘的植物,形状是一种“向上”三角形植物,每过一年,每个“向上”三角形植物会变成三个“向上”三角形植物和一个“向下”三角形植物,每个“向下”三角形植物会变成三个“向下”三角形植物和一个“向上”三角形植物。如下图:
Leyni想知道经过n年有多少个“向上”三角形植物。
Input
输入包含多组测试数据。
对于每组测试数据:
第1行,包含一个整数n (0 ≤ n ≤ 10^18)
处理到文件结束
Output
对于每组测试数据:
第1行,输出Leyni拥有多少个“向上”三角形植物。(MOD 1000000007)
Sample Input
1
2
Sample Output
3
10
Author
齐达拉图@HRBUST
这里先简单递推一下
序号 | 向上的三角形个数 | 向下的三角形个数 |
---|---|---|
0 | 1 | 0 |
1 | 3 | 1 |
2 | 10 | 6 |
3 | 36 | 28 |
不难观察出规律 ,规律如下
. | 递推公式 |
---|---|
向上的三角 | shang[i]=3*shang[i-1]+xia[i-1] |
向下的三角 | xia[i]=3*xia[i-1]+shang[i-1]; |
虽然观察出了本题的规律了
但是! 但是!! 但是!!!
观察input 题目说
n (0 ≤ n ≤ 10^18)
n (0 ≤ n ≤ 10^18)
n (0 ≤ n ≤ 10^18)
10^18次幂 先不说超时 光是数组也开不出来啊
怎么办呢 ??
仔细想想 用两个二维数组相乘的话 一个表示要乘的参数 一个用来存数据就能开出来了
数组如下
1 | long long int a[2][2],c[2][2]; |
其中a用来存储数据 ,c用来存储要乘的参数 即如下
1 | a[0][0]=1; a[0][1]=0; |
这样下来用矩阵的乘法就能求了
上述已经解决了 内存爆的情况 但是 时间上怎么优化呢
既然是矩阵 那自然可以用矩阵快速幂来优化 这样下来时间可是几何倍数的被优化
不懂矩阵快速幂的可以看这里 矩阵快速幂
时间 空间的优化都结束了 就可以A题了 ~~
附本题代码
1 | # include<stdio.h> |
2016-03-14 17:15:41 Tabris_ 阅读数:361
博客爬取于2020-06-14 22:44:49
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50888118
矩阵 快速幂
super_boy原创文章,转载请注明出处 这里链接
矩阵的快速幂是用来高效地计算矩阵的高次方的。将朴素的o(n)的时间复杂度,降到log(n)。
这里先对原理(主要运用了矩阵乘法的结合律)做下简单形象的介绍:
一般一个矩阵的n次方,我们会通过连乘n-1次来得到它的n次幂。
但做下简单的改进就能减少连乘的次数,方法如下:
把n个矩阵进行两两分组,比如:AAAAAA => (AA)(AA)(AA)
这样变的好处是,你只需要计算一次AA,然后将结果(AA)连乘自己两次就能得到A^6,即(A*A)^3=A^6。算一下发现这次一共乘了3次,少于原来的5次。
其实大家还可以取A^3作为一个基本单位。原理都一样:利用矩阵乘法的结合律,来减少重复计算的次数。
以上都是取一个具体的数来作为最小单位的长度,这样做虽然能够改进效率,但缺陷也是很明显的,取个极限的例子(可能有点不恰当,但基本能说明问题),当n无穷大的时候,你现在所取的长度其实和1没什么区别。所以就需要我们找到一种与n增长速度”相适应“的”单位长度“,那这个长度到底怎么去取呢???这点是我们要思考的问题。
有了以上的知识,我们现在再来看看,到底怎么迅速地求得矩阵的N次幂。
既然要减少重复计算,那么就要充分利用现有的计算结果咯!~怎么充分利用计算结果呢???这里考虑二分的思想。。
大家首先要认识到这一点:任何一个整数N,都能用二进制来表示。。这点大家都应该知道,但其中的内涵真的很深很深(这点笔者感触很深,在文章的最后,我将谈谈我对的感想)!!
计算机处理的是离散的信息,都是以0,1来作为信号的处理的。可想而知二进制在计算机上起着举足轻重的地位。它能将模拟信号转化成数字信号,将原来连续的实际模型,用一个离散的算法模型来解决。 好了,扯得有点多了,不过相信这写对下面的讲解还是有用的。
回头看看矩阵的快速幂问题,我们是不是也能把它离散化呢?比如A^19 => (A^16)(A^2)(A^1),显然采取这样的方式计算时因子数将是log(n)级别的(原来的因子数是n),不仅这样,因子间也是存在某种联系的,比如A^4能通过(A^2)(A^2)得到,A^8又能通过(A^4)(A^4)得到,这点也充分利用了现有的结果作为有利条件。下面举个例子进行说明:
现在要求A^156,而156(10)=10011100(2)
也就有A^156=>(A^4)(A^8)(A^16)*(A^128) 考虑到因子间的联系,我们从二进制10011100中的最右端开始计算到最左端。细节就说到这,下面给核心代码:
1 | while(N) |
里面的乘号,是矩阵乘的运算,res是结果矩阵。
第3行代码每进行一次,二进制数就少了最后面的一个1。二进制数有多少个1就第3行代码就执行多少次。
好吧,矩阵快速幂的讲解就到这里吧。在文章我最后给出我实现快速幂的具体代码(代码以3*3的矩阵为例)。
现在我就说下我对二进制的感想吧:
我们在做很多”连续“的问题的时候都会用到二进制将他们离散简化
1.多重背包问题
2.树状数组
3.状态压缩DP
……………还有很多。。。究其根本还是那句话:化连续为离散。。很多时候我们并不是为了解决一个问题而使用二进制,更多是时候是为了优化而使用它。所以如果你想让你的程序更加能适应大数据的情况,那么学习学习二进制及其算法思想将会对你有很大帮助。
最后贴出一些代码供大家学习,主要起演示的效果:
1 | # include <cstdlib> |
2016-03-13 16:27:26 Tabris_ 阅读数:579
博客爬取于2020-06-14 22:44:50
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50878582
中文题意
题目链接 HDU 5643
King’s Game Accepts: 249 Submissions: 671
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
问题描述
为了铭记历史,国王准备在阅兵的间隙玩约瑟夫游戏。它召来了 n(1\le n\le 5000)n(1≤n≤5000) 个士兵,逆时针围成一个圈,依次标号 1, 2, 3 … n1,2,3…n。
第一轮第一个人从 11 开始报数,报到 11 就停止且报到 11 的这个人出局。
第二轮从上一轮出局的人的下一个人开始从 11 报数,报到 22 就停止且报到 22 的这个人出局。
第三轮从上一轮出局的人的下一个人开始从 11 报数,报到 33 就停止且报到 33 的这个人出局。
第 n - 1n−1 轮从上一轮出局的人的下一个人开始从 11 报数,报到 n - 1n−1 就停止且报到 n - 1n−1 的这个人出局。
最后剩余的人是幸存者,请问这个人的标号是多少?
输入描述
第一行一个整数表示测试组数:T(0 < T≤5000) 。
每组数据占一行,包含一个整数 nn,表示 nn 个人围成一圈。
输出描述
共 TT 行。对每组数据,输出幸存者的编号。
输入样例
2
2
3
输出样例
2
2
Hint
对于第一组数据,一开始报到 11 的人即标号为 11 的人退出,幸存者是 22 号。
对于第二组数据,一开始报到 11 的人即标号 11 的人退出。接着 22 号报 11,33 号报 22,报到 22 的人即 33 号退出。幸存者是 22 号。
**本题是一个威瑟夫问题的变种 **
**跟题目讲述的一样 **
第几轮 报道第几个数的人 就出局
而且每一轮最先报数的是上一轮出局的人的下一个人 (昨天竟然 看成的每轮从标号最小的人开始报数 唉 模拟打表都打错了。。。)
所以要找到剩下的最后一人可以只找出局的人 最后一次出局的人的 下一个人就是最后剩下的人
这样就很好想了
我做个表来模拟下 0表示上一局出局了的人的位置 其他出局用X表示
---- | 第一轮 | 第二轮 | 第三轮 | 第四轮 | 第五轮 | 第六轮 |
---|---|---|---|---|---|---|
人 | 1 2 3 4 5 6 7 | 0 2 3 4 5 6 7 | X 2 0 4 5 6 7 | X 2 X 4 5 0 7 | X 2 X 4 0 X 7 | X 0 X 4 X X 7 |
标号 | 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 | X 5 0 1 2 3 4 | X 2 X 3 4 0 1 | X 2 X 3 X 0 1 | X X 0 1 X X 2 |
结果 | preson.1 out | person.3 out | person.6 out | person.5 out | person.2 out | person.7 out |
No.1 out | No.2 out | No.3 out | No.4 out | No.2(5%3) out | No.2(6%2) out |
person.4 is winer
**设 n为总人数 i为轮数 **
通过上面的表很容易看出
**每一轮重新标号的规律 **
**假设该轮有n个人,那么上一轮(n+1)人,编号为0的人上一轮编号****为k,也即编号为a[n]的人上一轮编号为(a[n]+k)%(n+1)。 **
我们知道最后剩下的人在最后一轮编号肯定为0,那么这样不断倒推就可以推出其在第一轮的编号,也即他本来的编号。
附本题代码
1 | # include<iostream> |
2016-03-12 21:22:58 Tabris_ 阅读数:644
博客爬取于2020-06-14 22:44:51
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50867690
King’s Phone Accepts: 629 Submissions: 2980
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
问题描述
阅兵式上,国王见到了很多新奇东西,包括一台安卓手机。他很快对手机的图形解锁产生了兴趣。
解锁界面是一个 3 \times 33×3 的正方形点阵,第一行的三个点标号 1, 2, 31,2,3,第二行的三个点标号 4, 5, 64,5,6,第三行的三个点标号 7, 8, 97,8,9。密码本身是一段序列,表示经过点的先后顺序,但遵循如下规则:
密码至少经过四个点。
不能重复经过同一个点。
路径上的中间点不能跳过,除非已经被经过(34273427 是合法的,但 37243724 不合法)。
他想设置的密码的长度为正整数 k(1\le k\le 9)k(1≤k≤9),密码序列为 s_1 s_2…s_k(0<=s_i < INT MAX) s 1 s 2…s k(0≤ s < int_max),
他想知道这个密码序列是否合法,这个问题交给了你。
输入描述
第一行一个整数表示测试组数:T (0 < T ≤100000) 。
每组数据占一行,每行第一个数 kk,设置密码的长度;接着 kk 个正整数,之间用空格隔开,表示密码序列 s_1s_2…s_ks 1 s 2 …s k
。
输出描述
共 TT 行。对每组数据,若合法输出 valid,否则输出 invalid。
输入样例
3
4 1 3 6 2
4 6 2 1 3
4 8 1 6 7
输出样例
invalid
valid
valid
Hint
对于第一组数据,11 到 33 跳过了路径上的点 22,所以不合法。
对于第二组数据,11 到 33 时点 22 已经被经过了,所以合法。
对于第三组数据,8-> 1-> 6 -> 7
8→1→6→7 路径均没有中间点,所以合法。
本题主要是对不可能成立的判断
比如说 1->3是不可以的 因为中间会经过2
这样的有共有16种
one 与other 是两头的数 mid是中间的数 one->other时 如果mid没有被经过就是错误的 用数组标记一下就能判断有没有背经过
当然 我这个是单向的 如果双向的话会省一半
| one | other | mid |
| ------------- :|:-------------:|:-----|
|1|7|4|
|1|9|5|
|1|3|2|
|2|8|5|
|3|1|2|
|3|7|5|
|3|9|6|
|4|6|5|
|6|4|5|
|7|1|4|
|7|3|5|
|7|9|8|
|8|2|5|
|9|1|5|
|9|3|6|
|9|7|8|
本题有个坑点吧
就是输入的数 要在1~9 上 否则就应是 invalid
附本题代码
1 | # include <string.h> |
2016-03-12 14:07:12 Tabris_ 阅读数:556
博客爬取于2020-06-14 22:44:52
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50865290
题目描述
设有NN的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。如下图所示(见样例):
某人从图的左上角的A 点出发,可以向下行走,也可以向右走,直到到达右下角的B点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。
此人从A点到B 点共走两次,试找出2条这样的路径,使得取得的数之和为最大。
输入格式
输入的第一行为一个整数N(表示NN的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。
输出格式
只需输出一个整数,表示2条路径上取得的最大的和。
Sample Input
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
Sample Output
67
本题是一个多线程DP
总体思路就是一个dp[x1][y1][x2][y2],来表示从x1,y1 到x2,y2最多能够拿到的数值 在这里已经是两条路径所能的和最大值了 依次向下规划 就得到最终的结果
附本题代码
1 | #include<iostream> |
以为题目规定了 只能向右向下走,所以 很多步是走不到的
完全可以在优化一维 用三维dp来解题
如果理解了题目 很容易就能写出
这里就不赘述了
2016-03-10 17:36:49 Tabris_ 阅读数:461
博客爬取于2020-06-14 22:44:53
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50848661
##POJ 2492 a bug’s life [并查集||二分图染色]
A Bug’s Life
Time Limit: 10000MSMemory Limit: 65536K
Total Submissions: 32887Accepted: 10772
Description
Background
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs.
Problem
Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.
Input
The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.
Output
The output for every scenario is a line containing “Scenario #i:”, where i is the number of the scenario starting at 1, followed by one line saying either “No suspicious bugs found!” if the experiment is consistent with his assumption about the bugs’ sexual behavior, or “Suspicious bugs found!” if Professor Hopper’s assumption is definitely wrong.
Sample Input
2
3 3
1 2
2 3
1 3
4 2
1 2
3 4
Sample Output
Scenario #1:
Suspicious bugs found!
Scenario #2:
No suspicious bugs found!
Hint
Huge input,scanf is recommended.
题目大意 :就是让虫子a与虫子b交配 不能同性交配 输入的数是两个虫子的序号 就是交配的两个虫子 如果性别相同了 就输出"Suspicious bugs found!" 否则输出"No suspicious bugs found!"…
Ps: 这题目 污的不是一星半点…
先说一说并查集吧
就是说利用并查集的父子节点来表示不同的性别 ,
要注意的是 每颗树上 先确定父节点的性别 以此来判断子节点的性别就行 差一辈的就是异性 差两辈的就是同性
之后在建一个数组来存储性别 可以定义0是一个性别 1是另一个性别 在join函数中 如果处理的两个节点 在同一颗树上 且同性 就是"Suspicious bugs found!" 其他情况 就是"No suspicious bugs found!"
1 | # include <iostream> |
二分图染色来自于此
稍后 就贴上
昨天一天就弄着一道题了。
一开始的时候想法是判断是否存在奇数圈。如果存在,肯定有同性恋存在。
后来看到了别人的想法。就是,判二分图。
后来在,上课翻离散书的时候看到一个定理:n阶无向图是一个二分图当且仅当图中没有无奇数圈。
这样,判奇数圈和判二分图就是一个意思了。
那么,怎么来判奇数圈或者二分图呢???
搜索了一下,看到一种染色法判断二分图。意思就是,将图中的节点染色,如果能够把所有的点染成不同的两个颜色,并且不产生矛盾(相连的节点颜色相同);
如图所示:
可以用BFS或DFS实现:
BFS:
1 | # include <cstdio> |
DFS:
1 | # include <cstdio> |
无论BFS还是DFS,需要注意的是,所有的节点可能出现在不同的集合中。需要多次BFS或DFS。
二分图染色来自于此
]]>2016-03-09 21:06:53 Tabris_ 阅读数:469
博客爬取于2020-06-14 22:44:54
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50838736
Is It A Tree?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 421 Accepted Submission(s): 157
Problem Description
A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties.
There is exactly one node, called the root, to which no directed edges point.
Every node except the root has exactly one edge pointing to it.
There is a unique sequence of directed edges from the root to each node.
For example, consider the illustrations below, in which nodes are represented by circles and edges are represented by lines with arrowheads. The first two of these are trees, but the last is not.
In this problem you will be given several descriptions of collections of nodes connected by directed edges. For each of these you are to determine if the collection satisfies the definition of a tree or not.
Input
The input will consist of a sequence of descriptions (test cases) followed by a pair of negative integers. Each test case will consist of a sequence of edge descriptions followed by a pair of zeroes Each edge description will consist of a pair of integers; the first integer identifies the node from which the edge begins, and the second integer identifies the node to which the edge is directed. Node numbers will always be greater than zero.
Output
For each test case display the line Case k is a tree.\\\\\\\" or the line
Case k is not a tree.\\\", where k corresponds to the test case number (they are sequentially numbered starting with 1).
Sample Input
6 8 5 3 5 2 6 4
5 6 0 0
8 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 0
3 8 6 8 6 4
5 3 5 6 5 2 0 0
-1 -1
Sample Output
Case 1 is a tree.
Case 2 is a tree.
Case 3 is not a tree.
程序分析(转载):
这道题跟小希的迷宫有很大的相似吧,只是一个是无向图一个是有向图。也是给你那些结点之间的信息,然后让你判断是不是一颗树罢了,用树的定义来 判断吧,无环,n个结点最多有n-1条边,不然就会有环。只有一个入度为0的结点,不存在入度大于1的结点。这些也足以判断是否为一棵树了吧。不过要注意 一些特殊数据的情况,空树也是树。比如输入0 0。
解决方法:
其实也可以不用并查集,这样就可以直接按照上面的条件来统计,就可以判断是不是一颗树了。
自我感言:额,这道题目关键就是判断树的那几个标准,1,无环;2,除了根,所有的入度为1,根入度为0;3,这个结构只有一个根,不然是森林了。
这是三个标准拿捏好,再注意这里空树也是树。基本上就ok了。。
坑爹的是下边的代码可以在hdu上通过,而不能在poj上通过。。。。。看了discuss才知道 1 1 0 0 不能是树。
下面几种情况要注意了。。。。
1: 0 0 空树是一棵树
2: 1 1 0 0 不是树 不能自己指向自己
3: 1 2 1 2 0 0 不是树…自己开始一直在这么WA 好郁闷 重复都不行呀~~5555
4: 1 2 2 3 4 5 不是树 森林不算是树(主要是注意自己)
5: 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 1 注意 一个节点在指向自己的父亲或祖先 都是错误的 即 9–>1 错
6: 1 2 2 1 0 0 也是错误的这样基本上就可以在poj上通过了,poj(1308) 题这是hdu上通过的代码:
1 | # include <stdio.h> |
中间只是稍作修改,把if(m!=n&&find_root(n)==find_root(m))改成了if((m!=n&&find_root(n)==find_root(m))||m==n)就在poj上通过了
1 | # include <stdio.h> |
2016-03-09 20:29:54 Tabris_ 阅读数:276
博客爬取于2020-06-14 22:44:55
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50838424
小希的迷宫
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 39392 Accepted Submission(s): 12092
Problem Description
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
Input
输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
整个文件以两个-1结尾。
Output
对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"Yes",否则输出"No"。
Sample Input
6 8 5 3 5 2 6 4
5 6 0 0
8 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 0
3 8 6 8 6 4
5 3 5 6 5 2 0 0
-1 -1
Sample Output
Yes
Yes
No
本题就是一个简单的用并查集判断回路有无的问题
1.在连接两个点的时候 如果这两个点的父节点相同 那 再进行连接这两个点的操作 就会产生回路.
2.连通图中 他的父节点只有一个 如果多于一个 就是存在 没有联通的点.
1 | # include <iostream> |
2016-03-09 13:08:53 Tabris_ 阅读数:276
博客爬取于2020-06-14 22:44:56
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50834496
The Suspects
Time Limit:1000MS Memory Limit:20000KB 64bit IO Format:%I64d & %I64u
Submit
Status
Description
严重急性呼吸系统综合症( SARS), 一种原因不明的非典型性肺炎,从2003年3月中旬开始被认为是全球威胁。为了减少传播给别人的机会, 最好的策略是隔离可能的患者。
在Not-Spreading-Your-Sickness大学( NSYSU), 有许多学生团体。同一组的学生经常彼此相通,一个学生可以同时加入几个小组。为了防止非典的传播,NSYSU收集了所有学生团体的成员名单。他们的标准操作程序(SOP)如下:
一旦一组中有一个可能的患者, 组内的所有成员就都是可能的患者。
然而,他们发现当一个学生被确认为可能的患者后不容易识别所有可能的患者。你的工作是编写一个程序, 发现所有可能的患者。
Input
输入文件包含多组数据。
对于每组测试数据:
第一行为两个整数n和m, 其中n是学生的数量, m是团体的数量。0 < n <= 30000,0 <= m <= 500。
每个学生编号是一个0到n-1之间的整数,一开始只有0号学生被视为可能的患者。
紧随其后的是团体的成员列表,每组一行。
每一行有一个整数k,代表成员数量。之后,有k个整数代表这个群体的学生。一行中的所有整数由至少一个空格隔开。
n = m = 0表示输入结束,不需要处理。
Output
对于每组测试数据, 输出一行可能的患者。
Sample Input
100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0
Sample Output
4
1
1
并查集基础
不解释
1 | # include <iostream> |
2016-03-08 14:06:30 Tabris_ 阅读数:1023
博客爬取于2020-06-14 22:44:57
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50826765
本题网址<-点此进入链接
Repeater
Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 4187
Accepted: 1114
Description
Harmony is indispensible in our daily lifeand no one can live without it----may be Facer is the only exception. One dayit is rumored that repeat painting will create harmony and then hundreds ofpeople started their endless drawing. Their paintings were based on a smalltemplate and a simple method of duplicating. Though Facer can easily imaginethe style of the whole picture, but he cannot find the essential harmony. Nowyou need to help Facer by showing the picture on computer.
You will be given a template containingonly one kind of character and spaces, and the template shows how the endlesspicture is created----use the characters as basic elements and put them in theright position to form a bigger template, and then repeat and repeat doingthat. Here is an example.
1 | # # |
本题就是一个基础的分形问题 ,只不过是在一个自己定义的图形中,再进行分形处理 。
所以我们一定要把最先定义的图形遍历一遍 找到他的基础结构。用一个二维的数组标记出他的最基础构型 ,就可以开始分型了。
稍有不同的是在分形打印的函数中的递归函数需要双层的for循环来遍历标记数组,
其实在遍历标记数组的时候发现比把每个都写出来要容易操作的多(但时间复杂度会变高),当然本题必须采用遍历的操作才可以,因为自己定义的图形,在没有定义的时候,他的结构就是未知的,所以必须遍历。
接下来就是简单的分型操作了相信你在做这道题的时候已经掌握分形的操作了 这里就不在赘述了
PS:如果真的不了解分形的话,可以看看这篇博客。
2014年蓝桥杯第五题 分型问题 判断递归起点稍有不同<-点此进入链接
哈理工OJ 题目格式较本题稍复杂<-点此进入链接
另附解题代码
1 | # include <stdio.h> |
2016-03-06 15:30:37 Tabris_ 阅读数:764
博客爬取于2020-06-14 22:39:23
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50813606
##本博客引用于此
一.逻辑运算符
1.& 位与运算
二.位移运算符
1.位左移
左移运算的实质是将对应的数据的二进制值逐位左移若干位,并在空出的位置上填0,最高位溢出并舍弃。例如int a,b;
a=5;
b=a<<2;
则b=20,分析过程如下:
(a)10=(5)10=(0000 0000 0000 0101)2
b=a<<2;
b=(0000 0000 0001 0100)2=(20)10
从上例可以看出位运算可以实现二倍乘运算。由于位移操作的运算速度比乘法的运算速度高很多。因此在处理数据的乘法运算的时,采用位移运算可以获得较快的速度。
提示 将所有对2的乘法运算转换为位移运算,可提高程序的运行效率
2.位右移
位右移运算的实质是将对应的数据的二进制值逐位右移若干位,并舍弃出界的数字。如果当前的数为无符号数,高位补零。例如:
int (a)10=(5)10=(0000 0000 0000 0101)2
b=a>>2;
b=(0000 0000 0000 0001)2=(1)10
如果当前的数据为有符号数,在进行右移的时候,根据符号位决定左边补0还是补1。如果符号位为0,则左边补0;但是如果符号位为1,则根据不同的计算机系统,可能有不同的处理方式。可以看出位右移运算,可以实现对除数为2的整除运算。
提示 将所有对2的整除运算转换为位移运算,可提高程序的运行效率
3.复合的位运算符
在C语言中还提供复合的位运算符,如下:
&=、!=、>>=、<<=和^=
例如:a&=0x11等价于 a= a&0x11,其他运算符以此类推。
不同类型的整数数据在进行混合类型的位运算时,按右端对齐原则进行处理,按数据长度大的数据进行处理,将数据长度小的数据左端补0或1。例如char a与int b进行位运算的时候,按int 进行处理,char a转化为整型数据,并在左端补0。
补位原则如下:
1 | # include <stdio.h> |
提示 在某一平台进行程序开发时,首先要求了解此系统的基本数据类型的有效范围, 对涉及的位运算进行评估,特别是要对边界数据进行检测,确保计算正确。
]]>2016-03-06 15:28:21 Tabris_ 阅读数:441
博客爬取于2020-06-14 22:44:58
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50813592
HDU1846<-点击此处进入链接
HDU1527<-点击此处进入链接
HDU2516<-点击此处进入链接
HDUXXX<-点击此处进入链接
题目链接:poj zoj
题意:有 N 堆石子,两人轮流从任一堆中取任意个石子(至少一个),最后一个取石子的人为胜利者。若先取者胜利,则输出第一次拿走石头的方法一共可以有多少种。
分析:
求出一个必胜局面有多少种方式可以导出必败局面.
也就是求由S态到T态有多少种路径.
一个S态要转化成为T态,
令C = k1^k2^k3…^kn.
C的二进制表示最高位为1.
假设ki的二进制表示最高位与C的二进制表示最高位相同,那么可以通过将ki的某些二进制位上的0置为1,1置为0来使得C’ = 0,也就是使S态转化为T态.
所以问题就是寻找有多少个ki,其最高位和C的最高位相同.
看本题前后 可以做一下斐波那契博弈 在思维上有些相关性
**斐波那契博弈**<-点击这里进入链接
先声明一下 每一个数 都可以用2的N次幂的数的集合里元素加起来表示 (联想2进制数把每位的数换成他所等价的10进制的值)
标准的Nim博弈是要求可以取任意个石子 因为这个任意的数能够用2的N次幂的数的集合里元素加起来表示 所以只取2^n(n=0,1,2.3……)个数的石子就可以了
而且相对后面判断奇异局势,比较好理解
还是和所有博弈一样 找到它的必败态也就是奇异局势
假设n堆为3堆
**1.(0,0,0)是理所当然的奇异局势 **
2.(0,n,n)也是奇异局势,只要先手拿多少,后手在另一堆里拿相同个数的石子 就总保持(0,n,n)等先手最后一次拿光的时候,后手就可以把最后一堆剩下的全部拿光了
**3.(a,b,c)满足奇异局势的时候,和(2)的情况一样先手拿多少后手就拿多少,这个时候假定每一次先手拿的石子个数是a[i],那么只要保证在(a,b,c)中保证a[i]均成对即可 这样对方拿出来多少你就拿多少 就能保证赢 **
举个例子(4,9,13)
如果先手拿8,4,1 后手也这样拿 那么先手一定输
当然 先手也可能拿2 不管拿那个数里的2 都可分解出来 成对的
如果说拿的是4里的2 可以拿13中的2 可以拿13中的2 保证接下来的是成对的
可以划成这样
如果说拿的是9里的2 也可以拿13中的2 保证接下来的是成对的
可以划成这样
如果说拿的是13里的2 也可以拿9或13中的2 保证接下来的是成对的
划分之后的和上两个图片是一样了
知道了上述这些 那么无论是3堆还是多少堆 都是这样凑成对就好了
**刚刚解释的就是Nim博弈的过程了 那么怎么用代码实现的呢 **
其实自习观察上几张图片 会发现点什么 先想一想再看下文
如果把出了0的数均换成1 并按照顺序呢列出 就会发现这就是一个二进制数
想到了而进制数 那就应该想到位运算
Ps: 如果想多了解一下位运算<-点击此处进入链接
那么只要用“^”异或运算就可以判断局势是不是奇异局势了
对于三堆的满足a^b^c=0就是奇异局势
N堆的话就是
付一下本题代码
1 | # include <iostream> |
2016-03-06 13:57:58 Tabris_ 阅读数:673
博客爬取于2020-06-14 22:44:59
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50813093
HDU1846<-点击此处进入链接
HDU1527<-点击此处进入链接
HDU2516<-点击此处进入链接
HDUXXX<-点击此处进入链接
HDUxxxx<-点击此处进入链接
取石子游戏
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3862 Accepted Submission(s): 2307
Problem Description
1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".
Input
输入有多组.每组第1行是2<=n<2^31. n=0退出.
Output
先取者负输出"Second win". 先取者胜输出"First win".
参看Sample Output.
Sample Input
2
13
10000
0
Sample Output
Second win
Second win
First win
斐波那契博弈这里需要借助“Zeckendorf定理”(齐肯多夫定理):任何正整数可以表示为若干个不连续的Fibonacci数之和。
先看看斐波那契数列的必败证明:
1、当i=2时,先手只能取1颗,显然必败,结论成立。
2、假设当i<=k时,结论成立。
则当i=k+1时,f[i] = f[k]+f[k-1]。
则我们可以把这一堆石子看成两堆,简称k堆和k-1堆。
(一定可以看成两堆,因为假如先手第一次取的石子数大于或等于f[k-1],则后手可以直接取完f[k],因为f[k] < 2*f[k-1])
对于k-1堆,由假设可知,不论先手怎样取,后手总能取到最后一颗。下面我们分析一下后手最后取的石子数x的情况。
如果先手第一次取的石子数y>=f[k-1]/3,则这小堆所剩的石子数小于2y,即后手可以直接取完,此时x=f[k-1]-y,则x<=2/3*f[k-1]。
我们来比较一下2/3f[k-1]与1/2f[k]的大小。即4f[k-1]与3f[k]的大小,由数学归纳法不难得出,后者大。
所以我们得到,x<1/2*f[k]。
即后手取完k-1堆后,先手不能一下取完k堆,所以游戏规则没有改变,则由假设可知,对于k堆,后手仍能取到最后一颗,所以后手必胜。
即i=k+1时,结论依然成立。
对于不是FIB数,首先进行分解。
分解的时候,要取尽量大的Fibonacci数。
比如分解85:85在55和89之间,于是可以写成85=55+30,然后继续分解30,30在21和34之间,所以可以写成30=21+9,
依此类推,最后分解成85=55+21+8+1。
则我们可以把n写成 n = f[a1]+f[a2]+……+f[ap]。(a1>a2>……>ap)
我们令先手先取完f[ap],即最小的这一堆。由于各个f之间不连续,则a(p-1) > ap + 1,则有f[a(p-1)] > 2*f[ap]。即后手只能取f[a(p-1)]这一堆,且不能一次取完。
此时后手相当于面临这个子游戏(只有f[a(p-1)]这一堆石子,且后手先取)的必败态,即先手一定可以取到这一堆的最后一颗石子。
同理可知,对于以后的每一堆,先手都可以取到这一堆的最后一颗石子,从而获得游戏的胜利。
1 | //齐肯多夫定理 代码 实现 |
附本题AC代码
1 | # include <iostream> |
2016-03-05 22:57:14 Tabris_ 阅读数:573
博客爬取于2020-06-14 22:45:01
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50811273
LCP Array
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 307 Accepted Submission(s): 86
Problem Description
Peter has a string s=s1s2…sn, let suffi=sisi+1…sn be the suffix start with i-th character of s. Peter knows the lcp (longest common prefix) of each two adjacent suffixes which denotes as ai=lcp(suffi,suffi+1)(1≤i*<*n).
Given the lcp array, Peter wants to know how many strings containing lowercase English letters only will satisfy the lcp array. The answer may be too large, just print it modulo 109+7.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer n (2≤n≤105) – the length of the string. The second line contains n−1 integers: a1,a2,…,an−1 (0≤ai≤n).
The sum of values of n in all test cases doesn’t exceed 106.
Output
For each test case output one integer denoting the answer. The answer must be printed modulo 109+7.
Sample Input
3
3
0 0
4
3 2 1
3
1 2
Sample Output
16250
26
0
题目就是说给你输入的a[i]后 第i个字符与后面a[i]个字符都是相同的 问你有多少个符合输入的种类
本题有主要有三个点
1.a[i]小于n-i
2.a[i]是每一段递减的 而且必须是依次减1 减到0后可以接着再有一段递减的 但最后都要到1 否则不符合1
3.每一段递减段的字符必须是相同的
可以把每一段规程一块 且相邻的两块不相同
Ps:取鱼之后的输出也超了int 要用long long int
博主在这里错了无数发才想到这个问题
最后正常写就好了
1 | # include <stdio.h> |
2016-03-03 17:21:04 Tabris_ 阅读数:820
博客爬取于2020-06-14 22:45:02
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50790140
HDU1846<-点击此处进入链接
HDU1527<-点击此处进入链接
HDU2516<-点击此处进入链接
HDUXXX<-点击此处进入链接
HDUxxxx<-点击此处进入链接
取石子游戏
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5425 Accepted Submission(s): 2833
Problem Description
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
Input
输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,000。
Output
输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。
Sample Input
2 1
8 4
4 7
Sample Output
0
1
0
如果做本题之前没有做过巴士博弈的题目,建议先做一下巴士博弈
巴士博弈
HDU1846<-点击此处进入链接
如果做本题之前没有做过巴士博弈的题目,建议先做一下巴士博弈
如果做本题之前没有做过巴士博弈的题目,建议先做一下巴士博弈
如果做本题之前没有做过巴士博弈的题目,建议先做一下巴士博弈
用(n,m) 表示当前的局势,n与m表示剩下的石子个数
先引出奇异局势的概念
奇异局势就是指当轮到甲取石子的时候局势(n,m)能确保甲无论怎么取石子都会输的局势
本题就要详细解释下奇异局势的性质
1.任何自然数都包含在一个且仅有一个奇异局势中。
2.任意操作都可将奇异局势变为非奇异局势。
3.采用适当的方法,可以将非奇异局势变为奇异局势。
其实做这类题只要找到奇异局势就好了
那么任给一个局势(a,b),怎样判断它是不是奇异局势呢?我们有如下公式: ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,…,n 方括号表示取整函数) 奇妙的是其中出现了黄金分割数(1+√5)/2 = 1。618…,因此,由ak,bk组成的矩形近似为黄金矩形,由于2/(1+√5)=(√5-1)/2,可以先求出j=[a(√5-1)/2],若a=[ j(1+√5)/2],那么a = aj,bj = aj + j,若不等于,那么a = aj+1,bj+1 = aj+1 + j + 1,若都不是,那么就不是奇异局势。然后再按照上述法则进行,一定会遇到奇异局势。
上述奇异局势的判断来自这里<-点击此处进入链接
附本题代码
1 | # include <iostream> |
2016-03-03 17:15:26 Tabris_ 阅读数:1602
博客爬取于2020-06-14 22:45:03
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50790076
HDU1846<-点击此处进入链接
HDU1527<-点击此处进入链接
HDU2516<-点击此处进入链接
HDUXXX<-点击此处进入链接
HDUxxxx<-点击此处进入链接
Brave Game
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9376 Accepted Submission(s): 6228
Problem Description
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫《勇敢者的游戏》(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻。
今天,大家选择上机考试,就是一种勇敢(brave)的选择;这个短学期,我们讲的是博弈(game)专题;所以,大家现在玩的也是“勇敢者的游戏”,这也是我命名这个题目的原因。
当然,除了“勇敢”,我还希望看到“诚信”,无论考试成绩如何,希望看到的都是一个真实的结果,我也相信大家一定能做到的~
各位勇敢者要玩的第一个游戏是什么呢?很简单,它是这样定义的:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;
如果游戏的双方使用的都是最优策略,请输出哪个人能赢。
Input
输入数据首先包含一个正整数C(C<=100),表示有C组测试数据。
每组测试数据占一行,包含两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。
Output
如果先走的人能赢,请输出“first”,否则请输出“second”,每个实例的输出占一行。
Sample Input
2
23 2
4 3
Sample Output
first
second
本题是巴士博弈
此处应为题目描述 请见上文
用**(n,m)** 表示当前的局势,n表示剩下的石子个数,m为每次最多能够取的石子个数
先引出奇异局势的概念
奇异局势就是指当轮到甲取石子的时候局势(n,m)能确保甲无论怎么取石子都会输的局势
简单一句话 奇异局势就是谁碰谁输的局势(无论你怎样取石子)
要想赢就要想办法让最后剩在自己面前的石子<=m
而想要保证上一点,就必须保证输家最后一次拿石子的时候剩余m+1个这样无论输家怎么拿,都能确保剩在自己面前的石子<=m 且输家不可能一次拿光石子
现在我们还可以知道这样的等式n=(m+1)*r+sr为任意自然数,s为小于m的自然数
我们只要先将s个数的石子取走 等到对方取了k个石子过后在取m+1-k个石子就能保证最后剩到对方的就是m+1个石子 来确保赢
综上所述 *我们可以知道只要面对(m+1)r个石子就必输无疑
*所以我们就能得到奇异局势就是剩余的石子个数是(m+1)r的情况
所以只要判断当前是不是奇异局势就能判断出最好谁是赢家
附一下本题代码
1 | # include <stdio.h> |
2016-03-03 13:19:37 Tabris_ 阅读数:553
博客爬取于2020-06-14 22:45:04
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50787788
螺旋矩阵
Time Limit: 1000 MSMemory Limit: 10240 K
Total Submit: 282(78 users)Total Accepted: 81(72 users)Rating: Special Judge: No
Description
对于给定的一个数n,要你打印n*n的螺旋矩阵。
比如n=3时,输出:
1 2 3
8 9 4
7 6 5
Input
多组测试数据,每个测试数据包含一个整数n(1<=n<=32)
Output
对于每组测试数据,输出一个n*n的螺旋矩阵,定义在题目描述里。
在一组测试数据中,每个数占的字符宽度是该组数据中最大的数位数加1,比如3*3的螺旋矩阵,最大值是9,那么每个数就要占2个字符宽度。
两组测试数据之间用一个空行隔开。
Sample Input
1
2
3
Sample Output
1
1 2
4 3
本题我用的是搜索
关键点在于搜索的方向控制
方向控制很简单 就是用fx[4]与fy[4]控制方向
“→”“↓”“←”“↑”这四个方向的循环
如果上一次搜索是那个搜索那个方向的 如果搜索的图已经到头了
就从下一个方向开始搜索
如下就是搜索的代码
1 | void dfs(int x,int y,int ii) |
本题非常容易PE 主要由以下两点
1.两组数据中间的空格。(这个很容易 但是要读题啊 博主就因为没看到而PE多次)
2.图内最大的数有几位 图内的所有数都占几+1位(这样想就没有空格的干扰了)
关于控制数据占位的个数可以这样表示
1 | printf("%*d",length+1,a[i][j]); //其中*号是位数 对应length是对应位数的数据 +1是数值之前的空格占一位 |
1 | # include <iostream> |
2016-03-01 20:57:20 Tabris_ 阅读数:3614
博客爬取于2020-06-14 22:45:05
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50775612
一、奖券数目
有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。
虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。
请提交该数字(一个整数),不要写任何多余的内容或说明性文字。
简单数学问题
排列组合一下
89999=52488
暴力搜索
1 | # include <stdio.h> |
二、
星系炸弹
在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。
每个炸弹都可以设定多少天之后爆炸。
比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。
有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。
请填写该日期,格式为 yyyy-mm-dd 即4位年份2位月份2位日期。比如:2015-02-19
请严格按照格式书写。不能出现其它文字或符号。
本题最好还是用Excel
一来题目不难就是麻烦点
二来比赛时间有限啊
答案是 2017-08-05
要注意格式
三、三羊献瑞
观察下面的加法算式:
![这里写图片描述](http://img.blog.csdn.net/20160301180449804)
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。
这就是个数学题
先按数学题的方法解一下
语言表述的话很长 但思考的时候是很快的 如果没兴趣可以跳过
1,因为是加法算式三是进位出来的 所以是三是1
2,因为三是1且三加祥能进位,只有1+9能进位,所以祥是9
**但是考虑可能有进位的情况祥可能为8或9 ***
⑴,当祥为8时8+1+1(进位的1)=10 这时羊只能为0 而0+任何1~9数均<10 不可能进位 ——不成立
⑵,当祥为9时9+1+1(进位的1)=1,羊为1 因为三为1 所以羊不为1 ——不成立
综上得到三为1 祥为9 所以羊为0
3,瑞+0=生只能是后面进位了,得到瑞+1等于生。
又有生+献=瑞 即 瑞+1+献=瑞 即 1+献=0
(到这可能有些不明白,解释下,这又是因为后位进1导致1+献=0 应为 1+献+1(进位的1)=0 即献=8)
此时设瑞=x,辉=y,气=z。
这时所有的数的关系如下
这时从x开始试数,1,0已经有了 从2开始试数
x=2时 x+y>=10,y>=8 而8,9已经存在—— 不成立
x=3时 x+y>=10,y>=7 8,9已经存在 也只能为7,但 x+y=3+7+10 z应为0 因0已经存在—— 不成立
x=4时 x+y>=10,y>=6 8,9已经存在 y可为6,7 当为6时z=0—— 不成立 当为7时 z=1 不成立
x=5时 x+y>=10,y>=5 8,9已经存在 y为7时 z为2 此时总式成立
所以得出结果为 9567+1085=10652
得出三样献瑞 为1085
***此题目用推理的方式做出来 上述只是他的证明过程 所以文字多 篇幅长 但是这都是思考出来的 在实际操作中很快就会得出结果 比写暴力的代码要省时的多 毕竟代码那么多的for语句 还有那么多数字加在一起 很容易出错了 虽然不用代码 有点违背蓝桥杯是C++比赛的事实 但是做出题来得分 取得名次 才是王道 ***
下面是常规暴力做法
1 | # include <iostream> |
这么繁杂的代码 写起来也很影响心情啊
---------------------------------Update-----------------------------
其实C++
它能够将序列的全排列全部计算出来,这样的话,这道题目的代码量就会减少太多了.
以下代码已经确认 ‘三’=1 ,‘祥’=9
1 | bool check(int *a){ |
第6题:加号改乘号
题目大意
把1+2+3+…+48+49中的两个加号改成乘号(修改位置不能相邻),使得式子的结果由1225变为2015。
解题分析:
用双循环暴力两个乘号的位置,计算在数字i、j后的加号改为乘号,式子数值的变化即可,注意j的起始位置为i+2。
简化一下能得到是判断式为792=i*(i-1)+j*(j-1)
代码:
1 | # include <iostream> |
7题:牌型种数
题目大意
原题:
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
解题分析:
这里也是两种方法, 暴力搜索。
题目很容易 记住剪枝 能快不少
1 | # include <iostream> |
就这么多吧
]]>2016-03-01 17:48:23 Tabris_ 阅读数:639
博客爬取于2020-06-14 22:45:06
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50774422
中文版的题目很人性化 有木有
B - The Suspects
Time Limit:1000MS Memory Limit:20000KB 64bit IO Format:%I64d & %I64u
Submit
Status
Description
严重急性呼吸系统综合症( SARS), 一种原因不明的非典型性肺炎,从2003年3月中旬开始被认为是全球威胁。为了减少传播给别人的机会, 最好的策略是隔离可能的患者。
在Not-Spreading-Your-Sickness大学( NSYSU), 有许多学生团体。同一组的学生经常彼此相通,一个学生可以同时加入几个小组。为了防止非典的传播,NSYSU收集了所有学生团体的成员名单。他们的标准操作程序(SOP)如下:
一旦一组中有一个可能的患者, 组内的所有成员就都是可能的患者。
然而,他们发现当一个学生被确认为可能的患者后不容易识别所有可能的患者。你的工作是编写一个程序, 发现所有可能的患者。
Input
输入文件包含多组数据。
对于每组测试数据:
第一行为两个整数n和m, 其中n是学生的数量, m是团体的数量。0 < n <= 30000,0 <= m <= 500。
每个学生编号是一个0到n-1之间的整数,一开始只有0号学生被视为可能的患者。
紧随其后的是团体的成员列表,每组一行。
每一行有一个整数k,代表成员数量。之后,有k个整数代表这个群体的学生。一行中的所有整数由至少一个空格隔开。
n = m = 0表示输入结束,不需要处理。
Output
对于每组测试数据, 输出一行可能的患者。
Sample Input
100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0
Sample Output
4
1
1
本题思路:就是并查集的基本使用 把与病人接触的和间接接触的放在一堆即可 然后遍历一下 记录一下有多少就行
一定要注意:本题后台数据量较大 一定要使用路径压缩 否则在遍历的时候 时间复杂度远大于O(n) 造成TLE
有人嫌上述的并查集代码比较麻烦所以用递归的并查集代码,但是并不能对路径进行压缩,对于那些不许路径压缩的题目很好 但是对于本类必须进行路径压缩的就不行了
当然递归的代码可能有路径压缩,但是我不会>_<
1 | # include<stdio.h> |
2016-03-01 16:12:00 Tabris_ 阅读数:396
博客爬取于2020-06-14 22:45:07
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50773461
第7题:六角填数(12’)
如图所示六角形中,填入1~12的数字。
使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?
请通过浏览器提交答案,不要填写多余的内容。
![](https://img-blog.csdn.net/20140325202603937?watermark/2/text/aHR0cDovL2Jsb
2cuY3Nkbi5uZXQvbGpkNDMwNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/disso
lve/70/gravity/SouthEast)
思路就是暴力解决 蓝桥杯还没有时间限制
之间运用了STL的一个函数 next_permutation();
next_permutation();是一个用来来寻找一组序列的下一个排列的函数 使用时与sort类似
解释一下什么是一个序列的下一个排列:
比如有一个序列 1 2 3 他的下一个排列就是1 3 2
这是所有1 2 3的所有排列
1 3 2
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
当本次排列已经是最后一个排列的时候 他的下一个排列就是第一个排列
附道题吧
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2005
这道题仅用这个函数就能做出来 题目对本函数的描述也是很详细的
1 |
|
2016-03-01 15:19:50 Tabris_ 阅读数:539
博客爬取于2020-06-14 22:45:08
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50772761
** Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14372 Accepted Submission(s): 5068
**
Problem Description
穿过幽谷意味着离大魔王lemon已经无限接近了!
可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个机关。要知道,不论何人,若在迷宫中被困1小时以
上,则必死无疑!
可怜的yifenfei为了去救MM,义无返顾地跳进了迷宫。让我们一起帮帮执着的他吧!
命运大迷宫可以看成是一个两维的方格阵列,如下图所示:
yifenfei一开始在左上角,目的当然是到达右下角的大魔王所在地。迷宫的每一个格子都受到幸运女神眷恋或者痛苦魔王的诅咒,所以每个格子都对应一个值,走到那里
便自动得到了对应的值。
现在规定yifenfei只能向右或者向下走,向下一次只能走一格。但是如果向右走,则每次可以走一格或者走到该行的列数是当前所在列数倍数的格子,即:如果当前格子
是(x,y),下一步可以是(x+1,y),(x,y+1)或者(x,y*k) 其中k>1。
为了能够最大把握的消灭魔王lemon,yifenfei希望能够在这个命运大迷宫中得到最大的幸运值。
Input
输入数据首先是一个整数C,表示测试数据的组数。
每组测试数据的第一行是两个整数n,m,分别表示行数和列数(1<=n<=20,10<=m<=1000);
接着是n行数据,每行包含m个整数,表示n行m列的格子对应的幸运值K ( |k|<100 )。
Output
请对应每组测试数据输出一个整数,表示yifenfei可以得到的最大幸运值。
Sample Input
1 3 8 9 10 10 10 10 -10 10 10 10 -11 -1 0 2 11 10 -20 -11 -11 10 11 2 10 -10
-10
Sample Output
52
Author
yifenfei
本题就是简单的DP 难点就在于几个细的点没有想到
1、如果全是负数的时候 。
2、向右跳的时候k值的界限 k<=m
直接上代码
AC代码
1 |
|
错误代码 差别就是k值取得是k<j 一开始想的是在每个点的时候 选取到这个点时的最大值 没有考虑那么多
1 |
|
精简版代码
1 |
|
2016-02-29 22:44:31 Tabris_ 阅读数:307
博客爬取于2020-06-14 22:45:09
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50768959
** Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1353 Accepted Submission(s): 813
**
Problem Description
It’s an interesting experience to move from ICPC to work, end my college life
and start a brand new journey in company.
As is known to all, every stuff in a company has a title, everyone except the
boss has a direct leader, and all the relationship forms a tree. If A’s title
is higher than B(A is the direct or indirect leader of B), we call it A
manages B.
Now, give you the relation of a company, can you calculate how many people
manage k people.
Input
There are multiple test cases.
Each test case begins with two integers n and k, n indicates the number of
stuff of the company.
Each of the following n-1 lines has two integers A and B, means A is the
direct leader of B.
1 <= n <= 100 , 0 <= k < n
1 <= A, B <= n
Output
For each test case, output the answer as described above.
Sample Input
7 2 1 2 1 3 2 4 2 5 3 6 3 7
Sample Output
2
Author
题目大意就是求子集节点数是K的有几个
然后做着做着就出来了
1 |
|
2016-02-28 20:28:28 Tabris_ 阅读数:316
博客爬取于2020-06-14 22:45:10
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50761497
http://acm.hdu.edu.cn/showproblem.php?pid=2709
** Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2052 Accepted Submission(s): 813
**
Problem Description
Farmer John commanded his cows to search for different sets of numbers that
sum to a given number. The cows use only numbers that are an integer power of
2. Here are the possible sets of numbers that sum to 7:
Help FJ count all possible representations for a given integer N (1 <= N <=
1,000,000).
Input
A single line with a single integer, N.
Output
The number of ways to represent N as the indicated sum. Due to the potential
huge size of this number, print only last 9 digits (in base 10
representation).
Sample Input
7
Sample Output
6
一、 DP解法(这应该是标准解法了 本人第一次 碰到这类题 也是用DP)
思路:
1.如果n为奇数,那么所求的分解结果中必含有1,因此,直接将n-1的分拆结果中添加一个1即可 为s[n-1]
2.如果n为偶数,那么n的分解结果分两种情况:
a) 含有1:这种情况可以直接在n-1的分解结果中添加一个1即可 s[n-1]
b) 不含1:那么,分解因子的都是偶数,将每个分解的因子都除以2,刚好是n/2的分解结果,并且可以与之一一对应,这种情况有 s[n/2]
所以,状态转移方程为
如果i为奇数 s[i] = s[i-1]
如果i为偶数 s[i] = s[i-1] + s[i/2]
1 |
|
二、这是递推的方法 (很简洁 偶然看到这个代码 只想说牛X)
如果所求的n为奇数,那么所求的分解结果中必含有1,因此,直接将n-1的分拆结果中添加一个1即可 为s[n-1]如果所求的n为偶数,那么n的分解结果分两种情况1.含有1 这种情况可以直接在n-1的分解结果中添加一个1即可 s[n-1]2.不含有1 那么,分解因子的都是偶数,将每个分解的因子都除以2,刚好是n/2的分解结果,并且可以与之一一对应,这种情况有 s[n/2]所以,状态转移方程为如果i为奇数, s[i] = s[i-1]如果i为偶数 s[i] = s[i-1] + s[i/2]
1 |
|
2016-01-23 18:40:20 Tabris_ 阅读数:284
博客爬取于2020-06-14 22:45:11
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50570897
A - Work
Time Limit: 1000 MS Memory Limit: 32768 KB 64bit IO Format: %I64d &
%I64u
Description
**
**
It’s an interesting experience to move from ICPC to work, end my college life
and start a brand new journey in company.
As is known to all, every stuff in a company has a title, everyone except the
boss has a direct leader, and all the relationship forms a tree. If A’s title
is higher than B(A is the direct or indirect leader of B), we call it A
manages B.
Now, give you the relation of a company, can you calculate how many people
manage k people.
Input
There are multiple test cases.
Each test case begins with two integers n and k, n indicates the number of
stuff of the company.
Each of the following n-1 lines has two integers A and B, means A is the
direct leader of B.
**
**
1 <= n <= 100 , 0 <= k < n
1 <= A, B <= n
Output
For each test case, output the answer as described above.
Sample Input
7 2
1 2
2 4
1 3 2 5
3 7
3 6
Sample Output
2
题目就是给了一堆数,分别对应一个人,然后吧就是A领导B,最后让你求出有K个手下的人的个数。(开始翻译成了求K的手下有几个。。英语不好真苦逼啊)。。。
本题其实是一道并查集的题目,但是并查集并没有写明白,所以用了苦逼的多维数组。。。
详情请看代码。。。
然后开始贴代码
1 |
|
2015-12-28 17:22:57 Tabris_ 阅读数:386
博客爬取于2020-06-14 22:45:13
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50420268
** 节点的连接 **
Time Limit: 1000 MS
Memory Limit: 32768 K
Total Submit: 80 (43 users)
Total Accepted: 45 (41 users)
Rating:
Special Judge: No
** Description **
有N个节点,一开始任意两个节点都没有相连,之后有两种操作:
1: 将 A 节点和 B 节点连接起来。
2: 问从A节点出发可以直接或间接到达的节点数量。
如果 A 节点和 B 节点被连接起来了,那么从A可以到达B,同时从B也可以到达A。
** Input **
第一行是一个整数T,表示有T组测试数据。
对于每组测试数据,第一行是一个整数 n (n<=1000) 代表节点数,一个整数 m (m<=1000)代表操作数,之后有m行,每行代表一种操作。
第一种操作是: 0 A B (1<=A,B<=n),表示将A,B节点连接起来;
第二种操作是: 1 A (1<=A<=n),表示询问从A节点出发可以直接或间接到达的节点的数量。
** Output **
对于每组测试数据,如果是第二种操作,输出一个整数表示答案,每组输出占一行。
** Sample Input **
1
4 5
0 1
1 1 2
0 1
1 1 3
0 3
** Sample Output **
1
2
3
本题是一道简单的并查集问题
并查集主要就是有找到自己的上级 然后使两伙人合并到一伙
其中路径压缩是为使两伙归终于一个老大 而下级之间并不存在关心
本题没什么难的看看 代码注释就能理解
1 |
|
2015-12-28 17:14:17 Tabris_ 阅读数:456
博客爬取于2020-06-14 22:45:14
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50420183
本题就是一个基础的分形问题 ,只不过是在一个自己定义的图形中,再进行分形处理 。
所以我们一定要把最先定义的图形遍历一遍 找到他的基础结构。用一个二维的数组标记出他的最基础构型 ,就可以开始分型了。
稍有不同的是在分形打印的函数中的递归函数需要双层的for循环来遍历标记数组,
其实在遍历标记数组的时候发现比把每个都写出来要容易操作的多(但时间复杂度会变高),当然本题必须采用遍历的操作才可以,因为自己定义的图形,在没有定义的时候,他
的结构就是未知的,所以必须遍历。
接下来就是简单的分型操作了相信你在做这道题的时候已经掌握分形的操作了 这里就不在赘述了
PS:如果真的不了解分形的话,可以看看这篇博客。
2014年蓝桥杯第五题 分型问题 判断递归起点稍有不同
http://blog.csdn.net/qq_33184171/article/details/50390031
哈理工OJ 题目格式较本题稍复杂
http://blog.csdn.net/qq_33184171/article/details/50274193
本题网址: http://poj.org/problem?id=3768
方便读者 题目放到了本文最后
另附解题代码
1 |
|
** Repeater **
** Time Limit: ** 1000MS
** Memory Limit: ** 65536K
** Total Submissions: ** 4187
** Accepted: ** 1114
** Description **
Harmony is indispensible in our daily lifeand no one can live without it----
may be Facer is the only exception. One dayit is rumored that repeat painting
will create harmony and then hundreds ofpeople started their endless drawing.
Their paintings were based on a smalltemplate and a simple method of
duplicating. Though Facer can easily imaginethe style of the whole picture,
but he cannot find the essential harmony. Nowyou need to help Facer by showing
the picture on computer.
You will be given a template containingonly one kind of character and spaces,
and the template shows how the endlesspicture is created----use the characters
as basic elements and put them in theright position to form a bigger template,
and then repeat and repeat doingthat. Here is an example.
# <-template
So the Level 1 picture will be
Level 2 picture will be
## # #
# #
## # #
## # #
# #
## # #
** Input **
The input contains multiple test cases.
Thefirst line of each case is an integer _ N _ , representing the size of the
template is _ N _ * _ N _ ( _ N _ could only be 3, 4 or 5).
Next Nlines describe the template.
Thefollowing line contains an integer _ Q _ , which is the Scale Level of the
picture.
Inputis ended with a case of _ N _ =0.
It isguaranteed that the size of one picture will not exceed 3000*3000.
** Output **
For each test case, just print the Level _ Q _ picture by using the given
template.
** Sample Input **
3
1
3
3
4
OO
O O
O O
OO
2
0
** Sample Output **
# # # #
# #
# # # #
# #
# #
# # # #
# #
# # # #
OO OO
O OO O
O OO O
OO OO
OO OO
O O O O
O O O O
OO OO
OO OO
O O O O
O O O O
OO OO
OO OO
O OO O
O OO O
OO OO
** Source **
]]>2015-12-23 21:59:18 Tabris_ 阅读数:651
博客爬取于2020-06-14 22:45:15
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50390031
蓝桥杯2014第五题
打印图形:
小明在X星球的城堡了发现了如下图形和文字:
Rank=3
![](https://img-blog.csdn.net/20151228172916859?watermark/2/text/aHR0cDovL2Jsb
2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravi
ty/Center)
Rank=4
![](https://img-blog.csdn.net/20151228172935235?watermark/2/text/aHR0cDovL2Jsb
2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravi
ty/Center)
Rank=5
![](https://img-blog.csdn.net/20151228172948657?watermark/2/text/aHR0cDovL2Jsb
2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravi
ty/Center)
题目是填空题 但是代码是自己写的
分形问题最主要的是找到图形的最基本的点
如POJ 2083 的那个X 基本构成 就是在九个方格里 左上,左下,中间,右上,右下,这5个位置 都有X 而数字没加一个
就把每一个X替换成这个基本的构成
POJ : http://poj.org/problem?id=2083
这道题个基本构成就不是这么简单 不是每个三角形上的每个点 而是三角形上的三个顶点 其实了解过分形的 看到这句就能解决了 之后就一遍又一遍的递归就好了
但千万注意 你递归的只是三角形的三个顶点 在打印图形的时候 要把 8个点 都打印上
详情请看代码注释 很详细的哦
1 |
|
2015-12-22 10:43:46 Tabris_ 阅读数:782
博客爬取于2020-06-14 22:45:16
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50378327
粉刷栅栏
Time Limit: 500 MS
Memory Limit: 32768 K
Total Submit: 58 (19 users)
Total Accepted: 14 (10 users)
Rating:
Special Judge: No
Description
给定一组长度为 n 的栅栏,从左到右高度依次是 h[i] 。
你需要对这个栅栏粉刷油漆,每次你可以粉刷一行或者一列。
问最少粉刷几次,可以给所有栅栏上漆。(不能多刷)
Input
第一行包含一个整数,表示栅栏的长度。
接下来的一行,包含 n 个数( n <= 5000 ),依次表示 h[i](0 <= h[i] <= 10) 。
Output
输出一行表示对应的答案。
Sample Input
5
2 2 1 2 1
Sample Output
3
Hint
![](http://acm.hrbust.edu.cn/contests/attached/image/20141231/20141231155623_9
1685.jpg)
其实本题很好想 做不出来 还是想的太多 就一层一层的刷 刷完这层下层分开了 那就当成新的两个栅栏刷就好了 之后接着再刷
看到这里你可能会想到会用到递归 没错!! 本题就是一个递归的思想解决
如果你每次都分出新的栅栏 就会发现每一层其实只有横着和竖着刷两种刷法 两种刷法的话就很好了 只要计算出横着刷用多少下就好了
当然要和竖着刷的次数比较一下 选择小的记录 竖着刷就是有机列就刷几下么
本题复杂的操作就是判断新的多个栅栏的时候 如何更新
首先把每一个栅栏都有的几层都刷上 然后减去 因为刷完了 就相当于没有这几行 之后在遍历一下 看一看那一段还有栅栏需要刷 在重复之前的操作就好了
用递归 !!
//===================================附代码
1 |
|
2015-12-18 21:16:40 Tabris_ 阅读数:451
博客爬取于2020-06-14 22:45:17
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50354268
http://poj.org/problem?id=3190
题目大意: 每一只奶牛都要在区间[a,b]的时段内独自享受一个牛栏 如果两只牛的时间岔开了
那很好 它们两个用一个牛栏就好了 如果不能岔开 那么只好分别用一个牛栏了
这题主要是贪心的思想 寻找最优解 但是单单贪心是不够的 你需要记录每只牛在第几只牛栏
而且你要判断这些牛那些能在一起而那些不能在一起 所以本题 用到了优先队列 优先级就为最小的结束时间
然后进行比较 这里就看代码的注释就好了
其实思路还是比较好像 但是操作起来着实不宜 再加上博主平时就不怎么用队列 更不用说优先队列的 所以本题迟迟不能写出来啊 所以粘了大神的代码
大神的代码 虽然看懂了 但是自己写的话很多地方都不能很好的处理 还是技术不行啊
1 |
|
1 | struct node |
1 |
|
2015-12-13 21:57:53 Tabris_ 阅读数:339
博客爬取于2020-06-14 22:45:18
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50287091
** 卡片游戏 **
** Time Limit: 3000/1000 MS(Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1675 Accepted Submission(s): 488
**
** Problem Description **
小明最近宅在家里无聊,于是他发明了一种有趣的游戏,游戏道具是N张叠在一起的卡片,每张卡片上都有一个数字,数字的范围是0~9,游戏规则如下:
首先取最上方的卡片放到桌子上,然后每次取最上方的卡片,放到桌子上已有卡片序列的最右边或者最左边。当N张卡片全部都放到桌子上后,桌子上的N张卡片构成了一个数。
这个数不能有前导0,也就是说最左边的卡片上的数字不能是0。游戏的目标是使这个数最小。
现在你的任务是帮小明写段程序,求出这个最小数。
** Input **
第一行是一个数T,表示有T组测试数据;
然后下面有T行, 每行是一个只含有0~9的字符串,表示N张叠在一起的卡片,最左边的数字表示最上方的卡片。
[Technical Specification]
T<=1000
1 <= N <= 100
** Output **
对于每组测试数据,请在一行内输出能得到的最小数。
** Sample Input **
3
565
9876543210
9876105432
** Sample Output **
556
1234567890
1678905432
主要思想就是模拟排一下序,把第一个数最为输出的第一个数(暂时的),然后进行比较,
看代码注释比较好 但一定注意含0的情况 坑点就是这个0.
有0的话第一个数就应该非0最小值,且排序的话之排序非0最小值之前的,之后的只能按输入的顺序放在后面(注释解释的更加详细)。
1 | //=================================本人AC代码 |
2015-12-12 13:06:01 Tabris_ 阅读数:990
博客爬取于2020-06-14 22:45:19
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/50274193
Help C5
Time Limit: 1000 MS
Memory Limit: 65535 K
Total Submit: 51(9 users)
Total Accepted: 12(8 users)
Rating:
Special Judge: No
Description
Hello, I’m Sea5, and you can call me C5 instead. I want a program which can sign my name automatically. And my brothers, C0, C1, C2, C3, C4, C6, C7, C8, each of them wants one as well. Can you help us?
Input
First line is the number of test cases T(T<=8).
T lines follow, each line includes an integer N(N<=7), and you should help C(N) to sign his name.
Output
C0’s signature is ‘C’.
When you draw C(N)’s name, you should print the name using C(N-1)’s name as its element, and using the following format to draw it.
*XX
X**
*XX
(X is the element, * is blank space)
And please don’t print extra spaces at the end of line.
For example, C1’s name should be
1 | *CC *CC |
(I use * to show you where are spaces.)
Sample Input
1 | 3 |
Sample Output
1 | C |
本类型题其实就是模版体 比赛的时候有模版还是很好做的 (其实没有模版也不难)
最主要的是格式 对输出图形空格的格式 以及没两组输出后又没有空格等
对不同的图行 只要找到相应的位置不断的递归就可以了
其实也可以先把所有的图形都打印下来 然后在选取部分输出就好了
附本题代码
1 |
|
这是一篇讲解如何正确使用 Markdown 的排版示例,学会这个很有必要,能让你的文章有更佳清晰的排版。
引用文本:Markdown is a text formatting syntax inspired
这段内容展示了在内容里面一些排版格式,比如:
**加粗**
*倾斜*
~~删除线~~
Code 标记
- `Code 标记`
[超级链接](https://ld246.com)
[username@gmail.com](mailto:username@gmail.com)
@Vanessa 通过 @User
可以在内容中提及用户,被提及的用户将会收到系统通知。
NOTE:
- @用户名之后需要有一个空格
- 新手没有艾特的功能权限
支持大部分标准的表情符号,可使用输入法直接输入,也可手动输入字符格式。通过输入 :
触发自动完成,可在个人设置中设置常用表情。
:smile: :laughing: :dizzy_face: :sob: :cold_sweat: :sweat_smile: :cry: :triumph: :heart_eyes: :relieved:
:+1: :-1: :100: :clap: :bell: :gift: :question: :bomb: :heart: :coffee: :cyclone: :bow: :kiss: :pray: :anger:
你可以选择使用 H1 至 H6,使用 ##(N) 打头。建议帖子或回帖中的顶级标题使用 Heading 3,不要使用 1 或 2,因为 1 是系统站点级,2 是帖子标题级。
NOTE: 别忘了 # 后面需要有空格!
1 | ![alt 文本](http://image-path.png) |
支持复制粘贴直接上传。
1 | *emphasize* **strong** |
如果在 ``` 后面跟随语言名称,可以有语法高亮的效果哦,比如:
1 | package main |
1 | public class HelloWorld { |
Tip: 语言名称支持下面这些:
ruby
,python
,js
,html
,erb
,css
,coffee
,bash
,json
,yml
,xml
…
如果需要展示数据什么的,可以选择使用表格。
header 1 | header 2 |
---|---|
cell 1 | cell 2 |
cell 3 | cell 4 |
cell 5 | cell 6 |
空行可以将内容进行分段,便于阅读。(这是第一段)
使用空行在 Markdown 排版中相当重要。(这是第二段)
1 | [链接文本][链接标识] |
多行公式块:
行内公式:
公式 是行内。
1 | - 教程 |
1 | @startuml component |
更多图形参考https://plantuml.com/zh/
1 | graph TB |
1 | sequenceDiagram |
1 | gantt |
1 | { |
1 | X: 24 |
1 | digraph finite_state_machine { |
1 | st=>start: Start |
支持 v.qq.com,youtube.com,youku.com,coub.com,facebook.com/video,dailymotion.com,.mp4,.m4v,.ogg,.ogv,.webm,.mp3,.wav 链接解析
https://v.qq.com/x/cover/zf2z0xpqcculhcz/y0016tj0qvh.html
这里是一个脚注引用^1,这里是另一个脚注引用^bignote。
缩进对齐的段落包含在这个脚注定义内。1
可以使用代码块。
还有其他行级排版语法,比如**加粗**和[链接](https://b3log.org)。
1 | 这里是一个脚注引用[^1],这里是另一个脚注引用[^bignote]。 |
可以使用代码块。1
2
还有其他行级排版语法,比如**加粗**和[链接](https://b3log.org)。
我们的编辑器支持很多快捷键,具体请参考 键盘快捷键
]]>1 | <textarea> |
<: < <
>: > >
이것은 Markdown 타이포그래피를 올바르게 사용하는 방법의 예입니다. 이를 배우면 글을 보다 선명하고 명료하게 작성하는 데 도움이 됩니다.
인용 텍스트: 마크 다운은 텍스트 서식 구문에서 영감을 얻은 것입니다.
이 컨텐츠는 다음과 같은 컨텐츠의 일부 활자체 형식을 보여줍니다.
**굵게**
*기울임꼴*
~~취소선 ~~
코드 태그
- ``코드 태그``
[하이퍼 링크](https://www.google.com "구글")
[username@gmail.com](mailto:username@gmail.com)
@Vanessa는 @User
를 통해 컨텐츠에서 사용자를 언급할 수 있으며 언급된 사용자에게 시스템에 의해 통지됩니다.
참고 :
- @username 뒤에 공백이 필요합니다
- 초보자에게는 @의 기능 권한이 없습니다.
대부분의 표준 이모티콘을 지원합니다. 입력 방법을 사용하여 직접 입력하거나 문자 형식을 수동으로 입력 할 수 있습니다. :
를 입력하여 자동 완성을 시작하며, 개인 설정에서 이모티콘 설정을 미리 등록 해 놓을 수 있습니다.
:smile: :laughing: :dizzy_face: :sob: :cold_sweat: :sweat_smile: :cry: :triumph: :heart_eyes: :relieved:
:+1: :-1: :100: :clap: :bell: :gift: :question: :bomb: :heart: :coffee: :cyclone: :bow: :kiss: :pray: :anger:
H1 ~ H6을 사용하도록 선택하고 ##(N)로 시작할 수 있습니다. 게시물 또는 답글의 최상위 제목에는 제목 3을 사용하는 것이 좋습니다. 제목1은 시스템 사이트 수준이고 제목2는 게시물 제목 수준이므로 1 또는 2는 사용하지 마십시오.
참고: # 뒤에 공백이 필요하다는 것을 잊지 마십시오!
1 | ![alt text](http://image-path.png) |
직접 복사하여 붙여 넣기 및 업로드를 지원합니다.
1 | *emphasize* **strong** |
``` 다음에 언어 이름을 따르는 경우 다음과 같이 구문 강조 효과가 나타날 수 있습니다.
1 | package main |
1 | public class HelloWorld { |
팁: 언어 이름은 다음을 지원합니다:
ruby
,python
,js
,html
,erb
,css
,coffee
,bash
,json
,yml
,xml
…
참조
데이터 또는 무언가를 표시해야하는 경우 테이블을 사용하도록 선택할 수 있습니다.
헤더 1 | 헤더 2 |
---|---|
셀 1 | 셀 2 |
셀 3 | 셀 4 |
셀 5 | 셀 6 |
자세한 내용은 다음과 같습니다.
빈 줄을 사용하면 쉽게 읽을 수 있도록 컨텐츠를 분할 할 수 있습니다. (이것은 첫 번째 단락입니다)
마크 다운 타이포그래피에서 빈 줄을 사용하는 것이 중요합니다. (이것은 두 번째 단락입니다)
1 | [링크 텍스트][링크 참조] |
여러 줄 수식 블록:
인라인 공식:
공식 는 인라인입니다.
1 | - 가이드 |
1 | graph TB |
1 | sequenceDiagram |
1 | gantt |
1 | { |
1 | X: 1 |
1 | digraph finite_state_machine { |
youtube.com
v.qq.com,youku.com,coub.com,facebook.com/video,dailymotion.com,.mp4,.m4v,.ogg,.ogv,.webm,.mp3,.wav 링크 지원 파싱
https://www.youtube.com/watch?v=S4xoOW4DVKE
각주 참조[^1], 다른 각주 참조[^bignote]가 있습니다.
[^1]: 첫 번째 각주 정의.
[^bignote]: 각주 정의는 여러 단락을 사용할 수 있습니다.
들여 쓰기 및 정렬된 단락이 이 각주 정의에 포함됩니다.1
코드 블록을 사용할 수 있습니다.
**굵게** 및 [링크](https://b3log.org)와 같은 다른 줄 수준의 타이포그래피 문법이 있습니다.
1 | 각주 참조[^1], 다른 각주 참조[^bignote]가 있습니다. |
코드 블록을 사용할 수 있습니다.1
2
**굵게** 및 [링크](https://b3log.org)와 같은 다른 줄 수준의 타이포그래피 문법이 있습니다.
우리 편집기는 많은 단축키를 지원합니다. 자세한 내용은 키보드 단축키를 참조하십시오 (또는 툴바의 “?
” 누르세요 ?).