( ext{Solution:})
首先,显然的策略是把一定不能翻倍的先加进来。继续考虑下一步操作。
考虑$x,y$两个可以翻倍的物品,且$a_x>a_y.$
那么,设原来答案为$sum$,则有下面情况:
先选择$x:$
- 若$a_x<sum$则翻倍,与此同时$a_y$也必定小于$sum.$
- 若$a_x>sum$则$sum o sum+a_x$与此同时$a_y<sum.$
先选择$y:$
- 若$a_y<sum$则翻倍,$a_x$待定。
- 若$a_y>sum$则$sum o sum+a_y$,$a_x$待定。
但对比上面的选法,先选$a_y$与先选$a_x$的一些情况无异,反而,如果加了$a_x$再翻倍和加了$a_y$翻倍显然$a_x$更优。于是我们推出先选择$a_x.$
由此,证毕,此题得解。
( ext{Q.E.D.})
#include<bits/stdc++.h>
using namespace std;
int n,a[500010],b[500010],m;
int mx,sum,vis[500010];
inline bool cmp(int x,int y){return a[x]>a[y];}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=m;++i)scanf("%d",&b[i]),vis[b[i]]=1;
if(n==m){
for(int i=1;i<=n;++i)mx=mx<a[i]?a[i]:mx;
cout<<(mx<<(n-1))<<endl;
return 0;
}
sort(b+1,b+m+1,cmp);
for(int i=1;i<=n;++i)sum+=(!vis[i]?1:0)*a[i];
for(int i=1;i<=m;++i){
if(a[b[i]]>=sum)sum+=a[b[i]];
else sum=sum+sum;
}
cout<<sum<<endl;
return 0;
}