cm

Aqr_Rn發表於2024-10-20

updated on 10.20 12:11 目前的問題是減去重複的部分寫錯了,改完差不多就 A 了

code
#include<bits/stdc++.h>
#define int long long
#define me(a) memset(a, 0, sizeof a)
#define lson ls[rt]
#define rson rs[rt]
#define Aqrfre(x, y) freopen(#x ".in", "r", stdin),freopen(#y ".out", "w", stdout)
#define mp make_pair
#define Type int
#define qr(x) x=read()
typedef __int128 INT;
typedef long long ll;
using namespace std;

inline Type read(){
    char c=getchar(); Type x=0, f=1;
    while(!isdigit(c)) (c=='-'?f=-1:f=1), c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48), c=getchar();
    return x*f;
}

const int N = 505; 
const int mod = 998244353;

int n, m, res, tot, dis[N][N];
vector<int>to[N], belong[N<<1];

int top, th, s[N], bcc, low[N], dfn[N];
vector<int>BCC[N]; int sz[N];
inline void tarjan(int x, int p){
    s[++top] = x;
    low[x] = dfn[x] = ++th;
    for(int y : to[x]){
        if(!dfn[y]){
            tarjan(y, x);
            low[x] = min(low[x], low[y]);
            if(low[y] == dfn[x]){
                ++bcc;
                do{ BCC[bcc].emplace_back(s[top]); sz[bcc]++;
                    belong[s[top]].emplace_back(bcc);
                }while(s[top--] != y);

                BCC[bcc].emplace_back(x); sz[bcc]++;
                belong[x].emplace_back(bcc);
            }
        }
        else low[x] = min(low[x], dfn[y]);
    }
}

vector<int>tw[N<<2][N];
int v[N<<5], rtot, ls[N<<5], rs[N<<5], root[(N*N)<<1];
inline void pushup(int rt){
    v[rt] = (ll)(v[lson] + v[rson]) % mod;
} 

inline void update(int &rt, int l, int r, int pos, int val){
    if(!rt) rt = ++rtot;
    if(l == r){
        (v[rt] += val) %= mod;
        return;
    }

    int mid = (l + r) >> 1;
    if(pos <= mid) update(lson, l, mid, pos, val);
    else update(rson, mid+1, r, pos, val);

    pushup(rt);
}

inline int merge(int x, int y, int l, int r){
    if(!x or !y) return x + y;
    if(l == r){
        (v[x] += v[y]) %= mod;
        return x;
    }
    int mid = (l + r) >> 1;
    ls[x] = merge(ls[x], ls[y], l, mid);
    rs[x] = merge(rs[x], rs[y], mid+1, r);

    pushup(x); return x;
}

inline void mcpy(int &x, int y, int l, int r){
    if(!y) return;
    if(!x) x = ++rtot;
    v[x] = v[y];
    if(l == r) return;
    int mid = (l + r) >> 1;
    mcpy(ls[x], ls[y], l, mid);
    mcpy(rs[x], rs[y], mid+1, r);
}

inline void mergeAdd(int &x, int y, int l, int r){
    if(!y) return;
    if(!x) x = (++rtot);
    if(l == r){
        (v[x] += v[y]) %= mod;
        return;
    }
    int mid = (l + r) >> 1;
    mergeAdd(ls[x], ls[y], l, mid);
    mergeAdd(rs[x], rs[y], mid+1, r);

    pushup(x); return;
}

inline int query(int rt, int l, int r, int pos){
    if(!rt) return 0;
    if(l >= pos){
        return v[rt] % mod;
    }
    int mid = (l + r) >> 1, res = 0;
    if(mid >= pos) res = query(lson, l, mid, pos);
    (res += query(rson, mid+1, r, pos)) %= mod;
    
    return res;
}
void watch(int rt, int l, int r)
{       
    int mid = l + r >> 1;
    if(ls[rt]) watch(lson, l, mid);
    if(rs[rt]) watch(rson, mid+1, r);
    if(rt) cout<<l<<" "<<r<<' '<<v[rt]<<'\n';
}
inline int qpos(int rt, int l, int r, int pos){
    if(l == r) return v[rt] % mod;
    int mid = (l + r) >> 1;
    if(mid >= pos) return qpos(lson, l, mid, pos);
    else return qpos(rson, mid+1, r, pos);
}

int ned;
inline void dp(int x, int p, int goal, int whi){
    if(x == goal) return;
    int num = 0;
    for(int y : tw[whi][x]){
        if(y == p) continue;

        num = query(root[ned], 1, n, y);

        // cout<<y<<" "<<num<<" Add in Prograss\n";

        // cout<<query(root[ned], 1, n, 1)<<" Now's Ans\n";
        // cout<<query(root[y], 1, n, 1)<<" Now's Ans\n";

        mergeAdd(root[ned], root[y], 1, n);

        // cout<<query(root[ned], 1, n, 2)<<" Now's Ans\n";


        // watch(root[ned], 1, n); 

        // cout<<ned<<' '<<query(root[ned], 1, n, 1)<<" Now's- Ans\n";

        update(root[ned], 1, n, y, num);
        
        if(y == goal) break;
        dp(y, x, goal, whi);
    }
}


inline void dfs(int x, int p, int bel){
    cout<<x<<" "<<p<<" "<<bel<<endl;
    update(root[x], 1, n, x, 1);
    for(int whi : belong[x]){
        if(whi == bel) continue;

        if(sz[whi] == 2){
            int num = 0;
            for(int y : tw[whi][x]){
                if(y == p) continue;
                dfs(y, x, whi);
                root[x] = merge(root[x], root[y], 1, n);
                num += query(root[y], 1, n, x);
            }
            update(root[x], 1, n, x, num);

            continue;
        }

        for(int i : BCC[whi]){
            if(x == i) continue;
            int num = 1; 
            for(int y : to[i]){
                if(y == x or y == p) continue;
                bool ch = 1;
                for(int p : belong[y])
                    if(p == whi){ ch = 0; break; }
                if(!ch) continue;
                dfs(y, i, whi);
                (num += query(root[y], 1, n, i)) %= mod;
                root[i] = merge(root[i], root[y], 1, n);
            }
            update(root[i], 1, n, i, num);
            // if(i == 4) cout<<query(root[i], 1, n, 1)<<" Query\n";
        }
        
        int a = 0, b = 0;
        for(int i : tw[whi][x]){
            if(a) b = i;
            else a = i;
        }

        cout<<a<<" 's goal is "<<b<<"\n";
        // cout<<query(root[4], 1, n, 1)<<"\n";

        ned++; mcpy(root[ned], root[a], 1, n);
        dp(a, x, b, whi);
        mergeAdd(root[x], root[ned], 1, n);
        update(root[x], 1, n, x, query(root[ned], 1, n, x));

        // cout<<query(root[ned], 1, n, x)<<"\n";

        

        ned++; mcpy(root[ned], root[b], 1, n);

        // cout<<query(root[ned], 1, n, 1)<<" Start\n";

        // cout<<ned<<" need\n";
        dp(b, x, a, whi);
        mergeAdd(root[x], root[ned], 1, n);
        update(root[x], 1, n, x, query(root[ned], 1, n, x));
        

        cout<<query(root[x], 1, n, 1)<<" NewQ\n";

        ned++;

        int valo = 0;
        for(int i : BCC[whi]){
            if(x == i) continue;
            // root[ned] = merge(root[ned], root[i], 1, n);
            cout<<x<<" "<<i<<" Del The i_th Point "<<query(root[i], 1, n, x)<<"\n";
            (valo += query(root[i], 1, n, 1)) %= mod;
            // if(x == 3) cout<<query(root[i], 1, n, x)<<" "<<i<<" TYree\n";
            (valo += query(root[i], 1, n, x)) %= mod;
        }
        cout<<valo<<" Del\n";
        valo = (mod - valo) % mod;

        update(root[x], 1, n, x, valo);
    }
}

inline void clean(){
    fill(root, root+1+ned, 0);
    fill(ls, ls+1+rtot, 0);
    fill(rs, rs+1+rtot, 0);
    fill(v, v+1+rtot, 0);
    rtot = 0; ned = n * 2;
}

signed main(){ //algebra
    Aqrfre(a, a);

    qr(n), qr(m); ned = n;
    for(int i=1; i<=m; i++){
        int qr(x), qr(y);
        dis[x][y] = dis[y][x] = 1;
        to[x].emplace_back(y);
        to[y].emplace_back(x);
    }

    for(int i=1; i<=n; i++)
        if(!dfn[i]) tarjan(i, 0);

    for(int i=1; i<=bcc; i++)
        for(int x : BCC[i])
            for(int y : BCC[i]){
                if(x == y) continue;
                tw[i][x].emplace_back(y);
            }


    int la = 0;
    for(int i=1; i<=n*2; i++){
        if(!belong[i].size()) continue;
        clean(); dfs(i, 0, 0);
        (res += qpos(root[i], 1, n, i)) %= mod;
        cout<<qpos(root[i], 1, n, i)<<" AnsFrom\n";
        cout<<(res-la+mod)%mod<<" AnsNow\n";
        la = res;
        cout<<"\n-----------------"<<endl;
    }

    cout<<res<<"\n";


    return 0;
}

後天再調

code
#include<bits/stdc++.h>
#define int long long
#define me(a) memset(a, 0, sizeof a)
#define lson ls[rt]
#define rson rs[rt]
#define Aqrfre(x, y) freopen(#x ".in", "r", stdin),freopen(#y ".out", "w", stdout)
#define mp make_pair
#define Type int
#define qr(x) x=read()
typedef __int128 INT;
typedef long long ll;
using namespace std;

inline Type read(){
    char c=getchar(); Type x=0, f=1;
    while(!isdigit(c)) (c=='-'?f=-1:f=1), c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48), c=getchar();
    return x*f;
}

const int N = 505; 
const int mod = 998244353;

int n, m, res, tot, dis[N][N];
vector<int>to[N], belong[N<<1];

int top, th, s[N], bcc, low[N], dfn[N];
vector<int>BCC[N]; int sz[N];
inline void tarjan(int x, int p){
    s[++top] = x;
    low[x] = dfn[x] = ++th;
    for(int y : to[x]){
        if(!dfn[y]){
            tarjan(y, x);
            low[x] = min(low[x], low[y]);
            if(low[y] == dfn[x]){
                ++bcc;
                do{ BCC[bcc].emplace_back(s[top]); sz[bcc]++;
                    belong[s[top]].emplace_back(bcc);
                }while(s[top--] != y);

                BCC[bcc].emplace_back(x); sz[bcc]++;
                belong[x].emplace_back(bcc);
            }
        }
        else low[x] = min(low[x], dfn[y]);
    }
}

vector<int>tw[N<<2][N];
int v[N<<5], rtot, ls[N<<5], rs[N<<5], root[(N*N)<<1];
inline void pushup(int rt){
    v[rt] = (ll)(v[lson] + v[rson]) % mod;
} 

inline void update(int &rt, int l, int r, int pos, int val){
    if(!rt) rt = ++rtot;
    if(l == r){
        (v[rt] += val) %= mod;
        return;
    }

    int mid = (l + r) >> 1;
    if(pos <= mid) update(lson, l, mid, pos, val);
    else update(rson, mid+1, r, pos, val);

    pushup(rt);
}

inline int merge(int x, int y, int l, int r){
    if(!x or !y) return x + y;
    if(l == r){
        (v[x] += v[y]) %= mod;
        return x;
    }
    int mid = (l + r) >> 1;
    ls[x] = merge(ls[x], ls[y], l, mid);
    rs[x] = merge(rs[x], rs[y], mid+1, r);

    pushup(x); return x;
}

inline void mcpy(int &x, int y, int l, int r){
    if(!y) return;
    if(!x) x = ++rtot;
    v[x] = v[y];
    if(l == r) return;
    int mid = (l + r) >> 1;
    mcpy(ls[x], ls[y], l, mid);
    mcpy(rs[x], rs[y], mid+1, r);
}

inline int query(int rt, int l, int r, int pos){
    if(!rt) return 0;
    if(l >= pos){
        return v[rt] % mod;
    }
    int mid = (l + r) >> 1, res = 0;
    if(mid >= pos) res = query(lson, l, mid, pos);
    (res += query(rson, mid+1, r, pos)) %= mod;
    
    return res;
}

inline int qpos(int rt, int l, int r, int pos){
    if(l == r) return v[rt] % mod;
    int mid = (l + r) >> 1;
    if(mid >= pos) return qpos(lson, l, mid, pos);
    else return qpos(rson, mid+1, r, pos);
}

int ned;
inline void dp(int x, int p, int goal, int whi){
    if(x == goal) return;
    int num = 0;
    for(int y : tw[whi][x]){
        if(y == p) continue;
        num = query(root[ned], 1, n, y);
        root[ned] = merge(root[ned], root[y], 1, n);
        update(root[ned], 1, n, y, num);
        
        if(y == goal) break;
        dp(y, x, goal, whi);
    }
}


inline void dfs(int x, int p, int bel){
    cout<<x<<" "<<p<<" "<<bel<<endl;
    update(root[x], 1, n, x, 1);
    for(int whi : belong[x]){
        if(whi == bel) continue;

        if(sz[whi] == 2){
            int num = 0;
            for(int y : tw[whi][x]){
                if(y == p) continue;
                dfs(y, x, whi);
                root[x] = merge(root[x], root[y], 1, n);
                num += query(root[y], 1, n, x);
            }
            update(root[x], 1, n, x, num);

            continue;
        }

        for(int i : BCC[whi]){
            if(x == i) continue;
            int num = 1; 
            for(int y : to[i]){
                if(y == x or y == p) continue;
                bool ch = 1;
                for(int p : belong[y])
                    if(p == whi){ ch = 0; break; }
                if(!ch) continue;
                dfs(y, i, whi);
                (num += query(root[y], 1, n, i)) %= mod;
                root[i] = merge(root[i], root[y], 1, n);
            }
            update(root[i], 1, n, i, num);
            // if(i == 3) cout<<query(root[i], 1, n, 1)<<" Query\n";
        }
        
        int a = 0, b = 0;
        for(int i : tw[whi][x]){
            if(a) b = i;
            else a = i;
        }

        cout<<a<<" 's goal is "<<b<<"\n";
        // cout<<query(root[5], 1, n, 1)<<"\n";

        ned++; mcpy(root[ned], root[a], 1, n);
        dp(a, x, b, whi);
        // root[x] = merge(root[x], root[ned], 1, n);
        update(root[x], 1, n, x, query(root[ned], 1, n, x));


        ned++; mcpy(root[ned], root[b], 1, n);
        // cout<<ned<<" need\n";
        dp(b, x, a, whi);
        update(root[x], 1, n, x, query(root[ned], 1, n, x));
        // root[x] = merge(root[x], root[ned], 1, n);

        cout<<query(root[x], 1, n, 1)<<" NewQ\n";

        ned++;

        int valo = 0;
        for(int i : BCC[whi]){
            if(x == i) continue;
            // root[ned] = merge(root[ned], root[i], 1, n);
            (valo += query(root[i], 1, n, x)) %= mod;
        }
        cout<<valo<<" Del\n";
        valo = (mod - valo) % mod;

        update(root[x], 1, n, x, valo);
    }
}

inline void clean(){
    fill(root, root+1+ned, 0);
    fill(ls, ls+1+rtot, 0);
    fill(rs, rs+1+rtot, 0);
    fill(v, v+1+rtot, 0);
    rtot = 0; ned = n * 2;
}

signed main(){ //algebra
    Aqrfre(a, a);

    qr(n), qr(m); ned = n;
    for(int i=1; i<=m; i++){
        int qr(x), qr(y);
        dis[x][y] = dis[y][x] = 1;
        to[x].emplace_back(y);
        to[y].emplace_back(x);
    }

    for(int i=1; i<=n; i++)
        if(!dfn[i]) tarjan(i, 0);

    for(int i=1; i<=bcc; i++)
        for(int x : BCC[i])
            for(int y : BCC[i]){
                if(x == y) continue;
                tw[i][x].emplace_back(y);
            }


    int la = 0;
    for(int i=1; i<=n*2; i++){
        if(!belong[i].size()) continue;
        clean(); dfs(i, 0, 0);
        (res += qpos(root[i], 1, n, i)) %= mod;
        cout<<(res-la+mod)%mod<<" AnsNow\n";
        la = res;
        cout<<"\n-----------------"<<endl;
    }

    cout<<res<<"\n";


    return 0;
}

updated on 10.18 21:38 發現可以直接把賽時程式碼中的函式粘過來直接爆改一發就可以了!!!

code
#include<bits/stdc++.h>
#define int long long
#define me(a) memset(a, 0, sizeof a)
#define lson ls[rt]
#define rson rs[rt]
#define Aqrfre(x, y) freopen(#x ".in", "r", stdin),freopen(#y ".out", "w", stdout)
#define mp make_pair
#define Type int
#define qr(x) x=read()
typedef __int128 INT;
typedef long long ll;
using namespace std;

inline Type read(){
    char c=getchar(); Type x=0, f=1;
    while(!isdigit(c)) (c=='-'?f=-1:f=1), c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48), c=getchar();
    return x*f;
}

const int N = 505; 
const int mod = 998244353;

int n, m, res, tot, dis[N][N];
vector<int>to[N], belong[N<<1];

int top, th, s[N], bcc, low[N], dfn[N];
vector<int>BCC[N]; int sz[N];
inline void tarjan(int x, int p){
    s[++top] = x;
    low[x] = dfn[x] = ++th;
    for(int y : to[x]){
        if(!dfn[y]){
            tarjan(y, x);
            low[x] = min(low[x], low[y]);
            if(low[y] == dfn[x]){
                ++bcc;
                do{ BCC[bcc].emplace_back(s[top]); sz[bcc]++;
                    belong[s[top]].emplace_back(bcc);
                }while(s[top--] != y);

                BCC[bcc].emplace_back(x); sz[bcc]++;
                belong[x].emplace_back(bcc);
            }
        }
        else low[x] = min(low[x], dfn[y]);
    }
}

vector<int>tw[N<<2][N];
int v[N<<5], rtot, ls[N<<5], rs[N<<5], root[(N*N)<<1];
inline void pushup(int rt){
    v[rt] = (ll)(v[lson] + v[rson]) % mod;
} 

inline void update(int &rt, int l, int r, int pos, int val){
    if(!rt) rt = ++rtot;
    if(l == r){
        (v[rt] += val) %= mod;
        return;
    }

    int mid = (l + r) >> 1;
    if(pos <= mid) update(lson, l, mid, pos, val);
    else update(rson, mid+1, r, pos, val);

    pushup(rt);
}

inline int merge(int x, int y, int l, int r){
    if(!x or !y) return x + y;
    if(l == r){
        (v[x] += v[y]) %= mod;
        return x;
    }
    int mid = (l + r) >> 1;
    ls[x] = merge(ls[x], ls[y], l, mid);
    rs[x] = merge(rs[x], rs[y], mid+1, r);

    pushup(x); return x;
}

inline void mcpy(int &x, int y, int l, int r){
    if(!y) return;
    if(!x) x = ++rtot;
    v[x] = v[y];
    if(l == r) return;
    int mid = (l + r) >> 1;
    mcpy(ls[x], ls[y], l, mid);
    mcpy(rs[x], rs[y], mid+1, r);
}

inline int query(int rt, int l, int r, int pos){
    if(!rt) return 0;
    if(l >= pos){
        return v[rt] % mod;
    }
    int mid = (l + r) >> 1, res = 0;
    if(mid >= pos) res = query(lson, l, mid, pos);
    (res += query(rson, mid+1, r, pos)) %= mod;
    
    return res;
}

inline int qpos(int rt, int l, int r, int pos){
    if(l == r) return v[rt] % mod;
    int mid = (l + r) >> 1;
    if(mid >= pos) return qpos(lson, l, mid, pos);
    else return qpos(rson, mid+1, r, pos);
}

int ned;
inline void dp(int x, int p, int goal, int whi){
    if(x == goal) return;
    int num = 0;
    for(int y : tw[whi][x]){
        if(y == p) continue;
        if(y == goal) continue;
        num = query(root[ned], 1, n, y);
        root[ned] = merge(root[ned], root[y], 1, n);
        update(root[ned], 1, n, y, num);
        dp(y, x, goal, whi);
    }
}


inline void dfs(int x, int p, int bel){
    // cout<<x<<" "<<p<<" "<<bel<<endl;
    update(root[x], 1, n, x, 1);
    for(int whi : belong[x]){
        if(whi == bel) continue;

        if(sz[whi] == 2){
            int num = 0;
            for(int y : tw[whi][x]){
                if(y == p) continue;
                dfs(y, x, whi);
                root[x] = merge(root[x], root[y], 1, n);
                num += query(root[y], 1, n, x);
            }
            update(root[x], 1, n, x, num);

            continue;
        }

        for(int i : BCC[whi]){
            if(x == i) continue;
            int num = 1; 
            for(int y : to[i]){
                if(y == x or y == p) continue;
                bool ch = 1;
                for(int p : belong[y])
                    if(p == whi){ ch = 0; break; }
                if(!ch) continue;
                dfs(y, i, whi);
                (num += query(root[y], 1, n, i)) %= mod;
                root[i] = merge(root[i], root[y], 1, n);
            }
            update(root[i], 1, n, i, num);
        }
        
        int a = 0, b = 0;
        for(int i : tw[whi][x]){
            if(a) b = i;
            else a = i;
        }

        ned++; mcpy(root[ned], root[a], 1, n);
        dp(a, x, b, whi);

        ned++; mcpy(root[ned], root[b], 1, n);
        dp(b, x, a, whi);

        
    }
}

inline void clean(){
    fill(root, root+1+ned, 0);
    fill(ls, ls+1+rtot, 0);
    fill(rs, rs+1+rtot, 0);
    fill(v, v+1+rtot, 0);
    rtot = 0; ned = n;
}

signed main(){ //algebra
    Aqrfre(a, a);

    qr(n), qr(m); ned = n;
    for(int i=1; i<=m; i++){
        int qr(x), qr(y);
        dis[x][y] = dis[y][x] = 1;
        to[x].emplace_back(y);
        to[y].emplace_back(x);
    }

    for(int i=1; i<=n; i++)
        if(!dfn[i]) tarjan(i, 0);

    for(int i=1; i<=bcc; i++)
        for(int x : BCC[i])
            for(int y : BCC[i]){
                if(x == y) continue;
                tw[i][x].emplace_back(y);
            }


    int la = 0;
    for(int i=1; i<=n; i++){
        clean(); dfs(i, 0, 0);
        (res += qpos(root[i], 1, n, i)) %= mod;
        cout<<res-la<<" AnsNow\n";
        la = res;
        cout<<"\n-----------------"<<endl;
    }

    cout<<res<<"\n";


    return 0;
}

10.18 21:14 CTH 使我假完了!都怪 CTH !!!

code
#include<bits/stdc++.h>
#define int long long
#define me(a) memset(a, 0, sizeof a)
#define lson ls[rt]
#define rson rs[rt]
#define Aqrfre(x, y) freopen(#x ".in", "r", stdin),freopen(#y ".out", "w", stdout)
#define mp make_pair
#define Type int
#define qr(x) x=read()
typedef __int128 INT;
typedef long long ll;
using namespace std;

inline Type read(){
    char c=getchar(); Type x=0, f=1;
    while(!isdigit(c)) (c=='-'?f=-1:f=1), c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48), c=getchar();
    return x*f;
}

const int N = 505; 
const int mod = 998244353;

int n, m, res, tot, dis[N][N];
vector<int>to[N], belong[N<<1];

int top, th, s[N], bcc, low[N], dfn[N];
vector<int>BCC[N]; int sz[N];
inline void tarjan(int x, int p){
    s[++top] = x;
    low[x] = dfn[x] = ++th;
    for(int y : to[x]){
        if(!dfn[y]){
            tarjan(y, x);
            low[x] = min(low[x], low[y]);
            if(low[y] == dfn[x]){
                ++bcc;
                do{ BCC[bcc].emplace_back(s[top]); sz[bcc]++;
                    belong[s[top]].emplace_back(bcc);
                }while(s[top--] != y);

                BCC[bcc].emplace_back(x); sz[bcc]++;
                belong[x].emplace_back(bcc);
            }
        }
        else low[x] = min(low[x], dfn[y]);
    }
}

vector<int>tw[N<<2][N];
int v[N<<5], rtot, ls[N<<5], rs[N<<5], root[(N*N)<<1];
inline void pushup(int rt){
    v[rt] = (ll)(v[lson] + v[rson]) % mod;
} 

inline void update(int &rt, int l, int r, int pos, int val){
    if(!rt) rt = ++rtot;
    if(l == r){
        (v[rt] += val) %= mod;
        return;
    }

    int mid = (l + r) >> 1;
    if(pos <= mid) update(lson, l, mid, pos, val);
    else update(rson, mid+1, r, pos, val);

    pushup(rt);
}

inline int merge(int x, int y, int l, int r){
    if(!x or !y) return x + y;
    if(l == r){
        (v[x] += v[y]) %= mod;
        return x;
    }
    int mid = (l + r) >> 1;
    ls[x] = merge(ls[x], ls[y], l, mid);
    rs[x] = merge(rs[x], rs[y], mid+1, r);

    pushup(x); return x;
}

inline void mcpy(int &x, int y, int l, int r){
    if(!y) return;
    if(!x) x = ++rtot;
    v[x] = v[y];
    if(l == r) return;
    int mid = (l + r) >> 1;
    mcpy(ls[x], ls[y], l, mid);
    mcpy(rs[x], rs[y], mid+1, r);
}

inline int query(int rt, int l, int r, int pos){
    if(!rt) return 0;
    if(l >= pos){
        return v[rt] % mod;
    }
    int mid = (l + r) >> 1, res = 0;
    if(mid >= pos) res = query(lson, l, mid, pos);
    (res += query(rson, mid+1, r, pos)) %= mod;
    
    return res;
}

inline int qpos(int rt, int l, int r, int pos){
    if(l == r) return v[rt] % mod;
    int mid = (l + r) >> 1;
    if(mid >= pos) return qpos(lson, l, mid, pos);
    else return qpos(rson, mid+1, r, pos);
}

int ned;
inline void dp(int x, int p, int goal, int whi){
    int num = 0, G = 0;
    for(int y : tw[whi][x]){
        if(y == p) continue;
        cout<<ned<<":|| ";
        if(G and !p){
            ++ned;
            mcpy(root[ned], root[x], 1, n);
            cout<<query(root[x], 1, n, 1)<<" "<<y<<" Cone Im\n";
        }
        if(y == goal){
            // root[st] = merge(root[st], root[ned], 1, n);
            int valo = query(root[ned], 1, n, goal);
            update(root[goal], 1, n, goal, valo);
            // if(ned == 8) cout<<query(root[x], 1, n, 1)<<" You Wanty\n"; 
            
            cout<<ned<<" "<<x<<" "<<valo<<" Get Goal\n";
            G = 1;
            continue;
        }
        if(!p){
            cout<<"Change ";
            G = 1;
        }

        // cout<<y<<": ";

        num = query(root[ned], 1, n, y);

        update(root[ned], 1, n, y, num);

        // cout<<num<<" "<<query(root[ned], 1, n, 1)<<"\n";

        dp(y, x, goal, whi);
    }
    
}

inline void dfs(int x, int p, int bel){
    cout<<x<<" "<<p<<" "<<bel<<endl;
    update(root[x], 1, n, x, 1);
    for(int whi : belong[x]){
        if(whi == bel) continue;

        if(sz[whi] == 2){
            int num = 0;
            // cout<<" "<<x<<" Kill You\n";
            for(int y : tw[whi][x]){
                if(y == p) continue;
                // cout<<y<<" To\n";
                dfs(y, x, whi);
                root[x] = merge(root[x], root[y], 1, n);
                num += query(root[y], 1, n, x);
            }
            update(root[x], 1, n, x, num);

            // cout<<qpos(root[x], 1, n, x)<<" PoOp\n";
            continue;
        }

        for(int i : BCC[whi]){
            if(x == i) continue;
            int num = 1; 
            // cout<<i<<"  has these things:"<<endl;
            for(int y : to[i]){
                if(y == x or y == p) continue;
                bool ch = 1;
                for(int p : belong[y])
                    if(p == whi){ ch = 0; break; }
                if(!ch) continue;
                // cout<<"See Me: "<<i<<" "<<y<<endl;
                dfs(y, i, whi);
                (num += query(root[y], 1, n, i)) %= mod;
                root[i] = merge(root[i], root[y], 1, n);
            }
            update(root[i], 1, n, i, num);
            // if(i == 5) cout<<query(root[i], 1, n, 1)<<" Query\n";
            // cout<<qpos(root[i], 1, n, i)<<" The Pos's Ans is \n";
        }

        for(int i : BCC[whi]){
            if(x == i) continue;
            ++ned;
            cout<<i<<" ";
            cout<<ned<<" with: "<<query(root[i], 1, n, 1)<<" Now's start\n";
            mcpy(root[ned], root[i], 1, n);
            // cout<<root[ned]<<":\n";
            dp(i, 0, x, whi);
            // merge(root[x], root[ned-1], 1, n);
            // merge(root[x], root[ned], 1, n);
        }
    }
}

inline void clean(){
    fill(root, root+1+ned, 0);
    fill(ls, ls+1+rtot, 0);
    fill(rs, rs+1+rtot, 0);
    fill(v, v+1+rtot, 0);
    rtot = 0; ned = n;
}

signed main(){ //algebra
    Aqrfre(a, a);

    qr(n), qr(m); ned = n;
    for(int i=1; i<=m; i++){
        int qr(x), qr(y);
        dis[x][y] = dis[y][x] = 1;
        to[x].emplace_back(y);
        to[y].emplace_back(x);
    }

    for(int i=1; i<=n; i++)
        if(!dfn[i]) tarjan(i, 0);

    for(int i=1; i<=bcc; i++)
        for(int x : BCC[i])
            for(int y : BCC[i]){
                if(x == y) continue;
                tw[i][x].emplace_back(y);
            }


    int la = 0;
    for(int i=1; i<=n; i++){
        clean(); dfs(i, 0, 0);
        (res += qpos(root[i], 1, n, i)) %= mod;
        cout<<res-la<<" AnsNow\n";
        la = res;
        cout<<"\n-----------------"<<endl;
    }

    cout<<res<<"\n";


    return 0;
}

相關文章