2016-5-15 交流会2 (百度之星资格赛,树形dp , 单调队列/栈,ST算法)
/* 如果已经在自己的博客上写了,格式:
hdu4122 Alice's mooncake shop[你博客的链接] (题目类型 )
如果向直接发表在这里,格式:
hdu4122 Alice's mooncake shop (题目类型)
题意。。。。+数据范围
解题思路:。。。。
防或不防自己的代码。。。
----------------------------------------------------------------
叙述尽量精简,题好不在题多。
-----------------------------------------------------------------------------------------------------------------
能结合题目讲就尽量吧,,,,==没了
//仓鼠区,禁止投喂{
2016"百度之星" - 资格赛(Astar Round1)
Problem A
}//仓鼠区over
*/
/**********************************************************************************
树形DP两道:
2012 Multi-University #9 D How to paint a tree
Manthan, Codefest 16 F - The Chocolate Spree
---Running_Time
***********************************************************************************/
/*halfapri , 哈哈哈哈哈
1 .百度之星资格赛C
主要就是提供一份规范的板子
2 .2012多校第8场E One hundred layer (单调队列优化dp)
单调队列能干啥?
答:维护一个符合某种特性的区间的最值;
怎么实现?
单调队列的优点:速度快O(n) ,书写复杂度很低(比其他 RMQ 算法短了4倍)。
然后大家可以去试试水,
HDU 5289 Assignment:连续的最大最小值之差不超过K的子序列的总个数。
1 #include <bits/stdc++.h> 2 using namespace std ; 3 typedef long long ll ; 4 typedef long double ld ; 5 typedef unsigned long long ull ; 6 #ifdef _WIN32 7 #define LLD "%I64d" 8 #else 9 #define LLD "%lld" 10 #endif 11 #define pi (acos(-1.0)) 12 #define fi first 13 #define se second 14 #define lson (o<<1),l,mid 15 #define rson (o<<1|1),mid+1,r 16 #define MP make_pair 17 const double eps = 1e-9 ; 18 const int inf = 0x3f3f3f3f ; 19 const ll INF = (ll)4e18 ; 20 int sign(double x){return x<-eps?-1:x>eps;} 21 22 int n , k; 23 struct NODE { 24 int id,val ; 25 NODE (int _id=0,int _val=0):id(_id),val(_val){} 26 } ; 27 28 void solve (int l=0) { 29 ll ret = 0 ; 30 deque<NODE> q1 , q2 ; 31 for (int i=0 ; i<n ; i++) { 32 int x ; 33 scanf ("%d" , &x) ; 34 while (!q1.empty() && x>q1.back().val) q1.pop_back(); 35 q1.push_back (NODE(i,x)) ; 36 while (!q2.empty() && x<q2.back().val) q2.pop_back(); 37 q2.push_back (NODE(i,x)) ; 38 while (!q1.empty()&&!q2.empty()&& 39 q1.front().val-q2.front().val>=k) { 40 if(q1.front().id<q2.front().id) { 41 l = q1.front().id+1 ; 42 q1.pop_front() ; 43 } 44 else { 45 l = q2.front().id+1 ; 46 q2.pop_front() ; 47 } 48 } 49 //printf ("[%d , %d]\n" , l,i) ; 50 ret += 1ll*(i-l+1) ; 51 } 52 printf (LLD "\n" , ret) ; 53 } 54 55 int main () { 56 int CASE ; 57 scanf ("%d" , &CASE) ; 58 while (CASE --) { 59 scanf ("%d%d" , &n,&k) ; 60 solve () ; 61 } 62 return 0 ; 63 }
(2015多校第1场1002,当年是进爷A的,14级好像都不会吧==)
3.POJ2559 Largest Rectangle in a Histogram(单调栈)
是不是很简单?
就去做做另一题:
hdu 5288 OO’s Sequence : f(l , r) :表示l , r这个区间内符合性质x的a(i)的数量 ;
x性质: a(i) 满足 a(i) % a(j) != 0 , j != i , l <= j <= r ;
好怀念,当初我多校做出的第一道题,,,,,好吧,其实是和欣爷一起搞的。
(我发现一个梗,去年多校第一场的1001是单调栈,1002是单调队列,这是那场最简单的两题,当时14级貌似全死光了==,15级的孩子要小心啊。。。。)
4 . ST 算法 (dp ....)
给出一个长度为 n 的序列,一个若干次询问(~ 1e6) , 每次询问求一个区间的最值;
dp( i , j) : 表示在[ i , i+(1<<j)-1 ]的最值
转移:dp(i , j) = mx (dp(i , j-1) , dp(i + (1<<j) , j-1)) ;
比如说我们现在要求[l , r]的 mx ;
int k = log2(r-l+1) = (int) ( log(1.0*(r-l+1)) / log(2.0) ;//在C++里log 就是 ln , 及以自然数为底
所以答案就是 mx (dp(i , k) , dp(i-(1<<k)+1 , k) ;
*/ hahahahahahahahaha