码迷,mamicode.com
首页 > 其他好文 > 详细

CF 689D A区间最大值等于B区间最小值的区间个数统计

时间:2018-08-14 23:59:50      阅读:371      评论:0      收藏:0      [点我收藏+]

标签:style   space   bit   out   题意   const   mes   its   oid   

  1 /*
  2   Source :CF689D
  3   题意:给出a,b两个长度为n的数组,问有多少个区间满足max(a[l,r])==min(b[l,r])  len(a)<10^5
  4   思路:对于一个固定的l,max(a[l,r])是一个单调不减的序列,min(b[l,r])是一个单调不增的序列,
  5         于是可以枚举区间的左端点,然后二分判断右端点的范围
  6         快速查询区间的最大最小值可以利用ST表实现。
  7   时间   :2018-08-14-12.26
  8 */
  9 #include <bits/stdc++.h>
 10 using namespace std;
 11 
 12 typedef long long LL;
 13 const int MAXN=200005;
 14 const LL MOD7 = 1e9+7;
 15 
 16 struct Min_STable
 17 {
 18     // int a[MAXN];
 19     int dp[MAXN][20];
 20     void init(int *a, int n)
 21     {
 22         for (int i=1;i<=n;++i) dp[i][0]=a[i];
 23         for (int j=1;(1<<j)<=n;++j)
 24         {
 25             for (int i=1;i+(1<<j)-1<=n;++i)
 26             {
 27                 dp[i][j]=(dp[i][j-1]<dp[i+(1<<(j-1))][j-1]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]);
 28             }
 29         }
 30     }
 31     int query(int x,int y)
 32     {
 33         if (x>y) swap(x,y);
 34         int k=log(y-x+1)/log(2);
 35         return (dp[x][k]<dp[y-(1<<k)+1][k]?dp[x][k]:dp[y-(1<<k)+1][k]);
 36     }
 37 }Min_st;
 38 
 39 struct Max_STable
 40 {
 41     int dp[MAXN][20];
 42     void init(int *a,int n)
 43     {
 44         for (int i=1;i<=n;++i) dp[i][0]=a[i];
 45         for (int j=1;(1<<j)<=n;++j)
 46         {
 47             for (int i=1;i+(1<<j)-1<=n;++i)
 48             {
 49                 dp[i][j]=(dp[i][j-1]>dp[i+(1<<(j-1))][j-1]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]);
 50             }
 51         }
 52     }
 53     int query(int x,int y)
 54     {
 55         if (x>y) swap(x,y);
 56         int k=log(y-x+1)/log(2);
 57         return (dp[x][k]>dp[y-(1<<k)+1][k]?dp[x][k]:dp[y-(1<<k)+1][k]);
 58     }
 59 }Max_st;
 60 
 61 int a[MAXN];
 62 int b[MAXN];
 63 int n;
 64 
 65 void work()
 66 {
 67     Max_st.init(a,n);
 68     Min_st.init(b,n);
 69     LL ans=0;
 70     for (int i=1;i<=n;++i)
 71     {
 72         if (a[i]>b[i]) continue;
 73         if (Max_st.query(i,n)<Min_st.query(i,n)) continue;
 74         int l=i,r=n;
 75         int ml;
 76         while (l<=r)
 77         {
 78             ml=(l+r)/2;
 79             // printf("l=%d r=%d ml=%d id_A=%d id_B=%d max_A=%d min_b=%d\n",l,r,ml,Max_st.query(a,i,ml),Min_st.query(b,i,ml),a[Max_st.query(a,i,ml)],b[Min_st.query(b,i,ml)]);
 80             if (Max_st.query(i,ml)>=Min_st.query(i,ml)) r=ml-1;
 81             else l=ml+1;
 82         }
 83         if (Max_st.query(i,r+1)!=Min_st.query(i,r+1)) continue;
 84         int pl = r+1;
 85         l=i,r=n;
 86         while (l<=r)
 87         {
 88             ml=(l+r)/2;
 89             // printf("2 l=%d r=%d ml=%d\n",l,r,ml);
 90             if (Max_st.query(i,ml)<=Min_st.query(i,ml)) l=ml+1;
 91             else r=ml-1;
 92         }
 93         ans+=(LL) (l-pl);
 94     }
 95     printf("%I64d\n",ans);
 96 }
 97 
 98 int main()
 99 {
100 #ifndef ONLINE_JUDGE
101     freopen("test.txt","r",stdin);
102 #endif // ONLINE_JUDGE
103     scanf("%d",&n);
104     for (int i=1;i<=n;++i) scanf("%d",&a[i]);
105     for (int i=1;i<=n;++i) scanf("%d",&b[i]);
106     work();
107     return 0;
108 }
109 
110 //in[1]:
111 //6
112 //1 2 3 2 1 4
113 //6 7 1 2 3 2
114 
115 //out[1]:
116 //2

 

CF 689D A区间最大值等于B区间最小值的区间个数统计

标签:style   space   bit   out   题意   const   mes   its   oid   

原文地址:https://www.cnblogs.com/LeeSongt/p/9478798.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!