Codeforces Round #614

  • NEKO's Maze Game

    • 题意
    • 题解
    • 代码
  • Aroma's Search
    • 题意
    • 题解
    • 代码
  • Xenon's Attack on the Gangs
    • 题意
    • 题解
    • 代码

NEKO's Maze Game

题目链接 https://codeforces.com/contest/1292/problem/A

题意

给出一个 2xN 的地图,每一时刻都有一个位置翻转状态(可走和不可走变换),输出每时刻是否可以从起点走到终点。

题解

地图只有 2xN,两个跨行相邻的位置不可走从起点就走不到终点。
[o][2][3][4][o]
[o][o][1][o][o]
如果 1 位置,2,3,4位置一个位置不可走都会产生一堵“墙”。统计产生的全部墙数,没墙时可以走到终点,否则不能走到。

代码

#include <cstdio>
using namespace std;
int N, Q;
int cnt;
bool die[2][100010];
void cg(int r, int c)
{
    int flag;
    if (die[r][c] == false)
    {
        flag = 1;
        die[r][c] = true;
    }
    else
    {
        flag = -1;
        die[r][c] = false;
    }
    for (int i = -1; i <= 1; i++)
    {
        if (die[r^1][c+i])
            cnt += flag;
    }
}
int main()
{
    scanf("%d %d", &N, &Q);
    int r, c;
    for (int i = 1; i <= Q; i++)
    {
        scanf("%d %d", &r, &c);
        r--;
        cg(r, c);
        if (cnt)
        {
            printf("No\n");
        }
        else
        {
            printf("Yes\n");
        }
    }
    return 0;
}

Aroma's Search

题目链接 https://codeforces.com/contest/1292/problem/B

题意

二维平面上按照规则产生一些得分点,问时间 t 内,从起点出发最多可以得到多少分。
??????????1+????,??????????1+????
得分点生成规则,给出 \((x_0,y_0)\),其他点 \((a_x x_{i-1} +b_x, a_y y_{i-1} +b_y)\)。

题解

按照生成规则,显然最多生成 64 个得分点,用平方算法枚举经过的得分段两端即可。
注意坐标较大,生成得分点的时候注意坐标太大的点不用生成,防止数据溢出。

代码

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAX 10000000000000000LL
typedef long long ll;
ll dis(ll x1, ll y1, ll x2, ll y2)
{
    return llabs(x1-x2) + llabs(y1-y2);
}
ll Ax, Ay, Bx, By;
ll Xs, Ys, T;
ll pts[100][2];
int ptt;
ll sm[100];
int main()
{
    scanf("%lld %lld %lld %lld %lld %lld",
            &pts[0][0], &pts[0][1], &Ax, &Ay, &Bx, &By);
    scanf("%lld %lld %lld", &Xs, &Ys, &T);
    for (ptt = 1; ptt < 100; ptt++)
    {
        pts[ptt][0] = Ax*pts[ptt-1][0] + Bx;
        pts[ptt][1] = Ay*pts[ptt-1][1] + By;
        if (dis(pts[ptt][0], pts[ptt][1], Xs, Ys) > MAX*2)
            break;
    }
    for (int i = 1; i < ptt; i++)
    {
        sm[i] = dis(pts[i][0], pts[i][1], pts[i-1][0], pts[i-1][1]);
        sm[i] += sm[i-1];
    }
    int ans = 0;
    ll K;
    for (int i = 0; i < ptt; i++) {
        for (int j = i; j < ptt; j++) {
            K = min(dis(pts[i][0], pts[i][1], Xs, Ys),
                    dis(pts[j][0], pts[j][1], Xs, Ys))
                    + (sm[j] - sm[i]);
            if (K <= T) {
                ans = max(ans, j-i+1);
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

Xenon's Attack on the Gangs

题目链接 https://codeforces.com/contest/1292/problem/C

题意

给出 N 个结点的树,定义
\[ S = \sum_{1 \leq u < v \leq n}mex(u, v) \]
\(mex(u, v)\) 定义为,u 到 v 的路径权值中不包含的最小自然数。
将权值 0 ~ n-2 分配到每条边上,每条边上权值不同,求 S 的最大值。

题解

从另一个方向维护答案:
\[ \begin{align}
S =& \sum_{1 \leq u < v \leq n}mex(u, v) \label{C1} \\
=& \sum_{1 \leq x \leq n} \sum_{mex(u,v)=x}x \label{C2} \\
=& \sum_{1 \leq x \leq n} \sum_{mex(u,v) \geq x} 1 \label{C3}
\end{align} \]

假设树中全部mex值为1,2,3,5,5
则 \(\ref{C1}\) 式是将每条路径上的mex值求和:

- 1
-- 2
--- 3
----- 5
----- 5
S = 1+2+3+5+5

\(\ref{C3}\) 式是从另一个方向求和:

| 1
|| 2
||| 3
||||| 5
||||| 5
54322
S = 5+4+3+2+2

显然两式等价。

由 mex 的特点可知,0~k-1 一定在长度为 K 的一条链上,且mex>=K的数量取决于链两端点的位置,与0~k-1的顺序无关。
可以使用 \(dp[u][v]\) 表示从\(u\)到\(v\)的一条路径上放置0~k-1时的S的最大值。
\[dp[u][v] = sub(u,v)sub(v,u) + max(dp[par(v,u)][v], dp[u][par(u,v)])\]
其中 \(sub(u,v)\) 是以u为根的v的子树大小,\(par(u,v)\) 是以\(u\)为根\(v\)的父结点

代码

#include <cstdio>
#include <vector>
using namespace std;
#define Nmax 3010
int N;
vector<int> gp[Nmax];
void init()
{
    scanf("%d", &N);
    int a, b;
    for (int i = 1; i < N; i++)
    {
        scanf("%d %d", &a, &b);
        gp[a].push_back(b);
        gp[b].push_back(a);
    }
}
int par[Nmax][Nmax];
int sub[Nmax][Nmax];
int root;
void DFS(int x, int fa)
{
    int t;
    sub[root][x] = 1;
    par[root][x] = fa;
    for (int i = 0; i < gp[x].size(); i++)
    {
        t = gp[x][i];
        if (t == fa)
            continue;
        DFS(t, x);
        sub[root][x] += sub[root][t];
    }
}
long long dp[Nmax][Nmax];
long long DP(int x, int y)
{
    if (x == y)
        return 0;
    if (dp[x][y])
        return dp[x][y];
    if (dp[y][x])
        return dp[x][y] = dp[y][x];
    dp[x][y] = sub[x][y]*sub[y][x] + max(DP(par[y][x], y), DP(x, par[x][y]));
    return dp[x][y];
}
void work()
{
    for (int i = 1; i <= N; i++)
    {
        root = i;
        DFS(i, 0);
    }

    long long ans = 0;
    for (int i = 1; i <= N; i++)
    {
        for (int j = i+1; j <= N; j++)
        {
            ans = max(ans, DP(i, j));
        }
    }
    printf("%lld\n", ans);
}
int main()
{
    init();
    work();
    return 0;
}

原文地址:https://www.cnblogs.com/KZNS/p/codeforces-round-614.html

时间: 2024-08-30 12:09:10

Codeforces Round #614的相关文章

Codeforces Round #614 (Div. 2) D. Aroma&#39;s Search

题目链接:http://codeforces.com/contest/1293/problem/D 题意: 给定x0,y0,ax,ay,bx,by 即一堆经验点:(x0,y0),(x1,y1)等价于(ax*x0+bx,ay*y0+by),(x2,y2)等价于(ax*x1+bx,ay*y1+by),(x3,y3)等价于(ax*x2+bx,ay*y2+by)...... 再给定xs,ys,t 即起点(xs,ys),时间t 上下左右每走一步都需要1单位时间,问在t时间内,从起点出发最多可以吃到多少个经

Codeforces Round #614 (Div. 2) C. NEKO&#39;s Maze Game

题目链接:http://codeforces.com/contest/1293/problem/C 题意:给定n,q,即给定一个2*n的格子,有q个查询. 每个查询给定一个ri和ci,ri为1或2,ci在1到n之间,即给定一个(ri,ci),该点自该查询起状态进行转变(可经过/不可经过). 如某个查询给定1,2,即点(1,2)无法经过,若之后查询再次给定1,2,则该点(1,2)可以经过. 问能否从(1,1)走到(2,n),保证给定的查询不会经过起点和终点. 思路: 由于n和q最大都是1e5,所以

Codeforces Round #614 (Div. 2) E. Xenon&#39;s Attack on the Gangs

On another floor of the A.R.C. Markland-N, the young man Simon "Xenon" Jackson, takes a break after finishing his project early (as always). Having a lot of free time, he decides to put on his legendary hacker "X" instinct and fight ag

Codeforces Round #614 (Div. 2)

A. ConneR and the A.R.C. Markland-N 题目链接:https://codeforces.com/contest/1293/problem/A 题意: 有一个长为 n 的楼层,其中有 k 个楼层没有餐厅 ,你现在在 s 层,问你最少走多少个楼层可以到达餐厅吃饭 分析: 因为 k 只有 1000,所以直接往 s 层上下方找(当找到 0 或者 n + 1 时说明这个方向没有答案) #include<bits/stdc++.h> using namespace std;

Codeforces Round #614 (Div. 2) B - JOE is on TV!

原题题面:https://codeforces.com/contest/1293/problem/B 解题思路: Σi=1~n 1/i ??? 1 /* 2 Written By. StelaYuri 3 On 2020/01/19 4 */ 5 #include<bits/stdc++.h> 6 using namespace std; 7 typedef long long ll; 8 int a[1005],b[1005]; 9 void solve(){ 10 int n,i; 11

Codeforces Round #614 (Div. 2) A - ConneR and the A.R.C. Markland-N

原题题面:https://codeforces.com/contest/1293/problem/A 题目大意: ConneR老师想吃东西,他现在在大楼的第s层,大楼总共有n层,但是其中有k层的餐厅关门了. 然后给了这k层关门的餐厅分别所在的楼层. 所以问ConneR老师最少得往上(或者往下)走几层楼,才能到最近的还开门的餐厅就餐? 解题思路1: 对于关闭的k层,存在数组a里排序.(放在1~k的位置) 先循环一遍数组a,看看s层是否存在于a数组里,如果不存在,直接输出0作为答案. 如果存在,开始

Codeforces Round #614 (Div. 2) A( A - ConneR and the A.R.C. Markland-N)

A - ConneR and the A.R.C. Markland-N 题目链接:http://codeforces.com/contest/1293/problem/A 题意:一栋楼房有n(1~n)层,有个人身处s楼,现在想要到餐厅吃饭,可是现在有k个餐厅关闭的,问你该人至少爬几层楼梯才能到开放的餐厅吃饭 思路:...这题暴力没戏..又是超时又是超内存...分两种,一个是往上找出最小的i-s即可,一个是往下找,找出最小的s-i即可,,用了数组还是超时..用了map就过了 // // Crea

Codeforces Round #614 选讲

http://codeforces.com/contest/1292/problem/C 注意到编号x的边对答案要有贡献,必须和0到x-1的边一起形成一条链,否则x及编号比x大的边都没有贡献.由此,对答案有贡献的边形成了一条链,且这条链的编号是个谷形,即中间编号小,往两边编号变大,编号最大的边在最外侧.由此可以进行dp,dp[u][v]表示如果上述链为点u到点v这条链的答案.令sz[u][v]为以u为根,子树v的大小:fa[u][v]为以u为根,点v的父亲,则有dp[u][v]=dp[v][u]

Codeforces Round #614 (Div. 2) 比赛总结

比赛情况 怒切 \(A,B,C,D\),后面 \(E,F\) 两题技术太菜不会做,不知道什么时候可以补起来. 比赛总结 事实证明: 比赛前喝一瓶抗疲劳饮料对比赛状态的进入有显著效果. 比赛有人陪着打对AC题目有显著效果. 说正经的: 不要紧张,也不要太过放松.这样才有利于发挥出真实水平. 下面就开始 喜闻乐见 的题解吧. A 入门题 枚举找到最近的可用楼层即可.用 \(STL\) 里面的 map 判断一个楼层是否可用使用. Code #include<bits/stdc++.h> #defin