https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1981
bitset说明书https://blog.youkuaiyun.com/hallmeow/article/details/76162536
bitset大法好 时空复杂度低的出奇 但这题内存太小 还是要处处小心 线段树数组只能开两倍 还要用永久化标记 最后又加了俩inline才卡过。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <bitset>
using namespace std;
bitset <10010> pre[10010];
bitset <10010> bit[150010],laz[150010];
int n,q;
void init()
{
int i;
pre[0][0]=1;
for(i=1;i<=10000;i++)
{
pre[i]=pre[i-1];
pre[i][i]=1;
}
}
inline void update(int pl,int pr,int tar,int l,int r,int cur)
{
int m;
bit[cur][tar]=1;
if(pl==l&&r==pr)
{
laz[cur][tar]=1;
return;
}
m=(l+r)/2;
if(pr<=m) update(pl,pr,tar,l,m,2*cur);
else if(pl>m) update(pl,pr,tar,m+1,r,2*cur+1);
else
{
update(pl,m,tar,l,m,2*cur);
update(m+1,pr,tar,m+1,r,2*cur+1);
}
}
inline bitset <10010> query(int pl,int pr,bitset <10010> tmp,int l,int r,int cur)
{
int m;
if(pl==l&&r==pr) return tmp|bit[cur];
tmp|=laz[cur];
m=(l+r)/2;
if(pr<=m) return query(pl,pr,tmp,l,m,2*cur);
else if(pl>m) return query(pl,pr,tmp,m+1,r,2*cur+1);
else return query(pl,m,tmp,l,m,2*cur)|query(m+1,pr,tmp,m+1,r,2*cur+1);
}
inline int solve(bitset <10010> tmp,int k)
{
int l,r,m,res;
l=0,r=10000;
while(l<=r)
{
m=(l+r)/2;
if((pre[m]&tmp).count()>=k) r=m-1,res=m;
else l=m+1;
}
return res;
}
int main()
{
bitset <10010> res;
int i,op,l,r,val;
scanf("%d%d",&n,&q);
init();
for(i=1;i<=n;i++)
{
scanf("%d%d%d%d",&op,&l,&r,&val);
if(op==1) update(l,r,val,1,n,1);
else
{
if(val==0) printf("-1\n");
else
{
res.reset();
res=query(l,r,res,1,n,1);
if(res.count()<val) printf("-1\n");
else printf("%d\n",solve(res,val));
}
}
}
return 0;
}