首页 > 其他分享 >Solution Set - CF787

Solution Set - CF787

时间:2023-11-16 16:34:36浏览次数:34  
标签:Set 游戏 int mid sqrt Solution CF787 ans 根号

Vive le R & M!

还被种草了 Hurt,真的颇有感触,但这是 Solution Set,就不写了。

A. The Monster

exgcd,但是发现 \(1 \leq a, b, c, d \leq 100\) 直接暴力枚举即可。我认为这是 \(O(1)\) 的,但题解认为是 \(O(n)\),感觉不如原神。

B. Not Afraid

每一组里面只要有来自同一个宇宙的 Rick and Morty 就不可能都是坏的。等价于只要判断是否每一组都有 \(x\) 和 \(-x\) 同时存在即可。

C. Berzerk

难度骤升。显然是一个 bot 论。

被傻逼 bot 论整破防了。

Definition.

游戏有两个人参与,二者轮流做出决策,双方均知道游戏的完整信息;任意一个游戏者在某一确定状态可以作出的决策集合只与当前的状态有关,而与游戏者无关;游戏中的同一个状态不可能多次抵达,游戏以玩家无法行动为结束,且游戏一定会在有限步后以非平局结束。

这个有限步我们先忽略,是可以处理的。关键是这个与游戏者无关,看起来这里和游戏者有关,但是你可以把游戏者抽象成一个状态。。。这样就相当于是个公平组合游戏了(纯纯侠极霸说)。

然后这里不能硬上 dfs & SG 函数,因为 Loop 的存在会导致这个写法 \(O(n ^ 3)\),得换用 bfs 的有向图游戏弄 \(O(n ^ 2)\),然后就是很 trivial 的有一个状态能到达输状态就是赢状态,只能到达赢状态就是输状态,否则不能确定,就是 Loop。

我的写法还被卡空间(微笑),要写 short 才能过 /fn

namespace liuzimingc {
const int N = 7e3 + 5;
#define int short
#define endl '\n'

int n, out[N << 1], ans[N << 1];
set<int> s[2];
vector<int> e[N << 1];
queue<int> q;
bool vis[N << 1];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n;
	for (int i = 0; i <= 1; i++) {
		int m, x;
		cin >> m;
		while (m--) {
			cin >> x;
			s[i].insert(x);
		}
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= 1; j++) {
			for (const int &k : s[j]) {
				int pos = (i + k) % n;
				if (pos * 2 + !j == i * 2 + j) continue;
				e[pos * 2 + !j].push_back(i * 2 + j);
				out[i * 2 + j]++;
			}
		}
	for (int i = 0; i <= 2 * n + 1; i++) ans[i] = 2;
	ans[2] = ans[3] = 0;
	q.push(2);
	q.push(3);
	vis[2] = vis[3] = true;
	while (q.size()) {
		int u = q.front(); q.pop();
		for (const int &v : e[u]) {
			if (ans[u] == 1) out[v]--;
			if (!out[v] && !vis[v]) ans[v] = 0, vis[v] = true, q.push(v);
			if (!ans[u] && !vis[v]) ans[v] = 1, vis[v] = true, q.push(v);
		}
	}
	for (int i = 0; i <= 1; i++)
		for (int j = 2; j <= n; j++) {
			if (ans[(j % n) * 2 + i] == 1) cout << "Win";
			else if (!ans[(j % n) * 2 + i]) cout << "Lose";
			else cout << "Loop";
			cout << " \n"[j == n];
		}
	return 0;
}
#undef int
} // namespace liuzimingc

D. Legacy

越做越感觉这是 educational round。C 博弈论,D 线段树优化建图,(SPOILER ALERT)E(根号)分治。

而且可喜可贺的是我们是学过线段树优化建图的,但是那天我请假了。

还是很 trivial,建完跑 Dijkstra 即可。

E. Till I Collapse

这道题是放在 vjudge 里的,标题是根号算法。但是这和根号算法有什么关系?

哦看标签可以知道是根号分治。

那么对于 \(k \leq \sqrt{n}\) 的情况直接暴力就是 \(O(n \sqrt{n})\) 的。

int calc(int i) {
	int tot = 0, lst = 1, ans = 1;
	for (int j = 1; j <= n; j++) {
		if (!vis[a[j]]) tot++, vis[a[j]] = true;
		if (tot > i) {
			ans++;
			tot = 1;
			for (int k = lst; k <= j; k++) vis[a[k]] = false;
			vis[a[j]] = true;
			lst = j;
		}
	}
	for (int k = lst; k <= n; k++) vis[a[k]] = false;
	return ans;
}

然后 \(k > \sqrt{n}\) 怎么做?我不会了。写了依托答辩,结果。。。

答案相同的一段一定连续,\(k > \sqrt{n}\) 时最多也只有 \(\sqrt{n}\) 段,二分相同的区间即可。时间复杂度应该是 \(O(n \sqrt{n} \log \sqrt{n})\) 的?然后显然不能直接对所有的 \(k\) 二分,不然会退化到 \(O(n ^ 2 \log n)\)。


但是其实有一个更加自然(?)的思路。首先答案序列单调不升是显然的,考虑分治。

void work(int l, int r, int x, int y) { // 计算区间 [l, r],答案区间为 [x, y]
	if (l > r) return;
	int mid = l + r >> 1;
	ans[mid] = x == y ? x : calc(mid);
	work(l, mid - 1, ans[mid], y); // 左边答案不会更小
	work(mid + 1, r, x, ans[mid]); // 右边答案不会更大
}

这样写正确性是显然的,但是时间复杂度却很玄学。猜测是带了根号或者 \(\log\) 啥的。

标签:Set,游戏,int,mid,sqrt,Solution,CF787,ans,根号
From: https://www.cnblogs.com/liuzimingc/p/cf787.html

相关文章

  • Solution - 公路旅行
    Link。又名:《不会T1记》。原来用到了神秘的倍增!但是我写了一个申必二分,最坏\(O(qn\logn)\),甚至不如暴力,我是......
  • VS 2005/2008 Web Setup Project
     Tip/Trick:CreatingPackagedASP.NETSetupProgramswithVS2005http://weblogs.asp.net/scottgu/archive/2007/06/15/tip-trick-creating-packaged-asp-net-setup-programs-with-vs-2005.aspx 如何用VS2005制作Web安装程序 TwoQuickTipsonWebSetupinVisualStudioh......
  • Get distinct count of rows in the DataSet
    ThetableintheDataSetisasfollows:Column1    Column211              A11              B22              C33              D33              E44              F Dist......
  • Setence Case using Javascript/SQL Server
    Howto ChangeaaaorAAAtobeAaa<scripttype="text/javascript"language="javascript">functionCorrectName(e){if(e.value!=""&&/^[a-zA-Z]/.test(e.value)){e.value=e.valu......
  • Can Report (rdlc) Table or Matrix Column Width Be Set at Runtime?
     UsinganrdlcreportinReportViewer,Ineedtocreateatableormatrixwherethenumberofcolumnsandthekindsofdatadisplayedinthecolumnschangeswitheachreport. Forexample,inonereport,thesecondcolumnmayholdpriceinformation. Ina......
  • CTFshow Reverse 36D杯 BBBigEqSet wp
    用ida打开程序,一点点看汇编,发现似乎是机器生成的,先是输入0x80长的flag,然后有0x80段运算,运算的内容是每一个字符乘一个系数相加后与一个数比较。查看代码.text:0000000000001175pushrbp.text:0000000000001176movrbp,rsp.text:00......
  • Kubernetes statefulset
    k8s的statefulset是用用于有状态服务的部署,存储和网络都是有顺序的,会按照顺序先down掉服务再起来,所以当部署的这台服务器down掉之后,就不能down掉这个服务,而会一直处于Terminating状态,无法启动新的服务。所以单副本的应用最好用deploy进行部署,使用statefulset可能会出现这种问题。......
  • setTimeout可以将字符串当成代码执行,类比eval函数。当遇到setTimeout或者SetInterval,
    请问以下JS代码的输出顺序是?letdate=newDate()setTimeout(()=>{console.log('1')},2000)setTimeout('console.log(2)',1000);setTimeout(function(){console.log('3')},1500);while((newDate()-date)<3000){}A报错B......
  • setTimeout 是浏览器环境提供的,JS 标准没有规定。不是JavaScript的全局函数,是浏览器(宿
    下列哪些函数是JavaScript的全局函数?AencodeURIBparseFloatCsetTimeoutDeval正确答案:ABD答案:A、B、D个人记忆方法:6(编码相关)+2(数据处理)+4(数字相关)+1(特殊)编码相关:escape()、unescape()、encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent......
  • 因为offset和scroll其实都是“相对”来计算的。有其他元素做参照物,所以会回流一次,确保
    以下哪些操作会触发Reflow:varobj=document.getElementById(“test”);Aalert(obj.className)Balert(obj.offsetHeight)Cobj.style.height=“100px”Dobj.style.color=“red”正确答案:BC正确答案:BC。B计算了offsetHeight,C重新设置了高度。A打印出类名,无影响......