题解:P11912 [PA 2025] 集合 2 / Zbiory 2
前言
小清新构造题。
Solution
首先设当前集合为
我们将
- 当
x\in S 且x\not\in T 时,考虑如何删除元素x 。这时我们可以通过 3 操作将集合变为U 的补集,然后与A_x 取并之后再取一次补集即可。 - 否则,直接
S\cup A_i\to S 即可。
直接做的操作次数最多是
我们发现集合
以下代码最多进行
Code
#include<bits/stdc++.h>
#include<cmath>
#define ll long long
#define ld long double
#define ull unsigned long long
#define lll __int128
#define N 500010
#define ls x<<1
#define rs x<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define For(i,a,b) for(ll i=a;i<=b;++i)
#define Rof(i,a,b) for(ll i=a;i>=b;--i)
#define mk make_pair
#define pb emplace_back
#define pii pair<ll,ll>
#define pque priority_queue
#define fi first
#define se second
using namespace std;
struct node{
int op,x,y;
};
vector<node >ans;
int a[N],b[N];
int n,k,now=0;
ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
n=read(),k=read();
For(i,1,k) a[read()]=1;
int m=n;
m++;
ans.pb((node){3,1,0});
For(i,1,n){
if(!b[i] && a[i]){
if(now){
now^=1;
m++;
ans.pb((node){3,m-1,0});
}
for(int j=i;j<=n;j+=i) b[j]=1;
ans.pb((node){1,m,i});
m++;
}else if(b[i] && !a[i]){
if(!now){
now^=1;
m++;
ans.pb((node){3,m-1,0});
}
for(int j=i;j<=n;j+=i) b[j]=0;
ans.pb((node){1,m,i});
m++;
}
}
if(now){
now^=1;
m++;
ans.pb((node){3,m-1,0});
}
cout<<(int)ans.size()<<endl;
for(node i:ans){
if(i.op==3) cout<<i.op<<' '<<i.x<<endl;
else cout<<i.op<<' '<<i.x<<' '<<i.y<<endl;
}
return 0;
}
/*
*/