您的位置:首页 > 其它

codeforces 689D

2016-07-25 10:59 387 查看
题意:给出两个序列,计算有多少个区间,第一个序列的最大值等于第二个序列的最小值。

题解:注意到第一个区间的最大值递增,第二个区间的最小值递减。我们可以枚举起点,二分相等位置。

#include<bits/stdc++.h>
using namespace std;

class RMQ{
int n;
vector<int> Log2;
vector<vector<int> > f;
vector<int> a;
public:
RMQ(int n){
this->n=n;
Log2 = vector<int>(n+1);
Log2[1]=0;
for(int i=1;i<=n;i++){
Log2[i]=Log2[i-1];
if(1<<(Log2[i]+1)==i){
Log2[i]++;
}
}
f = vector<vector<int> >(n,vector<int>(Log2
+1));
}
RMQ(){
}
void init(const vector<int> &a){
this->a=a;
for(int j=0;j<=Log2
;j++){
for(int i=0;i+(1<<j)-1<n;i++){
if(j==0){
f[i][j]=i;
}else{
int p1=f[i][j-1];
int p2=f[i+(1<<(j-1))][j-1];
if(a[p1]<a[p2]){
f[i][j]=p1;
}else{
f[i][j]=p2;
}
}
}
}
}
int query(int l,int r){
if(l>r){
swap(l,r);
}
//if(l==0&&r==1){
// cout<<"-------"<<endl;
//cout<<p1<<"----"<<p2<<endl;
//}
if(l==r){
return a[f[l][0]];
}
int k = Log2[r-l+1];
int p1 = f[l][k],p2 = f[r-(1<<k)+1][k];
//if(l==0&&r==1){
// cout<<"-------"<<endl;
//cout<<p1<<"----"<<p2<<endl;
//}
if(a[p1]<a[p2]){
return a[p1];
}else{
return a[p2];
}
}
};
int solve(RMQ &q1,RMQ &q2,int x,int n){
int Left=-1,Right=-1;
int l = x,r=n-1;
while(l<=r){
int mid = (l+r)/2;
int v1 = -q1.query(x,mid),v2=q2.query(x,mid);
if(v1==v2){
Left = mid;
r = mid-1;
}else if(v1<v2){
l = mid+1;
}else{
r = mid-1;
}
}
if(Left==-1) return 0;
l = Left,r=n-1;
while(l<=r){
int mid = (l+r)/2;
int v1 = -q1.query(x,mid),v2=q2.query(x,mid);
//cout<<"MID:"<<mid<<":"<<v1<<"--"<<v2<<endl;
if(v1==v2){
Right = mid;
l = mid+1;
}else if(v1<v2){
l = mid+1;
}else{
r = mid-1;
}
}
//cout<<x<<":"<<Left<<","<<Right<<endl;
return Right-Left+1;
}
typedef long long LL;
int main(){
int n;
while(scanf(" %d",&n)==1){
vector<int> a1(n),a2(n);
for(int i=0;i<n;i++){
scanf(" %d",&a1[i]);
a1[i]*=-1;
}
for(int i=0;i<n;i++){
scanf(" %d",&a2[i]);
}
RMQ rmq1(n),rmq2(n);
rmq1.init(a1);
rmq2.init(a2);
LL ret = 0;
for(int i=0;i<n;i++){
//cout<<"I:"<<i<<endl;
ret+=solve(rmq1,rmq2,i,n);
}
//printf("%I64d\n",ret);
cout<<ret<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces 算法 RMQ 二分