题会慢慢补完的,最近在帮别人上课,补题速度很慢,一边看ppt一边刷ppt的题还要补多校的,感觉有点应付不过来,不过以后会慢慢补完的(指整个暑假)
A
这场出题人的英文水平真的搞事,不说了(((
这题起码读了X遍才搞明白题意,每次读都是不同的意思,出题人好好表达不行吗(((
题意是说这个人在长度为N的环上走,等概率随机往左往右,如果全部走完一次就离开,问在M点离开的概率。
再次吐槽,这个N也真的搞事,有时用来表达N steps有时又是长度为N,而且输出还是前缀和
考虑吸收壁的随机游走,然后我们改一下,改成环,吸收条件也改一下,但是这依然可以感受出来极限情况下除了0不能作为结束之外等概率(严格证起来好像很日,然后就完了
/* ***********************************************
Author :BPM136
Created Time :7/21/2019 7:24:02 PM
File Name :A.cpp
************************************************ */
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<bitset>
#include<queue>
#include<ctime>
#include<set>
#include<map>
#include<list>
#include<vector>
#include<cassert>
#include<string>
#include<cinttypes>
#include<cstdint>
#include<array>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
ll const mod = 1e9 + 7;
ll KSM(ll a, ll k) {
ll ret = 1;
for (; k; k >>= 1, a = a * a % mod)
if (k & 1)
ret = ret * a % mod;
return ret;
}
int main() {
USE_CIN_COUT;
int T, n, m;
cin >> T;
ll ans = 1;
for (int i = 1; i <= T; ++i) {
cin >> n >> m;
if (n != 1) {
if (m == 0)
ans = 0;
else
ans = ans * KSM(n - 1, mod - 2) % mod;
}
cout << ans << '\n';
}
return 0;
}
B
C
D
显然大团是包含小团的,不过比赛的时候上头了没考虑怎么优化,只想着卡常(((
其实只要把bfs的时候让1的赋予顺序是从左往右就行,这样就从
O
(
K
n
l
o
g
(
K
n
)
)
O(Knlog(Kn))
O(Knlog(Kn))变成了
O
(
K
l
o
g
(
K
n
)
)
O(Klog(Kn))
O(Klog(Kn))
以及判断的时候可以压位,这样就
O
(
N
64
)
O(\frac{N}{64})
O(64N)的判断时间了(就是这个给了我盲目的信心想大力爆过去((((
/* ***********************************************
Author :BPM136
Created Time :7/20/2019 1:35:41 PM
File Name :D.cpp
************************************************ */
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<bitset>
#include<queue>
#include<ctime>
#include<set>
#include<map>
#include<list>
#include<vector>
#include<cassert>
#include<string>
#include<cinttypes>
#include<cstdint>
#include<array>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
int const N = 105;
string e[N];
ll e_st1[N], e_st2[N];
int a[N];
int n, K;
struct node {
ll st1, st2;
ll val;
node() {}
node(ll _st1, ll _st2, ll _val) : st1(_st1), st2(_st2), val(_val) {}
bool operator<(node const& oth) const {
return val > oth.val;
}
};
inline void getSt(ll st1, ll st2, ll& nst1, ll& nst2, int np) {
nst1 = st1;
nst2 = st2;
if (np < 50)
nst1 |= 1LL << np;
else
nst2 |= 1LL << (np - 50);
}
inline node getNewNode(node const& x, int np) {
node ret = x;
if (np < 50)
ret.st1 |= 1LL << np;
else
ret.st2 |= 1LL << (np - 50);
ret.val += a[np];
return ret;
}
inline bool pInSta(ll const& st1, ll const& st2, int p) {
if (p < 50)
return st1 & (1LL << p);
else
return st2 & (1LL << (p - 50));
}
inline bool eInSta(ll const& st1, ll const& st2, ll const& e1, ll const& e2) {
return ((st1 & e1) == st1) && ((st2 & e2) == st2);
}
//set<node> S;
int main() {
double tt = clock();
freopen("in.txt", "r", stdin);
cin >> n >> K;
--K;
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cin >> e[i];
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (e[i][j] == '1')
getSt(e_st1[i], e_st2[i], e_st1[i], e_st2[i], j);
//bitset<5> debug1, debug2;
auto Q = priority_queue<node>();
Q.push(node{ 0, 0, 0 });
// S.insert(node{ 0, 0, 0 });
node tmp;
while (Q.empty() == 0 && K--) {
auto now = Q.top();
Q.pop();
//debug1 = now.st1, debug2 = now.st2;
// cerr << debug1 << ' ' << debug2 << ' ' << now.val << ' ' << Q.size() << ' ' << K << '\n';
int mx = 0;
for (int i = 0; i < n; ++i)
if (pInSta(now.st1, now.st2, i))
mx = i + 1;
for (int i = mx; i < n; ++i)
if (eInSta(now.st1, now.st2, e_st1[i], e_st2[i])) {
tmp = getNewNode(now, i);
//if (S.count(tmp) == 0) {
Q.push(tmp);
// S.insert(tmp);
//}
}
}
// cerr << K << ' ' << Q.empty() << ' ' << Q.top().val << '\n';
if (K >= 0 || Q.empty())
cout << -1 << '\n';
else
cout << Q.top().val << '\n';
cerr << clock() - tt << '\n';
return 0;
}
E
F
dfs
#include <iostream>
#include <limits>
#include <cstdint>
#include <algorithm>
#include <string>
#include <vector>
using i64 = int64_t;
const int N = 14 * 2;
int n, v[N][N];
int ss1[N], ss2[N];
i64 ans, cur;
void dfs (int i, int cnt1) {
if (ans <= cur)
return;
if (i == n) {
ans = cur;
return;
}
if (cnt1 < (n >> 1)) {
i64 s1 = 0;
for (int j = 0; j < cnt1; ++j)
s1 += v[i][ss1[j]];
ss1[cnt1] = i;
// std::cerr << "> " << i << " " << s1 << "\n";
cur += s1;
dfs(i + 1, cnt1 + 1);
cur -= s1;
}
int cnt2 = i - cnt1;
if (cnt2 < (n >> 1)) {
i64 s2 = 0;
for (int j = 0; j < cnt2; ++j)
s2 += v[i][ss2[j]];
ss2[cnt2] = i;
cur += s2;
dfs(i + 1, cnt1);
cur -= s2;
}
}
int main () {
std::ios::sync_with_stdio(false);
std::cin >> n;
n *= 2;
i64 sum = 0;
for (int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j) {
std::cin >> v[i][j];
if (i < j)
sum += v[i][j];
}
ans = std::numeric_limits<i64>::max();
cur = 0;
dfs(0, 0);
// std::cerr << "s = " << ans << '\n';
std::cout << sum - ans << '\n';
return 0;
}
G
H
原题,单调栈爆过去就行
/* ***********************************************
Author :BPM136
Created Time :7/20/2019 12:41:43 PM
File Name :H.cpp
************************************************ */
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<bitset>
#include<queue>
#include<ctime>
#include<set>
#include<map>
#include<list>
#include<vector>
#include<cassert>
#include<string>
#include<cinttypes>
#include<cstdint>
#include<array>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
int const N = 1005;
int lef[N], sta[N];
int row[N][N];
int val[N][N];
int a[N][N];
int n, m;
void update(int& ans1, int& ans2, int tmp) {
if (tmp >= ans1) {
ans2 = ans1;
ans1 = tmp;
} else
if (tmp > ans2)
ans2 = tmp;
}
int main() {
cin >> n >> m;
string s;
for (int i = 1; i <= n; ++i) {
cin >> s;
for (int j = 1; j <= m; ++j) {
a[i][j] = s[j - 1] == '1';
if (a[i][j])
a[i][j] = a[i][j - 1] + 1;
}
}
auto ans1 = 0, ans2 = 0;
for (int j = 1; j <= m; ++j) {
int top = 0;
a[n + 1][j] = -1;
for (int i = 1; i <= n + 1; ++i) {
if (top == 0 || a[i][j] > a[sta[top - 1]][j]) {
sta[top++] = i;
lef[i] = i;
continue;
}
if (a[i][j] == a[sta[top - 1]][j])
continue;
while (top >= 1 && a[i][j] < a[sta[top - 1]][j]) {
--top;
update(ans1, ans2, (i - lef[sta[top]]) * a[sta[top]][j]);
update(ans1, ans2, (i - lef[sta[top]] - 1) * a[sta[top]][j]);
update(ans1, ans2, (i - lef[sta[top]]) * (a[sta[top]][j] - 1));
}
lef[i] = lef[sta[top]];
sta[top++] = i;
}
}
cout << ans2 << endl;
}