首页 > 其他分享 >P8866 [NOIP2022] 喵了个喵

P8866 [NOIP2022] 喵了个喵

时间:2022-11-29 19:35:22浏览次数:79  
标签:GetC 空栈 int 元素 P8866 NOIP2022 2n include

\(\mathcal Link\)

当 \(k=2n-2\):保证任意时刻每种元素只出现一次,并保留一个空栈,让其他栈大小不超过 \(2\) 即可。

当 \(k=2n-1\):延续上面的做法,对于多出来的第 \(2n-1\) 元素 \(x\) ,意识到空栈只在进行操作二时有用,因此考虑对下一个出现的非栈顶元素 \(x'\) 分类讨论。

  • \(x=x'\):此时直接将 \(x\) 放入空栈。
  • \(x'\) 上方元素在扫描过程中出现奇数次:此时将 \(x\) 放入空栈后,进行到 \(x'\) 时,\(x'\) 上方无元素,可以直接消掉后得到新的空栈。
  • 若出现偶数次:将 \(x\) 放在 \(x'\) 所在栈最上方,然后将偶数次的元素放入空栈消光,用操作二消去 \(x'\) 即可。

代码实现有难度。

#include <cstdio>
#include <cctype>
#include <queue>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
char buf[1<<14],*p1=buf,*p2=buf;
#define GetC() ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++)
struct Ios{}io;
template <typename _tp>
Ios &operator >>(Ios &in,_tp &x){
	x=0;int w=0;char c=GetC();
	for(;!isdigit(c);w|=c=='-',c=GetC());
	for(;isdigit(c);x=x*10+(c^'0'),c=GetC());
	if(w) x=-x;
	return in;
}
const int N=305,M=2e6+5;
int a[M];
int is[N*2];
int sz[N],val[N][3];
struct ans_t{int op,s1,s2;};
#define pb push_back
int main(){
	int T;io>>T;
	while(T--){
		vector<ans_t> v;
		queue<int> q1,q2;
		int n,m,k;io>>n>>m>>k;
		for(int i=1;i<=m;++i) io>>a[i];
		for(int i=1;i<=n;++i) sz[i]=0,val[i][1]=val[i][2]=0;
		for(int i=1;i<n;++i) q1.push(i),q2.push(i);
		for(int i=1;i<=k;++i) is[i]=0;
		int point=n;
		for(int i=1;i<=m;++i){
			if(is[a[i]]){
				int pos=is[a[i]];
				if(val[pos][sz[pos]]==a[i]){
					v.pb({1,pos,0});
					if(sz[pos]==2) q2.push(pos);
					else q1.push(pos);
					--sz[pos];
				}
				else{
					v.pb({1,point,0});
					v.pb({2,pos,point});
					val[pos][1]=val[pos][2];
					--sz[pos];
					q2.push(pos);
				}
				is[a[i]]=0;
			}
			else{
				if(!q1.empty()){
					int pos=q1.front();q1.pop();
					v.pb({1,pos,0});
					is[a[i]]=pos;
					val[pos][++sz[pos]]=a[i];
				}
				else if(!q2.empty()){
					int pos=q2.front();q2.pop();
					v.pb({1,pos,0});
					is[a[i]]=pos;
					val[pos][++sz[pos]]=a[i];
				}
				else{
					bitset<N*2> s;
					s.reset();
					int j=i+1;
					for(;j<=m;++j){
						if(a[j]==a[i]||val[is[a[j]]][1]==a[j]) break;
						s.flip(a[j]);
					}
					int tmp=j;
					if(a[tmp]==a[i]){
						v.pb({1,point,0});
						for(j=i+1;j<tmp;++j){
							if(is[a[j]]){
								int pos=is[a[j]];
								v.pb({1,pos,0});
								--sz[pos];
								q2.push(pos);
								is[a[j]]=0;
							}
							else{
								int pos=q2.front();q2.pop();
								v.pb({1,pos,0});
								is[a[j]]=pos;
								val[pos][++sz[pos]]=a[j];
							}
						}
						v.pb({1,point,0});
					}
					else if((int)s[val[is[a[tmp]]][2]]==1){//挂了,记之
						v.pb({1,point,0});
						for(j=i+1;j<tmp;++j){
							if(a[j]==val[is[a[tmp]]][2]){
								v.pb({1,is[a[tmp]],0});
								is[a[j]]=0;
							}
							else if(is[a[j]]){
								int pos=is[a[j]];
								v.pb({1,pos,0});
								--sz[pos];
								is[a[j]]=0;
								q2.push(pos);
							}
							else{
								int pos=q2.front();q2.pop();
								v.pb({1,pos,0});
								is[a[j]]=pos;
								val[pos][++sz[pos]]=a[j];
							}
						}
						v.pb({1,is[a[tmp]],0});
						sz[point]=1;
						val[point][1]=a[i];
						q2.push(point);
						is[a[i]]=point;

						sz[is[a[tmp]]]=0;
						point=is[a[tmp]];
						is[a[tmp]]=0;
					}
					else{
						v.pb({1,is[a[tmp]],0});
						for(j=i+1;j<tmp;++j){
							if(a[j]==val[is[a[tmp]]][2]) v.pb({1,point,0});//挂了,记之。
							else if(is[a[j]]){
								int pos=is[a[j]];
								v.pb({1,pos,0});
								--sz[pos];
								is[a[j]]=0;
								q2.push(pos);
							}
							else{
								int pos=q2.front();q2.pop();
								v.pb({1,pos,0});
								is[a[j]]=pos;
								val[pos][++sz[pos]]=a[j];
							}
						}
						v.pb({1,point,0});
						v.pb({2,is[a[tmp]],point});
						int pos=is[a[tmp]];
						val[pos][1]=val[pos][2];
						val[pos][2]=a[i];
						sz[pos]=2;
						is[a[i]]=pos;
						is[a[tmp]]=0;
					}
					i=tmp;
				}
			}
		}
		printf("%d\n",(int)v.size());
		for(auto tmp:v){
			if(tmp.op==1) printf("1 %d\n",tmp.s1);
			if(tmp.op==2) printf("2 %d %d\n",tmp.s1,tmp.s2);
		}
	}
	return 0;
}

Bug 合集:

考场代码:删除未更新 is[],插入未更新 val[]

35pts: bitset 类型未转为 int 就比较。

50pts: i,j, tmp 分不清。

标签:GetC,空栈,int,元素,P8866,NOIP2022,2n,include
From: https://www.cnblogs.com/pref-ctrl27/p/16936454.html

相关文章

  • NOIP2022 游记
    怕不是真要NOIP退役了……Day-10果断停课,回归机房。(但whk已经在上三角函数了……血亏,以后再补吧)补了补之前的题目。晚上模拟赛爆零了!!好耶(埋伏笔)Day-9~Day-5......
  • NOIP2022 VP 游寄
    考前给大家说一下我糟糕的模拟赛成绩:\(\operatorname{rk}29\)(总人数\(32\))感觉NOIP2022无望了。(最后再说一句,我的CSP/S太菜了,才\(165\)分,无缘NOIP正式名额,只......
  • NOIP2022
    NOIP2022总结考前早上主要看了点随机化和部分分写法什么的感觉有点脱离了大纲,图论那块一直不是很好也没怎么复习有点紧张,尽管不是现场赛,但是还是有点怕分数太低QA......
  • NOIP2022 游记
    今年的NOIP已经结束了,因为T2的细节错误和T3的傻逼大样例,308分挂成了不到200分。这成绩还不如学了一年文化课的khj……在infoj上排名67,今年省队是肯定没戏了。......
  • NOIp2022 游记
    无论结局如何,我都曾经来过。Day-1zak模拟赛,被殴打了。Day0上午补模拟赛题。下午补模拟赛题。徐老师过来分配了第二天下午造数据名单。我造T2。希望不会太难......
  • NOIP2022 游记
    想到什么说什么吧,这个人语文很差,文笔无聊day0上午在水B站,下午突然心血来潮新开了个神居的存档一下午打了3个门,万神殿打了大半,辐辉级都打了好几个晚上突然意识到明......
  • NOIP2022 Prewalk
    2022.11.25PreTalkNOIP前的一晚不知觉5个月飞逝,作为高二生也3月有余。很喜欢Alex_Wei说过的,收获来源于成长一切都是未知,我们渴望、尝试从已知推向或者说推导未知之......
  • NOIP2022 游记
    无所谓失败可言,等待你是明天。Day2022.11.27Day2022.11.25写过一篇总结应该算是,没来得及发出,Siteishere。Day2022.11.26NOIP2022如约而至8:30开考,T1plant30......
  • P8867 [noip2022]建造军营 题解
    题意:给定一张图,选择一些点和一些边,使得割断任意没有选的边,被选中的点仍连通。对\(10^9+7\)取膜。\(n\leq5\cdot10^5\)这篇题解会略讲缩边,详讲自己推dp状态与......
  • NOIP2022 又寄。
    前30min照常写板子。在缺省源末尾加上了以下注释,旨在挂分的时候少挂一点(flag)。/***Author:chenxia25*Pleasegivememorepoints!*/看T1。怎么这么简单?看......