EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2)

传送门

赛时没打,赛后补的。

D题过的太慢,估计赛时过不了。

A#

每行里隔 k 个放一个,最少 min(k,m) 种。列同理,因此答案为 min(k,n)min(k,m)

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 7;
void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    cout << min(n, k) * min(m, k) << endl;
}
int main() {
    int T;
    cin >> T;
    while(T --) solve();
}

B#

如果 ab 完全相同或者 a 倒过来之后和 b 完全相同则爱丽丝获胜。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e6 + 7;
int a[N], b[N];
void solve() {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) {
        if(a[i] != n) cout << a[i] + 1 << " ";
        else cout << 1 << " ";
    }
    cout << endl;
}
signed main() {
    int T;
    cin >> T;

    while(T --) solve();
}

C#

只需要判断 s 是否能在每个圆到达 t 之前到达即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e6 + 7;
int x[N], y[N];
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
void solve() {
    int n;
    n = read();
    for(int i = 1; i <= n; i ++) x[i] = read(), y[i] = read();
    int xs, ys, xt, yt;
    xs = read(), ys = read(), xt = read(), yt = read();
    int diss = (xs - xt) * (xs - xt) + (yt - ys) * (yt - ys);
    for(int i = 1; i <= n; i ++) {
        int now = (x[i] - xt) * (x[i] - xt) + (y[i] - yt) * (y[i] - yt);
        if(now <= diss) {
            puts("NO");
            return;
        }
    }
    puts("YES");
}
signed main() {
    int T;
    T = read();
    while(T --) solve();
}

D1#

对于排列中相邻的两个数 (i,j)vi 表示对于 pi,pi+1 是否合法,若 ij 的父亲,或 ij 父亲的子树里,vi=1。当 vi=n1 的时候这个排列合法。若 xy 的父亲,当且仅当 x=y/2,若是后者可以从 x 往上跳。时间复杂度 O(n+qlog2n)

#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 7;
int vis[N];
int p[N], a[N];
int chk(int x, int y) {
    int f = y / 2;
    
    if(f == 1) return 1;
    while(x != 1) {
        x /= 2;
        if(x == f) return 1;
    }
    return 0;
}
void solve() {
    int n, q;
    cin >> n >> q;
    for(int i = 2; i <= n; i ++) cin >> a[i];
    // for(int i = 2; i <= n; i ++) {
    //     v[i].push_back(a[i]);
    //     v[a[i]].push_back(a[j]);
    // }
    for(int i = 1; i <= n; i ++) cin >> p[i];
    for(int i = 1; i <= n + 1; i ++) vis[i] = 0;
    int nw = 0;
    for(int i = 1; i < n; i ++) {
        if((p[i + 1] / 2) == p[i] || chk(p[i], p[i + 1])) vis[i] = 1, nw ++;
    }
    for(int i = 1; i <= q; i ++) {
        int x, y;
        cin >> x >> y;
        if(x > y) swap(x, y);
        if(vis[y] && y != n) vis[y] = 0, nw --;
        if(vis[y - 1] && y - 1 != 0) vis[y - 1] = 0, nw --;
        if(vis[x] && x != n && x + 1 != y) vis[x] = 0, nw --;
        if(x != 1 && vis[x - 1]) vis[x - 1] = 0, nw --;
        swap(p[y], p[x]);
        if(y != n && (p[y + 1] / 2 == p[y] || chk(p[y], p[y + 1]))) vis[y] = 1, nw ++;
        if(y != 1 && (p[y] / 2 == p[y - 1] || chk(p[y - 1], p[y]) == 1)) vis[y - 1] = 1, nw ++;
        if(x != n && x + 1 != y && (p[x + 1] / 2 == p[x] || chk(p[x], p[x + 1]) == 1)) vis[x] = 1, nw ++;
        if(x != 1 && (p[x] / 2 == p[x - 1] || chk(p[x - 1], p[x]) == 1)) vis[x - 1] = 1, nw ++;
        if(nw == n - 1) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
}
int main() {
    int T;
    cin >> T;
    while(T --) solve();
}

D2#

上面算法的时间复杂度是对的,存一下边然后查询的时候倍增跳就可以。

写的有点丑。。

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 7;
vector<int> v[N];
int vis[N];
int p[N], a[N];
int chk1(int x, int y) {
    if(a[y] == x) return 1;
    return 0;
}
int Log[N];
int fa[N][32];
int dep[N];

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
inline void dfs(int now,int father)
{
    fa[now][0]=father;
    dep[now]=dep[father]+1;
    for(int i=1;i<=Log[dep[now]];++i)
    {
        fa[now][i]=fa[fa[now][i-1]][i-1];
    }
    for(int i = 0; i < v[now].size(); i ++)
    {
        int o = v[now][i];
        if(o!=father)
        {
            dfs(o,now);
        }
    }
}
 inline int lca(int x,int y)
 {
    if(dep[x]<dep[y]) swap(x,y);
    while(dep[x]>dep[y])
    {
        x=fa[x][Log[dep[x]-dep[y]]-1];
    }
    if(x==y) return x;
    for(int k=Log[dep[x]];k>=0;k--)
    {
        if(fa[x][k]!=fa[y][k])
        {
            x=fa[x][k];
            y=fa[y][k];
        }
    }
    return fa[x][0];
 }
int chk2(int x, int y) {
    int fy = a[y];
    if(y == 1) return 0;
    if(fy == 1) return 1;
    if(lca(x, fy) == fy) return 1;
    return 0;
}
void solve() {
    int n, q;
    n = read(), q = read();
    for(int i = 1; i <= n; i ++) v[i].clear();
    for(int i = 1; i <= n; i ++) Log[i] = Log[i - 1] + (1 << Log[i - 1] == i);
    for(int i = 2; i <= n; i ++) a[i] = read();
    for(int i = 1; i <= n; i ++) p[i] = read();

    for(int i = 2; i <= n; i ++) {
        v[i].push_back(a[i]);
        v[a[i]].push_back(i);
    }
    for(int i = 0; i <= n + 1; i ++) vis[i] = 0, dep[i] = 0;
    for(int i = 1; i <= n; i ++) {
        for(int j = 0; j <= 31; j ++) fa[i][j] = 0;
    }
    dfs(1, 0);
    
    
    int nw = 0;
    for(int i = 1; i < n; i ++) {
        if(chk1(p[i], p[i + 1]) || chk2(p[i], p[i + 1])) vis[i] = 1, nw ++;
    }
    for(int i = 1; i <= q; i ++) {
        int x, y;
        x = read(), y = read();
        if(x > y) swap(x, y);
        if(vis[y] && y != n) vis[y] = 0, nw --;
        if(vis[y - 1] && y - 1 != 0) vis[y - 1] = 0, nw --;
        if(vis[x] && x != n && x + 1 != y) vis[x] = 0, nw --;
        if(x != 1 && vis[x - 1]) vis[x - 1] = 0, nw --;
        swap(p[y], p[x]);
        if(y != n && (chk1(p[y], p[y + 1]) || chk2(p[y], p[y + 1]))) vis[y] = 1, nw ++;
        if(y != 1 && (chk1(p[y - 1], p[y]) || chk2(p[y - 1], p[y]) == 1)) vis[y - 1] = 1, nw ++;
        if(x != n && x + 1 != y && (chk1(p[x], p[x + 1]) || chk2(p[x], p[x + 1]) == 1)) vis[x] = 1, nw ++;
        if(x != 1 && (chk1(p[x - 1], p[x]) || chk2(p[x - 1], p[x]) == 1)) vis[x - 1] = 1, nw ++;
        if(nw == n - 1) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
}
int main() {
    int T;
    cin >> T;
    while(T --) solve();
}

E#

作者:wyyqwq

出处:https://www.cnblogs.com/wyyqwq/p/18358016

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   你说得太对辣  阅读(144)  评论(0编辑  收藏  举报
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示