人,只有自己站起来,这个世界才能属于他。|

园龄:粉丝:关注:

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(nlnn)

#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 方式:设 fi 表示以 i 结尾的 LIS。

转移:

fai=maxj=1ai1fj+1

用 BIT 可以优化到 O(nlogn)

考虑将询问挂到每个点上,从左到右扫维护 f 即可。

需要离散化。

复杂度 O((n+m)logn)

#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

太困难。不会。

本文作者:Kenma

本文链接:https://www.cnblogs.com/Kenma/p/18717426

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   _Kenma  阅读(36)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起