HDU-2790

fib[50] > 1e10;
所以在结构体中定义一个数组 存放区间内 各个fib下标的数量
如果存在点下标大于等于50, 标记一下即可

代码很长, 写的时候很随意, 看的时候很恶心

#include<cstdio>
#include<cstring>

using namespace std;
const int maxn = 1e5 + 10;
typedef long long ll; 
inline ll rd() {
	ll x = 0, f = 1; char ch = getchar();
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
	return x * f;
}
ll fib[60], have, ans;
int op, l, r;

bool flag = false;
void init(){
	fib[0] = 0;
	fib[1] = 1;
	int cnt;
	for(cnt = 2; fib[cnt-1] <= 1e10; ++ cnt)
		fib[cnt] = fib[cnt-1] + fib[cnt-2];
	//fib[50] > 1e10
}

struct node{
	int l, r, w[50];
	int f;
	bool over;
}tree[maxn<<2];

void down(int k){
	if(tree[k].f){
		tree[k<<1].f += tree[k].f;
		tree[k<<1|1].f += tree[k].f;
		if(tree[k].f >= 49)	tree[k].over = true;
		if(tree[k<<1].f >= 49)	tree[k<<1].over = true;
		if(tree[k<<1|1].f >= 49)	tree[k<<1|1].over = true;
		for(int i = 49; i >= tree[k].f; -- i){
			if(!tree[k<<1].over && i + tree[k].f >= 50 && tree[k<<1].w[i] > 0)
				tree[k<<1].over = true;
			if(!tree[k<<1|1].over && i + tree[k].f >= 50 && tree[k<<1|1].w[i] > 0)
				tree[k<<1|1].over = true;
			tree[k<<1].w[i] = tree[k<<1].w[i-tree[k].f];
			tree[k<<1].w[i-tree[k].f] = 0;
			tree[k<<1|1].w[i] = tree[k<<1|1].w[i-tree[k].f];
			tree[k<<1|1].w[i-tree[k].f] = 0; 
		}
		tree[k].f = 0;
	}	
}

void build(int k, int l, int r){
	tree[k].l = l, tree[k].r = r;
	tree[k].over = false, tree[k].f = 0;
	memset(tree[k].w, 0, sizeof tree[k].w);
	if(l == r){
		tree[k].w[1] = 1;
		return;
	}
	int mid = (l+r) >> 1;
	build(k<<1, l ,mid);
	build(k<<1|1, mid+1, r);
	tree[k].w[1] = r-l+1; 
}

void updata(int k, int l, int r){
	if(tree[k].l >= l && tree[k].r <= r){
		tree[k].f += 1;
		if(tree[k].f >= 49)
			tree[k].over = true;
		if(tree[k].w[49] > 0)
			tree[k].over = true;
		for(int i = 49; i >= 1; -- i){
			tree[k].w[i] = tree[k].w[i-1];
		}
		return;
	}
	down(k);
	int mid = (tree[k].l + tree[k].r) >> 1;
	if(l <= mid)	updata(k<<1, l, r);
	if(r > mid)		updata(k<<1|1, l, r);
	for(int i = 1; i < 50; ++ i){
		tree[k].w[i] = tree[k<<1].w[i] + tree[k<<1|1].w[i];
		if(!tree[k].over)
			tree[k].over = (tree[k<<1].over || tree[k<<1|1].over);
	}
		
}

void query(int k, int l, int r){
	if(flag)	return;
	if(tree[k].l >= l && tree[k].r <= r){
		if(tree[k].over){
			flag = true;
			return;
		}
		for(int i = 1; i <= 49; ++ i){
			have += fib[i] * tree[k].w[i];
			if(have >= ans){
				flag = true;
				return;
			}
		}
		return;
	}
	down(k);
	int mid = (tree[k].l + tree[k].r) >> 1;
	if(l <= mid)	query(k<<1, l, r);
	if(r > mid)		query(k<<1|1, l, r);
}

int main(){
	init();
	int n, m;
	n = rd(); m = rd();
	build(1, 1, n);
	for(int i = 0; i < m; ++ i){
		op = rd(); l = rd(); r = rd();
		if(op == 1){
			updata(1, l, r);
		}
		if(op == 2)	{
			ans = rd();
			have = 0;
			flag = false;
			query(1, l, r);
			puts(flag ? "YES" : "NO");
		}
	}
	return 0;
}
上一篇:vim - Leader


下一篇:[社群QA] “专家坐诊”第49期问答汇总