B:
#include<bits/stdc++.h>
#define N 100010
#define int long long
using namespace std;
int limit,sum;
//int lowb[N];
struct node{
int lowb;
int yuan;
}shu[N];
inline cmp(node a,node b)
{
return a.lowb>b.lowb;
}
//signed getzhi(int a)
//{
// int num=1;
// if(a==2)
// return 1;
// while(pow(2,num)<a)
// {
// num++;
// }
// return num;
//}
int getlow (int x) {
int c = 0;
while (x) {
if (x&1)
return 1<<c;
x /= 2;
c++;
}
return 0;
}
signed main()
{
cin>>sum>>limit;
for(int i=1;i<=limit;i++)
shu[i].yuan=i;
for(int i=1;i<=limit;i++)
{
// if(i%2==1)
// shu[i].lowb=1;
// else
// {
// int t=getzhi(i);
// if(pow(2,t)==i)
// shu[i].lowb=i;
// else
// shu[i].lowb=i-pow(2,t);
// }
shu[i].lowb=getlow(i);
}
sort(shu+1,shu+1+limit,cmp);
int zhi=limit;
int size=0;
int ans[N];
// while(zhi)
// {
// if(shu[zhi].lowb<=sum)
// {
// sum-=shu[zhi].lowb;
// size++;
// ans[size]=shu[zhi].yuan;
// }
// zhi--;
// }
// if(sum)
// cout<<"-1"<<endl;
// else
// {
// cout<<size<<endl;
// cout<<ans[1];
// for(int i=2;i<=size;i++)
// {
// cout<<" "<<ans[i];
// }
// cout<<endl;
// }
int cnt=0;
for(int i=1;i<=limit;i++)
{
if(sum>=shu[i].lowb)
{
sum-=shu[i].lowb;
ans[++cnt]=shu[i].yuan;
}
}
if(sum)
cout<<"-1"<<endl;
else{
cout<<cnt<<endl;
cout<<ans[1];
for(int i=2;i<=cnt;i++)
cout<<" "<<ans[i];
cout<<endl;
}
return 0;
}
D:
#include<bits/stdc++.h>
#define N 100010
#define int long long
using namespace std;
struct node{
int l,r;
int minn;
}rope[N];
int n,m;
int a[N];
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
{
int l,r;
cin>>l>>r;
rope[i].l=a[l];
rope[i].r=a[r];
rope[i].minn=min(rope[i].l,rope[i].r);
}
int sum=0;
for(int i=1;i<=m;i++)
{
sum+=rope[i].minn;
}
cout<<sum<<endl;
return 0;
}
D:并查集(巧妙)
#include<bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
int num[N];
int p[N];
struct node{
int l,r;
int minn;
}e[N];
int find(int x)
{
if(p[x]!=x)
p[x]=find(p[x]);
return p[x];
}
bool cmp(node a,node b){
return a.minn>b.minn;
}
int n,m;
int a[N];
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
p[i]=i;
num[i]=1;
}
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
{
cin>>e[i].l>>e[i].r;
e[i].minn=min(a[e[i].l],a[e[i].r]);
}
sort(e+1,e+1+m,cmp);
int ans=0;
for(int i=1;i<=m;i++)
{
int aa=find(e[i].l);
int bb=find(e[i].r);
//已经排过序了,所以每次新取得边都比之前的边要小
//所以不用再更新区间的最小值了
if(aa!=bb)
{//因为现在的最小边乘上点的个数==现在这个点可以和多少个点构成联系
ans+=num[aa]*num[bb]*e[i].minn;
p[aa]=bb;
num[bb]+=num[aa];
}
}
cout<<setprecision(6)<<ans*2.0/(n*(n-1))<<endl;
return 0;
}
优化并查集算法:区间最小值应用
本文介绍了如何在C++中使用并查集数据结构,通过巧妙地计算区间内的最小值来优化问题解决。涉及的主要算法包括计算节点最低位、并查集的合并操作和最小边的查找。通过实例展示了如何在给定限制条件下找出满足条件的元素组合。
1330

被折叠的 条评论
为什么被折叠?



