2022.9.26———HZOI【CSP-S模拟12】游寄

Preface

好的今天是 Rank37/42

得分 25pts + 0pts + 0pts + 20pts = 48pts

+

建议去看kiritokazuto的博

T1:开挂,T2:叁仟柒佰万,T3:超级加倍,T4:欢乐豆

T1 

场切题写丑了。气的我直接开贺

T1
/*
#include <iostream>
#include <algorithm>
#include <set>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define int unsigned long long
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 1000005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
struct node{int ai, bi;};
/*
	这是个什么贪心捏。
	显然地,应当是数列递增。
	n 10^6我超
	我知道了
	但是不确定正确性
	大胆猜规律
	可以用bi交换。
	我不大会弄,因为是基于值域的
	看了一下似乎有68pts,如果这个贪心是对的话
	再想一下特殊性质也许可以更高
	大样例过了
	但是最大的那个值域太大我算法整不了
	所以现在写一下特殊性质A 
	哦哦然后忘记取模了(
	等会,傻b吧,对2^64取模
	这longlong开不下啊
	我改成ull得了,啥玩意
	性质A的分咋拿谔谔
	不行,,也是基于值域的。。
	我先开T2吧,有时间再回来
	希望这个贪心别fake
*//*
unsigned long long final_ans;
int n, nn;
int dis[N];
multiset<int> hav[N];
multiset<int> s;
struct node a[N];

inline bool comp1(node A, node B){return ((A.ai == B.ai) ? (A.bi < B.bi) : (A.ai < B.ai));}
inline bool comp2(int A, int B){return A > B;}

inline void work(){
	cin >> n;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i].ai;
	for (re i = 1 ; i <= n ; ++ i){
		cin >> a[i].bi;
	}
	int l, r;
	sort(a+1, a+n+1, comp1); nn = n << 1;
	for (re i = 1 ; i <= n ; ++ i)
		hav[a[i].ai].insert(i);
	/*for (re i = 1 ; i <= 10 ; ++ i)
		cerr << hav[i].size() << _;
	Dl;*//*
	l = a[1].ai, r = a[1].ai;
	for (; r <= nn ; ++ r){
		if (hav[r].size() == 0){
			while (hav[l].size() <= 1 and l < r)
				l ++;
			if (l == r)
				continue;
			dis[*hav[l].begin()] = r-l;
			hav[l].erase(hav[l].begin());
		}
	}
	/*for (re i = 1 ; i <= 10 ; ++ i)
		cerr << hav[i].size() << _;
	Dl;
	cerr << "dis ";
	for (re i = 1 ; i <= 10 ; ++ i)
		cerr << dis[i] << _;
	Dl;*//*
	for (re i = 1 ; i <= n ; ++ i)
		s.insert(a[i].bi);
	/*for (re i = 1 ; i <= n ; ++ i){
		if (dis[i] != 0)
			final_ans = final_ans + (long long)dis[i] * (*s.begin());
	}*//*
	sort(dis+1, dis+n+1, comp2);
	/*cerr << "dis ";
	for (re i = 1 ; i <= 10 ; ++ i)
		cerr << dis[i] << _;
	Dl;
	cerr << "s: ";
	for (auto it = s.begin() ; it != s.end() ; ++ it)
		cerr << *it << _;
	Dl;*//*
	for (re i = 1 ; i <= n ; ++ i){
		if (dis[i] == 0)
			break;
		// cerr << final_ans << _ << dis[i] << _ << (*s.begin()) << _ << dis[i] * (*s.begin()) << '\n';
		final_ans = final_ans + (unsigned long long)dis[i] * (*s.begin());
		s.erase(s.begin());
	}
	cout << final_ans << '\n';
	return ;
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}
*/
#include <iostream>
#include <algorithm>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 1000005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
struct Stack{int l, r, len;};
/*
	场切题写丑了
*/
int n, top;
unsigned long long final_ans;
int a[N], b[N], dis[N];
struct Stack s[N];

inline bool comp1(int A, int B){return A > B;}

inline void work(){
	cin >> n;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i];
	for (re i = 1 ; i <= n ; ++ i)
		cin >> b[i];
	sort(a+1, a+n+1); s[++ top] = (Stack){a[n], a[n], 1};
	for (re i = n ; i >= 1 ; -- i){
		if (a[i] == a[i+1])
			dis[++ dis[0]] = s[top].len, s[top].r ++, s[top].len ++;
		else 
			s[++ top] = (Stack){a[i], a[i], 1};
		while (top > 1 and s[top].r == s[top-1].l - 1)
			s[top-1].l = s[top].l, s[top-1].len += s[top].len, top --;
	}
	sort(b+1, b+n+1); sort(dis+1, dis+dis[0]+1, comp1);
	for (re i = 1 ; i <= dis[0] ; ++ i)
		final_ans = final_ans + (unsigned long long)b[i] * dis[i];
	cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}

T2 

题面说的那个 mex 就是 [1,n] 整个序列的 mex。浅证一下。

设题面说的那个 mexx,总序列的 mexy

首先 x 肯定不会大于 y。考虑 x<y 时是否成立。

image

假设你要选区间①的 mex 作为答案 mex(也就是 x),那么 x 这个数显然不会在区间①内出现。但是由于区间总 mex 不等于 x,所以 x 一定在其他区间内出现,这就意味着在总有一个区间他的 mex 不能为 x(可能比 x 小也可能比 x 大,但不会是 x)。

然后就证毕了。

啊对对对,你证了这个了,然后呢?

我不会!开贺!

T2
#include <iostream>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 37000005
#define P 1000000007
#define mod %
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
/*
	“mex是整个序列的mex”
	确实
	“记一个单调指针就可以达到线性了。”
	确实
	然后嘞
	我记f[i][0/1]在这个数不断开或断开一次,然后我咋转移嘞
*/
int T, n, mex;
int a[N], f[N], cnt[N];
inline void Clean(){memset(f, 0, sizeof(f)); memset(cnt, 0, sizeof(cnt));}

inline void work(){
	Clean();
	cin >> n;
	if (n == 37000000){
		a[1] = 0; cnt[0] = 1;
		int x, y; cin >> x >> y;
		for (re i = 2 ; i <= n ; ++ i)
			{a[i] = (((long long)a[i-1]*x + y + i) & 262143); cnt[a[i]] ++;}
	}
	else {
		for (re i = 1 ; i <= n ; ++ i)
			{cin >> a[i]; cnt[a[i]] ++;}
	}
	
	mex = 0;
	while (cnt[mex] != 0)
		mex ++;
	f[0] = 1; memset(cnt, 0, sizeof(cnt));
	
	for (re i = 1, l(1), mxs(0) ; i <= n ; ++ i){
		cnt[a[i]] ++;
		while (cnt[mxs] != 0)
			mxs ++;
		f[i] = f[i-1];
		if (mxs == mex){
			while ((a[l] > mex or cnt[a[l]] > 1) and l < i)
				cnt[a[l]] --, l ++;
			f[i] = ((long long)f[i] + f[l-1]) mod P;
		}
	}
	cout << (f[n]-f[n-1]+P) mod P << '\n';
	/*Clean();
	cin >> n;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i];
	for (re i = 1, ans ; i <= n ; ++ i){
		cnt[a[i]] ++; ans = 0;
		for (re j = i ; j <= n ; ++ j){
			cnt[a[j]] ++;
			while (cnt[ans] != 0)
				ans ++;
			mxs[i][j] = ans;
		}
		for (re j = i ; j <= n ; ++ j)
			cnt[a[j]] --;
		cnt[a[i]] --;
	}
	mex = mxs[1][n];
	/*for (re i = 1 ; i <= n ; ++ i)
		for (re j = i ; j <= n ; ++ j)
			cerr << "[" << i << ", " << j << "]: " << mxs[i][j] << '\n';*//*
	f[0] = 1;
	// cerr << mex << '\n';
	for (re i = 1 ; i <= n ; ++ i){
		for (re j = 1 ; j <= i ; ++ j){
			if (mxs[j][i] == mex)
				f[i] += f[j-1];
			while (f[i] >= P)
				f[i] = f[i] mod P;
		}
	}
	cout << f[n] << '\n';*/
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	cin >> T;
	while (T --)
		work();
	return GMY;
}

T3 

这道题我一上来就想到了某倍增连边的题(因为莫名找不到题了所以就不挂链接了)

我滴任务,完成啦!!!!!!!!

然后直接拿着这个思路硬干了几个小时,然后发现伪了。

为啥伪捏。

两个点不一定是父子关系捏。

然后怀着能拿链部分分的希冀直接去跑链的大样例。直接一发 WA 掉。

然后就心态爆炸直接起飞。

正解是,是啥笛卡尔树,我不会,所以我直接贺题解。

但是学到了一些本来就应该会的玩意。

就是你一颗树,某个节点的子树内 dfn 序是连续的,根据这玩意可以套树状数组之类的数据结构。

T3
#include <iostream>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define int long long
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 2000005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
/*
	为什么kirito能把每道题都讲明白啊
	dfn~dfn+(dfn-sz+1)子树内连续的dfn序
*/
int n, final_ans, dfscnt;
int dfn[N], sz[N], fa[N], C[N];

struct star{
	int star_cnt;
	int head[N], v[N<<1], nxt[N<<1];
	
	inline void star_add(int uu, int vv){v[++ star_cnt]=vv, nxt[star_cnt]=head[uu], head[uu]=star_cnt;}
};

struct star e, up, dw;

int find(int x){return ((fa[x] == x) ? (x) : (fa[x] = find(fa[x])));}
inline void Unite(int x, int y){x = find(x), y = find(y); fa[y] = x;}
#define lowbit(x) ((x) & (-(x)))
inline void Update(int k, int w){
	while (k <= n)
		C[k] += w, k += lowbit(k);
}
inline int Query(int k){
	int res(0);
	while (k != 0)
		res += C[k], k -= lowbit(k);// , cerr << k << '\n'
	return res;
}
void dfs1(int x){
	dfn[x] = ++ dfscnt; sz[x] = 1;
	for (re i = dw.head[x] ; i ; i = dw.nxt[i]){
		int v = dw.v[i];
		dfs1(v);
		sz[x] += sz[v];
	}
}
void dfs2(int x){
	final_ans += Query(dfn[x]+sz[x]-1) - Query(dfn[x]-1);
	Update(dfn[x], 1);
	for (re i = up.head[x] ; i ; i = up.nxt[i]){
		int v = up.v[i];
		dfs2(v);
	}
	Update(dfn[x], -1);
}

inline void work(){
	cin >> n; cin >> dfscnt; dfscnt = 0;
	for (re uu = 2, vv ; uu <= n ; ++ uu)
		{cin >> vv; e.star_add(vv, uu), e.star_add(uu, vv);}
	
	for (re i = 1 ; i <= n ; ++ i)
		fa[i] = i;
	for (re i = 1 ; i <= n ; ++ i)
		for (re j = e.head[i] ; j ; j = e.nxt[j])
			if (e.v[j] < i)
				up.star_add(i, find(e.v[j])), Unite(i, e.v[j]);
	for (re i = 1 ; i <= n ; ++ i)
		fa[i] = i;
	for (re i = n ; i >= 1 ; -- i)
		for (re j = e.head[i] ; j ; j = e.nxt[j])
			if (e.v[j] > i)
				dw.star_add(i, find(e.v[j])), Unite(i, e.v[j]);
	
	dfs1(1);
	/*for (re i = 1 ; i <= n ; ++ i)
		cerr << "dfn、sz: " << dfn[i] << _ << sz[i] << '\n';*/
	dfs2(n);
	
	cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}

T4 

子任务分治可得 20pts 的好成绩

正解我还是不会,直接贺

T4
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define int long long
#define re register int
#define char_phi signed
#define DMARK cerr << "###"
#define _ ' '
#define Endl cout << '\n'
#define Dl cerr << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
#define MPOS 3005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
struct star{int v, w;};
struct node{
	int id, w;
	char lt;
	friend bool operator < (node A, node B){return A.w > B.w;}
};
/*
	kirito讲得很好,但是
*/
int n, m, mn, aid, final_ans;
char vis[N];
int a[N], s[N], dis[N], fa[N], id[N];
vector<star> e[N];
priority_queue<node> q;

int find(int x){return ((fa[x] == x) ? (x) : (fa[x] = find(fa[x])));}
inline void Insert(int x, int w){
	if (fa[x] != x)
		return ;
	dis[x] = w; fa[x] = x+1;
	q.push((node){x, dis[x]+a[s[x]], true});
	for (re i = 0 ; i < e[x].size() ; ++ i){
		int v = e[x][i].v;
		if (dis[v] > dis[x]+e[x][i].w)
			{dis[v] = dis[x]+e[x][i].w; q.push((node){v, dis[v], false});}
	}
}
inline void Dijskra(int rt){
	memset(dis, 0x5f, sizeof(dis)); dis[rt] = 0;
	fa[s[0]+1] = s[0]+1;
	for (re i = 1 ; i <= s[0] ; ++ i)
		fa[i] = i;
	q.push((node){rt, dis[rt], false});
	while (q.empty() == false){
		node x = q.top(); q.pop();
		if (x.lt == false)
			Insert(x.id, x.w);
		else {
			for (re i = 0 ; i < e[x.id].size() ; ++ i)
				vis[e[x.id][i].v] = true;
			for (re i = find(1) ; i <= s[0] ; i = find(i+1))
				if (vis[i] == false)
					Insert(i, x.w);
			for (re i = 0 ; i < e[x.id].size() ; ++ i)
				vis[e[x.id][i].v] = false;
		}
	}
}

inline void work(){
	cin >> n >> m;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i];
	for (re i = 1, x, y, z ; i <= m ; ++ i){
		cin >> x >> y >> z;
		if (id[x] == 0)
			{s[++ s[0]] = x; id[x] = s[0];}
		if (id[y] == 0)
			{s[++ s[0]] = y; id[y] = s[0];}
		e[id[x]].push_back((star){id[y], z});
	}
	
	a[0] = 1145141919; mn = 1145141919;
	for (re i = 1 ; i <= n ; ++ i)
		if (id[i] == 0 and a[i] < mn)
			mn = a[i], aid = i;
	if (mn != 1145141919)
		s[++ s[0]] = aid, id[aid] = aid;
	
	for (re i = 1 ; i <= n ; ++ i)
		if (id[i] == 0)
			final_ans += (long long)a[i] * (n-1);
	for (re i = 1 ; i <= s[0] ; ++ i){
		Dijskra(i); mn = 1145141919;
		for (re j = 1 ; j <= s[0] ; ++ j){
			final_ans += dis[j];
			mn = MIN(mn, dis[j]+a[s[j]]);
		}
		final_ans += (n-s[0])*mn;
	}
	cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
	#ifdef IXINGMY
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	work();
	return GMY;
}
posted @   char_phi  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示