Submission #542363

#TimeUsernameProblemLanguageResultExecution timeMemory
542363gs14004Fibonacci representations (CEOI18_fib)C++17
50 / 100
4090 ms4032 KiB
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using pi = pair<int, int>;
const int mod = 1e9 + 7;
const int MAXN = 200005;
 
struct mtrx{
	int a[2][2];
	mtrx operator*(const mtrx &m)const{
		mtrx ret;
		memset(ret.a, 0, sizeof(ret.a));
		for(int i=0; i<2; i++){
			for(int j=0; j<2; j++){
				for(int k=0; k<2; k++){
					ret.a[j][k] += 1ll * a[j][i] * m.a[i][k] % mod;
					if(ret.a[j][k] >= mod) ret.a[j][k] -= mod;
				}
			}
		}
		return ret;
	}
}E, pwr[MAXN];
 
mtrx num(int n){
	mtrx m;
	m.a[1][0] = m.a[1][1] = (n % 2 == 0);
	m.a[0][0] = (n + 1) / 2;
	m.a[0][1] = (n - 1) / 2;
	return m;
}
 
set<pi> s;
 
int query(){
	int prv = 0;
	mtrx m = E;
	for(auto &i : s){
		m = m * num(i.first - prv);
		m = m * pwr[(i.second - i.first) / 2];
		prv = i.second;
	}
	return m.a[0][0];
}
 
void add(int x){ 
	if(x == 0) x = 1;
	if(x == -1) return;
	auto ins = [](pi x){
		s.insert(x);
	};
	auto rem = [](pi x){
		s.erase(x);
	};
	auto it = s.upper_bound(pi(x + 1, -1));
	if(it != s.begin() && prev(it)->second >= x){
		auto intv = *--it;
		rem(intv);
		if(intv.first % 2 == x % 2){
			add(intv.second + 1);
			intv.second = x - 2;
			if(intv.first <= intv.second){
				auto l = s.lower_bound(pi(intv.second + 3, -1));
				auto nxt = pi(intv.first + 1, intv.second + 1);
				if(l != s.end() && l->first == intv.second + 3){
					nxt.second = l->second;
					rem(*l);
				}
				ins(nxt);
			}
			add(intv.first - 2);
		}
		else{
			ins(pi(intv.first, x - 1));
			add(intv.second + 1);
		}
	}
	else{
		auto nxt = it;
		if(nxt != s.begin()){
			nxt = prev(nxt);
			if(nxt->second == x - 1){
				auto prv = *nxt;
				rem(prv);
				if(prv.first != prv.second){
					prv.second -= 2;
					ins(prv);
				}
				add(x + 1);
				return;
			}
			if(nxt->second == x - 2){
				auto l = s.lower_bound(pi(x + 1, -1));
				if(l != s.end() && l->first == x + 1){
					int pos = l->second + 1;
					rem(*l);
					add(pos);
				}
				else if(l != s.end() && l->first == x + 2){
					auto it = *nxt;
					it.second = l->second;
					rem(*l);
					rem(*nxt);
					ins(it);
				}
				else{
					auto it = *nxt;
					it.second += 2;
					rem(*nxt);
					ins(it);
				}
				return;
			}
		}
		auto l = s.lower_bound(pi(x + 1, -1));
		if(l->first == x + 1){
			int pos = l->second + 1;
			rem(*l);
			add(pos);
		}
		else if(l->first == x + 2){
			auto nxt = *l; nxt.first -= 2;
			rem(*l);
			ins(nxt);
		}
		else{
			ins(pi(x, x));
		}
	}
}
 
int main(){
	E.a[0][0] = E.a[1][1] = 1;
	pwr[0] = E;
	pwr[1] = num(2);
	for(int i=2; i<MAXN; i++) pwr[i] = pwr[i-1] * pwr[1];
	int n, x;
	scanf("%d",&n);
	for(int i=0; i<n; i++){
		scanf("%d",&x);
		add(x);
		printf("%d\n", query());
	}
}
 

Compilation message (stderr)

fib.cpp: In function 'int main()':
fib.cpp:138:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  138 |  scanf("%d",&n);
      |  ~~~~~^~~~~~~~~
fib.cpp:140:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  140 |   scanf("%d",&x);
      |   ~~~~~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...