首页 > 其他分享 >[考试记录] 2024.11.22 noip模拟赛19

[考试记录] 2024.11.22 noip模拟赛19

时间:2024-11-22 19:33:17浏览次数:1  
标签:2024.11 return 22 noip int res pos val id

T1 镜的绮想 (mirror)

考虑维护中点 \(y\) 坐标数量,\(mid_y=(a_y+b_y)/2\),不过不用除。枚举所有相同 \(x\) 坐标点对即可。

#include<bits/stdc++.h>
using namespace std;
constexpr int N = 5e3 + 5, MX = 2e6 + 5;
int a[N<<1], pos[N<<1], cnt, ans, val[MX<<1];
struct node{ int x, y; }tn[N], fn[N];
vector<int> tvec[N<<1], fvec[N<<1];
int main(){
	freopen("mirror.in", "r", stdin); freopen("mirror.out", "w", stdout);
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n, m; cin>>n>>m; 
	for(int i=1; i<=n; ++i) cin>>tn[i].x>>tn[i].y, a[++cnt] = tn[i].x;
	for(int i=1; i<=m; ++i) cin>>fn[i].x>>fn[i].y, a[++cnt] = fn[i].x;
	sort(a+1, a+1+cnt); cnt = unique(a+1, a+1+cnt) - a - 1;
	for(int i=1; i<=n; ++i) tvec[lower_bound(a+1, a+1+cnt, tn[i].x)-a].emplace_back(tn[i].y);
	for(int i=1; i<=m; ++i) fvec[lower_bound(a+1, a+1+cnt, fn[i].x)-a].emplace_back(fn[i].y);
	for(int i=1; i<=cnt; ++i) if(!tvec[i].empty() && !fvec[i].empty())
		for(int tv : tvec[i]) for(int fv : fvec[i])
			++val[tv + fv + MX], ans = max(ans, val[tv + fv + MX]);
	return cout<<ans, 0;
}

T2 万物有灵 (animism)

不知道最大独立集是什么,然后就跳了,我有可能真的错过了 100pts

规律是简单的,我们称深度为 \(1\sim k\) 的树为基础树。那么最大独立集即为从树的最底层开始,取一层跳过一层以此类推。考虑利用一下周期性,当 \(k\) 为偶数的时候计算出基础树的奇数层的节点总数,和偶数层的节点总数,然后计算一下整棵树包含多少颗基础树。令 \(b_k\) 表示基础树的叶子数量,那么基础树的数量即为 \(1+b_k+b_k^2+b_k^3\dots\),等比数列求和即可。不过考虑到没有逆元的情况,可以使用矩阵乘法或者递归求解。对于 \(k\) 为奇数的情况,直接将 \(k*2\) 即可转化。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define it __int128
constexpr int N = 5e5 + 5;
int n, k, M, a[N<<1], b[N<<1];
inline int qpow(int a, int k){
	int res = 1; while(k){
		if(k & 1) res = (it)res * a % M;
		a = (it)a * a % M; k >>= 1;
	} return res;
}
inline int add(initializer_list<int> Add){
	int res = 0;
	for(int v : Add) res = res + v >= M ? res + v - M : res + v;
	return res;
}
inline int mul(initializer_list<int> Mul){
	int res = 1;
	for(int v : Mul) res = (it)res * v % M;
	return res;
}
inline void eg(int a, int b, int &x, int &y){
	if(!b) return x = 1, y = 0, void();
	eg(b, a%b, y, x); y -= a / b * x;
}
inline int inv(int k){
	int x = 0, y = 0; eg(k, M, x, y);
	x = ((x % M) + M) % M;
	if(x < 0) printf("fvv\n"), exit(0);
	return x;
}
signed main(){
	freopen("animism.in", "r", stdin); freopen("animism.out", "w", stdout);
	cin>>n>>k>>M;
	for(int i=1; i<=k; ++i) cin>>a[i];
	for(int i=k+1; i<=k<<1; ++i) a[i] = a[i-k];
	if(k & 1) k *= 2;
	b[1] = a[1]; int sum1 = a[1], sum2 = 0;
	for(int i=2; i<=k; ++i){
		b[i] = mul({b[i-1], a[i]});
		if(i & 1) sum1 = add({sum1, b[i]});
		else sum2 = add({sum2, b[i]});
	}
	if(!((n % k) & 1)){
		int res = 1, lst = qpow(b[k], n/k);
		int sum = mul({lst-1, inv(b[k]-1)});
		res = add({res, mul({sum, sum2})});
		for(int i=2; i<=n%k; i+=2)
			res = add({res, mul({b[i], lst})});
		cout<<abs(res); exit(0);
	} else {
		int res = 0, lst = qpow(b[k], n/k);
		int sum = mul({lst-1, inv(b[k]-1)});
		res = add({res, mul({sum, sum1})});
		for(int i=1; i<=n%k; i+=2)
			res = add({res, mul({b[i], lst})});
		cout<<abs(res); exit(0);
	}
}

T3 白石溪 (creek)

考场上苦思冥想如何优化 45pts dp 没想到是个贪心……

没太明白,颓过去的……

#include<bits/stdc++.h>
using namespace std;
constexpr int B = 1 << 15;
char buf[B], *p1 = buf, *p2 = buf;
#define gt() (p1==p2 && (p2=(p1=buf)+fread(buf, 1, B, stdin), p1==p2) ? EOF : *p1++)
template <typename T> inline void rd(T &x){
	x = 0; int f = 0; char ch = gt();
	for(; !isdigit(ch); ch = gt()) f ^= ch == '-';
	for(; isdigit(ch); ch = gt()) x = (x<<1) + (x<<3) + (ch^48);
	x = f ? -x : x;
}
template <typename T, typename ...TT> inline void rd(T &x, TT &...y){ rd(x), rd(y...); }
#define int long long
int p[1000005];
signed main(){
	freopen("creek.in", "r", stdin); freopen("creek.out", "w", stdout);
	int n, c, d; rd(n, c, d); int ans = 0, res = 0;
	for(int i=1, a, b; i<=n; ++i){
		rd(a, b); ans += a;
		p[i] = a - b - (i-1) * c - (n-i) * d;
	} sort(p+1, p+1+n); res = ans;
	for(int i=1; i<=n; ++i) ans -= p[i], res = max(res, ans - (c+d)*i*(i-1)/2);
	return printf("%lld", res), 0;
}

T4 上山岗 (uphill)

首先考虑构造出匹配数最多的方案,采用 田忌赛马 策略,先将能力值排序,从小到大枚举每一个登山队员找到最靠右的合法匹配位置,这样构造下来字典序是较小的,并且匹配数是最多的。

然后考虑在保证匹配数最多的情况下移动。贪心地,按能力值从大到小枚举队员。如果该队员当前有匹配的位置,那么找到最左端的未匹配的位置来置换,这样的位置是确定下来的;如果没有匹配的位置,那就随便找到一个最靠左没有被确定的位置,如果这个位置被其他人匹配过了,那就强制把那个人拆下来,把现在这个人换上去。因为比他小的人都有匹配,那这个人一定也有匹配。由于从大到小确定位置构造,这样的字典序一定最大。

具体维护方式可以使用两颗线段树,一棵维护没有被匹配的位置的最小值,一棵维护没有被确定的位置的最小值。支持单点修改,查最靠左、右最小值,线段树上二分即可。复杂度 \(\mathcal{O}(n\log n)\)。

#include<bits/stdc++.h>
using namespace std;
constexpr int N = 5e5 + 5, Inf = 1e9;
int n, a[N], b[N], mch[N], ans[N];
struct ST{
	#define ls (id << 1)
	#define rs (id << 1 | 1)
	#define pushup(id) t[id].mn = min(t[ls].mn, t[rs].mn)
	struct node{ int l, r, mn; }t[N<<2];
	inline void build(int id, int l, int r){
		t[id] = node{l, r, 0};
		if(l == r) return t[id].mn = a[l], void();
		int mid = (l + r) >> 1;
		build(ls, l, mid), build(rs, mid+1, r);
		pushup(id);
	}
	inline void modify(int id, int pos, int val){
		if(pos <= 0 || pos > n) return;
		if(t[id].l == t[id].r) return t[id].mn = val, void();
		int mid = (t[id].l + t[id].r) >> 1;
		if(pos <= mid) modify(ls, pos, val);
		else modify(rs, pos, val);
		pushup(id);
	}
	inline int query_l(int id, int val){
		if(t[id].mn >= val) return 0;
		if(t[id].l == t[id].r) return t[id].l;
		if(t[ls].mn < val) return query_l(ls, val);
		else return query_l(rs, val);
	}
	inline int query_r(int id, int val){
		if(t[id].mn >= val) return 0;
		if(t[id].l == t[id].r) return t[id].l;
		if(t[rs].mn < val) return query_r(rs, val);
		else return query_r(ls, val);
	}
} ST1, ST2;
int main(){
	freopen("uphill.in", "r", stdin); freopen("uphill.out", "w", stdout);
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin>>n;
	for(int i=1; i<=n; ++i) cin>>a[i];
	for(int i=1; i<=n; ++i) cin>>b[i];
	sort(b+1, b+1+n); ST1.build(1, 1, n); ST2.build(1, 1, n);
	for(int i=1, pos; i<=n; ++i){
		pos = ST1.query_r(1, b[i]);
		ans[mch[i] = pos] = i;
		ST1.modify(1, pos, Inf);
	} 
	for(int i=n, pos; i>=1; --i){
		if(mch[i]){
			ST1.modify(1, mch[i], a[mch[i]]);
			pos = ST1.query_l(1, b[i]);
			ans[mch[i]] = 0; ans[pos] = i;
		} else {
			pos = ST2.query_l(1, Inf);
			if(ans[pos]) mch[ans[pos]] = 0;
			ans[pos] = i;
		}
		ST1.modify(1, pos, Inf), ST2.modify(1, pos, Inf);
	}
	for(int i=1; i<=n; ++i) cout<<b[ans[i]]<<' ';
	return 0;
}

标签:2024.11,return,22,noip,int,res,pos,val,id
From: https://www.cnblogs.com/xiaolemc/p/18563552

相关文章

  • 2024.11.22 考试总结
    赛时T1画了画图,知道最多转两下,对称三次,这六种情况取最优就行了。T2想从最高位贪心,那一定有一个串是\(fs(1,n)\),考虑继续贪心,让第一串\(1\)后面那一串\(0\)尽量有\(1\)与之匹配,思路很清晰,但一开始写就写成了一坨,写写删删,交完10点多一点。T3,没什么想法,最后想回来写暴力,......
  • NOIP 模拟赛:2024-11-21
    T1:题意:至少交换几次相邻字符,使得原串变成相邻串。结论:每种字符必然前一半在前面,后一半在后面。把最终的每个字符所到的位置求出来,用BIT求逆序对即可。T2:原题总之就是观察到\(1,2\)分出的两段必须递减,然后加个调和级数优化DP就行了。T3:多彩路径题目描述给定一个\(n......
  • 玩酷之家启动U盘制作工具 v10.0 2024.11.18-
    介绍玩酷之家启动U盘制作工具使用起来非常简单,可以帮助用户快速制作出USB启动盘,支持加载多个不同类型的文件启动,还具备了多种启动方式的安装功能,用户可以通过软件将系统备份,满足用户各种U盘启动的需求,启动的速度和拷贝文件的速度一样快,帮助用户节省了很多的时间和精力。软件截图......
  • NOIP 模拟赛 #16
    Alink设\(f[i,j,x,y,w]\)表示走到了\((i,j)\)且之前已经买了\(x\)张向下走的票和\(y\)张向右走的票,总花费为\(w\)的方案数。大力dp即可。Blink注意\(\prodx=\minx\)的限制比较严格,很容易想到\(\minx=0\),发现除此之外只有一种可能:\(\{1,1\}\)。......
  • 11.22 CW 模拟赛 T2.通信
    算法显然的,我们可以先转化问题对于无向图上的\(n\)个点,点之间的边权就是\(\min(\text{图上的欧氏距离的平方和},v)\),求走完所有点时经过的最小边权和手玩样例看下有没有思路?显然的,对于\(50\rm{pts}\),状压可以解决考虑剩下的\(50\rm{pts}\),注意到我们......
  • EMC电磁兼容设计与测试案例分析(第3版)(11.22)
    EMC电磁兼容设计与测试案例分析(第3版)(11.22)EMC电磁兼容设计与测试案例:1、EMC共模电流不入地2、金属外壳可以更好接地、屏蔽线缆:单端/双端接地是否存在连接层导致双端失效3、电感频增而增;电容频增而减;串感、并荣;有概率发生谐振(点),应避开emc测试点4、浪涌与过压:低频、干扰......
  • [73] (NOIP集训) NOIP2024 加赛 7
    DZ:你逆元过了?DZ:我去,那造数据的比较牛DZ:出题人精心构造的坑,造数据的一下就给弄没了这场真像NOIP难度吗,感觉还不如CSPflowchartTB A(镜的绮想) styleAcolor:#ffffff,fill:#00c0c0,stroke:#ffffff两个点能对称当且仅当横坐标相等\(nm\)枚举所有点,横坐标相等的记录......
  • NOIP 模拟赛:2024-11-19
    T1:对两个字符串\(a,b\),分别选择\(a\)的一个前缀和\(b\)的一个后缀(均允许为空或等于原串),并拼接形成一个新的字符串。求共有多少种可能得到的本质不同的拼接串。结论题。对于一个\(a\)的前缀\(a[1\simi]\),有\(m+1-cntb[a[i]]\)个新的串。证明:T2:对一个\(n\)个点\(m\)条......
  • 11.22 模拟赛
    前言大唐胜屎\(T1\)镜的绮想水签CODE#include<bits/stdc++.h>typedeflonglongll;usingnamespacestd;constintN=5e3+100;constintM=4e6+100;intn,m;structPoi{ intx,y;}a[N],b[N];intnum[M];signedmain(){ autoRet1=f......
  • 打卡信奥刷题(288)用C++工具信奥P2242[普及组/提高] 公路维修问题
    公路维修问题题目描述由于长期没有得到维修,A国的高速公路上出现了nnn个坑。为了尽快填补好这n......