首页 > 其他分享 >CF1899F题解

CF1899F题解

时间:2024-01-19 15:35:41浏览次数:20  
标签:ch int 题解 CF1899F back -- lld

Alex's whims

题目传送门

题解

构造题,感觉比 G 更难?可能是我不擅长构造。

考虑点的度数,发现一次操作 \(u,v_1,v_2\) 会使 \(deg_{v_1}\) 减 \(1\),使 \(deg_{v_2}\) 加 \(1\),即一次操作最多减少一个叶子,那如果存在一个时刻使我们的叶子数量大于 \(3\) 个,下一次若问 \(n-1\) 则直接爆炸,所以要么就是离线下来考虑,要么就是使每时每刻的叶子数量 \(\le 3\)。显然后者更简单。

考虑一个更一般的思路,使 \(1\) 始终为叶子,从点 \(2\) 开始引出两个分叉,大概是这样子的:

我们强制选择一个分叉,比如左边那个,然后多了就移到右边,少了就从右边补,就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int rd() {
	int s=0,m=0;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
	while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return m?-s:s;
}
int t,n,q;
vector<int> a,b;
signed main() {
	cin>>t;
	while(t--) {
		n=rd(),q=rd();
		a.clear(),b.clear();
		a.push_back(2);
		for(int i=2;i<=n;i++)
			b.push_back(i),printf("%lld %lld\n",i-1,i);
		while(q--) {
			int d=rd();
			if(a.size()==d||b.size()==d) 
				printf("-1 -1 -1\n");
			else if(a.size()<d) {
				int id=b.size()-(d-a.size());
				printf("%lld %lld %lld\n",b[id],b[id-1],a[a.size()-1]);
				for(int i=id;i<b.size();i++)
					a.push_back(b[i]);
				for(int i=b.size()-1;i>=id;i--)
					b.pop_back();
			}
			else {
				printf("%lld %lld %lld\n",a[d],a[d-1],b[b.size()-1]);
				for(int i=d;i<a.size();i++)
					b.push_back(a[i]);
				for(int i=a.size()-1;i>=d;i--)
					a.pop_back();
			}
		}
	}
	return 0;
}

标签:ch,int,题解,CF1899F,back,--,lld
From: https://www.cnblogs.com/operator-/p/17974760

相关文章

  • P6550题解
    P6550[COCI2010-2011#2]LUNAPARK题目传送门题解论证简单,构造逆天(好吧其实就是烦了点)。每个格子是正整数,所以我们必然尝试多走格子。我们发现,只要\(r,c\)中有一个是奇数,我们就可以全部走到,构造很简单:我们找准奇数边,假设是\(r\),蛇形地走,显然在奇数行我们会结束在末尾,在偶数......
  • P5133题解
    P5133tb148的客人题目传送门题解唯一的一篇题解还是交错题的……很简单的一个二分加差分题。显然是二分答案,考虑检验。如果\(2mid+1\gen\),那么所有人可以自由去到任意位置,一定可行;否则,我们求出每个人可以去到的区间范围,并以此推出要满足这个人的限制,\(1\)号需要在哪个区......
  • P3867题解
    P3867[TJOI2009]排列计数题目传送门题解\(k\)很小,不是分讨就是突破口。如果我们用这种方式生成排列:将\(1\)到\(n\)按顺序插入当前状态,那么你会发现当前的数\(x\)的插入被很大程度的限制住了,我们只需记录当前\(x-k\)到\(x-1\)的位置即可枚举出所有可能的下一状态,因......
  • P7312题解
    P7312[COCI2018-2019#2]Sunčanje题目传送门题解分类讨论的思想有点像P4169?要你对于每一个矩形,求是否存在编号比它大,与它有交的矩形。直接做需要用一个比较神仙的线段树用法,所以我们可以容斥:我们求出编号比它大,与它无交的矩形数量,最后与所有可能覆盖它的矩形共\(n-i\)个......
  • P6554题解
    P6554PromisesICan'tKeep题目传送门题解看题解都有些做烦了,就来发一篇。换根dp。第一遍dfs处理出\(Lef_u\)表示\(u\)子树内的叶子个数(包含自己),然后求出以\(1\)为根时的答案\(\sumLef_u*val_u\),注意特判根为叶子的情况。第二遍dfs大力换根就好了,从根\(u\)......
  • P9744题解
    P9744「KDOI-06-S」消除序列题目传送门题解记错时间错过模拟赛的sb来也。题目中的最关键信息就是\(a_i,b_i,c_i\ge0\),这意味着多做无用的操作一定不优,所以有:结论\(1\):优先进行\(1\)操作。这是因为我们不管我们在\(1\)操作前做什么操作都会被其推平覆盖,是无用操......
  • P8047题解
    P8047[COCI2015-2016#4]GALAKSIJA题目传送门题解显然是要删边变加边的,然后联通性也是显然要用并查集维护的,就是路径异或和需要一个数据结构来维护。发现:加边删边不影响两个点的路径异或和。所以我们可以处理出每个点到\(1\)号节点的路径异或和\(d\),于是\(Path_{u,v}=d_u......
  • P8034题解
    P8034[COCI2015-2016#7]Ozljeda题目传送门题解评橙差不多了。手玩一下样例,很容易发现\(x\)的循环节为\(K+1\),每一段分别为\(a_1,a_2,a_3,\dots,a_K,\bigoplus_{i=1}^Ka_i\)这几项,然后恰好循环节的异或值为\(0\),所以就可以直接维护前缀异或值,然后取模求答案。代码:#i......
  • [AGC048D] Pocky Game 题解
    题目链接点击打开链接题目解法好难的题,想不出来一点!!!首先给出一个第一个结论:最优策略下,每个人每次只会取一个石子或者取完一堆石子题解区都没有严谨证明,\(at\)的\(editorial\)也没证,所以我只能感性理解:下面以先手为例。如果最左边的石子数\(>\)其余所有堆的石子数,那么先......
  • 题解 WD与数列
    P5161WD与数列可以想到原条件是一个差分形式,所以我们对原数组差分。然后发现答案其实就是\(\sum_{i<j}\min(lcp(i+1,j+1)+1,j-i)\)。这个东西先跑SA,然后建笛卡尔树。考虑对于一个区间,其值为\(x\)。那么相当于是求\(\sum_{l\inS,r\inT}\min(|sa_{l}-sa_{r}|,x)\)。笛......