abc393 题解合集
\(perf:2017\)
啥啊。
越来越过分了是吧。
我现在不仅怀疑参赛者有人机,还怀疑出题者是人机。
D
以最中间的 \(1\) 作为基准点,两边向这个 \(1\) 靠拢即可。
复杂度 \(O(n)\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
char ch;
int n,a[2000005],l,r,ans,cnt,tmp,p;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>ch;
a[i]=ch-'0';
}
for(int i=1;i<=n;i++){
if(a[i]) cnt++;
}
if(cnt<=1){
cout<<0;
return 0;
}
tmp=0;
for(int i=1;i<=n;i++){
if(a[i]) tmp++;
if(tmp==(cnt+1)/2){
p=i;
break;
}
};
l=p-1,r=p+1;
for(int i=p-1;i>=1;i--){
if(a[i]){
a[l]=i;
ans+=(l-i);
l--;
}
}
for(int i=p+1;i<=n;i++){
if(a[i]){
a[r]=i;
ans+=(i-r);
r++;
}
}
cout<<ans;
return 0;
}
E
预处理出每个数的所有因数,开个桶记录每个数作为因数的出现次数,查询每个数的因数中,出现次数至少为 \(k\) 的最大的即可。
复杂度 \(O(n \ln n)\)。
#include<bits/stdc++.h>
using namespace std;
int n,k,maxn,ans,a[2000005],b[2000005];
vector<int> v[2000005];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
maxn=max(maxn,a[i]);
}
for(int i=1;i<=maxn;i++){
for(int j=i;j<=maxn;j+=i){
v[j].push_back(i);
}
}
for(int i=1;i<=n;i++){
for(int j=0;j<v[a[i]].size();j++){
b[v[a[i]][j]]++;
}
}
for(int i=1;i<=n;i++){
ans=0;
for(int j=0;j<v[a[i]].size();j++){
if(b[v[a[i]][j]]>=k) ans=max(ans,v[a[i]][j]);
}
cout<<ans<<'\n';
}
return 0;
}
F
考虑 LIS 的一种 DP 方式:设 \(f_i\) 表示以 \(i\) 结尾的 LIS。
转移:
\[f_{a_i}=\max_{j=1}^{a_i-1} f_{j}+1
\]
用 BIT 可以优化到 \(O(n \log n)\)。
考虑将询问挂到每个点上,从左到右扫维护 \(f\) 即可。
需要离散化。
复杂度 \(O((n+m)\log n)\)。
#include<bits/stdc++.h>
using namespace std;
int n,m,maxn,x[2000005],k[2000005],a[2000005],ans[2000005];
struct node{
int id,k;
};
vector<node> v[2000005];
vector<int> t;
#define lowbit(i) ((i)&(-(i)))
int c[2000005];
void modify(int x,int k){
for(int i=x;i<=maxn;i+=lowbit(i)){
c[i]=max(c[i],k);
}
}
int query(int x){
int ans=0;
for(int i=x;i;i-=lowbit(i)){
ans=max(ans,c[i]);
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
t.push_back(a[i]);
}
for(int i=1;i<=m;i++){
cin>>x[i]>>k[i];
t.push_back(k[i]);
}
sort(t.begin(),t.end());
t.erase(unique(t.begin(),t.end()),t.end());
maxn=t.size();
for(int i=1;i<=n;i++){
a[i]=lower_bound(t.begin(),t.end(),a[i])-t.begin()+1;
}
for(int i=1;i<=m;i++){
k[i]=lower_bound(t.begin(),t.end(),k[i])-t.begin()+1;
v[x[i]].push_back((node){i,k[i]});
}
for(int i=1;i<=n;i++){
modify(a[i],query(a[i]-1)+1);
for(int j=0;j<v[i].size();j++){
ans[v[i][j].id]=query(v[i][j].k);
}
}
for(int i=1;i<=m;i++){
cout<<ans[i]<<'\n';
}
return 0;
}
G
太困难。不会。

浙公网安备 33010602011771号