0924模擬賽總結

A.String Master

\(O(n^3)\)跑跑跑,至關與\(LCS\)加一維,而後考場上彷佛內存炸了,突發奇想改了\(short\)A掉了,妙啊ios

B.Tourist Attractions


考慮只枚舉\(2-3\)這樣的邊,而後對答案的貢獻就是,(u所鏈接點的個數-1) * (v所鏈接點的個數-1)而後再減去一個重複計算的部分,就是同時鏈接了\(u\)\(v\)的點作的貢獻
像這樣

5顯然作了兩次貢獻
\((d_u - 1) * (d_v - 1) - son[u]\cap son[v]\)
獲得了70分的好成績
而後用\(bitset\)維護一下取交集的操做就okk了
注意題目中較小的數據範圍spa

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <bitset>
using namespace std;

inline int read(){
	int x = 0, w = 1;
	char ch = getchar();
	for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return x * w;
}

const int ss = 2333;

bitset<1501> b[ss];

int d[ss];
long long dp[ss][ss], ans;
char s[ss][ss];

signed main(){
	freopen("tourist.in", "r", stdin);
	freopen("tourist.out", "w", stdout);
	int n = read();
	for(register int i = 1; i <= n; i++)
		scanf("%s", s[i] + 1);
	for(register int i = 1; i <= n; i++) dp[1][i] = 1;
	for(register int i = 1; i <= n; i++)
		for(register int j = 1; j <= n; j++)
			if(s[i][j] == '1') d[i]++;
	for(register int t = 2; t <= 4; t++)
		for(register int i = 1; i <= n; i++)
			for(register int j = 1; j <= n; j++)
				if(s[i][j] == '1') dp[t][i] += dp[t - 1][j];
	for(register int i = 1; i <= n; i++)
		ans += dp[4][i];
	for(register int i = 1; i <= n; i++)
		ans -= d[i] * d[i] * 2;
	for(register int i = 1; i <= n; i++){
		for(register int j = 1; j <= n; j++){
			if(s[i][j] == '1') b[i][j] = 1, ans++;
		}
	}
	for(register int i = 1; i <= n; i++){
		for(register int j = i + 1; j <= n; j++){
			if(b[i][j]) ans -= (b[i] & b[j]).count() * 2;
		}
	}
	cout << ans << endl;
}

C.Walk

對於每個值,只有可能和本身的子集連邊,而後不得不復習一下如何求一個數的全部子集code

signed main(){
	int n = read();
	for(register int i = n; i; i = (i - 1) & n)
		cout << i << endl;
}
相關文章
相關標籤/搜索