首页 > 其他分享 >2022NOIP A层联测35

2022NOIP A层联测35

时间:2023-01-26 21:55:48浏览次数:66  
标签:long int 2022NOIP pos 35 -- maxn 联测 ans

好久之前的题了。

A. 弹珠游戏

\(R, G, B\) 任意时刻只能出现两种,出现第三种时优先匹配剩下两种的组合,再考虑形成新的组合,匹配啥是一样的,于是每次乘上方案数

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int mod = 998244353;
const int maxn = 600005;
int n, ans;
string s;
map <string, int>f;
int main(){
	freopen("A.in","r",stdin);
	freopen("A.out","w",stdout);
	cin >> n >> s;
	n = n * 3;
	f[s.substr(0, 1)] = ans = 1;
	for(int i = 1; i < n; ++i)
	if(s[i] == 'R'){
		if(f["GB"]){ans = 1ll * ans * f["GB"] % mod; --f["GB"]; continue;}
		if(f["G"]){ans = 1ll * ans * f["G"] % mod; --f["G"]; ++f["RG"]; continue;}
		if(f["B"]){ans = 1ll * ans * f["B"] % mod; --f["B"]; ++f["RB"]; continue;}
		++f["R"];
	}else if(s[i] == 'G'){
		if(f["RB"]){ans = 1ll * ans * f["RB"] % mod; --f["RB"]; continue;}
		if(f["R"]){ans = 1ll * ans * f["R"] % mod; --f["R"]; ++f["RG"]; continue;}
		if(f["B"]){ans = 1ll * ans * f["B"] % mod; --f["B"]; ++f["GB"]; continue;}
		++f["G"];
	}else{
		if(f["RG"]){ans = 1ll * ans * f["RG"] % mod; --f["RG"]; continue;}
		if(f["R"]){ans = 1ll * ans * f["R"] % mod; --f["R"]; ++f["RB"]; continue;}
		if(f["G"]){ans = 1ll * ans * f["G"] % mod; --f["G"]; ++f["GB"]; continue;}
		++f["B"];
	}
	for(int i = 1; i <= n / 3; ++i)ans = 1ll * ans * i % mod;
	cout << ans << endl;
	return 0;
}

B. 晚会

建立一棵生成树,考虑非树边

发现合法情况会形成类似等腰三角形的情况并且底边长要大于等于腰长

那么建立最大生成树,判断时查询路径最小值,合法情况下等于当前非树边边权

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
int n, m;
const int maxn = 600005;
struct DSU{
	int f[maxn];
	void init(){for(int i = 1; i <= n + n; ++i)f[i] = i;}
	int fa(int x){return f[x] == x ? x : f[x] = fa(f[x]);}
}S;
struct EDGE{
	int u, v, w;
	friend bool operator < (const EDGE &x, const EDGE &y){
		return x.w > y.w;
	}
}E[maxn];
int cnt, val[maxn];
vector<int>g[maxn];
int dep[maxn], son[maxn], fa[maxn], siz[maxn], top[maxn], leaf[maxn];
void dfs(int x){
	siz[x] = 1;if(x <= n)leaf[x] = 1;
	for(int v : g[x]){
		fa[v] = x; dep[v] = dep[x] + 1;
		dfs(v);
		leaf[x] += leaf[v];
		siz[x] += siz[v]; son[x] = siz[son[x]] > siz[v] ? son[x] : v;
	}
}
void dfs2(int x, int tp){
	top[x] = tp;
	if(son[x])dfs2(son[x], tp);
	for(int v : g[x])if(v != son[x])dfs2(v, v);	
}
int lca(int x, int y){
	while(top[x] != top[y]){
		if(dep[top[x]] < dep[top[y]])swap(x, y);
		x = fa[top[x]];
	}
	return dep[x] < dep[y] ? x : y;
}
vector <int> notree;
bool check(){
	for(int i : notree){
		if(val[lca(E[i].u, E[i].v)] != E[i].w)return false;
	}
	return true;
}
ll ans;
void solve(int x){
	if(x <= n)return;
	int sil = 0, sir = 0;
	for(int v : g[x]){
		solve(v);
		if(sil) sir = leaf[v];
		else sil = leaf[v];
	}
	ans = ans - 1ll * sil * sir + 1ll * sil * sir * val[x];
}
ll sol(){
	ans = 1ll * n * (n - 1) / 2;
	for(int i = cnt; i >= 1; --i)if(!fa[i])solve(i);
	return ans;
}
int main(){
	freopen("B.in","r",stdin);
	freopen("B.out","w",stdout);
	n = read(), m = read(); S.init();
	for(int i = 1; i <= m; ++i)E[i].u = read(), E[i].v = read(), E[i].w = read();
	sort(E + 1, E + m + 1); cnt = n;
	for(int i = 1; i <= m; ++i)if(S.fa(E[i].u) != S.fa(E[i].v)){
		int u = S.fa(E[i].u), v = S.fa(E[i].v);
		val[++cnt] = E[i].w;
		g[cnt].push_back(u);
		g[cnt].push_back(v);
		S.f[u] = S.f[v] = cnt;
	}else notree.push_back(i);
	for(int i = cnt; i >= 1; --i)if(!siz[i])dfs(i), dfs2(i, i);
	if(check())printf("%lld\n",sol());
	else printf("-1\n");
	return 0;
}

C. 优美的字符串

DP 套 DP

牛神题解

D. 选举

回滚莫队+分块

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int maxn = 300005;
int n, m, Q;
int len, bl[maxn];
int lem, bm[maxn];
int a[maxn], b[maxn];
struct node{
	int l, r, ql, qr, id;
	friend bool operator < (const node &x, const node &y){
		return bl[x.l] == bl[y.l] ? x.r < y.r : x.l < y.l;
	}
}q[maxn];
ll cnt[maxn], ans[maxn], mx[maxn], rem[maxn];
void Ckmx(ll &x, ll y){if(y > x)x = y;}
void Add(int pos){
	cnt[a[pos]] += b[pos];
	rem[pos] = mx[bm[a[pos]]];
	Ckmx(mx[bm[a[pos]]], cnt[a[pos]]);
}
void Del(int pos){
	cnt[a[pos]] -= b[pos];
	mx[bm[a[pos]]] = rem[pos];
}
void clear(int r){
	while(r && cnt[a[r]] > 0){
		mx[bm[a[r]]] = 0;
		cnt[a[r]] -= b[r];
		--r;
	}
}
ll query(int l, int r){
	ll ans = 0;
	if(bm[l] == bm[r]){
		for(int i = l; i <= r; ++i)Ckmx(ans, cnt[i]);
		return ans;
	}
	for(int i = bm[l] * lem; i >= l; --i)Ckmx(ans, cnt[i]);
	for(int i = (bm[r] - 1) * lem + 1; i <= r; ++i)Ckmx(ans, cnt[i]);
	for(int i = bm[l] + 1; i < bm[r]; ++i)Ckmx(ans, mx[i]);
	return ans;
}
void sol(){
	int r = 0;
	for(int i = 1; i <= Q; ++i){
		if(bl[q[i].l] != bl[q[i - 1].l]){clear(r); r = min(bl[q[i].l] * len, n);}
		while(r < q[i].r)Add(++r);
		int up = min(q[i].r, bl[q[i].l] * len);	
		for(int j = q[i].l; j <= up; ++j)Add(j);
		ans[q[i].id] = query(q[i].ql, q[i].qr);	
		for(int j = up; j >= q[i].l; --j)Del(j);
	}
}

int main(){
	freopen("D.in","r",stdin);
	freopen("D.out","w",stdout);
	n = read(), m = read(), Q = read();
	for(int i = 1; i <= n; ++i)a[i] = read();
	for(int i = 1; i <= n; ++i)b[i] = read();
	for(int i = 1; i <= Q; ++i){
		q[i].l = read(), q[i].r = read();
		q[i].ql = read(), q[i].qr = read();
		q[i].id = i;
	}
	len = sqrt(n); for(int i = 1; i <= n; ++i)bl[i] = (i + len - 1) / len;
	lem = sqrt(m); for(int i = 1; i <= m; ++i)bm[i] = (i + lem - 1) / lem;
	sort(q + 1, q + Q + 1); sol();
	for(int i = 1; i <= Q; ++i)printf("%lld\n",ans[i]);
	return 0;
}

标签:long,int,2022NOIP,pos,35,--,maxn,联测,ans
From: https://www.cnblogs.com/Chencgy/p/17068294.html

相关文章

  • 洛谷P1835-素数密度
    素数密度题目描述给定区间\([L,R]\)(\(1\leqL\leqR<2^{31}\),\(R-L\leq10^6\)),请计算区间中素数的个数。输入格式第一行,两个正整数\(L\)和\(R\)。输出格式一行......
  • hdu4135
    求[a,b]中与n互素的数字个数  #include<iostream>#include<algorithm>usingnamespacestd;constintN=200;#defineintlonglonginttot,fac[N];......
  • 刷刷刷 Day 22 | 235. 二叉搜索树的最近公共祖先
    235.二叉搜索树的最近公共祖先LeetCode题目要求给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个结......
  • RK3568源码编译与交叉编译环境搭建
    本篇进行飞凌OK3568-C开发板的Linux系统开发需要用的软件交叉编译环境的配置。对于软件开发,如果只是使用C/C++代码,则在自己的Ubuntu虚拟机中添加RK3568对应的交叉编译器(gcc......
  • 天梯赛练习题L2(031-035)
    L2-031深入虎穴这个题目我疑惑了好久,因为它说只有一个入口,但是却没有告诉我们哪个是入口,并且需要我们找出距离入口最远的那扇门所以我们在做题时要一一判断哪个是入口,......
  • [loj3835]千岛
    独木舟可以看作将边定向,并在每次经过后反向,要求最终每条边方向不变在此基础上,考虑以下两种情况:对于出度为\(0\)的点,到达其后仅能原路返回,不妨删除若起点出度为\(1\)......
  • ABB 800XA学习笔记35:AC 800M硬件结构16
    这一片学习笔记我在新浪博客发表过,地址是ABB800XA学习笔记35:A800M硬件16_来自金沙江的小鱼_新浪博客(sina.com.cn)在这里我再记录一遍,以免丢失继续学习,AC800M硬件快学习......
  • 序列凑零(冬季每日一题 35)
    给定一个长度为的整数序列。所有都是非零整数并且绝对值不超过。另外,现在,请你构造另一个整数序列,使得要求,所有都是非零整数并且绝对值不超过。输入格式第一行包......
  • 代码随想录day 22 LeetCode 235. 二叉搜索树的最近公共祖先 701. 二叉搜索树中的插入
    235.二叉搜索树的最近公共祖先classSolution{public:TreeNode*lowestCommonAncestor(TreeNode*root,TreeNode*p,TreeNode*q){if(root==NULL)returnNULL......
  • CF1635E做题记录
    *2200的绿,是道好题不想投题解,因为思路重复,而且太麻烦了。先设任意一点向左,判断方向关系是否矛盾,类似二分图判定的染色。确定下方向后,就可以将原条件转换成为若干个类似......