Educational Codeforces Round 105 [Rated for Div. 2]-小结

前言:

这场被B卡了一个小时。。蠢了

B.

题目大意 :

给你一个 n ∗ n n*n nn的矩阵,然后你需要在四个边界上分别放 u , r , d , l u,r,d,l u,r,d,l个方块。问是否存在方案?

2 ≤ n ≤ 500 , 0 ≤ u , r , d , l ≤ n 2\leq n \leq 500, 0 \leq u,r,d,l \leq n 2n500,0u,r,d,ln

题目思路:

主要是存在四个角影响的问题,比如 u = n , r = 0 u=n,r=0 u=n,r=0这样的情况发生。所以我们枚举四个角放或不放,然后再检查剩下的 n − 2 n-2 n2个地方是否能够放得下即可.就这想了一万年。。。重开算了。

C.水题,略

D.

题目大意:

给你所有叶子节点两个点之间的 L C A LCA LCA的深度。让你构造出原树。原树保证每个非叶子节点至少两个子树。
n ≤ 500 n \leq 500 n500

题目思路:

题目允许我们使用 n 3 n^3 n3的算法。

我们利用分治的思想:对于所有点对,我们找到深度最小的 L C A = m i LCA=mi LCA=mi.这就是这棵树的根.

容易发现:当 d e p i , j ≠ m i dep_{i,j} \neq mi depi,j=mi时,两个点 i , j i,j i,j在同一颗子树下(相对于根)。这个地方将同一颗子树关系看成集合关系,使用并查集, n 2 n^2 n2合并集合即可得到所有子树以及子树里的点集情况。

然后对于得到的 k k k个集合。我们 v e c t o r vector vector暴力传递点递归解决即可。代码也很简单,不放了。

E.无敌水题

题目大意:

给你 n n n个点,开始没有边。现在进行 m m m次操作.

1. 1. 1.连一条 u → v u\rightarrow v uv的有向边,边权为 c c c,是一个小写字母.保证原先没边.
2. 2. 2.删除一条 u → v u\rightarrow v uv的有向边,保证原先有边.
3. 3. 3.询问图中是否存在任意两个点 u , v u,v u,v之间两条长度恰好为 k k k的来回路径(不一定是简单路径),将他们边权写下来,两条路径全等.

n , m ≤ 2 e 5 n,m \leq 2e5 n,m2e5

题目思路:

k k k是奇数,那么只要寻找两个点互通即可。因为 u − > v − > . . − > u u->v->..->u u>v>..>u是一个回文路径,他们的边权一定全等.
k k k是偶数时,我们发现它的边权的长度为奇数,则一定有中间那条边来回边权相同。所以寻找两个点互通且边权相等即可.

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
int a[maxn];
map<pii , char> e;
int main()
{
    
    
    ios::sync_with_stdio(false);
    int n , m; cin >> n >> m;
    int x , y; x = y = 0;
    for (int i = 1 ; i <= m ; i++){
    
    
        char c; cin >> c;
        int u , v;
        char w;
        if (c == '+'){
    
    
            cin >> u >> v >> w;
            e[mp(u,v)] = w;
            pii g = mp(v,u);
            x += (e.find(g) != e.end());
            y += (e.find(g) != e.end() && e[g] == w);
        }
        else if (c == '-'){
    
    
            cin >> u >> v;
            w = e[mp(u,v)];
            e.erase(mp(u,v));
            pii g = mp(v,u);
            x -= (e.find(g) != e.end());
            y -= (e.find(g) != e.end() && e[g] == w);

        }else {
    
    
            int k; cin >> k;
            if (k & 1) cout << (x ? "YES" : "NO") << endl;
            else cout << (y ? "YES" : "NO") << endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35577488/article/details/114322208