题解真的是太神奇了2333
用离线和树状数组(为什么感觉和HH的项链是的,什么鬼),比较巧妙的是他把整个数列分成几段。用一个vector来记录每个数出现的位置。一共就是data[a[i]][sz]---data[a[i]][sz-a[i]],data[a[i]][sz-a[i]]----data[a[i]][sz-a[i]-1],0----data[a[i]][sz-a[i]-1],第一个区间的数是1,第二个区间是-1,第三个是0,这样区间加减的话就直接出来了是不是成立一共有a[i]个a[i]而且,还可以往后递推,太神奇了2333
1 #include<bits/stdc++.h> 2 #define lowbit(x) x&(-x) 3 #define LL long long 4 #define N 200005 5 #define M 1000005 6 #define mod 1000000007LL 7 #define inf 0x7ffffffff 8 using namespace std; 9 inline int ra() 10 { 11 int x=0,f=1; char ch=getchar(); 12 while (ch<'0' || ch>'9'){if (ch=='-') f=-1; ch=getchar();} 13 while (ch>='0' && ch<='9'){x=x*10+ch-'0'; ch=getchar();} 14 return x*f; 15 } 16 int c[N],ans[N],a[N],n,m; 17 struct node{ 18 int l,r,id; 19 bool operator < (const node t) {return r<t.r;} 20 }q[N]; 21 void add(int i, int v) 22 { 23 while (i<=n) 24 { 25 c[i]+=v; 26 i+=lowbit(i); 27 } 28 } 29 int ask(int x) 30 { 31 int sum=0; 32 while (x>0) 33 { 34 sum+=c[x]; 35 x-=lowbit(x); 36 } 37 return sum; 38 } 39 vector<int> data[N]; 40 int main() 41 { 42 int sz; n=ra();m=ra(); 43 for (int i=1; i<=n; i++) a[i]=ra(); 44 for (int i=1; i<=m; i++) 45 { 46 q[i].l=ra(),q[i].r=ra(); 47 q[i].id=i; 48 } 49 sort(q+1,q+m+1); 50 for (int i=1,k=1; i<=n; i++) 51 { 52 if (a[i]<=n) 53 { 54 data[a[i]].push_back(i); 55 sz=data[a[i]].size(); 56 if (sz>=a[i]) 57 { 58 add(data[a[i]][sz-a[i]],1); 59 if (sz>a[i]) add(data[a[i]][sz-a[i]-1],-2); 60 if (sz>a[i]+1) add(data[a[i]][sz-a[i]-2],1); 61 } 62 } 63 while (q[k].r==i && k<=m) 64 { 65 ans[q[k].id]=ask(q[k].r)-ask(q[k].l-1); 66 k++; 67 } 68 for (int j=1; j<=n; j++) 69 printf("%d ",ask(j)); 70 cout<<endl; 71 } 72 for (int i=1; i<=m; i++) 73 printf("%d ",ans[i]); 74 return 0; 75 }