先是树状数组代码
在线做法应该是非常耗时的
所以这里考虑离线做法
按照每次询问的r边界进行从小到大的排序
就可以处理了
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N];
int tree[N];
int flag[N];
int n;
int res[N];
struct node{
int l,r;
int id;
int pos;
bool operator < (const node &a)const{
return r<a.r;
}
}ask[N];
int lowbit(int x)
{
return x&(-x);
}
void add(int nowv,int now)
{
while(nowv<=n){
tree[nowv]+=now;
nowv+=lowbit(nowv);
}
}
int sum(int x)
{
int tmp=0;
while(x!=0){
tmp+=tree[x];
x-=lowbit(x);
}
return tmp;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",a+i);
}
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&ask[i].l,&ask[i].r);
ask[i].pos=i;
}
sort(ask+1,ask+m+1);
int las_r=1;
for(int i=1;i<=m;i++){
int l=ask[i].l;
int r=ask[i].r;
for(int j=las_r;j<=r;j++){
if(flag[a[j]]){
add(flag[a[j]],-1);
}
add(j,1);
flag[a[j]]=j;
}
res[ask[i].pos]=sum(r)-sum(l-1);
las_r=r+1;
}
for(int i=1;i<=m;i++){
printf("%d\n",res[i]);
}
return 0;
}
线段树代码
没有加快读会TLE掉
但是线段树功能强大
加深一下理解
#include <bits/stdc++.h> //线段树TLE掉了
using namespace std;
const int N=1e6+5;
int a[N];
int las[N];
int pos[N];
int ans[N];
struct node{
int l,r;
int v;
}tree[N<<6];
struct node2{
int l,r;
int id;
bool operator < (const node2& a)const{
return r<a.r;
}
}q[N];
void build(int l,int r,int flag)
{
if(l==r){
tree[flag].l=tree[flag].r=l;
return ;
}
tree[flag].l=l;
tree[flag].r=r;
int mid=(l+r)/2;
build(l,mid,flag*2);
build(mid+1,r,flag*2+1);
}
void change(int flag,int pos,int type)
{
if(tree[flag].r==tree[flag].l){
tree[flag].v=type;
return ;
}
int mid=(tree[flag].r+tree[flag].l)/2;
if(pos<=mid){
change(flag*2,pos,type);
}else{
change(flag*2+1,pos,type);
}
tree[flag].v=tree[flag*2].v+tree[flag*2+1].v;
}
int ask(int flag,int l,int r)
{
if(tree[flag].l==l&&tree[flag].r==r){
return tree[flag].v;
}
int mid=(tree[flag].l+tree[flag].r)/2;
if(r<=mid){
return ask(flag*2,l,r);
}else if(l>mid){
return ask(flag*2+1,l,r);
}
return ask(flag*2,l,mid)+ask(flag*2+1,mid+1,r);
}
int main()
{
build(1,N-4,1);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",a+i);
las[i]=pos[a[i]];
pos[a[i]]=i;
}
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+m+1);
int las_r=1;
for(int i=1;i<=m;i++){
int l=q[i].l;
int r=q[i].r;
for(int i=las_r;i<=r;i++){
if(las[i]!=0){
change(1,las[i],0);
}
change(1,i,1);
}
ans[q[i].id]=ask(1,l,r);
las_r=r+1;
}
for(int i=1;i<=m;i++){
printf("%d\n",ans[i]);
}
return 0;
}
转载:https://blog.csdn.net/qq_44833767/article/details/104415893
查看评论