Codeforces Round 316 D. Tree Requests 树剥分
题意:
给一颗包含n个节点的树。每个节点上都有一个小写字母。现在给节点v和深度h,求节点v子树的深度为h的点上的字符能否组成回文。
链接:http://codeforces.com/contest/570/problem/D
我的做法:对所有点都重编号,使得同一层的点都是连续的(按层次重编号),然后记录每一层的26个字母出现的次数,对于每个查询u,h,找u下深度为h的左右端点,明显可知道如果字母出现次数为奇数的出现一次以上一定不能组成回文。。
tips:写完后发现根本不用树状数组啊。直接求前缀和就行。。。
tips2:这里有一个优化,只需要求异或和就行了,我们只在意奇偶并不在意具体数量。
tips3:这里还有一个优化,用一个int就可以存下了,因为只有26个字母。
代码:
//author: CHC//First Edit Time: 2015-08-14 12:02#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <se ...
zoj 3820 求三遍树的中心
题意:给一颗节点数>=2的树,在树上标记两个点,使得所有点到离它最近的点的最大距离最小。
这题需要了解树的直径以及树的中心这两个概念
树的中心是树上所有点到这个点的最大距离最小
树的直径是树的最长链
我的做法是,先找到树的中心,如果中心有两个(树的中心一定不会大于2个),就劈成两个子树,求两个子树的中心
如果树的中心有一个,就劈开直径上一条边,拆成两颗子树,求这两棵子树的中心。
代码复用性比较挫。。一份个代码写了6遍。。
代码:
//author: CHC//First Edit Time: 2015-08-15 09:45#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#inclu ...
【算法】米勒拉宾素数测试
http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646396.htmlhttp://www.cnblogs.com/xiaohongmao/archive/2012/06/01/2531212.htmlhttp://www.cnblogs.com/skyivben/archive/2010/07/10/1775001.html
hdu 5379 Mahjong tree dfs
题意:在一棵树上给所有点标号,要求任意一个子树里的点编号连续,每一个点的儿子编号连续。
分析:考虑到一个连续的序列[l,r],如果这颗子树有超过3个非叶子儿子,那么一定是无解的。因为对于一个连续序列[l,r]最多可以分配给两个非叶子节点。分别是l和r,[l+1,r-1]这些可以随意分配给叶子节点。
考虑到这一点其实问题就可以简化了
对于每一个节点。
如果确定[l,r]是分配到以这个节点为根的子树,只有两种情况,分别是:l分配给该节点或者r分配给该节点,除此以外别无选择。
这样一来就很简单了。
假设以该节点为根的子树中,叶子儿子数为S,所有儿子方案的乘积记为T,
1.当非叶子儿子数等于0的时候,那么有两种分配方式(分配l或者r),因次该点方案数为2 * T * S!
2.当非叶子儿子数等于1的时候,那么也有两种分配方式(分配l或者r),因此该点方案数为2 * T * S!
3.当非叶子儿子数等于2的时候,那么也有两种分配方式(分配l或者r),但是发现这样会算重,把[l1,r1][l_1,r_1][l1,r1]分配给其中一个非叶子儿子,那么叶子儿子上的点是不能改变的,但是非叶子儿子处理 ...
C++/G++ 手动扩栈
C++/G++ 手动扩栈
http://blog.csdn.net/fcxxzux/article/details/40053937
//hdu g似乎现在无法扩栈啊?
g:
int size = 256 << 20; // 256MB char *p = (char*)malloc(size) + size; __asm__("movl %0, %%esp\n" :: "r"(p));
c++:
#pragma comment(linker, "/STACK:102400000,102400000")
BestCoder Round 48 (hdu 5284、hdu 5285)
1001
模拟
//author: CHC//First Edit Time: 2015-07-18 19:39#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=3145728+1000;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();char strs1[MAXN],strs2[MAXN ...
HDU 4747 Mex 区间更新
题意:给一个长度为n的数组a[n],然后定义mex[l,r]为[l,r]这个区间内最小的非负整数,然后求sum(mex[l,r])(1<=l<=r<=n)
先求出mex[1,1]~mex[1,n]的值,然后枚举删掉a[i]后的变化
首先可以知道mex[1,1]~mex[1,n]为非递减的
如果删掉a[1],那么mex[2,2]~mex[2,n]的变化为,下一个a[1]出现前大于a[1]的都要变为a[1],又因为其是非递减的,所以可以找到第一个mex值大于a[i]的那个位置到下一个出现a[1]的位置之前的这段区间赋值为a[1],然后线段树求和就行了。
//author: CHC//First Edit Time: 2015-07-20 21:09#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#includ ...
FZU 2105 Digits Count 区间更新
题意:有四个操作
l r v,对于[l,r]区间内的所有数都和v按位且(a[i]=a[i]&v)
l r v,对于[l,r]区间内的所有数都和v按位或(a[i]=a[i]|v)
l r v,对于[l,r]区间内的所有数都和v按位异或(a[i]=a[i]^v)
l r,对于[l,r]区间内的数求和
但是数据很小,所有的数和被操作数都是4位的,所以只需要统计每一位的1的个数就行。
但是需要注意的地方
且操作:如果对应位为0,那么就是区间赋值为0
或操作:如果对应位为1,那么就是区间赋值为1
异或操作:若对应位为1,那么区间内1的数量变为0的数量,区间内的1和0的数量互换
假设且操作和异或操作为op1
假设异或操作为op2
op1和op2的操作顺序需要考虑:
若当前节点为op1、子节点为op1,那么无意义,op1直接覆盖
若当前节点为op1、子节点为op2,op1直接覆盖
若当前节点为op2、子节点为op1,那么子节点op1的结果影响op2,所以先把子节点的op1推向子节点的子节点
若当前节点为op2、子节点为op2,这种情况有点复杂,其实画画图就可以得出,某个节点更新两遍 ...
zoj 3299 Fall the Brick 离散化+区间更新+区间查询
离散化然后套线段树就行。
//author: CHC//First Edit Time: 2015-07-17 17:46#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=100000+5;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();#define lson L,mid,rt<&l ...
uva 12436 Rip Van Winkle's Code 区间更新区间查询
题意:
就是给4段代码,说这四段代码重复执行很多次,现在要求你实现这段代码。
long long data[250001];void A( int st, int nd ) { for( int i = st; i <= nd; i++ ) data[i] = data[i] + (i - st + 1);}void B( int st, int nd ) { for( int i = st; i <= nd; i++ ) data[i] = data[i] + (nd - i + 1);}void C( int st, int nd, int x ) { for( int i = st; i <= nd; i++ ) data[i] = x;}long long S( int st, int nd ) { long long res = 0; for( int i = st; i <= nd; i++ ) res += data[i]; return res;}
当然不能直接用这个 ...