首页 > 其他分享 >AtCoder Beginner Contest 287

AtCoder Beginner Contest 287

时间:2023-02-01 23:44:56浏览次数:50  
标签:AtCoder return qt Beginner read bo int 287 define

F Components

考虑树形 \(DP\) 。

有 \(f_{i, j, 0/1}\) 为以 \(i\) 为根的子树,一共有 \(j\) 个连通块,选/不选的方案数。

\[pre_{x, 0/1} \leftarrow f_{u, x, 0/1} \]

\[f_{u, i, 0} = f_{u, i, 0} + pref_{i-j,0} \times (f_{v, j, 0} + f_{v, j, 1}) \]

\[f_{u, i, 1} = f_{u, i, 1} + pref_{i-j,1} \times(f_{v, j, 0} + f_{v, j+1, 1}) \]

#include <bits/stdc++.h>
#define _for(i, a, b) for(I i = (a); i <= (b); i ++)
#define _rep(i, a, b) for(I i = (a); i < (b); i ++)
#define _rof(i, a, b) for(I i = (a); i >= (b); i --)
#define _pre(i, a, b) for(I i = (a); i > (b); i --)
#define inl inline
#define I int
#define ll long long
inl I read(){
    static I bo, x; bo = x = 0;
    static char c; c = getchar();
    while(c < '0' || c > '9') {if(c == '-')bo = 1; c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<3) + (x<<1) + c - '0'; c = getchar();}
    return bo ? -x : x;
}
inl void out(ll x, bool bo = true){
    if(x < 0) putchar('-'), x = -x;
    if(x == 0){if(bo)putchar('0'); return;}
    out(x/10, false), putchar('0' + x%10);
}
using namespace std;

const int N = 5e3+1;
const ll mod = 998244353;
int n;
int h[N], nt[N<<1], to[N<<1], cnt;
void link(int u, int v){
    nt[++cnt] = h[u], h[u] = cnt, to[cnt] = v;
    nt[++cnt] = h[v], h[v] = cnt, to[cnt] = u;
}
ll f[N][N][2], sz[N];
ll pref[N][2];
void dp(int u, int fa){
    sz[u] = 1ll, f[u][1][1] = f[u][0][0] = 1ll;
    for(int i = h[u], v; i; i = nt[i]){
        if((v = to[i]) == fa) continue;
        dp(v, u);
        _for(i, 0, sz[u] + sz[v]){pref[i][0] = f[u][i][0], pref[i][1] = f[u][i][1], f[u][i][0] = f[u][i][1] = 0;}
        _rof(i, sz[u]+sz[v], 0){
            _for(j, max(0ll, i - sz[u]), min((ll) i, sz[v])){
                (f[u][i][0] += pref[i-j][0] * (f[v][j][0] + f[v][j][1]) % mod) %= mod;
                (f[u][i][1] += pref[i-j][1] * (f[v][j][0] + f[v][j+1][1]) % mod) %= mod;
            }
        }
        sz[u] += sz[v];
    }
}

int main(){
    n = read();
    _rep(i, 1, n) {
        static int u, v;
        u = read(), v = read();
        link(u, v);
    }
    dp(1, 0);
    _for(i, 1, n)
        out((f[1][i][0] + f[1][i][1]) % mod), puts("");
    return 0;
}

G Balance Update Query

整体区间前 \(x\) 大和。

值域很大,而 \(n\) 很小,考虑离线 \(a_i\) 和询问 \(1\) 的 \(y\),离散化,值域线段树上修改/查询。

#include <bits/stdc++.h>
#define _for(i, a, b) for(I i = (a); i <= (b); i ++)
#define _rep(i, a, b) for(I i = (a); i < (b); i ++)
#define _rof(i, a, b) for(I i = (a); i >= (b); i --)
#define _pre(i, a, b) for(I i = (a); i > (b); i --)
#define inl inline
#define I int
#define L long long
#define LL 1ll
inl I read(){
    static I bo, x; bo = x = 0;
    static char c; c = getchar();
    while(c < '0' || c > '9') {if(c == '-')bo = 1; c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<3) + (x<<1) + c - '0'; c = getchar();}
    return bo ? -x : x;
}
inl void out(L x, bool bo = true){
    if(x < 0) putchar('-'), x = -x;
    if(x == 0){if(bo)putchar('0'); return;}
    out(x/10, false), putchar('0' + x%10);
}
using namespace std;
const int N = 4e5;
const int LEN = 4e5+11;
struct opt{int op, x, y;};
vector<opt> op;
int n, a[N], b[N], total, ls[N*3], q;

namespace sgt{
    #define lc ((k)<<(1))
    #define rc ((k)<<(1)|(1))
    #define mid ((l) + (r) >> (1))
    L sum[LEN<<2], cnt[LEN<<2];
    void pushup(int k){
        cnt[k] = cnt[lc] + cnt[rc];
        sum[k] = sum[lc] + sum[rc];
    }
    void modify(int x, int y, int k = 1, int l = 1, int r = total){
        if(x > r || x < l) return;
        if(l == r){
            cnt[k] += y, sum[k] += LL * ls[x] * y;
            return;
        }
        modify(x, y, lc, l, mid), modify(x, y, rc, mid+1, r);
        pushup(k);
    }
    L query(int x, int k = 1, int l = 1, int r = total){
        if(cnt[k] < x) return -1;
        if(l == r) return LL * ls[l] * x;
        if(x > cnt[rc]) return sum[rc] + query(x-cnt[rc], lc, l, mid);
        else return query(x, rc, mid+1, r);
    }
}

int main(){
    n = read();
    _for(i, 1, n) a[i] = read(), b[i] = read(), ls[++total] = a[i];
    q = read();
    _for(i, 1, q){
        int opts = read(), x = read(), y = 0;
        if(opts <= 2){
            y = read();
            if(opts == 1) ls[++total] = y;
        }
        op.push_back((opt){opts, x, y});
    }
    sort(ls+1, ls+total+1);
    total = unique(ls+1, ls+total+1)-ls-1;
    _for(i, 1, n) a[i] = lower_bound(ls+1, ls+total+1, a[i])-ls;
    _for(i, 0, q-1) if(op[i].op == 1)
        op[i].y = lower_bound(ls+1, ls+total+1, op[i].y)-ls;
    _for(i, 1, n) sgt::modify(a[i], b[i]);
    _for(i, 0, q-1){
        if(op[i].op == 3) out(sgt::query(op[i].x)), puts("");
        else{
            sgt::modify(a[op[i].x], -b[op[i].x]);
            if(op[i].op == 1) a[op[i].x] = op[i].y;
            else b[op[i].x] = op[i].y;
            sgt::modify(a[op[i].x], b[op[i].x]);
        }
    }
    return 0;
}

H Directed Graph and Query

考虑 \(Floyd\) 的性质,第一个枚举的 \(k\) 的意义是只经过 \(1\) 至 \(k\) 的节点的最短距离。

考虑离线枚举答案看是否有解( \(u\) 可以到达 \(v\) )。

\(bitset\) 优化 \(Floyd\) 传递闭包,时间复杂度 \(O(\dfrac{n^3}{w} + nq)\)。

#include <bits/stdc++.h>
#define _for(i, a, b) for(I i = (a); i <= (b); i ++)
#define _rep(i, a, b) for(I i = (a); i < (b); i ++)
#define _rof(i, a, b) for(I i = (a); i >= (b); i --)
#define _pre(i, a, b) for(I i = (a); i > (b); i --)
#define inl inline
#define I int
inl I read(){
    static I bo, x; bo = x = 0;
    static char c; c = getchar();
    while(c < '0' || c > '9') {if(c == '-')bo = 1; c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<3) + (x<<1) + c - '0'; c = getchar();}
    return bo ? -x : x;
}
inl void out(I x, bool bo = true){
    if(x < 0) putchar('-'), x = -x;
    if(x == 0){if(bo)putchar('0'); return;}
    out(x/10, false), putchar('0' + x%10);
}
using namespace std;
const int N = 2001;
bitset<2001> e[N];
int n, m, q, qa[N*10], qb[N*10], ans[N*10];
int main(){
    n = read(), m = read();
    _for(i, 1, m){
        static int u, v;
        u = read(), v = read();
        e[u][v] = 1;
    }
    q = read();
    _for(i, 1, q) qa[i] = read(), qb[i] = read(), ans[i] = -1;
    _for(i, 1, n){
        _for(u, 1, n) if(e[u][i]) e[u] |= e[i];
        _for(qt, 1, q) if(ans[qt] == -1 && e[qa[qt]][qb[qt]] == 1) ans[qt] = max(i, max(qa[qt], qb[qt]));
    }
    _for(i, 1, q) out(ans[i]), puts("");
    return 0;
}

标签:AtCoder,return,qt,Beginner,read,bo,int,287,define
From: https://www.cnblogs.com/dadidididi/p/17084491.html

相关文章

  • AtCoder Beginner Contest 285
    C:abc285_brutmhyhiizp题目大意一串序列A,B,...,Z,AA,AB,...,ZZ,AAA,...给定一个字符串求在序列中的排名(保证存在)思路将每个A看作\(1\),B看作\(2\),....,Z......
  • (AtCoder Beginner Contest 287)(D 字符串前后缀合并匹配)(E Trie求最长公共前缀(LCP)
    D-MatchorNot(字符串前后缀合并匹配)题目大意:给定两个字符串S和T,对于每个x=0,1,2...|T|求S的子串(前x个字符和后|T|-x个字符在不改变顺序的情况下组成)是否与T相......
  • 【字典树】Atcoder Beginner Contest 287----E
    题目:E-Karuta(atcoder.jp)题解:这道题就是一个字典树求最长公共前缀的板子题。可以直接交板子。但我在翻题解的时候发现了另一种思路,就是将字符串按字典序排列后,每一个......
  • ABC287Ex Directed Graph and Query
    传送门思路用bitset优化Floyd,我们可以通过\(O(\frac{n^3}{\omega})\)的时间判断\(i,~j\)两点间是否联通。因此,我们可以从小到大加入“中转点”,每加入一个,就将所......
  • 【题解】ABC287
    \(\text{AtCoderBeginnerContest287}\)AMajority无意义题,问同意的是不是占半数以上。BPostalCard无意义题,对一个字符串集合开桶,对应匹配另一个字符串集合。CPa......
  • AtCoder Beginner Contest 287 解题报告
    AtCoderBeginnerContest287解题报告\(\text{ByDaiRuiChen007}\)ContestLinkA.Majority用map分别统计两种字符串出现的次数并与\(\left\lfloor\dfracn2\righ......
  • ABC 287 (E-Ex) 题解
    E我的做法对于每个串枚举他的答案,然后直接hash硬干就完了。卡一卡就过去了#include<bits/stdc++.h>usingnamespacestd;typedefunsignedlonglongull;const......
  • AtCoder Beginner Contest 287
    A-Majority(abc287a)题目大意给定\(n\)个人对某个提案的意见,问大多数意见是支持还是反对解题思路统计比较即可。神奇的代码#include<bits/stdc++.h>usingnam......
  • AtCoder Beginner Contest 287
    纯纯手速场C首先这张图必须是一棵树,必有\(M=N-1\)。接下来只需求出树的直径,判断其长度(边数)是否为\(N-1\)即可。https://atcoder.jp/contests/abc287/submissions/3......
  • Atcoder Beginner Contest 287
    赛时吃了三个法师,不过问题不大。赛时AB简单字符串处理。C中需要满足:\(m=n-1\)只有两个度数为\(1\)的点,剩下点的度数都为\(2\)。记得判连通!!D根据题目要求观......