社区讨论
关于lower_bound&upper_bound
P1975[国家集训队] 排队参与者 3已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @mi7wcsy9
- 此快照首次捕获于
- 2025/11/21 04:41 4 个月前
- 此快照最后确认于
- 2025/11/21 04:41 4 个月前
,可以直接这样在分块内查找大于或小于的数的个数吗
CPPfor(int i=block[l]+1;i<=block[r]-1;++i)
temp+=atag[i].size()-(upper_bound(atag[i].begin(),atag[i].end(),x)-atag[i].begin());//查找块内大于x的数的个数
for(int i=block[l]+1;i<=block[r]-1;++i)
temp+=lower_bound(atag[i].begin(),atag[i].end(),x)-atag[i].begin();//查找块内小于x的数的个数
昨晚自己造数据调了一个晚上,发现把上述代码改成循环暴力答案就对。找不出有什么错,求助们。
另外挂上自己的源代码,(其他应该没什么错。。吧)
CPP#include<bits/stdc++.h>
#define N 20005
using namespace std;
vector<int> atag[200];
int block[N],v[N],blo,Ans,n;
inline int read()
{
int 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;
}
inline int greater_query(int x,int l,int r)
{
int temp=0;
for(int i=l;i<=min(r,block[l]*blo);i++)
if(v[i]>x) temp++;
if(block[l]==block[r]) return temp;
for(int i=(block[r]-1)*blo+1;i<=r;++i)
if(v[i]>x) temp++;
for(int i=block[l]+1;i<=block[r]-1;++i)
temp+=atag[i].size()-(upper_bound(atag[i].begin(),atag[i].end(),x)-atag[i].begin());
return temp;
}
inline int less_query(int x,int l,int r)
{
int temp=0;
for(int i=l;i<=min(r,block[l]*blo);i++)
if(v[i]<x) temp++;
if(block[l]==block[r]) return temp;
for(int i=(block[r]-1)*blo+1;i<=r;++i)
if(v[i]<x) temp++;
for(int i=block[l]+1;i<=block[r]-1;++i)
temp+=lower_bound(atag[i].begin(),atag[i].end(),x)-atag[i].begin();
return temp;
}
inline void modify_pos(int l,int r)
{
if(block[l]==block[r]) {swap(v[l],v[r]);return;}
int pl=lower_bound(atag[l].begin(),atag[l].end(),v[l])-atag[l].begin();
atag[block[l]][pl]=v[r];
while(pl&&atag[block[l]][pl]<atag[block[l]][pl-1])
swap(atag[block[l]][pl],atag[block[l]][pl-1]),pl--;
while(pl<atag[block[l]].size()-1&&atag[block[l]][pl]>atag[block[l]][pl+1])
swap(atag[block[l]][pl],atag[block[l]][pl+1]),pl++;
int pr=lower_bound(atag[r].begin(),atag[r].end(),v[r])-atag[r].begin();
atag[block[r]][pr]=v[l];
while(pr&&atag[block[r]][pr]<atag[block[r]][pr-1])
swap(atag[block[r]][pr],atag[block[r]][pr-1]),pr--;
while(pr<atag[block[r]].size()-1&&atag[block[r]][pr]>atag[block[r]][pr+1])
swap(atag[block[r]][pr],atag[block[r]][pr+1]),pr++;
swap(v[l],v[r]);
return;
}
inline void update(int l,int r)
{
if(l==r||v[l]==v[r]) {swap(v[l],v[r]);return;}
int temp_l=less_query(v[l],l,r);
int temp_r=greater_query(v[r],l,r);
modify_pos(l,r);
Ans-=(temp_l+temp_r);
temp_l=less_query(v[l],l,r);
temp_r=greater_query(v[r],l,r);
Ans+=temp_l+temp_r;
if(v[l]<v[r]) Ans++;
if(v[l]>v[r]) Ans--;
}
int main()
{
n=read();
blo=sqrt(n);
for(int i=1;i<=n;++i)
{
v[i]=read();
block[i]=(i-1)/blo+1;
atag[block[i]].push_back(v[i]);
}
for(int i=1;i<=block[n];++i) sort(atag[i].begin(),atag[i].end());
for(int i=1;i<n;++i) Ans+=less_query(v[i],i+1,n);
printf("%d\n",Ans);
int m=read();
for(int i=1;i<=m;++i)
{
int x=read(),y=read();
if(x>y) swap(x,y);
update(x,y);
printf("%d\n",Ans);
}
}
回复
共 9 条回复,欢迎继续交流。
正在加载回复...