A
https://ac.nowcoder.com/acm/contest/4853/A
题意:
优化如下代码到线性阶
int n;cin>>n; int a[n];for(int i=0;i<n;++n)cin>>a[i]; ll ans=0; for(int i=0;i<n;++i) for(int j=0;j<n;++j) ans+=a[i]&a[j]; cout<<ans<<endl;
题目示例为:
输入
5
1 2 3 4 5
输出
33
题目示例可转化为
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
按位思考,每一个位,都是n个点的完全图。
求得到每一个数互相与的结果,可以转化为求每一个数每一位上互相与,再按位加和的结果。
以第三列(最末尾,权值为1)为例
1
0
1
0
1
这样的完全图,因为与运算的实质,所以只需要计算1的个数,这一位上的结果即为 。
优化后时间复杂度T(32n)
#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { int n; cin >> n; int a[n + 1]; for (int i = 0; i < n; ++i) cin >> a[i]; int cnt[32] = {0}; for (int j = 0; j < 32; ++j) for (int i = 0; i < n; ++i) if ((a[i] >> j) & 1) ++cnt[j]; ll ans = 0; for (int i = 0; i < 32; ++i) ans += cnt[i] * cnt[i] * (1LL << i); cout << ans << endl; return 0; }
B
https://ac.nowcoder.com/acm/contest/4853/B
题意:n个点能组成的三角形周长之和。任意三点不在同一直线上。
完全图。
对于任意两个点而言,都能找到第三个点与它们组成三角形。
也就是说,任何一条边都能和n-2个其余点组成三角形。
也就是说,完全图的任意一条边都被计算了n-2次。
最后longlong。
#include <bits/stdc++.h> #define sscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) using namespace std; typedef long long ll; const int N=1e3+7; const int mod=998244353; struct poi { ll x,y; } a[N]; ll getdis(poi a,poi b) { return (abs(a.x-b.x)+abs(a.y-b.y)); } int main() { sscc; int n; cin>>n; for(int i=0; i<n; ++i) cin>>a[i].x>>a[i].y; ll ans=0; for(int i=0; i<n; ++i) for(int j=0; j<i; ++j){ ans+=getdis(a[i],a[j])*(n-2); ans%=mod; } cout<<ans<<endl; return 0; }
#include <bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; const ll mod = 998244353; int main() { int n; cin >> n; pair<ll, ll> a[n]; for (int i = 0; i < n; ++i) cin >> a[i].x >> a[i].y; ll ans = 0; for (int i = 0; i < n - 1; ++i) for (int j = i + 1; j < n; ++j) ans += abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y), ans %= mod; ans = ans * (n - 2) % mod; cout << ans << endl; return 0; }
C
dp
#include <bits/stdc++.h> using namespace std; const int mod = 1e9 + 7; char s[1005]; long long f[1005][1005], g[130] = {0}; int main() { int n, k; scanf("%d%d%s", &n, &k, s + 1); for (int i = 1; i <= n; i++) { f[i - 1][0] = 1; for (int j = 1; j <= i; j++) { f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) % mod; if (g[s[i]]) f[i][j] -= f[g[s[i]] - 1][j - 1]; f[i][j] = (f[i][j] + mod) % mod; } g[s[i]] = i; } f[n][0] = 1; cout << f[n][k] % mod << endl; return 0; }