屯题?
BZOJ1635
傻逼题,差分一下。
#include <iostream>
#include <cstdio>
#include <vector>
#include <map>
const int MAXN = 10000;
using namespace std;
inline int read() {
int x = 0, w = 1; char c = ' ';
while (c < '0' || c > '9') {c = getchar(); if (c == '-') w = -1;}
while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * w;
}
map < pair <int , int>, bool > H;
int c[MAXN + 5], S[MAXN + 5];
int main() {
int n = read(), p = read(), h = read(), r = read(), tot = 0;
for (int i = 1; i <= r; ++i) {
int x = read(), y = read();
if (x > y) swap(x, y);
if (H.find(make_pair(x, y))->second) continue;
--c[x + 1], ++c[y];
H[make_pair(x, y)] = true;
}
for (int i = 1; i <= n; ++i) {
S[i] = S[i - 1] + c[i];
printf("%d\n", h + S[i]);
}
return 0;
}
POJ2018
\(二分+DP\),其实就是乱搞,用斜率优化的\(DP\)也可以做。挺裸的,就是精度有点毒。
#include <iostream>
#include <cstdio>
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a < b ? b : a)
const double INF = 1e10;
const int MAXN = 100000;
const double eps = 1e-5;
using namespace std;
int n, f;
double a[MAXN + 5], tmp[MAXN + 5], S[MAXN + 5], l = -1e6, r = 1e6;
inline bool check(double mid) {
for (int i = 1; i <= n; ++i)
tmp[i] = a[i] - mid, S[i] = S[i - 1] + tmp[i];
double minv = INF, ret = -INF;
for (int i = f; i <= n; ++i) {
minv = min(minv, S[i - f]);
ret = max(ret, S[i] - minv);
}
return ret >= 0;
}
int main() {
scanf("%d%d", &n, &f);
for (int i = 1; i <= n; ++i)
scanf("%lf", &a[i]);
while (r - l > eps) {
double mid = (l + r) / 2;
if (check(mid))
l = mid;
else
r = mid;
}
printf("%d\n", int(r * 1000));
return 0;
}
BZOJ2002
\(LCT\)好题(大雾),可能因为我太懒了,不想打分块。
这道题关键在于\(LCT\)要求节点的深度,随便\(PushUp\)一下就好了。
#include <iostream>
#include <cstdio>
#define ls ch[0]
#define rs ch[1]
#define lson s[x].ls
#define rson s[x].rs
#define father s[x].fa
const int MAXN = 200000;
using namespace std;
inline int read() {
int x = 0, w = 1; char c = ' ';
while (c < '0' || c > '9') {c = getchar(); if (c == '-') w = -1;}
while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * w;
}
struct Node {
int ch[2], fa, rev, sz;
};
class LCT {
public :
void PushDown(int x) {
if (s[x].rev) {
s[lson].rev ^= 1, s[rson].rev ^= 1, s[x].rev ^= 1;
swap(lson, rson);
}
}
void PushUp(int x) {
s[x].sz = s[lson].sz + s[rson].sz + 1;
}
bool IsRoot(int x);
void rotate(int x); void Splay(int x);
void access(int x); void MakeRoot(int x);
void link(int x, int y); void cut(int x, int y);
int query(int x, int y);
private :
Node s[MAXN + 5];
int top, ST[MAXN + 5];
}T;
bool LCT::IsRoot(int x) {
return s[father].ls != x && s[father].rs != x;
}
void LCT::rotate(int x) {
int y = father, z = s[y].fa, l, r;
if (s[y].ls == x) l = 0; else l = 1;
r = l ^ 1;
if (!IsRoot(y))
if (s[z].ls == y) s[z].ls = x; else s[z].rs = x;
father = z, s[y].fa = x, s[ s[x].ch[r] ].fa = y, s[y].ch[l] = s[x].ch[r], s[x].ch[r] = y;
PushUp(y), PushUp(x);
}
void LCT::Splay(int x) {
top = 0, ST[++top] = x;
for (int i = x; !IsRoot(i); i = s[i].fa) ST[++top] = s[i].fa;
for (int i = top; i; --i) PushDown(ST[i]);
while (!IsRoot(x)) {
int y = father, z = s[y].fa;
if (!IsRoot(y))
if (s[y].ls == x ^ s[z].ls == y) rotate(x); else rotate(y);
rotate(x);
}
}
void LCT::access(int x) {
for (int last = 0; x; last = x, x = father)
Splay(x), rson = last, PushUp(x);
}
void LCT::MakeRoot(int x) {
access(x), Splay(x), s[x].rev ^= 1;
}
void LCT::link(int x, int y) {
MakeRoot(x), father = y;
}
void LCT::cut(int x, int y) {
MakeRoot(x), access(y), Splay(y);
if (s[y].ls == x) s[y].ls = father = 0;
}
int LCT::query(int x, int y) {
MakeRoot(x), access(y), Splay(y);
return s[y].sz - 1;
}
int k[MAXN + 5];
int main() {
int n = read();
for (int i = 1; i <= n; ++i) {
k[i] = read(); int v = k[i] + i <= n ? k[i] + i : n + 1;
T.link(i, v);
}
int m = read();
for (int i = 1; i <= m; ++i) {
int opt = read(), u = read() + 1, v = u + k[u] <= n ? u + k[u] : n + 1, num;
switch(opt) {
case 1 : printf("%d\n", T.query(u, n + 1)); break;
case 2 : {
T.cut(u, v); num = read(), v = u + num <= n ? u + num : n + 1;
T.link(u, v), k[u] = num;
break;
}
}
}
return 0;
}