703B |
给n个点 围成一个环
相邻节点有边
给你k个点 这k点与另外所有点右边
问 对于所有边 edge[i][j] 求Σedge[i][j].val
edge[i]j[j].val==val[i]*val[j];
解决:
1.先求环上的边
2.对于 对于每个特殊的点 顺次求出他对这张图的贡献
(要对a[0]和a[n-1]特判)
#define en '\n'
#define ll long long
using namespace std;
ll sum,sumt,n,ans,k;
bool vis[maxn];
ll a[maxn];
int main(){
#ifdef local
freopen("input2.txt","r",stdin);
#endif // local
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>a[i];
sum+=a[i];
}
for(int i=0;i<k;i++){
int tem;
cin>>tem;
vis[tem-1]=1;
}
a[n]=a[0];
for(int i=0;i<n;i++){
ans+=a[i]*a[i+1];
}
for(int i=0;i<n;i++){
if(vis[i]){
ll temmul=sum-sumt;/// sumt表示该点之前已经计算过的特殊点的Σa[i]
int left,right;
if(i==0){
temmul-=a[i]+a[n-1]+a[i+1];
}
else if(i==n-1){
if(!vis[i-1]){
temmul-=a[i-1];
}
temmul-=a[i];
if(!vis[0]){
temmul-=a[0];/// 其他点的 temmul 都可以直接减去 a[right]
}///只有a[n-1]需要注意要判断a[0]是否已经在sumt里面
}
else {
left=i-1;
if(!vis[left]){
temmul-=a[left];
}
temmul-=a[i];
temmul-=a[i+1];
}
ans+=a[i]*temmul;
sumt+=a[i];
}
}
cout<<ans<<en;
return 0;
}