牛客练习赛60(A-C)

A 已知n个数,求任意两个数(包括自身与自身)&运算之后的和
n的范围是1e5肯定不能暴力了,所以从与运算的角度考虑,两个数与运算二进制位同为1得1,否则得0,求ai与那个数与运算的和,ai的第j位为1,那个n个数中共有cnt[j]个数di就位为1,那么与运算共可以的得到cnt[j]个结果的第j位是1就是cnt[j]个2^(j-1),所以暴力枚举n个数相加就可以了,注意爆int。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
int  a[N],b[N],s[N];
int t,n; 
int cnt[N];
void get(int x)//统计每一位1的个数保存在cnt里
{
	for(int i=1;i<=50;i++)
	{
		cnt[i]+=(x&1);
		x>>=1;
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],get(a[i]);
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=50;j++)
		{
			if(a[i]&1) ans+=1ll*cnt[j]*(1<<(j-1));
			a[i]>>=1;
		}
	}
	cout<<ans;
	return 0;
}

B 已知n个点的坐标,求着n个点所能组成的所有三角形的周长和,边长用曼哈顿距离计算。
n个点可以组成n*(n-1)条边,每条边与剩余的n-2个点可以分别组成n-2个三角形,那么这条边就贡献了n-2次,暴力枚举每条边计算就可以了,没有重复的

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int N = 100010,mod=998244353;
ll  a[N],b[N],s[N];
int t,n; 
ll get(int i,int j)//计算曼哈顿距离
{
	return abs(a[i]-a[j])+abs(b[i]-b[j]);
}
int main(){
	
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			ans=(ans+get(i,j)*(ll)(n-2))%mod; 
		}
	}
	cout<<ans;
	return 0;
}

C 计算已知字符串中有多少个不同的长度为k的子串。
定义 dp[i][j]表示前i个字符中长度为j的字串的个数。
那么接下来就是找状态转移方程了,dpij是长度为j的字符串,可以分为两种状态,包含si(第i个字符)和不含si,不含si的个数就是dp[i-1][j],包含si的个数就是dp[i-1][j-1](前i-1个字符中长度为j-1的串后边再加一个si就是了),所以dp[i][j]=dp[i-1][j-1]+dp[i-1][j];这只是一个粗略的转移没有去重,dp[i-1][j-1]都是在末位加了一个si当做没有重复,dp[i-1][j]中可能包含以si结尾的长度为j的串这样聚会与dp[i-1[j-1]重复了,所以我们需要减去其中重复的那部分,前i-1个字符中以si结尾长度为j的子串,这个位置i-1没有用到,所以f[j][s]表示长度为j以字符s结尾的子串,减去就行了,所以状态转移方程就是
dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]-f[j][s[i]-‘a’]+mod)%mod;
注意数组f的更新一下就可以了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1010,mod=1e9+7;
int t,n,k; 
char s[N];
ll dp[N][N],f[N][30];
int main(){
	cin>>n>>k>>s+1;
	dp[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		dp[i][0]=1;
		for(int j=1;j<=k;j++)
		{
			dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]-f[j][s[i]-'a']+mod)%mod;
			f[j][s[i]-'a']=dp[i-1][j-1];
		}
	}
	ll ans=0;
	cout<<dp[n][k]; 
	return 0;
}
原文地址:https://www.cnblogs.com/neflibata/p/12871770.html