區間內所有元素排序後,任意相鄰兩個元素值差為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 如果沒有...