2 条题解
-
0
思路
题目给定个区间,要求查询区间内不同元素的个数,又轮到莫队发力了。
AC代码
#include<bits/stdc++.h> using namespace std; const int N=5e5+10; struct node{int l,r,x,id;}q[N]; int a[N],b[N],v[N],n,Q,ans[N],B,cnt; void add(int x){if(!v[b[x]])cnt++;v[b[x]]++;} void del(int x){v[b[x]]--;if(!v[b[x]])cnt--;} bool cmp(node n1,node n2) { if(n1.l/B!=n2.l/B)return n1.l<n2.l; if((n1.l/B)&1)return n1.r<n2.r; return n1.r>n2.r; } int main() { scanf("%d%d",&n,&Q); B=sqrt(max(1,n)); for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i]; sort(a+1,a+n+1); int m=unique(a+1,a+n+1)-a-1; for(int i=1;i<=Q;i++) { scanf("%d%d",&q[i].l,&q[i].r); q[i].l++;q[i].id=i; } for(int i=1;i<=n;i++)b[i]=lower_bound(a+1,a+m+1,b[i])-a; sort(q+1,q+Q+1,cmp); int l=1,r=0; for(int i=1;i<=Q;i++) { while(r<q[i].r)add(++r); while(r>q[i].r)del(r--); while(l<q[i].l)del(l++); while(l>q[i].l)add(--l); ans[q[i].id]=cnt; } for(int i=1;i<=Q;i++)printf("%d\n",ans[i]); return 0; }还是不能忘记的情况啊!
-
0
#include<bits/stdc++.h> using namespace std; const int N=5e5+10; int c[N],n,pre[N],a[N],b[N],blen,ans[N]; void add(int x,int k){for(;x<=n;x+=x&-x)c[x]+=k;} int get(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;} struct node{int l,r,id;}e[N]; bool cmp(node n1,node n2){return n1.r<n2.r;} int main() { cin>>n;int m;cin>>m; for(int i=1;i<=n;i++)cin>>a[i],b[++blen]=a[i]; sort(b+1,b+blen+1);int k=unique(b+1,b+blen+1)-b-1; for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+k+1,a[i])-b; for(int i=1;i<=m;i++)cin>>e[i].l>>e[i].r,e[i].id=i,e[i].l++; sort(e+1,e+m+1,cmp); int sum=0; for(int i=1;i<=m;i++) { while(sum<e[i].r) { sum++; if(pre[a[sum]])add(pre[a[sum]],-1); add(sum,1);pre[a[sum]]=sum; } ans[e[i].id]=get(e[i].r)-get(e[i].l-1); } for(int i=1;i<=m;i++)cout<<ans[i]<<'\n'; return 0; }
- 1
信息
- ID
- 8145
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 7
- 标签
- 递交数
- 22
- 已通过
- 8
- 上传者