1.莫队算法 TLE 80
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) using namespace std; const int N=50005,M=200005; int h[N],n,m,a[N],ans[M]; struct node{ int l,r,id; bool operator<(const node&b)const{ if(h[l]==h[b.l])return r<b.r; return l<b.l;}}q[M]; inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f;} void block(){ int k=sqrt(n); rep(i,1,n) h[i]=(i-1)/k+1;} int L,R,now,vis[1000005]; //vis实质上记录的是出现次数 void revise(int i,int d){ if(d==1){ if(vis[a[i]]==0)now++;vis[a[i]]++;} else{ vis[a[i]]--;if(!vis[a[i]])now--;}} int main(){ n=read(); rep(i,1,n) a[i]=read(); block();m=read(); rep(i,1,m) q[i].l=read(),q[i].r=read(),q[i].id=i; sort(q+1,q+1+m); rep(i,1,m){ while(L<q[i].l) revise(L++,-1); while(L>q[i].l) revise(--L,1); while(R<q[i].r) revise(++R,1); while (R>q[i].r) revise(R--,-1); ans[q[i].id]=now;} //注意编号问题,会影响值(unknown reasons) rep(i,1,m) printf("%d\n",ans[i]); return 0; }
2.离线树状数组
别人的代码,没看懂,链接:https://www.cnblogs.com/five20/p/7603849.html
#include<bits/stdc++.h> 2 using namespace std; 3 int a[50005],s[50005],has[50005],last[50005],n,m; 4 struct o{ 5 int x,y,num; 6 }q[200005]; 7 inline int gi() 8 { 9 int a=0;char x=getchar();bool f=0; 10 while((x>‘9‘||x<‘0‘)&&x!=‘-‘)x=getchar(); 11 if(x==‘-‘)x=getchar(),f=1; 12 while(x>=‘0‘&&x<=‘9‘)a=a*10+x-‘0‘,x=getchar(); 13 return f?-a:a; 14 } 15 bool cmp(o a,o b) 16 {return a.y<b.y;} 17 inline void add(int k,int a) 18 { 19 while(k<=n) 20 { 21 s[k]+=a; 22 k+=k&-k; 23 } 24 } 25 int ans(int x) 26 { 27 int sum=0; 28 while(x) 29 { 30 sum+=s[x]; 31 x-=x&-x; 32 } 33 return sum; 34 } 35 int main() 36 { 37 n=gi(); 38 for(int i=1;i<=n;i++) 39 {int A=gi();has[i]=last[A]+1;last[A]=i;} 40 m=gi(); 41 for(int i=1;i<=m;i++) 42 { 43 q[i].x=gi();q[i].y=gi();q[i].num=i; 44 } 45 sort(q+1,q+m+1,cmp); 46 int now=1; 47 for(int i=1;i<=m;i++) 48 { 49 while(now<=q[i].y) 50 { 51 now++; 52 add(has[now-1],1); 53 add(now,-1); 54 } 55 a[q[i].num]=ans(q[i].x); 56 } 57 for(int i=1;i<=m;i++) 58 printf("%d\n",a[i]); 59 return 0; 60 }
原文地址:https://www.cnblogs.com/asdic/p/9573910.html
时间: 2025-01-18 02:57:58