51Nod1962 区间计数
这题与之前那道区间最值的题非常类似,依旧是二分区间,然后统计跨过中间点的区间贡献。
我们要选出小于等于和小于的,这样就可以算出相等的区间长了。
复杂度O(nlogn)
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll ans;int n; 5 const int N=350005; 6 void add(ll x){ans+=x;} 7 int a[2][N],p[2][3],l[2][N],r[2][N]; 8 void solve(int ll,int rr) 9 { 10 if(ll==rr){if(a[0][ll]==a[1][ll])add(1);return;} 11 int mid=ll+rr>>1; 12 solve(ll,mid);solve(mid+1,rr); 13 for(int k=0;k<=1;++k) 14 { 15 l[k][mid]=a[k][mid];for(int i=mid-1;i>=ll;--i)l[k][i]=max(l[k][i+1],a[k][i]); 16 r[k][mid]=a[k][mid];for(int i=mid+1;i<=rr;++i)r[k][i]=max(r[k][i-1],a[k][i]); 17 } 18 for(int k=0;k<=1;++k)for(int i=0;i<=3;++i)p[k][i]=mid; 19 for(int i=mid;i>=ll;--i) 20 { 21 for(int k=0;k<=1;++k) 22 { 23 while(p[k][0]<rr&&r[k][p[k][0]+1]<=l[k][i])p[k][0]++; 24 while(p[k][1]<rr&&r[k][p[k][1]+1]<l[k^1][i])p[k][1]++; 25 while(p[k][2]<rr&&r[k][p[k][2]+1]<=l[k^1][i])p[k][2]++; 26 } 27 if(l[0][i]==l[1][i])add(max(0,min(p[0][0],p[1][0])-mid)); 28 else if(l[0][i]>l[1][i])add(max(0,min(p[1][2],p[0][0])-p[1][1])); 29 else add(max(0,min(p[0][2],p[1][0])-p[0][1])); 30 } 31 int pos=mid+1; 32 for(int i=mid+1;i<=rr;++i) 33 { 34 while(pos>ll&&max(l[1][pos-1],l[0][pos-1])<max(r[1][i],r[0][i]))--pos; 35 if(r[0][i]==r[1][i])add(max(0,mid-pos+1)); 36 } 37 } 38 int main() 39 { 40 scanf("%d",&n); 41 for(int k=0;k<=1;++k) 42 for(int i=1;i<=n;++i) 43 scanf("%d",&a[k][i]); 44 solve(1,n); 45 printf("%lld\n",ans); 46 return 0; 47 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。