JZOJ4975. 区间
来源:互联网 发布:115签到软件 编辑:程序博客网 时间:2024/06/05 18:30
题目大意
给定一个长度为
求有多少个连续的数字区间
Data Constraint
题解
设
考虑从小到大枚举
时间复杂度:
SRC
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std ;#define N 300000 + 10typedef long long ll ;struct Tree { int tag ; int Min1 , Min2 ; int Num1 , Num2 ;} T[4*N] ;int P[N] , Q[N] ;int n ;ll ans , ret ;int min( int x , int y ) { return x < y ? x : y ; }int max( int x , int y ) { return x > y ? x : y ; }void Update( int v ) { if ( !T[v].tag ) return ; int lv = v + v , rv = v + v + 1 ; T[lv].Min1 += T[v].tag ; T[lv].Min2 += T[v].tag ; T[rv].Min1 += T[v].tag ; T[rv].Min2 += T[v].tag ; T[lv].tag += T[v].tag ; T[rv].tag += T[v].tag ; T[v].tag = 0 ;}void Merge( int v ) { int lv = v + v , rv = v + v + 1 ; T[v].Min1 = min( T[lv].Min1 , T[rv].Min1 ) ; int tp = 0x7FFFFFFF ; if ( T[lv].Min1 > T[v].Min1 ) tp = min( tp , T[lv].Min1 ) ; if ( T[lv].Min2 > T[v].Min1 ) tp = min( tp , T[lv].Min2 ) ; if ( T[rv].Min1 > T[v].Min1 ) tp = min( tp , T[rv].Min1 ) ; if ( T[rv].Min2 > T[v].Min1 ) tp = min( tp , T[rv].Min2 ) ; T[v].Min2 = tp ; T[v].Num1 = T[v].Num2 = 0 ; T[v].Num1 += T[lv].Min1 == T[v].Min1 ? T[lv].Num1 : 0 ; T[v].Num1 += T[rv].Min1 == T[v].Min1 ? T[rv].Num1 : 0 ; T[v].Num2 += T[lv].Min1 == T[v].Min2 ? T[lv].Num1 : 0 ; T[v].Num2 += T[lv].Min2 == T[v].Min2 ? T[lv].Num2 : 0 ; T[v].Num2 += T[rv].Min1 == T[v].Min2 ? T[rv].Num1 : 0 ; T[v].Num2 += T[rv].Min2 == T[v].Min2 ? T[rv].Num2 : 0 ;}void Modify( int v , int l , int r , int x , int y , int del ) { if ( x > y ) return ; if ( l == x && r == y ) { T[v].Min1 += del , T[v].Min2 += del ; T[v].tag += del ; return ; } Update(v) ; int mid = (l + r) >> 1 ; if ( y <= mid ) Modify( v + v , l , mid , x , y , del ) ; else if ( x > mid ) Modify( v + v + 1 , mid + 1 , r , x , y , del ) ; else { Modify( v + v , l , mid , x , mid , del ) ; Modify( v + v + 1 , mid + 1 , r , mid + 1 , y , del ) ; } Merge(v) ;}void Search( int v , int l , int r , int x , int y ) { if ( l == x && r == y ) { ret += T[v].Min1 <= 2 ? T[v].Num1 : 0 ; ret += T[v].Min2 <= 2 ? T[v].Num2 : 0 ; return ; } Update(v) ; int mid = (l + r) >> 1 ; if ( y <= mid ) Search( v + v , l , mid , x , y ) ; else if ( x > mid ) Search( v + v + 1 , mid + 1 , r , x , y ) ; else { Search( v + v , l , mid , x , mid ) ; Search( v + v + 1 , mid + 1 , r , mid + 1 , y ) ; } Merge(v) ;}void MakeTree( int v , int l , int r ) { T[v].Num1 = r - l + 1 ; if ( l == r ) return ; int mid = (l + r) >> 1 ; MakeTree( v + v , l , mid ) ; MakeTree( v + v + 1 , mid + 1 , r ) ;}int main() { scanf( "%d" , &n ) ; for (int i = 1 ; i <= n ; i ++ ) { scanf( "%d" , &P[i] ) ; Q[P[i]] = i ; } P[0] = P[n+1] = n + 1 ; MakeTree( 1 , 1 , n ) ; for (int i = 1 ; i <= n ; ++ i ) { int x = Q[i] ; Modify( 1 , 1 , n , 1 , i , 1 ) ; if ( P[x-1] < i ) Modify( 1 , 1 , n , 1 , P[x-1] , -1 ) ; if ( P[x+1] < i ) Modify( 1 , 1 , n , 1 , P[x+1] , -1 ) ; ret = 0 ; Search( 1 , 1 , n , 1 , i ) ; ans += ret ; } printf( "%lld\n" , ans - n ) ; return 0 ;}
以上.
1 0
- JZOJ4975. 区间
- 区间
- 区间
- 区间选点+区间覆盖
- 插入区间,区间合并
- 区间修改,区间查询
- 区间查询
- 区间运算
- 区间树
- 区间计算
- Ruby区间
- 区间树
- 区间DP
- 区间合并
- 区间DP
- 区间DP
- 区间重合
- 区间DP
- AIX相关(1)
- 零散的知识点
- Message、Handler、Message Queue、Looper之间的关系。
- HTML4,HTML5,XHTML 之间有什么区别?
- Android 如何直播RTMP流
- JZOJ4975. 区间
- java之sleep, wait, notify, notifyall
- 探索 unity thread
- 关于JqueryMobile的加载框的一些记录
- 大型网站架构技术一览 高并发的访问和海量数据
- 在SQL语言中,join什么时候用
- YDB场景精选
- Oracle 索引的五种类型
- 程序员的沟通之痛