UNV637 【美团杯2021 A】数据结构
题意简介
给定一个长度为
做法分析
问的是颜色数,也即考虑每一种数值出现与否。考虑每种数什么时候出现或不出现。一个数
由于这是CNDS考虑把询问离线下来,贡献加减变成矩形做扫描线。具体来说,这个扫描线长这个样子。我们记
具体怎么框定?对于只能由
除此之外,其做不出贡献的区间形如
特殊地,当存在
(为什么这里维护做不出贡献的区间?因为区间数量少,空间复杂度有保证。)
举个例子:当序列为
(废话?预警)哦那么扫描线有多少条呢?首先一个矩形对应两条线,所以空间自带两倍常熟。二类贡献显然是每个
所以简简简而言之就是:存线段数组开四倍空间。
代码实现
找那啥二类的
如果 tmp1
找到了 N+1
要特殊处理。
#include <bits/stdc++.h>
using namespace std;
namespace obasic{
typedef vector<int> vecint;
template <typename _T>
void frdi(_T &x){
_T k=1;x=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')k=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
x*=k;return;
}
template <typename _T>
void fwri(_T x){
if(x<0)putchar('-'),x=-x;
if(x>9)fwri(x/10);
putchar(x%10+'0');
}
template <typename _T>
int lwberv(vector<_T> &vec,_T val){return *lower_bound(vec.begin(),vec.end(),val);}
};
using namespace obasic;
const int MaxN=1e6+5;
int N,M,A[MaxN],pre[MaxN],pap[MaxN];
int acnt[MaxN],tot,ans[MaxN];
struct quer{int x,y,id;}Q[MaxN];
bool cmp1(quer a,quer b){return a.x<b.x;}
vecint apr[MaxN];int scnt;
struct aseg{int x,ly,ry,v;}S[MaxN<<2];
void addrect(int lx,int rx,int ly,int ry){
S[++scnt]={lx,ly,ry,1};
S[++scnt]={rx+1,ly,ry,-1};
}
bool cmp2(aseg a,aseg b){return a.x<b.x;}
struct BinidTree{
int n,t[MaxN];
void init(int x){n=x,memset(t,0,sizeof(t));}
int lowbit(int x){return x&(-x);}
void add(int p,int x){for(;p<=n;p+=lowbit(p))t[p]+=x;}
void update(int l,int r,int x){add(l,x),add(r+1,-x);}
int gts(int p){int res=0;for(;p;p-=lowbit(p)){res+=t[p];}return res;}
}BidTr;
int main(){
frdi(N),frdi(M);BidTr.init(N+1),tot=N+1;
for(int i=0;i<=N+1;i++)apr[i].push_back(0);
for(int i=1;i<=N;i++){
frdi(A[i]);apr[A[i]].push_back(i);
acnt[A[i]]++;pre[i]=pap[A[i]],pap[A[i]]=i;
}
for(int i=0;i<=N+1;i++)apr[i].push_back(N+1);
int tmp1,tmp2,clx,crx,cly,cry;
for(int i=1;i<=N+1;i++){
int cc=acnt[i],pc=acnt[i-1];
if(!cc){
if(!pc){tot--;continue;}
for(int j=1,p,q=0;j<=pc+1;j++){
p=q,q=apr[i-1][j];
if(q==p+1)continue;
addrect(p+1,q-1,p+1,q-1);
}
continue;
}
tmp1=lwberv(apr[i-1],apr[i][1]);
if(tmp1<apr[i][acnt[i]])continue;
tmp2=lwberv(apr[i-1],apr[i][cc]);
crx=apr[i][1],cly=apr[i][acnt[i]];
clx=(tmp1==N+1?apr[i-1][pc]:pre[tmp1])+1,cry=tmp2-1;
addrect(clx,crx,cly,cry);
continue;
}
sort(S+1,S+scnt+1,cmp2);
for(int i=1;i<=M;i++)frdi(Q[i].x),frdi(Q[i].y),Q[i].id=i;
sort(Q+1,Q+M+1,cmp1);for(int i=1,p=1,q=1;i<=N+1;i++){
for(;p<=scnt&&S[p].x==i;p++)BidTr.update(S[p].ly,S[p].ry,S[p].v);
for(;q<=M&&Q[q].x==i;q++)ans[Q[q].id]=tot-BidTr.gts(Q[q].y);
}
for(int i=1;i<=M;i++)fwri(ans[i]),puts("");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架