abc393 题解合集

here.

\(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

太困难。不会。

posted @ 2025-02-15 21:24  _Kenma  阅读(56)  评论(0)    收藏  举报