https://nanti.jisuanke.com/t/41384
树状数组是天,1e6*logn*logn随便跑
离散化所有点和区间,要染色的点单点作为一个点,然后两个染色点之间的区间也作为一个点,然后二分找第一个位置在哪。
但是牛逼的标程用unorderd_map+并查集,f[x]存x右边第一个在哪,初始的是f[x]=x+1
unorderd_map的存取查询操作都近似于O(1),map是带log的,而且1e6太大,map会T
#include<bits/stdc++.h>
using namespace std;
int n,q;
unordered_map<int,int> f;
inline int find(int x)
{
if(!f.count(x))
return x;
else
{
f[x]=find(f[x]);
return f[x];
}
}
int main()
{
int x,op;
scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&op,&x);
if(op==1)
f[x]=find(x+1);
else
printf("%d\n",find(x));
}
return 0;
}
#include<bits/stdc++.h>
#define maxl 2000010
using namespace std;
int n,q,cnt,cnt1,cnt2,tot,ans;
int op[maxl],a[maxl],num[maxl],dyl[maxl],dyr[maxl];
int b[maxl];
bool flag;
bool in[maxl];
inline void prework()
{
cnt1=0,cnt2=0;
for(int i=1;i<=q;i++)
{
scanf("%d%d",&op[i],&a[i]);
if(op[i]==1)
num[++cnt1]=a[i];
}
sort(num+1,num+1+cnt1);
cnt=unique(num+1,num+1+cnt1)-num-1;
tot=0;
if(num[1]>1)
++tot,dyl[1]=1,dyr[1]=num[1]-1;
for(int i=1;i<=cnt;i++)
{
++tot;dyl[tot]=num[i];dyr[tot]=num[i];
if(i<cnt)
{
if(num[i]+1<num[i+1])
++tot,dyl[tot]=num[i]+1,dyr[tot]=num[i+1]-1;
}
else
{
if(num[i]+1<=n)
++tot,dyl[tot]=num[i]+1,dyr[tot]=n;
}
}
}
inline void add(int i)
{
while(i<=tot)
{
b[i]++;
i+=i&-i;
}
}
inline int sum(int i)
{
int ret=0;
while(i)
{
ret+=b[i];
i-=i&-i;
}
return ret;
}
inline void mainwork()
{
for(int i=1;i<=tot;i++)
b[i]=0,in[i]=false;
int id,l,r,mid;
for(int i=1;i<=q;i++)
if(op[i]==1)
{
id=lower_bound(dyl+1,dyl+1+tot,a[i])-dyl;
if(!in[id])
in[id]=true,add(id);
}
else
{
id=upper_bound(dyl+1,dyl+1+tot,a[i])-dyl;
id--;
l=id,r=tot;
while(l+1<r)
{
mid=(l+r)>>1;
if(sum(mid)-sum(id-1)==(mid-(id-1)))
l=mid;
else
r=mid;
}
if(sum(l)-sum(id-1)<(l-(id-1)))
ans=l;
else
ans=l+1;
if(ans==id)
ans=a[i];
else
ans=dyl[ans];
printf("%d\n",ans);
}
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
prework();
mainwork();
}
return 0;
}