Submission #636000

#TimeUsernameProblemLanguageResultExecution timeMemory
636000K4YANSubtree (INOI20_subtree)C++17
100 / 100
109 ms32708 KiB
//Be Name Khoda

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
#define pll pair<ll, ll>
#define plll pair<ll, pll>
#define all(x) x.begin(), x.end()

const ll mxn = 1e5 + 16, INF = 1e16 + 16, md = 1e9 + 7;
ll n, m, q, w, cnt;
ll dp[mxn], blg[mxn], par[mxn], dpall[mxn], cpar[mxn];
vector<ll> adj[mxn], C[mxn], cdp[mxn];
bitset<mxn> mark, dor;

inline ll tav(ll a, ll b) {
    ll res = 1;
    while(b > 0) {
        if(b & 1) res = res * a % md;
        a = a * a % md, b >>= 1;
    } return res;
}

inline void input() {

    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        cin >> q >> w;
        adj[q].push_back(w);
        adj[w].push_back(q);
    }

}

void DFS(int v) {
    mark.set(v);
    for(auto u : adj[v]) {
        if(u == par[v]) continue;
        if(!mark[u]) {
            par[u] = v;
            DFS(u);
        } else {
            if(dor[v]) continue;
            cnt++, q = v;
            while(q != u) {
                C[cnt].push_back(q);
                dor.set(q); blg[q] = cnt;
                q = par[q];
                
            } C[cnt].push_back(u);
            dor.set(u); blg[u] = cnt;
            continue;
        }
    }
    if(!dor[v]) {
        cnt++;
        dor.set(v); blg[v] = cnt;
        C[cnt].push_back(v);
    }
}
void SAGZAN(int cy, int v) {
    mark.set(cy);
    bool barg = 1;
    if(v != -1) {
        int id = 0;
        for(auto u : C[cy]) {
            if(u == v) {
                break;
            } id++;
        }
        vector<ll> f;
        f.push_back(C[cy][id]);
        for(int i = id + 1; i < int(C[cy].size()); i++) {
            f.push_back(C[cy][i]);
        } for(int i = 0; i < id; i++) {
            f.push_back(C[cy][i]);
        } C[cy] = f;
    }
    for(auto x : C[cy]) {
        for(auto u : adj[x]) {
            if(mark[blg[u]]) continue;
            barg = 0;
            cpar[blg[u]] = cy;
            SAGZAN(blg[u], u);
        }
    }
    if(barg) {
        q = int(C[cy].size());
        if(q == 1) {
            dpall[cy] = 1;
            dp[C[cy][0]] = 1;
            return;
        }
        dpall[cy] = q * (q - 1) % md;
        for(auto u : C[cy]) {
            dp[u] = (q * (q - 1) / 2) % md;
            dp[u] %= md;
        } return;
    } 
    q = int(C[cy].size());
    if(q == 1) {
        for(auto u : adj[C[cy][0]]) {
            if(blg[u] == cpar[cy]) continue;
            q *= (dp[u] + 1);
            q %= md;
        } dp[C[cy][0]] = dpall[cy] = q;
        return;
    }

    ll sum = 0, ans = 0; w = 1;
    vector<ll> ps;
    for(auto x : C[cy]) {
        q = 1;
        for(auto u : adj[x]) {
            if(blg[u] == cpar[cy]) continue;
            if(blg[u] == cy) continue;
            q *= (dp[u] + 1);
            q %= md;
        } cdp[cy].push_back(q);
        w = w * q % md;
        sum = (sum + w) % md;
        ps.push_back(sum);
    } ans = ps[int(ps.size()) - 2];
    w = 1, sum = ps[int(ps.size()) - 2];
    for(int i = int(C[cy].size()) - 1; i > 1; i--) {
        sum = (sum - (w * (ps[i - 1] - ps[i - 2]) % md) + md) % md;
        sum = sum * cdp[cy][i] % md;
        w = w * cdp[cy][i] % md;
        ans = (ans + sum) % md;
    } if(v > 0) dp[v] = ans;
    ans = sum = ps[int(ps.size()) - 2], w = 1;
    for(int i = int(C[cy].size()) - 1; i > 0; i--) {
        if(i == 1) {
            sum = (sum - ps[i - 1] * w % md + md) % md;    
        }
        else sum = (sum - (ps[i - 1] - ps[i - 2]) * w % md + md) % md;
        sum = (sum * cdp[cy][i] % md + cdp[cy][i]) % md;
        w = w * cdp[cy][i] % md;
        ans = (ans + sum) % md;
    } dpall[cy] = ans;
    return;
 
}

inline void solve() {

    DFS(1);
    mark.reset();
    fill(dp, dp + mxn, 1);
    SAGZAN(1, -1);
    ll ans = 0;
    for(int i = 1; i <= cnt; i++) {
        ans += dpall[i];
        ans %= md;
    } cout << ans << endl;
    return;

}

int main() {

    ios::sync_with_stdio(false); cin.tie(NULL);

    input(), solve();

    return 0;

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...