#include #include #include #include using namespace std; typedef long long lint; typedef vectorvi; typedef pairpii; #define rep(i,n)for(int i=0;i<(int)(n);++i) vectorbit; void init(int sz){ bit.resize(sz+1); rep(i,sz+1)bit[i]=0; } void add(int x,lint v){ while(x<(int)bit.size()){ bit[x]+=v; x+=x&-x; } } lint acc(int x){ lint s=0; while(x>0){ s+=bit[x]; x&=x-1; } return s; } bool kado(lint a,lint b,lint c){ return (a-b)*(c-b)>0; } /* 周りの要素を見れば、各要素をどの値に置き換えても問題ないかがわかる。 a[x] = i のとき、cand[i] を x 番目に置ける値の集合とする。 cand[x] は 2 個以下の区間の和集合。 十分 (3 以上) 遠い要素については、平面走査でできる。 左側から見て、 (1) cand[i] の全ての要素 j に対して dp[j]++, (2) cand[i] のうち i-3 以下の要素 j に対して cand[j] の追加時に i があったか調べその個数を計算する の 2 個のクエリが処理できれば良い。これは BIT で計算できる。 近い要素は全探索。 */ int main(){ int n; cin>>n; vi a(n); rep(i,n)cin>>a[i],a[i]--; lint ans=0; //近い要素 rep(i,n){ for(int j=i+1;j<=min(n-1,i+2);j++){ swap(a[i],a[j]); int ok=1; for(int k=max(0,i-2);k<=min(n-3,j);k++){ ok&=kado(a[k],a[k+1],a[k+2]); } if(ok)ans++; swap(a[i],a[j]); } } //遠い要素 //cand[i] を計算する vector>cand(n); rep(i,n){ int ma=n-1,mi=0; int x=a[i]; if(i=2){ if(a[i-1]c; if(i>0&&i>qs(n); vectorbig(n); rep(i,n){ assert(cand[i].size()==1); int l=cand[i][0].first,r=cand[i][0].second; r=min(r,i-1); if(l<=r){ qs[r].push_back(i); if(l>0)qs[l-1].push_back(i+n); } } rep(i,n){ int l=cand[i][0].first,r=cand[i][0].second; add(r+2,-1); add(l+1,1); for(int idx:qs[i]){ lint v=acc(idx%n+1); big[idx%n]+=idx>=n?-v:v; } } //近い要素の影響を消す。 rep(i,n){ int l=cand[a[i]][0].first,r=cand[a[i]][0].second; for(int j=max(0,i-2);j<=min(n-1,i+2);j++){ if(a[i]<=a[j])continue; if(l<=a[j]&&a[j]<=r){ int lj=cand[a[j]][0].first,rj=cand[a[j]][0].second; if(lj<=a[i]&&a[i]<=rj){ big[a[i]]--; } } } } rep(i,n)ans+=big[i]; cout<