我的思路是维护每一条线段中出现过的数的最小值和没有出现过的数的最小值。
操作一就把线段中出现最小值赋为左端点的值 ,没出现最小值赋为 inf 。
操作二和操作一相反,操作三就把最大值最小值 swap 。
代码实现没什么问题,动态开点然后维护这俩个值,样例过了但是在第5个点上 WA 了。
想知道一下自己的思路哪里有问题 qaq 。
#include<bits/stdc++.h>
#define int long long
#define rint register int
using namespace std;
const int N=1e5+5;
const int inf=1e18;
struct node{
int l,r;
int m0,m1; // m0 没出现过 ,m1 出现过
}tr[N<<6];
int n,op,x,y,root,tot,lz[N<<6];
inline int read()
{
rint x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch<='9'&&ch>='0')
x=(x*10)+(ch^48),ch=getchar();
return x;
}
void newnode(int &u,int l,int r)
{
u=++tot;tr[u].m0=l;tr[u].m1=inf+1;
}
void fze(int u,int l,int r,int k)
{
rint mid=l+r>>1;
if(k==3) swap(tr[u].m0,tr[u].m1);
if(k==1) tr[u].m0=inf+1,tr[u].m1=l;
if(k==2) tr[u].m0=l,tr[u].m1=inf+1;
lz[u]=(k<3)?k:k-lz[u]; return;
}
void push_up(int u,int l,int r)
{
rint mid=l+r>>1;
if(!tr[u].l) newnode(tr[u].l,l,mid);
if(!tr[u].r) newnode(tr[u].r,mid+1,r);
tr[u].m0=min(tr[tr[u].l].m0,tr[tr[u].r].m0);
tr[u].m1=min(tr[tr[u].l].m1,tr[tr[u].r].m1);
}
void push_down(int u,int l,int r)
{
if(!lz[u]) return;
rint mid=l+r>>1;
if(!tr[u].l) newnode(tr[u].l,l,mid);
if(!tr[u].r) newnode(tr[u].r,mid+1,r);
fze(tr[u].l,l,r,lz[u]);
fze(tr[u].r,l,r,lz[u]); lz[u]=0; return;
}
void change(int &u,int l,int r)
{
if(!u) newnode(u,l,r);
if(x<=l&&r<=y)
{fze(u,l,r,op);return;}
push_down(u,l,r);
rint mid=l+r>>1;
if(x<=mid) change(tr[u].l,l,mid);
if(y>mid) change(tr[u].r,mid+1,r);
push_up(u,l,r);
}
signed main()
{
n=read();
for(rint i(1);i<=n;++i)
{
op=read(),x=read(),y=read();
change(root,1,inf);
printf("%lld\n",tr[root].m0);
}
return 0;
}