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

POJ2154 Color

<div class="post_brief"><p> 首先是burnside,对于旋转x下都要当作一个置换,所以总共有n个。然后第i个的不动点数量等于n<sup>gcd(n,i)</sup>,然后统计一下个数是phi(gcd(n,i))个。</p>   然后发现要用奇奇怪怪的东西来求phi。我用的方法是分解质因数然后DFS,跑得飞快。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define _l (long long int) const int maxn = 50009; int n, mod; int tp, pn[maxn], phi[maxn]; bool pr[maxn]; void pre() { memset(pr, 0, sizeof(pr)); tp = 0; phi[1] = 1; for (int i = 2; i < maxn; ++ i) { if (!pr[i]) { pn[tp ++] = i; phi[i] = i - 1; } for (int j = 0; j < tp && i * pn[j] < maxn; ++ j) { pr[i * pn[j]] = 1; if (i % pn[j] == 0) { phi[i * pn[j]] = phi[i] * pn[j]; break; } else phi[i * pn[j]] = phi[i] * phi[pn[j]]; } } }...

January 31, 2015 · 2 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

BZOJ3251 树上三角形

<div class="post_brief"><p> 原来在win下也有敲回车的bug。开心。</p>   这题坑啊。暴力还是很好想的,如果个数超过几十个的话就肯定有解了。比较坑的是两边之和大于第三边,边权231-1然后加起来就超过int的范围了。连WA若干次再见。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct edge { int t; edge *next; }; const int maxn = 100009; const int maxc = 88; int n, m, v[maxn], d[maxn], fa[maxn], c[maxc]; edge *head[maxn], elst[maxn << 1], *ep(elst); void bfs() { static int q[maxn]; int hd(0), tl(1); q[0] = 1; memset(d, 0, sizeof(d)); d[1] = 1; while (hd < tl) { int p(q[hd ++]); for (edge* e = head[p]; e; e = e-> next) if (!...

January 26, 2015 · 2 min · laekov

BZOJ2419 电阻

<div class="post_brief"><p> 记得这是高一的时候ty同学和我说的东西了。然后现在才解决,可以打败上帝造题的七分钟,荣登解决时间最长的题目了。</p>   其实也就是一个高斯消元,用电势来列方程。不过高斯消元写得不熟,平时有空都写ds的题去了。以后不能再这样了。   用自己的代码高亮脚本了,虽然还不完善不过还是很开心的。   #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; const int maxn = 109; const double inf = 1e100; const double eps = 1e-8; double x[maxn], a[maxn][maxn], b[maxn][maxn]; int n, m, perm[maxn]; int main() { #ifndef ONLINE_JUDGE freopen(“in.txt”, “r”, stdin); #endif srand(19970911); while (scanf("%d%d", &amp;n, &amp;m) != EOF) { for (int i = 1; i &lt;= n; ++ i) perm[i] = i; if (n &gt; 2) random_shuffle(perm + 2, perm + n); for (int i = 1; i &lt;= n; ++ i) for (int j = 1; j &lt;= n; ++ j) if (i == j) a[i][j] = 0; else a[i][j] = inf; while (m --) { int u, v; double p; scanf("%d%d%lf", &amp;u, &amp;v, &amp;p); u = perm[u]; v = perm[v]; if (u == v) continue; a[u][v] = 1....

January 25, 2015 · 2 min · laekov