首页 > 其他分享 >P9546 [湖北省选模拟 2023] 山路长环 / ring

P9546 [湖北省选模拟 2023] 山路长环 / ring

时间:2023-09-26 22:35:29浏览次数:31  
标签:rt int P9546 mn 长环 lt 2023 res rh

Day \(\mathbb{P}_9\)。

如果有权值为 \(0\) 的边,用所有这样的边把环分成若干条链。

不难发现若起始点在链的一端,先手必胜当且仅当链长(边数)为奇数。可以进行归纳证明,这种情况下先手每次移动必将边权置为 \(0\)。

继续推性质:

  • 起始点在长度为奇数的链(奇链)上,那么删掉这个点后,这条链将会分成两个链,总恰好有其中一个链的长度为奇数,所以先手往那条链走并将走过的边权置为 \(0\) 即可。先手必胜。
  • 起始点在长度为偶数的链(偶链)上,那么删掉这个点后,剩下两条链长度要不同时是奇数要不同时是偶数。根据前面的结论,奇数时先手必胜,偶数时后手必胜。
  • 起始点在长度为奇环上,先手随便走一步并将边权置为 \(0\),后手操作时相当于偶链的情况,于是先手必胜。
  • 起始点在长度为偶环上,若先手直接将一条边权值置为 \(0\),后手操作相当于奇链的情况,此时后手必胜。所以先手尽量不会将边权置为 \(0\),不难得到两者策略均为走同一个方向,每次将边权 \(-1\)。由于是偶环,必定存在一个时刻,使得所有边权都减去了原来的边权最小值,即被分成若干的链,而棋子停留在起始点。所以先手必胜当且仅当此时状态下先手必胜。

所以线段树维护区间最小值、区间长度、区间最左侧的最小值到区间左端点的长度、区间最右侧最小值到区间右端点的长度、区间被最小值分割后每个段中(不包括两边,下同)奇数长度的段的长度 \(+1\) 总和、区间内被最小值分割后每个段中偶数长度的段的长度总和除以 \(2\) 即可。复杂度 \(O(q\log m)\)。

// Problem: P9546 [湖北省选模拟 2023] 山路长环 / ring
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P9546
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define mt make_tuple
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef tuple<int, int, int> tu;
bool Med;

const int N = 3e5 + 300;

int n, q, a[N];

struct node {
	int mn, le, lt, rt, vo, ve;
	node () : mn(0), le(0), lt(0), rt(0), vo(0), ve(0) { }
	node (int x) : mn(x), le(1), lt(0), rt(0), vo(0), ve(0) { }
	node operator + (const node &rh) const {
		node res; 
		res.mn = min(mn, rh.mn), res.le = le + rh.le;
		if (mn == res.mn) res.lt = lt, res.vo = vo, res.ve = ve;
		else res.lt = le + rh.lt;
		if (rh.mn == res.mn) res.rt = rh.rt, res.vo += rh.vo, res.ve += rh.ve;
		else res.rt = rh.le + rt;
		if (mn == res.mn && rh.mn == res.mn) {
			if ((rt + rh.lt) & 1) res.vo += rt + rh.lt + 1;
			else res.ve += (rt + rh.lt) >> 1;
		}
		return res;
	}
} tr[N << 2];

#define ls x << 1
#define rs x << 1 | 1
#define mid ((l + r) >> 1)

void upd(int l, int r, int p, int c, int x) {
	if (l == r) return tr[x] = node(c), void();
	if (p <= mid) upd(l, mid, p, c, ls);
	else upd(mid + 1, r, p, c, rs);
	tr[x] = tr[ls] + tr[rs];
}

node qry(int l, int r, int s, int t, int x) {
	if (s <= l && r <= t) return tr[x];
	if (s > mid) return qry(mid + 1, r, s, t, rs);
	else if (t <= mid) return qry(l, mid, s, t, ls);
	return qry(l, mid, s, t, ls) + qry(mid + 1, r, s, t, rs);
}

void solve() {
	cin >> n >> q;
	for (int i = 1; i <= n; i++) 
		cin >> a[i], upd(1, n, i, a[i], 1);
	while (q--) {
		int op, x, y; cin >> op >> x >> y;
		if (op == 1) upd(1, n, x, y, 1);
		else {
			node res = qry(1, n, x, y, 1);
			if (res.mn != 0 && ((y - x + 1) & 1)) cout << y - x + 1 << '\n';
			else {
				int ans = res.ve + res.vo;
				if ((res.lt + res.rt) & 1) ans += res.lt + res.rt + 1;
				else ans += (res.lt + res.rt) >> 1;
				cout << ans << '\n';
			}
		}
	}
}

bool Mbe;
int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cerr << (&Med - &Mbe) / 1048576.0 << " MB\n";
	#ifdef FILE
		freopen("1.in", "r", stdin);
		freopen("1.out", "w", stdout);
	#endif
	int T = 1;
	// cin >> T;
	while (T--) solve();
	cerr << (int)(1e3 * clock() / CLOCKS_PER_SEC) << " ms\n";
	return 0;
}

标签:rt,int,P9546,mn,长环,lt,2023,res,rh
From: https://www.cnblogs.com/Ender32k/p/17731425.html

相关文章

  • 2023/09/26 动手动脑
    Java的类在构造时会提供一个无参的构造方法,如果已存在用户已经自定义的构造方法,则原有的无参构造方法将无法调用,只能调用自己定义的构造方法。静态初始化的执行顺序:classRoot{static{System.out.println("Root的静态初始化块");}{Syst......
  • 2023年9月26日每日随笔
    今天,学习了一个新的数据库,mongoDB,并在其shell界面进行增删改查,学习了c#的一些语法,也出现了一些的问题,同时,对于设计模式也没有落下,学习了外观模式:外观模式有两种角色:外观类和子类,外观类:定义子类对象,集成处理子类方法以实现一系列操作子类:每一个具体的类主要就是简化操......
  • 2023/9/27 讲课用
    杂谈表达式首先来明确一些概念值(value)即为一个静态的数据。值可以是整数,浮点数,字符,字符串等变量(variable)可以形象地理解为,存储值得容器。变量有诸多类型,一般而言,变量只能存储对应类型的值。inta=0;“我向系统声明:我需要一小块内存,来存储一个整数变量,变量的值为\(0......
  • 【Android面试】2023最新面试专题二:ArrayList篇
    1.4 请说一说ArrayList如何保证线程安全,除了加关键字的方式?这道题想考察什么?1、ArrayList的底层原理?考察的知识点ArrayList底层的源码的理解考生如何回答ArrayList如何保证线程安全继承Arraylist,然后重写或按需求编写自己的方法,这些方法要写成synchronized,在这些synchronized的......
  • 2023年最新京东app端sign签名算法与cipher加解密逆向分析(2023-09-26)
    前言:  本文仅供学习交流,只提供关键思路不会给出完整代码,严禁用于非法用途,若有侵权请联系我删除!技术交流合作请私信!一.工具的选择(抓包工具的选择,是门学问)用到工具如下:1、安卓手机一台,系统版本:android6.01;型号:小米MI4LTE  之所以要选择android6手机,原理如下:  ......
  • kubernetes集群搭建2023
    参考:https://zhuanlan.zhihu.com/p/627310856(比较详细的一篇k8s集群部署文章)https://www.cnblogs.com/libruce/p/17477374.html或者https://zhuanlan.zhihu.com/p/590652259(不关闭防火墙的情况,如何配置端口)https://www.cnblogs.com/suuuch/p/16728103.html(初始化集群或者新节......
  • SMU Autumn 2023 Round 5
    SMUAutumn2023Round5A.EveryoneLovestoSleep把时间都转成分钟,然后存起来,二分找到离他睡觉点最近的一个时间段,减去他的睡觉点,如果最近的在第二天,则把中间的这段时间加起来#include<bits/stdc++.h>#defineintlonglong#definedebug(a)cout<<#a<<"="<<a<<'\n'......
  • 2023-2024-1 20211319蓝宇 《信息安全专业导论》第一周学习总结
    作业信息|这个作业属于哪个课程|2020-2021-1信息安全专业导论(https://edu.cnblogs.com/campus/besti/2020-2021-1fois))||这个作业要求在哪里|[2020-2021-1信息安全专业导论第一周作业](https://edu.cnblogs.com/campus/besti/2020-2021-1fois/homework/11249))||这个作业的......
  • 2023.09.26 联考总结&题解
    T1derby你考虑直接贪心进行匹配即可,就是说对于每一个\(1\)去匹配最大的\(0\)#include<bits/stdc++.h>usingnamespacestd;intn,m;vector<int>A[2],B[2];intmain(){ freopen("derby.in","r",stdin); freopen("derby.out","w",s......
  • 2023.09.25
      今天进行了回文串的练习,上午进行了金属创意制作,充分发挥了自己的动手能力。下午进行了建民老师的课,对类和对象进行了加深学习。课上代码还未完成。。。。。。。#include<stdio.h>#include<stdlib.h>#include<string.h>#defineMAXSIZE100intpush(char*zhan,inttop......