BZOJ1079 [SCOI2008]着色方案

<div class="post_brief"><p> 看上去比较不可做的DP。好像别人写的记搜跑得飞快。</p>   我看我是写最小表示写上瘾了。   压一下状态,有点像今天第二题。算每种值的有多少。然后直接跑。   感觉废状态比较多啊,跑得好慢。另外用memset清空高维数组会比较快。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int mod = 1e9 + 7; const int maxn = 17; const int maxst = 16009; #define mbit(a,b) ((a)<<((b)<<2)) #define gbit(a,b) (((a)>>((b)<<2))&0xf) #define _l (long long int) int m, c[maxn], n, mt, tots, slst[maxst]; int f[2][7][maxst]; void dfsState(int t, int l, int v) { if (l == mt + 1) { slst[tots ++] = v | t; } else { for (int i = 0; i <= t; ++ i) dfsState(t - i, l + 1, v | mbit(i, l)); } }...

March 2, 2015 · 2 min · laekov

BZOJ2770 YY的Treap

<div class="post_brief"><p> 今天考试题的弱化版。只用求LCA是谁,不用求它的深度。所以直接用线段树找下区间最值就搞定了。然后long的范围有负数坑了一发。</p>   好像在不平衡的平衡树上的题也比较热啊。而且我还做得比较少。是要补一补。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef pair <int, int> vpr; typedef pair <bool, vpr> dpr; struct seg { int l, r; dpr d; seg *ls, *rs; }; struct query { int t, a, b; }; const int maxn = 400009; int n, m, vl[maxn], tv; vpr a[maxn]; query q[maxn]; seg slst[maxn * 3], *sp(slst), *rt; inline int gpos(int x) { return lower_bound(vl, vl + tv, x) - vl; }...

March 2, 2015 · 2 min · laekov

BZOJ1187 [HNOI2007]神奇游乐园

<div class="post_brief"><p> 我的第二道插头DP。差不多纠结了一天。</p>   这道题网上的题解都讲的好简略啊。最后还得自己yy。没有用括号序列法让我觉得自己比较厉害。   考虑轮廓线上的m个格子,有3种情况:没有插头,有且只能往一边走,有且要往两边走。对于第二种,要用最多3个不同的值来记录连通性。还要有两个不同的值来表示第一种情况和第三种情况。我比较懒,所以直接用一个八进制数去表示,然后每次二分找编号。   考虑转移,分一堆情况进行讨论。默认从左上朝右下走。   首先是要走当前格子的情况。   如果左边和上面都有插头,那么看它们是否连通。如果不连通则把它们连通,如果已经连通,看是否还有其它插头。没有就更新答案,否则忽略。   如果只有左边有插头,再分类。如果它是第二种,那么这个格子可以新建一个第三种插头,或者把左边格子的插头接过来。如果它是第三种那么它必需把左边格子接过来。   如果只有上面有插头,那么必需把上面的插头接上来。   如果左边和上面都没有插头,那么可以新建一个第三种插头。   然后如果不走这个格子的话,要求上面没有插头,且左边不是第三种插头。   按mhy的话说,插头dp就是写起来很麻烦。的确。不过写出来也还是挺高兴的。   然后代码丑到不能看了。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 109; const int maxm = 9; const int maxst = 50009; const int inf = 0x3f3f3f3f; #define pow8(x) (1<<(x)<<(x)<<(x)) #define mbit(x,y) ((x)<<(y)<<(y)<<(y)) #define gbit(x,y) (((x)>>(y)>>(y)>>(y))&7) int f[2][maxst], n, m, a[maxn][maxm], ans; int slst[maxst], tots;...

March 1, 2015 · 4 min · laekov

BZOJ3438 小M的作物

<div class="post_brief"><p> 我以为是最大权闭合子图来着。然后好像就直接最小割就行了吧。突然觉得我的网络流好弱。</p>   建源汇,分别连每个作物。对于每个组合建两个点分别边源汇,然后中间像源汇一样连它的成员。如果全在一边,那么会有一条边不用割。这也是一个集合都选对答案有贡献的建图方式。   然后就完了。建图和dinic都写得有些丑,所以调了半天。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct edge { int t, c; edge *next, *rv; }; const int maxn = 3009; const int inf = 0x3f3f3f3f; int n, m, c, d[maxn], t, st, te; edge *head[maxn]; inline edge* newEdge(int u, int v, int c) { edge* e(new edge); e-> t = v; e-> c = c; e-> next = head[u]; return head[u] = e; } inline void addEdge(int u, int v, int c) { edge *a(newEdge(u, v, c)), *b(newEdge(v, u, 0)); a-> rv = b; b-> rv = a; }...

March 1, 2015 · 2 min · laekov

BZOJ3888 [Usaco2015 Jan]Stampede

<div class="post_brief"><p> usaco的银组都开始考这种题了么。其实还是挺水的,不过题号比较好。</p>   就按y排序,挨个把时间轴上的东西扔掉就完了。写离散可能还没有直接写smt快呢。   然后线段有一边要减1有点坑。   #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; typedef long long dint; #define _l (long long int) struct cow { int y; int ta, tb; }; struct node { int l, r, w; node ls, rs; }; typedef pair <node, node > npr; const int maxn = 50009; inline bool operator <(const cow& a, const cow& b) { return a....

March 1, 2015 · 2 min · laekov

BZOJ1455 罗马游戏

<div class="post_brief"><p> 左偏树+并查集的一眼题嘛。然后合并的时候搞忘了如果两个人已经在同一个团里要跳过,于是左偏树自交去了。</p>   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define szof(p) ((p)?(p->sz):0) struct node { int sz, vl, id; node *ls, rs; node() {} node(int v, int i) { vl = v; id = i; sz = 1; ls = rs = 0; } inline void update() { if (szof(ls) < szof(rs)) swap(ls, rs); } }; node merge(node p, node q) { if (!p) return q; else if (!...

February 26, 2015 · 2 min · laekov

BZOJ1295 [SCOI2009]最长距离

<div class="post_brief"><p> 多老的省选题了。</p>   就处理一下任意两个格子之间最少要经过几个1,如果小于等于t就更新答案。   #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; #define mkword(x,y) (((x)<<16)|(y)) #define hiword(x) ((x)>>16) #define loword(x) ((x)&0x0000ffff) const int maxn = 33; const int maxnd = 909; const int movx[4] = {0, 0, 1, -1}; const int movy[4] = {1, -1, 0, 0}; typedef pair <int, int> dpr; inline int sqr(int x) { return x * x; } int n, m, t, d[maxn][maxn], ans; int mp[maxn][maxn]; dpr hp[maxnd << 2];...

February 25, 2015 · 2 min · laekov

BZOJ3757 苹果树

<div class="post_brief"><p> 今天晚上的效率比白天高啊。</p>   树上莫队的另一道题。比糖果公园好写到哪里去了。   然后手写链表丑掉了导致调试半天+RE了一发。我还是太年轻了。   #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; typedef struct node { int t; node *next; } edge; const int maxn = 50009; const int maxm = 100009; const int maxl = 17; node nlst[maxn], *np(nlst); struct chain { int sz; node *hd, *tl; chain() { hd = tl = 0; sz = 0; } inline void clear() { hd = tl = 0; sz = 0; } inline void push(int x) { np-> t = x; np-> next = 0; if (sz) { tl-> next = np; tl = np; } else { hd = np; tl = np; } ++ np; ++ sz; } inline void merge(chain a) { if (a....

February 25, 2015 · 4 min · laekov

BZOJ1415 [Noi2005]聪聪和可可

<div class="post_brief"><p> 最近很颓啊。</p>   这题很久之前看过。当时以为是高消就没管。然后开坑之神idy做了之后仔细一想才知道不是。   这题的做法是dp。首先因为边数少所以不用floyd,直接bfs预处理出所有t[i][j]表狼在i,兔子在j的时候狼下一步去哪。然后有一个结论是每一步两个玩意的距离至少缩短1,所以状态是不会有环的,这也是为啥可以不用高消。然后坑点是不能直接开状态队列,因为那不是拓补序。要先把每个点的入度算出来再跑dp。结局是我的代码超长。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct edge { int t; edge *next; }; #define mkword(x,y) (((x)<<16)|(y)) #define hiword(x) ((x)>>16) #define loword(x) ((x)&0x0000ffff) const int maxn = 1009; const int maxst = 1000009; const int inf = 0x3f3f3f3f; int n, m, st, te, deg[maxn], d[maxn], t[maxn][maxn], ind[maxn][maxn]; edge elst[maxn << 1], *ep(elst), *head[maxn]; double f[maxn][maxn], g[maxn][maxn], c[maxn], ans;...

February 25, 2015 · 3 min · laekov

BZOJ3052 [wc2013]糖果公园

<div class="post_brief"><p> 盯idy发现的题,之前想学然后放弃了,于是今天几乎写了一天。有种紧迫感啊。然后发现好多认识的人都是最近过的。</p>   思路比较简单,树上莫队。因为要修改,所以要把块的大小变成n2/3,然后用1086的方法分块。好像也可以直接按dfs序分块。两个端点和时间为三个关键字跑莫队。复杂度可以感受一下反正我也不会证。   要注意千万要控制LCA的用量,必需只能是O(n)级别的。在爬树的时候必需O(1)。我就是在移动时间的时候不小心手贱每次用一遍LCA,然后去检查在移动端点花了好久的时间。   比较不开心的是发现mac没法改栈空间?有两个点始终暴栈。而且拿另一台电脑的openSUSE跑,结果发现它的cpu没有mac好,跑得还比mac快!我猜是操作系统在捣鬼。mac还是比较坑啊不开心。然后在bzoj上跑的时间几乎是本地的5倍也是比较厉害啊。   #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100009; const int maxl = 19; typedef struct node { int t; node *next; } edge; node nlst[maxn], *np(nlst); struct chain { int sz; node *hd, *tl; chain() { hd = tl = 0; sz = 0; } inline void clear() { hd = tl = 0; sz = 0; } inline void push(int x) { np-> t = x; np-> next = 0; if (sz) { tl-> next = np; tl = np; } else { hd = np; tl = np; } ++ np; ++ sz; } inline void merge(chain a) { sz += a....

February 25, 2015 · 6 min · laekov