51nod 1810 連續區間

2021-08-10 13:37:13 字數 1317 閱讀 7313

區間內所有元素排序後,任意相鄰兩個元素值差為1的區間稱為「連續區間」

如:3,1,2是連續區間,但3,1,4不是連續區間

給出乙個1~n的排列,求出有多少個連續區間

乙個數n(n<=1,000,000)

第二行n個數,表示乙個1~n的排列

乙個數,表示有多少個連續區間

5 2 1 5 3 4

**考慮分治,每次找出乙個mid,算出左端點在[l,mid]區間內,右端點在(mid,r]區間內的答案數量。

每次以mid為分界點維護乙個前字尾max和前字尾min,分四種情況討論:

max(max[i],max[j])=max[i] min(min[i],min[j])=min[i]

則 j-i=max[i]-min[i]

max(max[i],max[j])=max[j] min(min[i],min[j])=min[i]

則 j-i=max[j]-min[i] 這種情況開個桶維護一下即可

**實現上有不少細節要考慮**

#include 

#include

#include

#define fo(i,a,b) for (int i=a;i<=b;i++)

#define fd(i,a,b) for (int i=a;i>=b;i--)

using namespace std;

const

int n=1000050;

typedef long

long ll;

ll ans;

int n;

int b[3*n],a[n];

int mi[n],mx[n];

int read()

return sum;

}void solve(int l,int r)

mi[mid+1]=a[mid+1],mx[mid+1]=a[mid+1];

fo(i,mid+2,r)

fo(i,l,mid)

for (int j=mid+1;j<=r;j++)

while (y<=x) b[mi[y]+y+n]--,y++;

x=mid; y=mid+1;

fo(i,mid+1,r)

while (x>=y) b[mi[x]-x+n]--,x--;

/////////

//////

///////

if (l==r) return;

solve(l,mid);

solve(mid+1,r);

}int main()

51Nod1810 連續區間

區間內所有元素排序後,任意相鄰兩個元素值差為1的區間稱為 連續區間 如 3,1,2是連續區間,但3,1,4不是連續區間 給出乙個1 n的排列,求出有多少個連續區間 input 乙個數n n 1,000,000 第二行n個數,表示乙個1 n的排列 output 乙個數,表示有多少個連續區間 input...

51nod1094連續為k的區間和

一整數數列a1,a2,an 有正有負 以及另乙個整數k,求乙個區間 i,j 1 i j n 使得a i a j k。input 第1行 2個數n,k。n為數列的長度。k為需要求的和。2 n 10000,10 9 k 10 9 第2 n 1行 a i 10 9 a i 10 9 output 如果沒有...

51nod 1094 和為k的連續區間

一整數數列a1,a2,an 有正有負 以及另乙個整數k,求乙個區間 i,j 1 i j n 使得a i a j k。input 第1行 2個數n,k。n為數列的長度。k為需要求的和。2 n 10000,10 9 k 10 9 第2 n 1行 a i 10 9 a i 10 9 output 如果沒有...