BZOJ2642 Pku3968 Jungle Outpost

<div class="post_brief"><p> 看mhy写了好几天了啊。然后研究了一下,居然过得比他早。</p>   首先敌人一定可以炸连续的一段。然后就是要看炸掉任意连续一段之后还有没有剩下的公共部分,既半平面交。   然后我yy出了一个半平面交的做法。找出一条基准直线,按方向顺时针方向排序。然后按照正常半平面交的方法根据栈顶两个元素和当前直线的位置关系判断是否需要退栈。然后当找到一条与基准直线的角度大于等于π的直线(直线是有向的,也可以说是成负角)且它把栈里退到只剩基准直线一条的时候,这些半平面没有交。否则这些半平面有交。   至于证明嘛,我也不会(挠头),毕竟是感受出来的。然后感觉这次代码写得比较漂亮,开心。   #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; inline double sqr(double x) { return x * x; } struct point { double x, y; inline point() {} inline point(double x0, double y0) { x = x0, y = y0; } inline void read() { scanf("%lf%lf", &x, &y); } }; struct vect { double x, y; inline vect() {} inline vect(double x0, double y0) { x = x0, y = y0; } inline vect(point a, point b) { x = b....

February 4, 2015 · 3 min · laekov

BZOJ1815 [Shoi2006]color 有色图

<div class="post_brief"><p> 一道burnside,做了几次之后感觉比较经典了。然后发现网上居然没有题解。</p>   枚举正整数拆分,既每个质换的长度。然后枚举gcd算每类置换的贡献。再用错排公式来算每类置换的数量。然后求和。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define _l (long long int) const int maxn = 63; int n, m, mod, ans, g[maxn][maxn]; int sq[maxn], tq, fac[maxn], finv[maxn], vinv[maxn]; int modPow(int a, int x) { int s(1); for (; x; x >>= 1, a = _l a * a % mod) if (x & 1) s = _l s * a % mod; return s; }...

February 4, 2015 · 2 min · laekov

BZOJ2401 陶陶的难题I

<div class="post_brief"><p> 推了半天,发现还是得sqrt,过不到啊。</p>   然后发现与经典的问题相比,就是n=n。然后这不是做过的那个LCM sum的前缀和就完了嘛。傻了。   然后第一次MLE是因为明明压了8位,还是开了30长的数组。第二次WA是因为高精输出的时候%08d写成了%8d。是不是明天又要逗极而死了。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long dint; #define _l (long long int) const int maxlen = 7; const dint base = 1e8; struct BigInt { dint dig[maxlen], len; BigInt() { len = 0; } void set(dint x) { dig[0] = x; len = 1; while (dig[len - 1] >= base) { dig[len] = dig[len - 1] / base; dig[len - 1] %= base; ++ len; } } void copy(const BigInt& x) { len = x....

February 1, 2015 · 2 min · laekov

BZOJ3435 [Wc2014]紫荆花之恋

想起去年在考场上完全没有思路不想写数据结构于是骗了30分。现在想想当初还是naive。   这题看上去就是点分治。因为要动态加点所以要动态。然后利用替罪羊树的方法重构树上的一团东西(不能叫团,否则命名重复了)。   本来以为要写很久,结果也没写多久。奇怪的是,把maintain展开到insert里面之后就跑得飞快了,否则过不到而且根本跑不下来9和10。又丑了郁闷。   #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> using namespace std; const int buf_len = 4000; const size_t buf_size = buf_len * sizeof(char); char buf[buf_len], *bufb(buf), *bufe(buf + 1); #define readBuf() { if (++ bufb == bufe) bufe = (bufb = buf) + fread(buf, 1, buf_size, stdin); } #define readInt(x) { register int s(0); do { readBuf(); } while (!isdigit(*bufb)); do { s = s * 10 + *bufb - 48; readBuf(); } while (isdigit(*bufb)); x = s; }...

February 1, 2015 · 6 min · laekov

BZOJ2653 middle

<div class="post_brief"><p> 老久之前就看到过的题,不过不会做。今天晚上也是花了差不多俩小时才调过,虽然大概一个半小时都在纠结二分怎么写的问题。我没救了。</p>   考虑经典的中位数二分,是把≤x的数字取-1,>x的数取1,然后算最大子串看是否大于-1或1中的某一个,具体要看题目要求偶数是取上整还是下整什么的。   然后这题就把所有东西排序之后拿可持久化线段树把这个序列搞出来,然后照着之前的思路二分就好了。线段树用来维护最大和最小前缀和。 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct dat { int sm, s; }; struct seg { int l, r; dat v[2]; seg *ls, *rs; }; #define _l (long long int) typedef pair <int, int> vpr; typedef dat(*dat_mf)(const dat&, const dat&); const int maxn = 20009; const int maxnd = maxn * 19; const dat null_str = {0, 0}; const dat neg_str0 = {-1, -1}; const dat neg_str1 = {-1, -1}; const dat pos_str0 = {1, 1}; const dat pos_str1 = {1, 1};...

January 29, 2015 · 3 min · laekov

BZOJ3351 [ioi2009]Regions

<div class="post_brief"><p> ioi的数据结构题,果然还是比较BT的。</p>   做法是对颜色分开,大的颜色预处理,小的颜色直接暴力。   然后一个小错又坑了好久。我真的没救了。 #include <cstdio> #include <cstdlib> #include <cctype> #include <cstring> #include <algorithm> using namespace std; const int buf_len = 4000; const size_t buf_size = buf_len * sizeof(char); char buf[buf_len], *bufb(buf), *bufe(buf + 1); #define readBuf() { if (++ bufb == bufe) bufe = (bufb = buf) + fread(buf, 1, buf_size, stdin); } #define readInt(x) { register int s(0); do { readBuf(); } while (!isdigit(*bufb)); do { s = s * 10 + *bufb - 48; readBuf(); } while (isdigit(*bufb)); x = s; }...

January 28, 2015 · 3 min · laekov

BZOJ1502 [NOI2005]月下柠檬树

<div class="post_brief"><p> 今天几乎讲了一天的算几。或者说能听的只有算几。然后就去做了一道基础题。</p>   刚开始的时候比较naive,把相交的情况想简单了,打算直接上数学,然后悲剧地发现还有其它的不好算交点的情况,于是就去写simpson了。   simpson就是一个估计用的,s = (4 * f(mid) + f(l) + f(r))*(r-l)/6。至于为啥是对的就不知道了。反正比较能用。然后每次直接去扫一遍所有能交的地方,取max就行了,比挨个算交点方便许多。   然后第一次写,代码也比较乱。 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int maxn = 509; const double pi = asin(1) * 2; const double eps = 1e-6; #define x1 x1 #define x2 x2 #define y1 y1 #define y2 y2 int n; double tht, x[maxn], h[maxn], r[maxn]; double crd[maxn]; double x1[maxn], x2[maxn], y1[maxn], y2[maxn]; bool c[maxn];...

January 27, 2015 · 3 min · laekov

BZOJ2816 [ZJOI2012]网络

<div class="post_brief"><p> 听说是水水的splay,果然是。</p>   乍一看要用lct,然后因为度数只有2,所以肯定是一条链。然后就直接用splay来维护。然后因为少写了句splay(v)导致多调了至少一节课的时间。我没救了。 #include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; #define upmax(a,b) { if (a < b) a = b; } struct splay_node { int vl, vm, rv; splay_node *pt, *ls, *rs; inline void update() { vm = vl; if (ls) upmax(vm, ls-> vm); if (rs) upmax(vm, rs-> vm); } inline void fix() { if (rv) { swap(ls, rs); if (ls) ls-> rv ^= 1; if (rs) rs-> rv ^= 1; rv = 0; } } };...

January 27, 2015 · 4 min · laekov

BZOJ3870 Our happy ending

<div class="post_brief"><p> 立杰出的题,orz。</p>   一个时间比较微妙的状压DP。用一个二进制状态表示0~k中哪些数已经可以被表示出来了,然后大于k的数直接乘,因为对状态不产生影响。 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define pow2(x) (1<<(x)) #define _l (long long int) const int maxn = 21; const int maxb = pow2(maxn) + 9; const int mod = 1e9 + 7; int n, k, l, f[2][maxb], zu, va; #define incm(a,b) { a += b; if (a >= mod) a %= mod; } int sov() { int prv(0), cur(1); memset(f, 0, sizeof(f)); va = max(0, l - k) + 1; zu = pow2(k + 1) - 1; f[cur][1] = 1; for (int ti = 0; ti < n; ++ ti) { swap(cur, prv); for (int i = zu; i; – i) f[cur][i] = 0; for (int i = zu; i; – i) if (f[prv][i]) { for (int j = 1; j <= k; ++ j) { int zn((i | (i << j)) & zu); incm(f[cur][zn], f[prv][i]); } incm(f[cur][i], _l f[prv][i] * va % mod); } } int ans(0); for (int i = zu, e = pow2(k); i >= e; – i) incm(ans, f[cur][i]); return ans; }...

January 27, 2015 · 1 min · laekov

BZOJ2815 [ZJOI2012]灾难

<div class="post_brief"><p> 灭绝树的模板题么。之前不知道这题,差点当原创题出出去了。</p>   好像有不少人不知道这东西的样子?orz zhx。   灭绝树只有一句口诀:一个东西的父亲是所有入边的另一端的点的LCA。 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct edge { int t; edge *next; }; const int maxn = 70009; const int maxl = 19; const int maxe = 2000009; int n, ind[maxn], oud[maxn], tpo[maxn], ath[maxn][maxl], sz[maxn], d[maxn]; edge *ha[maxn], *hr[maxn], *ht[maxn]; inline void addEdge(edge** head, int u, int v) { edge* ep = new edge; ep-> t = v; ep-> next = head[u]; head[u] = ep; }...

January 27, 2015 · 2 min · laekov