Submission #73450

#TimeUsernameProblemLanguageResultExecution timeMemory
73450zscoderFibonacci representations (CEOI18_fib)C++17
65 / 100
472 ms13704 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; #define fi first #define se second #define mp make_pair #define pb push_back typedef long long ll; typedef pair<int,int> ii; typedef vector<int> vi; typedef long double ld; typedef tree<ii, null_type, less<ii>, rb_tree_tag, tree_order_statistics_node_update> pbds; const int MOD=1e9+7; int add(int a, int b) { a+=b; while(a>=MOD) a-=MOD; return a; } int mult(int a, int b) { return (a*1LL*b)%MOD; } vector<int> getZeckendorf(vi a) { sort(a.rbegin(),a.rend()); while(1) { vi nw; bool reset=0; /* for(int x:a) { cerr<<x<<' '; } cerr<<'\n'; */ for(int i=0;i<a.size();i++) { if(reset) { nw.pb(a[i]); continue; } if(i+1==int(a.size())) { nw.pb(a[i]); break; } if(a[i]==a[i+1]) { if(a[i]==1) { nw.pb(2); i++; reset=1; continue; } else if(a[i]==2) { nw.pb(1); nw.pb(1); reset=1; continue; } else { nw.pb(a[i]+1); nw.pb(a[i]-2); i++; reset=1; continue; } } else if(a[i]-a[i+1]==1) { nw.pb(a[i]+1); i++; reset=1; } else { nw.pb(a[i]); } } sort(nw.rbegin(),nw.rend()); a=nw; if(!reset) break; } return a; } int solve(vi vec) //solve given zeckendorf monkaS { reverse(vec.begin(),vec.end()); vector<int> dp[2]; dp[0].assign(int(vec.size()),0); dp[1].assign(int(vec.size()),0); dp[0][0] = (vec[0]-1)/2; dp[1][0] = add(dp[0][0], 1); int n=vec.size(); for(int i=1;i<n;i++) { int x=vec[i-1]; int y=vec[i]; if((y-x)&1) { dp[1][i] = mult(dp[1][i-1], (y-x+1)/2); dp[0][i] = mult(dp[1][i-1], (y-x-1)/2); } else { dp[0][i] = add(mult((y-x)/2 - 1, dp[1][i-1]), dp[0][i-1]); dp[1][i] = add(mult((y-x)/2, dp[1][i-1]), dp[0][i-1]); } } return dp[1][n-1]; } struct matrix { int a[2][2]; matrix() { memset(a,0,sizeof(a)); } }; matrix unit; matrix operator*(matrix a, matrix b) { matrix c; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { c.a[i][j]=0; for(int k=0;k<2;k++) { c.a[i][j]=add(c.a[i][j],mult(a.a[i][k], b.a[k][j])); } } } return c; } matrix init(int d) { matrix c; c.a[0][0] = 1; c.a[0][1] = d-1; c.a[1][0] = 1; c.a[1][1] = d; return c; } matrix st[422222]; void build(int id, int l, int r) { if(r-l<2) { st[id]=unit; return ; } int mid=(l+r)>>1; build(id*2,l,mid); build(id*2+1,mid,r); st[id]=st[id*2+1]*st[id*2]; } void update(int id, int l, int r, int pos, matrix v) { if(pos<l||pos>=r) return ; if(r-l<2) { st[id]=v; return ; } int mid=(l+r)>>1; update(id*2,l,mid,pos,v); update(id*2+1,mid,r,pos,v); st[id]=st[id*2+1]*st[id*2]; } int a[111111]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); srand(time(NULL)); int n; cin>>n; //n=15; cout<<n<<endl; for(int i=0;i<n;i++) { cin>>a[i]; //a[i]=rand()%15+1; //cout<<a[i]<<' '; } //cout<<endl; unit=matrix(); unit.a[0][0]=unit.a[1][1]=1; if(n<=100) { vi vec; for(int i=0;i<n;i++) { vec.pb(a[i]); vi nw = getZeckendorf(vec); cout<<solve(nw)<<'\n'; } } else { vi coord; for(int i=0;i<n;i++) { coord.pb(a[i]); } sort(coord.begin(),coord.end()); set<int> S; build(1,0,n); for(int i=0;i<n;i++) { S.insert(a[i]); int pos = lower_bound(coord.begin(),coord.end(),a[i])-coord.begin(); auto it = S.lower_bound(a[i]); if(it==S.begin()) { it++; if(it==S.end()) { update(1,0,n,pos,init(a[i]/2)); } else { int idnext = lower_bound(coord.begin(),coord.end(),(*it))-coord.begin(); update(1,0,n,pos,init(a[i]/2)); update(1,0,n,idnext,init(((*it)-a[i])/2)); } } else { if(next(it)==S.end()) { update(1,0,n,pos,init((a[i]-(*prev(it)))/2)); } else { update(1,0,n,pos,init((a[i]-(*prev(it)))/2)); it++; int idnext = lower_bound(coord.begin(),coord.end(),(*it))-coord.begin(); update(1,0,n,idnext,init(((*it)-a[i])/2)); } } cout<<st[1].a[1][1]<<'\n'; } } }

Compilation message (stderr)

fib.cpp: In function 'std::vector<int> getZeckendorf(vi)':
fib.cpp:46:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0;i<a.size();i++)
               ~^~~~~~~~~
#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...