传送门:【HDU】4893 Wow! Such Sequence!
题目分析:
比赛中错了五次才过= =||,我简直逗比。。明显应该对该段是否为Fibonacci数做标记的,如果都是Fibonacci数,那么就不用管了,否则更新到包含的段内全是Fibonacci数或者叶子节点为止就好了。。。
其他的都是一些逗比操作,就不说了。。
重写又错了两次T U T
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define rt o , l , r
#define root 1 , 1 , n
#define mid ( ( l + r ) >> 1 )
#define CLR( a , x ) memset ( a , x , sizeof a )
typedef long long LL ;
const int MAXN = 100005 ;
const int MAXF = 80 ;
const LL INF = 1e18 ;
LL f[MAXF] ;
bool set[MAXN << 2] ;
LL sum[MAXN << 2] ;
LL search ( LL x ) {
int l = 1 , r = MAXF ;
while ( l < r ) {
int m = mid ;
if ( f[m] >= x )
r = m ;
else
l = m + 1 ;
}
if ( x - f[l - 1] <= f[l] - x )
return f[l - 1] ;
return f[l] ;
}
void pushup ( int o ) {
if ( set[ls] && set[rs] )
set[o] = 1 ;
else
set[o] = 0 ;
sum[o] = sum[ls] + sum[rs] ;
}
void pushdown ( int o ) {
if ( set[o] ) {
set[ls] = set[rs] = set[o] ;
set[o] = 0 ;
}
}
void build ( int o , int l , int r ) {
sum[o] = 0 ;
set[o] = 0 ;
if ( l == r )
return ;
int m = mid ;
build ( lson ) ;
build ( rson ) ;
}
void modify ( int pos , int x , int o , int l , int r ) {
if ( l == r ) {
sum[o] += x ;
if ( sum[o] == search ( sum[o] ) )
set[o] = 1 ;
set[o] = 0 ;
return ;
}
pushdown ( o ) ;
int m = mid ;
if ( pos <= m )
modify ( pos , x , lson ) ;
else
modify ( pos , x , rson ) ;
pushup ( o ) ;
}
void update ( int L , int R , int o , int l , int r ) {
if ( set[o] )
return ;
if ( l == r ) {
sum[o] = search ( sum[o] ) ;
set[o] = 1 ;
return ;
}
pushdown ( o ) ;
int m = mid ;
if ( L <= m )
update ( L , R , lson ) ;
if ( m < R )
update ( L , R , rson ) ;
pushup ( o ) ;
}
LL query ( int L , int R , int o , int l , int r ) {
if ( L <= l && r <= R )
return sum[o] ;
pushdown ( o ) ;
int m = mid ;
LL ans = 0 ;
if ( L <= m )
ans += query ( L , R , lson ) ;
if ( m < R )
ans += query ( L , R , rson ) ;
pushup ( o ) ;
return ans ;
}
void fun () {
f[0] = f[1] = 1 ;
REP ( i , 2 , MAXF )
f[i] = f[i - 1] + f[i - 2] ;
}
void solve () {
int n , m ;
int ch , l , r ;
fun () ;
while ( ~scanf ( "%d%d" , &n , &m ) ) {
build ( root ) ;
REP ( i , 0 , m ) {
scanf ( "%d%d%d" , &ch , &l , &r ) ;
if ( ch == 1 )
modify ( l , r , root ) ;
if ( ch == 2 )
printf ( "%I64d\n" , query ( l , r , root ) ) ;
if ( ch == 3 )
update ( l , r , root ) ;
}
}
}
int main () {
solve () ;
return 0 ;
}