1. 程式人生 > >luogu 1972 小H的項鏈

luogu 1972 小H的項鏈

getch isdigit spa known efi bits c++ () a*

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 }

luogu 1972 小H的項鏈