NOIP 2017 模拟
11 6
T1:
题目:
点击回复即可查看
——正解思路:
基础数据结构体,队列操作。
——我的乱搞:
诶WC,第一反应是数论,,然后推了很久很久,,最后果断 bitset 大暴力DP。
——tips:
真的勇士,敢于直面惨淡的数学,敢于正视淋漓的暴力,这是怎样的数据结构才可以AK这道题啊啊??反正我不造。
——满载悲伤的代码:
uses math;
var
t1, t2 : int64;
c, a, n, t, e, s : longint;
q : array [0..1000010] of int64;
begin
repeat
read (a, n);
c := 2;
q[1] := a;
e := 1;
s := 1;
while c <= n do begin
t1 := q[e] * 2 + 1;
t2 := q[s] * 3 + 1;
if t1 < t2 then inc (e)
else inc (s);
t := min (t1, t2);
if t = q[c - 1] then continue;
q[c] := t;
inc (c);
end;
if q[n] <> 0 then writeln (q[n]);
until eof;
end.
T2:
题目:
点击回复即可查看
——正解思路:
二分答案。
——我的乱搞:
暴力 sort。
——tips:
辣鸡出题人,卡老衲Pascal!!!
满载悲伤的代码:
#pragma GCC optimize("O3")
#include
#include
#include
using namespace std;
int n, m, l, r, ans;
int h[1000010], c[1000010], cnt[1000010];
inline void read(int &x) {
register char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
}
inline bool check (int m) {
memset (cnt, 0, sizeof (cnt));
int sum = 0, val = 0;
for (register int i = 1; i <= m; ++i) {
if (c[i] > n) return false;
++cnt[c[i]];
sum += c[i];
}
for (register int i = n; i >= 1; --i) cnt[i] += cnt[i + 1];
for (register int i = 1; i <= n; ++i) {
val += min(h[i], cnt[i]);
if (h[i] < cnt[i]) cnt[i + 1] += cnt[i] - h[i];
}
return val == sum;
}
int main () {
read(n), read(m);
for (register int i = 1; i <= n; ++i) read(h[i]);
for (register int i = 1; i <= m; ++i) read(c[i]);
sort(h + 1, h + 1 + n);
for (register int i = 1; i <= n >> 1; ++i) swap(h[n - i + 1], h[i]);
r = m;
while (l <= r) {
m = l + r >> 1;
check(m) ? ans = m, l = 1 + m : r = m - 1;
}
printf ("%d\n", ans);
return 0;
}
uses math;
var
n, m, l, r, i, ans : longint;
h, c, cnt : array [0..1000010] of longint;
procedure sort (l, r : longint);
var i, j, x : longint;
begin
if l < r then begin
i := l;
j := r;
x := h[i];
while i < j do begin
while (i < j) and (h[j] > x) do dec (j);
if i < j then begin
h[i] := h[j];
inc (i);
end;
while (i < j) and (h[i] < x) do inc (i);
if i < j then begin
h[j] := h[i];
dec (j);
end;
end;
h[i] := x;
sort (l, i - 1);
sort (i + 1, r);
end;
end;
function check (m : longint) : boolean;
var i, sum, val : longint;
begin
fillchar (cnt, sizeof (cnt), 0);
sum := 0;
for i := 1 to m do begin
if c[i] > n then exit (false);
inc (cnt[c[i]]);
inc (sum, c[i]);
end;
for i := n downto 1 do inc (cnt[i], cnt[i + 1]);
val := 0;
for i := 1 to n do begin
inc (val, min (h[i], cnt[i]));
if h[i] < cnt[i] then inc (cnt[i + 1], cnt[i] - h[i]);
end;
exit (val = sum);
end;
begin
read (n, m);
for i := 1 to n do read (h[i]);
for i := 1 to m do read (c[i]);
sort (0, n);
r := m;
for i := 1 to n div 2 do begin
m := h[i];
h[i] := h[n - i + 1];
h[n - i + 1] := m;
end;
while l <= r do begin
m := (l + r) div 2;
if check (m) then begin
ans := m;
l := 1 + m;
end
else r := m - 1;
end;
write (ans);
end.
T3:
题目:
点击回复即可查看
——正解思路:
splay (WC,这是NOIP模拟嚒??!!)
——我的乱搞:
我可以说我连克鲁斯卡尔都忘了嚒。。。。。
——tips:
出题人这么阴险,我能怎么办???
满载悲伤的代码:
#pragma GCC optimize("O3")
#include
#include
#include
#define GetTree(e, t) \
for (register int i = 1; i <= n; ++i) father[i] = i;\
sort (e + 1, e + 1 + t);\
for (register int i = 1, u = 0; i <= t; ++i) {\
int fx = getfather(e[i].x), fy = getfather(e[i].y);\
if (fx == fy) continue;\
father[fx] = fy;\
e[++u] = e[i];\
}
#define down(x) \
if (tree[x].b) {\
swap(tree[x].s[0], tree[x].s[1]);\
tree[tree[x].s[0]].b ^= 1;\
tree[tree[x].s[1]].b ^= 1;\
tree[x].b = 0;\
}
#define MakeRoot(x) \
Access(x), Splay(x), tree[x].b ^= 1
#define merge(x, y) \
tree[x].s[1] = y, update(x)
using namespace std;
struct node {
bool b;
int id, val, s[2];
}tree[200020];
struct edge {
int x, y, k;
inline friend bool operator < (const edge &a, const edge &b) {
return a.k < b.k;
}
}e0[200020], e1[200020];
struct query {
int v, id;
inline friend bool operator < (const query &a, const query &b) {
return a.v < b.v;
}
}qry[100010];
const int inf = 1 << 30;
int n, a, b, q, k;
int value[200020], fatree[200010], father[100010], stack[100010], key[100010];
long long ans[100010];
namespace stream {
inline char read () {
static const int IN_LEN = 20;
static char buf[IN_LEN], *s, *t;
s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin) : 0;
return s == t ? -1 : *s++;
}
template
inline bool read (T &x) {
static char c;
static bool iosig;
for (c = read(), iosig = false; !isdigit(c); c = read()) {
if (c == -1) return false;
c == '-' ? iosig = true : 0;
}
for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
iosig ? x = -x : 0;
return true;
}
inline void read (char &c) {
while (c = read(), isspace(c) && c != -1);
}
inline int read (char *buf) {
register int s = 0;
register char c;
while (c = read(), isspace(c) && c != -1);
if (c == -1) {
*buf = 0;
return -1;
}
do buf[s++] = c;
while (c = read(), !isspace(c) && c != -1);
buf[s] = 0;
return s;
}
const int OUT_LEN = 20;
char obuf[OUT_LEN], *oh = obuf;
inline void print (char c) {
oh == obuf + OUT_LEN ? (fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf) : 0;
*oh++ = c;
}
template
inline void print (T x) {
static int buf[20], cnt;
if (x == 0) print('0');
else {
x < 0 ? (print ('-'), x = -x) : 0;
for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
while (cnt) print ((char) buf[cnt--]);
}
}
inline void print (const char *s) {
for (; *s; s++) print(*s);
}
inline void flush() {fwrite (obuf, 1, oh - obuf, stdout);}
struct InputStream {
template
inline InputStream &operator >> (T &x) {
read (x);
return *this;
}
} in;
struct OutputStream {
template
inline OutputStream &operator << (const T &x) {
print (x);
return *this;
}
~OutputStream() {flush();}
} out;
}
using stream::in;
using stream::out;
inline int getfather (int x) {
return father[x] == x ? x : father[x] = getfather(father[x]);
}
inline int judge(int x) {
return x == tree[fatree[x]].s[0] ? 0 : x == tree[fatree[x]].s[1] ? 1 : -1;
}
inline void update(int x) {
tree[x].val = value[x], tree[x].id = x;
if (tree[x].s[0] and tree[tree[x].s[0]].val > tree[x].val) tree[x].val = tree[tree[x].s[0]].val, tree[x].id = tree[tree[x].s[0]].id;
if (tree[x].s[1] and tree[tree[x].s[1]].val > tree[x].val) tree[x].val = tree[tree[x].s[1]].val, tree[x].id = tree[tree[x].s[1]].id;
}
inline void rotate(int x) {
int y = fatree[x], z = fatree[y], tx = judge(x), ty = judge(y);
if (ty != -1) tree[z].s[ty] = x;
fatree[x] = z;
if (tree[x].s[tx ^ 1]) fatree[tree[x].s[tx ^ 1]] = y;
tree[y].s[tx] = tree[x].s[tx ^ 1];
tree[x].s[tx ^ 1] = y;
fatree[y] = x;
update(y);
update(x);
if (ty != -1) update(z);
}
inline void clear(int x) {
register int tp = 0;
for (; judge(x) != -1; x = fatree[x]) stack[++tp] = x;
stack[++tp] = x;
for (int i = tp; i >= 1; --i) down(stack[i])
}
inline void Splay(int x) {
clear(x);
while (judge(x) != -1) {
if (judge(fatree[x]) != -1) rotate(judge(x) == judge(fatree[x]) ? fatree[x] : x);
rotate(x);
}
}
inline void Split(int x) {
down(x)
if (!tree[x].s[1]) return;
tree[x].s[1] = 0;
update(x);
}
inline void Access(int x) {
Splay(x);
Split(x);
for (; fatree[x]; x = fatree[x]) {
Splay(fatree[x]);
Split(fatree[x]);
merge(fatree[x], x);
}
}
int main () {
in>>n>>a>>b>>q;
for (register int i = 1; i <= a; ++i) in>>e0[i].x>>e0[i].y>>e0[i].k;
for (register int i = 1; i <= b; ++i) in>>e1[i].x>>e1[i].y>>e1[i].k;
GetTree (e0, a)
GetTree (e1, b)
for (register int i = 1; i <= n; ++i) tree[i].val = value[i] = -inf, tree[i].id = i;
long long now = 0;
for (register int i = 1; i < n ; ++i) {
int x = e0[i].x, y = e0[i].y;
MakeRoot(x);
MakeRoot(y);
Splay(x);
Splay(y);
fatree[x] = fatree[y] = n + i;
tree[n + i].val = value[n + i] = e0[i].k;
tree[n + i].id = i;
now += e0[i].k;
}
for (register int i = 1; i < n ; ++i) {
int x = e1[i].x, y = e1[i].y;
MakeRoot(x);
Access(y);
Splay(y);
int t = tree[y].id;
if (value[t] == -inf) continue;
Splay(t);
key[++k] = e1[i].k - value[t];
fatree[tree[t].s[0]] = fatree[tree[t].s[1]] = 0;
MakeRoot(x);
MakeRoot(y);
fatree[y] = x;
}
for (register int i = 1; i <= q; ++i) in>>qry[i].v, qry[i].id = i;
sort(qry + 1, qry + 1 + q);
sort(key + 1, key + 1 + k);
register int w = 1;
for (register int i = 1; i <= q; ++i) {
while (w <= k and key[w] <= qry[i].v << 1) now += key[w++];
ans[qry[i].id] = now + 1ll * qry[i].v * (n - 1 - (w - 1) * 2);
}
for (register int i = 1; i <= q; ++i) out<