上一页 1 2 3 4 5 6 7 8 ··· 25 下一页
摘要: 给你最多1000个圆,问画一条直线最多能与几个圆相交,相切也算。显然临界条件是这条线是某两圆的公切线,最容易想到的就是每两两圆求出所有公切线,暴力判断一下。可惜圆有1000个,时间复杂度太高。网上题解的做法是枚举每个“中心圆”,求出这个圆与其他圆的切线,然后按极角排序,扫一圈。把每条切线看成扫入线——添加一个圆,或扫出线——删除一个圆。形象一点就是一条与中心圆相切的直线,沿着中心圆滚了一圈,当这个直线碰到其他圆时,是添加了一个圆还是删除了一个圆。PS:这题C++交死活TLE,G++才能交过。为什么为什么为什么orz……PS2:这题我之前少判了一种情况(就是那个A内含B的情况),导致fix调整角 阅读全文
posted @ 2013-10-04 11:37 冰鸮 阅读(850) 评论(0) 推荐(0)
摘要: 题意:给你一个数,每次把这个数尾巴上的一个数字放到前面来,问如此循环一遍形成的新的(不重复)数字中,大于,等于,小于原数字的数各有多少个。比如样例:341->134->413->341,小于、等于、大于的各有1个。这个串后面接上它本身,作为主串,原串作为模式串。显然这题就是要求出主串每个后缀与模式串的最长公共前缀,直接套扩展KMP模板即可。因为形成的新的数字必须不重复,因此还需要用KMP的next函数求一下最短循环节。#include #include #include #include using namespace std;const int MAXN = 2001000 阅读全文
posted @ 2013-10-03 17:32 冰鸮 阅读(388) 评论(0) 推荐(0)
摘要: 把所有的字符串连接起来,中间用一个未出现的字符分隔开,题意是求这个串的所有子串(中间不含分隔符)形成的数之和。把这个串加入SAM,对所有子串进行拓扑排序,从前往后统计。记录到达这个节点的路径个数cnt,以及到达这个节点的总和sum。设父节点是u,子节点是vsum[v] = sum[u] * 10 + sum[v] + cnt[v]*j;cnt[v] += cnt[u];ans就是把所有的sum加起来。注意:1.忽略前导零2.子串中不要含分隔符#include #include #include #include using namespace std;const int MAXN = 1001 阅读全文
posted @ 2013-10-02 19:21 冰鸮 阅读(307) 评论(0) 推荐(0)
摘要: 题意:问第二行的串能不能恰好分割成几个串,使得这几个串都是第一行串的前缀。如果是,输出No, 并输出这几个串,否则输出Yes。这题是Special Judge,把两个串连接起来,中间用一个未出现过的字符分隔开。从新串串尾开始,每次向前移动一个最大前缀的长度。如果期间遇到nextval值为0的点(即没有公共前缀),则肯定不行。记录分割点位置,输出结果。#include #include #include const int MAXN = 75010;char str[MAXN strL+1; ) { int tp = nextval[i]; ... 阅读全文
posted @ 2013-10-01 23:06 冰鸮 阅读(275) 评论(0) 推荐(0)
摘要: 问在第一个串中删掉几个字符能否得到第二个串。注意在第二个串中不连续的单词在第一个串中也必须不连续。一组数据:Input:abababbbbababbb aba abOutput:I HAVE FAILED!!!#include #include #include using namespace std;const int MAXN = 100100;char str[MAXN];char tmp[MAXN];int nextval[MAXN];int flag[MAXN];int strL, tmpL;void getNextval( char* s, int* nextval, int le 阅读全文
posted @ 2013-10-01 21:44 冰鸮 阅读(247) 评论(0) 推荐(0)
摘要: HDU 3746 Cyclic Nacklace ( KMP求最小循环节 )len - nextval[len]即为最小循环节长度。#include #include #include #include using namespace std;const int MAXN = 100100;const int INF = 1 #include #include #include using namespace std;const int MAXN = 1000010;char str[MAXN];int nextval[MAXN];int len;void getNext( char s[]. 阅读全文
posted @ 2013-09-29 21:04 冰鸮 阅读(318) 评论(0) 推荐(0)
摘要: dp[i]代表前i个字符组成的串中所有前缀出现的次数。dp[i] = dp[next[i]] + 1;因为next函数的含义是str[1]~str[ next[i] ]等于str[ len-next[i]+1 ]~str[len],即串的前缀后缀中最长的公共长度。对于串ababa,所有前缀为:a, ab,aba,abab, ababa, dp[3] = 3;到达dp[5]的时候,next = 3, 它与前面的最长公共前缀为aba,因此dp[5]的凑法应该加上dp[3],再+1是加上ababa它本身。说不太清楚……从感觉上比较类似于那个“给你几种面值的硬币,问凑出指定钱数的所有凑法”的dp方式。 阅读全文
posted @ 2013-09-29 14:40 冰鸮 阅读(224) 评论(0) 推荐(0)
摘要: 设串为str, 串长为len。对整个串求一遍next函数,从串结尾开始顺着next函数往前找#include #include #include using namespace std;const int MAXN = 1000100;char str[MAXN];char tmp[MAXN];int nextval[MAXN];int len;void GetNextVal( char *s, int lenth ){ int i = 0, j = -1; nextval[0] = -1; while ( i len/3 ) ans = nextval[ans]; ... 阅读全文
posted @ 2013-09-29 09:18 冰鸮 阅读(293) 评论(0) 推荐(0)
摘要: 一开始看的时候就想歪了,比赛的时候一直在YY线段树区间覆盖,然后纠结节点数太多开不下怎么办啊啊啊啊……然后昨天吃饭的时候也在纠结这到底是个啥题,后来发现公共前缀->前缀??!!!!->这不是很显然的Trie么……QAQ举例说明:对于subnet: 123.45.4.0/22,转化成二进制后,取前22位(长度由子网掩码决定)加入Trie树,后面的IP一定是0所以无意义,然后每个节点开一个vector保存能到达这个节点的所有子网的Pid,以及该子网IP的最大值。对于ip_src:查找它所属于的所有子网组的Pid,并标记出来。对于ip_dst:看它与ip_src所属的所有子网组的Pid跟 阅读全文
posted @ 2013-09-29 09:06 冰鸮 阅读(482) 评论(0) 推荐(0)
摘要: 按边从小到大排序。对于每条边(from, to, dist),如果from和to在同一个集合中,那么这条边无意义,因为之前肯定有比它更小的边连接了from和to。如果from和to不属于同一个集合,那么增加这条边后增加的点对数目是cnt[from]*cnt[to]*2( 因为(u, v)和(v, u)不算同一点对,所以*2 )统计出所有点对数total。对于查询,按t值从小到大排序,边从小到大一条一条往里加。tmpSum为f值小于t的点对总数。当边权大于等于t值时:ans[i] = total - tmpSum。当边权小于t值时,更新tmpSum。#include #include #incl 阅读全文
posted @ 2013-09-26 21:09 冰鸮 阅读(209) 评论(0) 推荐(0)
上一页 1 2 3 4 5 6 7 8 ··· 25 下一页