總結——關於2017 11 6測試的分析總結

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 <fstream>
#include <cstring>
#include <algorithm>

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 <cstdio>
#include <cctype>
#include <algorithm>

#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 <typename T>
	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 <typename T>
	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 <typename T>
		inline InputStream &operator >> (T &x) {
			read (x);
			return *this;
		}
	} in;
	
	struct OutputStream {
		template <typename T>
		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<<ans[i]<<'\n';
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值