刚做完= =第五题写炸了
先大概讲讲我的思路,有机会我会写个完整的题解(估计不可能啦,忙的要死)
这些代码都是我比赛时候写的,不保证正确性
水题,记录最后一次的得分即可
#include
using namespace std;
int main() {
int ans = 0, base = 1, x;
while (true) {
scanf("%d", &x);
if (x == 0) {
printf("%d\n", ans);
break;
}
else if (x == 1) base = 1;
else if (base == 1) base = 2;
else base += 2;
ans += base;
}
return 0;
}
考虑到两个球相碰只会变方向,所以模拟球的运行即可
#include
#include
#include
using namespace std;
int a[105], d[105], vis[1005];
int main() {
int n, L, t;
scanf("%d%d%d", &n, &L, &t);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
d[i] = 1;
}
for (int i = 1; i <= t; i++) {
memset(vis, -1, sizeof(vis));
for (int j = 0; j < n; j++) {
a[j] += d[j];
if (vis[a[j]] != -1) swap(d[j], d[vis[a[j]]]);
else vis[a[j]] = j;
if (a[j] == 0) d[j] = 1;
if (a[j] == L) d[j] = -1;
}
}
for (int i = 0; i < n; i++) {
printf("%d%c", a[i], i == n - 1 ? '\n' : ' ');
}
return 0;
}
按照题意理解,会发现只需要考虑三种匹配的情况即可。
#include
#include
#include
using namespace std;
string S, R, rule[105], name[105], str;
vector ans;
int L[105];
int main() {
int n, m, len, rule_pos, str_pos;
bool error, flag;
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> rule[i] >> name[i];
L[i] = rule[i].length();
}
for (int i = 0; i < m; i++) {
flag = false;
cin >> str;
len = str.length();
for (int j = 0; j < n; j++) {
//cout << "Here is rule NO." << j << endl;
ans.clear();
rule_pos = 0, str_pos = 0, error = false;
while (str_pos < len && rule_pos < L[j]) {
//cout << "At str_pos = " << str_pos << " , rule_pos = " << rule_pos << endl;
if (rule[j][rule_pos] == '<') {
rule_pos++;
R.clear();
while (rule[j][rule_pos] != '>') {
R += rule[j][rule_pos];
rule_pos++;
}
rule_pos++;
if (R == "int") {
S.clear();
while (true) {
if (str_pos == len) {
if (S.length() == 0) {
error = true;
}
break;
}
if (str[str_pos] == '/') {
if (S.length() == 0) {
error = true;
}
break;
}
else if (str[str_pos] >= '0' && str[str_pos] <= '9') {
S += str[str_pos];
str_pos++;
}
else {
error = true;
break;
}
}
if (error) break;
if (S.find_first_not_of('0') == string::npos) ans.push_back("0");
else {
S = S.substr(S.find_first_not_of('0'));
ans.push_back(S);
}
}
else if (R == "str") {
S.clear();
while (true) {
if (str_pos == len) {
if (S.length() == 0) {
error = true;
}
break;
}
if (str[str_pos] == '/') {
if (S.length() == 0) {
error = true;
}
break;
}
else if (str[str_pos] >= '0' && str[str_pos] <= '9') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] == '-') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] == '_') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] == '.') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] >= 'a' && str[str_pos] <= 'z') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] >= 'A' && str[str_pos] <= 'Z') {
S += str[str_pos];
str_pos++;
}
else {
error = true;
break;
}
}
if (error) break;
ans.push_back(S);
}
else {
S.clear();
while (true) {
if (str_pos == len) {
if (S.length() == 0) {
error = true;
}
break;
}
if (str[str_pos] == '/') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] >= '0' && str[str_pos] <= '9') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] == '-') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] == '_') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] == '.') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] >= 'a' && str[str_pos] <= 'z') {
S += str[str_pos];
str_pos++;
}
else if (str[str_pos] >= 'A' && str[str_pos] <= 'Z') {
S += str[str_pos];
str_pos++;
}
else {
error = true;
break;
}
}
if (error) break;
ans.push_back(S);
}
}
else {
if (rule[j][rule_pos] != str[str_pos]) {
error = true;
break;
}
str_pos++;
rule_pos++;
}
}
if (str_pos < len || rule_pos < L[j]) error = true;
if (!error) {
cout << name[j];
for (int m = 0; m < ans.size(); m++) cout << " " << ans[m];
cout << endl;
flag = true;
break;
}
}
if (!flag) cout << "404" << endl;
}
return 0;
}
下棋的情况最多9!种,暴力枚举所有情况即可
#include
#include
using namespace std;
int mp[5][5];
int judge() {
int cnt = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (mp[i][j] == 0) cnt++;
}
}
for (int d = 1; d <= 2; d++) {
for (int i = 0; i < 3; i++) {
bool flag = true;
for (int j = 0; j < 3; j++) {
flag = (flag && (mp[i][j] == d));
}
if (flag) {
if (d == 1) return cnt + 1;
else return -cnt - 1;
}
}
}
for (int d = 1; d <= 2; d++) {
for (int j = 0; j < 3; j++) {
bool flag = true;
for (int i = 0; i < 3; i++) {
flag = (flag && (mp[i][j] == d));
}
if (flag) {
if (d == 1) return cnt + 1;
else return -cnt - 1;
}
}
}
for (int d = 1; d <= 2; d++) {
bool flag = true;
for (int i = 0; i < 3; i++) {
flag = (flag && (mp[i][i] == d));
}
if (flag) {
if (d == 1) return cnt + 1;
else return -cnt - 1;
}
}
for (int d = 1; d <= 2; d++) {
bool flag = true;
for (int i = 0; i < 3; i++) {
flag = (flag && (mp[i][2 - i] == d));
}
if (flag) {
if (d == 1) return cnt + 1;
else return -cnt - 1;
}
}
return 0;
}
int dfs(int cnt, bool flag) {
int ans;
if (flag) ans = -10;
else ans = 10;
int X = judge();
if (X != 0) return X;
if (cnt == 9) return X;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (mp[i][j] == 0) {
if (flag) mp[i][j] = 1;
else mp[i][j] = 2;
if (flag) ans = max(ans, dfs(cnt + 1, !flag));
else ans = min(ans, dfs(cnt + 1, !flag));
mp[i][j] = 0;
}
}
}
return ans;
}
int main() {
int T, cnt;
scanf("%d", &T);
while (T--) {
cnt = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
scanf("%d", &mp[i][j]);
if (mp[i][j] != 0) cnt++;
}
}
printf("%d\n", dfs(cnt, true));
}
return 0;
}
考虑到每次操作只是对一条链加一个值,所以我们可以预处理出每个节点对答案的贡献倍数,然后每次记录答案,那么我们就不需要更新节点值,而是直接在答案上加。
我写的是n^2预处理贡献,mlognlogn进行计算答案,可惜写炸了。。。
貌似100%的通过需要用树分治预处理贡献
以下的代码是写炸的,等到cspro把题挂出来了我再尝试改正吧= =||
#include
#include
#include
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ms(x) memset(x, 0, sizeof(x))
typedef vector vi;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int MAX_N = 2e3 + 5;
vi mp[MAX_N];
int Size[MAX_N], pre[MAX_N], depth[MAX_N], Top[MAX_N], ID[MAX_N], son[MAX_N], tot, n, lmtL, lmtR;
ll w[MAX_N], a[MAX_N];
//map num[MAX_N];
struct Segment_Tree {
struct Node {
ll seg;
} T[MAX_N << 2];
void push_up(int rt) {
T[rt].seg = (T[rt << 1].seg + T[rt << 1 | 1].seg) % MOD;
}
void Build(int l, int r, int rt) {
T[rt].seg = 0;
if (l == r) {
T[rt].seg = 0;
return;
}
int m = (l + r) >> 1;
Build(lson), Build(rson), push_up(rt);
}
void Update(int pos, ll c, int l, int r, int rt) {
if (l == r) {
T[rt].seg = c;
return;
}
int m = (l + r) >> 1;
if (pos <= m) Update(pos, c, lson);
if (pos > m) Update(pos, c, rson);
push_up(rt);
}
ll Query(int L, int R, int l, int r, int rt) {
if (L > R) return -1;
if (L <= l && r <= R) return T[rt].seg;
int m = (l + r) >> 1;
ll ret = 0;
if (L <= m) ret = (ret + Query(L, R, lson)) % MOD;
if (m < R) ret = (ret + Query(L, R, rson)) % MOD;
return ret;
}
} ST;
void init_HLD(int x, int dad) {
Size[x] = 1, pre[x] = dad;
for (int i = 0; i < mp[x].size(); i++) {
int y = mp[x][i];
if (y == dad) continue;
depth[y] = depth[x] + 1;
init_HLD(y, x);
Size[x] += Size[y];
if (Size[y] > Size[son[x]]) son[x] = y;
}
}
void HLD(int x, int Tp) {
Top[x] = Tp, tot++;
ID[x] = tot;
ST.Update(ID[x], w[x], 1, n, 1);
if (son[x] > 0) HLD(son[x], Tp);
for (int i = 0; i < mp[x].size(); i++) {
int y = mp[x][i];
if (y == pre[x]) continue;
if (y == son[x]) continue;
HLD(y, y);
}
}
ll Query(int x, int y) {
int X = Top[x], Y = Top[y];
ll ans = 0;
while (X != Y) {
if (depth[X] < depth[Y]) swap(X, Y), swap(x, y);
ans = (ans + ST.Query(ID[x], ID[y], 1, n, 1)) % MOD;
x = pre[X], X = Top[x];
}
if (depth[x] > depth[y]) swap(x, y);
ans = (ans + ST.Query(ID[x], ID[y], 1, n, 1)) % MOD;
//printf("Query(%d, %d) = %lld\n", x, y, ans);
return ans;
}
void HLD_INIT(int root) {
ms(son), tot = 0, depth[root] = 0;
init_HLD(root, 0);
HLD(root, root);
}
ll dfs(int x, int dad, int d) {
ll ans = 0;
if (d >= lmtL && d <= lmtR) ans++;
for (int i = 0; i < mp[x].size(); i++) {
int y = mp[x][i];
if (y == dad) continue;
ans = (ans + dfs(y, x, d + 1)) % MOD;
}
w[x] = (ans + w[x]) % MOD;
return ans;
}
int main() {
int T, m, x, u, v;
ll ans, d;
scanf("%d", &T);
while (T--) {
ms(w), ms(a), ans = 0;
scanf("%d%d%d%d", &n, &m, &lmtL, &lmtR);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for (int i = 2; i <= n; i++) {
scanf("%d", &x);
mp[x].push_back(i);
mp[i].push_back(x);
}
for (int i = 1; i <= n; i++) {
dfs(i, 0, 1);
ans = (ans + w[i] * a[i] % MOD) % MOD;
}
for (int j = 1; j <= n; j++) w[j] /= 2;
ST.Build(1, n, 1);
HLD_INIT(1);
//printf("ans = %lld\n", ans);
while (m--) {
scanf("%d%d%lld", &u, &v, &d);
ans = (ans + Query(u, v) * d % MOD) % MOD;
printf("%lld\n", ans);
}
}
return 0;
}