标签:扫描线 技术 while 1.5 view 比较 style 线段 code
两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下:
Ans:=Σni=1Σnj=i[max{Ai,Ai+1,...,Aj}=max{Bi,Bi+1,...,Bj}]
注:[ ]内表达式为真,则为1,否则为0.
第一行一个整数N 第二行N个整数Ai 第三行N个整数Bi
一行,一个整数Ans
5 1 4 2 3 4 3 2 2 4 1
#include <bits/stdc++.h> inline long long read(){long long x=0,f=1;char ch=getchar();while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}return x*f;} using namespace std; #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define MP make_pair typedef long long LL; typedef unsigned long long ULL; const long long INF = 1e18+1LL; const double pi = acos(-1.0); const int N = 4e5 + 10, M = 1e3, inf = 2e9; int n,a[N],b[N]; int l[2],r[2],q[2][N],pos[2][N]; LL cal(int x,int p,int i) { int ll = l[p], rr = r[p],ok = ll; while(ll <= rr) { if(q[p][mid] > x) { ll = mid + 1; } else ok = mid,rr = mid - 1; } // cout<<i<<" "<<p<<" "<<ok<<" "<<q[p][ok]<<" "<<x<<endl; int mmp1,mmp2; mmp1 = max(pos[p][ok-1]+1,pos[p^1][r[p^1]-1]+1); mmp2 = i-1; if(q[p][ok] == x) return 1LL * max(min(pos[p^1][r[p^1]],pos[p][ok]) - mmp1+1,0) * max(mmp2 - max(pos[p^1][r[p^1]],pos[p][ok]) + 1,0); else return 0; } int main() { cin >> n; for(int i = 1; i <= n; ++i) scanf("%d",&a[i]); for(int i = 1; i <= n; ++i) scanf("%d",&b[i]); l[0] = l[1] = 1; r[0] = r[1] = 0; pos[0][0] = pos[1][0] = 0; LL ans = 0; for(int i = 1; i <= n; ++i) { LL ret = 0; while(l[0] <= r[0] && a[i] >= q[0][r[0]]) { ret += cal(q[0][r[0]],1,i); r[0]--; } q[0][++r[0]] = a[i];pos[0][r[0]] = i; while(l[1] <= r[1] && b[i] >= q[1][r[1]]) { ret += cal(q[1][r[1]],0,i); r[1]--; } q[1][++r[1]] = b[i];pos[1][r[1]] = i; //cout<<"fuck "<<i<<" " << ret<<endl; ans += ret; } while(l[0] <= r[0]) { ans += cal(q[0][r[0]],1,n+1); r[0]--; } cout<<ans<<endl; return 0; }
51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线
标签:扫描线 技术 while 1.5 view 比较 style 线段 code
原文地址:http://www.cnblogs.com/zxhl/p/7596793.html