Atcoder 436 总结+E-F题解

总结

A,B,C,D,E

考场上想出了正解并打出了代码,没什么问题。

F

考场上没想出来一个小小的优化。

题解

E

我们会发现如果当前这个值和另外一个值可以交换。那么它交换完之后可以和其他的进行交换,使得在规定的次数内完成。会发现能够满足的值只有一部分。

你会发现这部分的值我们可以对,\(i\) 到$ a_i$ 连一条边,你就会发现这里会连成一个环。而只有在还上的我们才会满足条件。

且我们会发现这道题只会连成若干个环。不会连出其他的形状。所以直接用并查集就行了。

求出它的总共的大小来一个我先对这个总大小-1,然后再把它家加到答案里即可。

代码

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=3e5+5;
int fa[maxn],siz[maxn];
int get(int x)
{
	return fa[x]==x?x:fa[x]=get(fa[x]);
}
void merge(int u,int v)
{
	u=get(u),v=get(v);
	if(u!=v) fa[v]=u,siz[u]+=siz[v];
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n,ans=0;cin>>n;
	for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++)
	{
		int x;cin>>x;
		merge(i,x);
	}
	for(int i=1;i<=n;i++)
	{
		int x=get(i);
		siz[x]--,ans+=siz[x];
	}
	cout<<ans;
	return 0;
}

F

由于这里我们需要固定三个值显然是枚举不了的。但是我们可以先固定我们拍到的照片里面那个最不亮的星星是第几亮的。

固定完之后,我们去找左右端点。会发现,只有那些比它亮的可以作为端点,否则的话,其他的就会跟这些重复,那么我们这里是不可以计算的。

至于左右两边,我们可以用权值树状数组来完成。

代码

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=5e5+5;
int a[maxn],bit[maxn],n,id[maxn];
int lb(int x)
{
	return x&-x;
}
void update(int x,int y)
{
	while(x<=n) bit[x]+=y,x+=lb(x);
}
int query(int x)
{
	int ans=0;
	while(x) ans+=bit[x],x-=lb(x);
	return ans;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int ans=0;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],id[a[i]]=i;
	for(int i=1;i<=n;i++)
	{
		update(id[i],1);
		int l=query(id[i]),r=i-query(id[i]-1);
		ans+=l*r;
	}
	cout<<ans;
	return 0;
}
posted @ 2025-12-14 14:13  Engle_Chen  阅读(4)  评论(0)    收藏  举报