Codeforces Round #365 (Div. 2)

第一题:水的不能再水了,小学生都会。。。

第二题:给你n个城市,k个省市,每个城市和它序号相邻的城市相连,例如当n==3时,1-2-3-1,当城市为省市时,省市会和其他的城市都有一条边直接相连,求所有城市的边的权重和。

Examples
input
4 1
2 3 1 2
3
output
17
input
5 2
3 5 2 2 4
1 4
output
71
Note

This image describes first sample case:

It is easy to see that summary price is equal to 17.

This image describes second sample case:

一开始用O(N^2),TLE,一直想不出怎么降时间复杂度,总觉得至少都要算n*k次的啊(秀智商了),看题解,尼玛,有规律的(小学生都会),

先预处理总和ans,每一条边和其他边相连的权重和为S=(ans-a[i])*a[i],如果有多个省市,那么需要减去这些省市之间的重复计算,

S=(ans-res)*a[i];    res计算已经就算过的省市权重和

当然最后还要遍历一遍相邻城市之间的权重是否计算了,我是用F[N][2]来计算每个节点相邻节点是否计算,同样也可以用一维来记录;

唉,反正这题真的是秀智商了,渣渣渣~~~难过

--------------------------------------------------------------------------------------------------------

敲代码中一些问题:

1.刚开始由于LL,int混用,导致到大数据就会出错,虽然不知道为什么,但是以后记住不要LL,int 混用

2.忘记自己F数组只是开到【2】,然而一直写的都是记录两个节点,唉,调试了好久,后来才发现,,改为前节点记录为f[i][0],后节点记录为f[i][1]

----------------------------------------------------------------------------------------------------------

一道大水题弄了一早上,羞耻~~~

#include <iostream>
#include <cassert>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iterator>
using namespace std;
typedef long long ll;
#define N 100100
int n,k;
ll sum,ans,res;
int b[N],a[N];
bool f[N][2];
//bool f[N][N];
int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif

	while(~scanf("%d%d",&n,&k)) {
		memset(f,0,sizeof(f));
		int x;
		sum=0;
		ans=0;
		res=0;
		for(int i=0; i<n; i++) scanf("%d",&a[i]);
		for(int i=0; i<n; i++) {
			ans+=a[i];
			//f[i][(i+1)%n]=f[(i+1)%n][i]=true;
			//cout<<sum<<endl;
		}
		for(int i=0; i<k; i++) {
			scanf("%d",&b[i]);
			b[i]=b[i]-1;
			res+=a[b[i]];
			sum+=(ans-res)*a[b[i]];
			int x=(b[i]+1)%n,y=b[i]==0?n-1:(b[i]-1);
			
			f[b[i]][0]=f[b[i]][1]=1;
			f[x][1]=f[y][0]=1;

		}
		for(int i=0; i<n; i++) {
			int x=(i+1)%n,y=(i==0?n-1:(i-1));

			if(!f[i][0]||!f[x][1])  {
				sum+=a[i]*a[x];
				f[i][0]=f[x][1]=1;

			}
			if(!f[i][1]||!f[y][0]) {
				sum+=a[i]*a[y];
				f[i][1]=f[y][0]=1;

			}
		}
		printf("%I64d\n",sum);

	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值