[COCI 2024/2025 #5] 塔楼 / Tornjevi 题解
枚举
放代码:
#include<bits/stdc++.h>
using namespace std;
namespace IAOI_lib{
template<typename T,T(*op)(T,T)> class sparse_table{
private:
vector<vector<T> > s;
public:
sparse_table(vector<T> a){
int k=__lg(a.size());
s.resize(a.size(),vector<T>(k+1));
for(int i=0;i<a.size();i++)
s[i][0]=a[i];
for(int i=1;i<=k;i++)
for(int j=0;j+(1<<i)<=a.size();j++)
s[j][i]=op(s[j][i-1],s[j+(1<<i-1)][i-1]);
}
inline T query(int l,int r){
int k=__lg(r-l+1);
return op(s[l][k],s[r-(1<<k)+1][k]);
}
}; // ST 表维护区间 gcd
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n; cin>>n;
vector<int> h(n);
for(auto &i:h)cin>>i;
IAOI_lib::sparse_table<int,gcd> s(h);
for(int i=0;i<n;i++){
int L=0,R=i,x=-1;
while(L<R){
int m=L+R>>1;
if(s.query(m,i)<h[i])L=m+1;
else R=m;
} // 二分找左端点
x=R,L=i,R=n-1;
while(L<R){
int m=L+R+1>>1;
if(s.query(i,m)<h[i])R=m-1;
else L=m;
} // 二分找右端点
cout<<L-x+1<<' ';
}
cout<<endl;
return 0;
}