#include #include #include #include using namespace std; using namespace atcoder; using mint = modint998244353; vector> G[100010]; int c[100010],comp[100010],par[100010],par_id[100010],d[100010]; void dfs(int s,int p,int col,int x){ c[s] = col; comp[s] = x; par[s] = p; for(auto [v,id]:G[s]){ if(c[v]!=-1) continue; par[v] = v; par_id[v] = id; d[v] = d[s] + 1; dfs(v,s,1 - col,x); } } mint deb_a[100010]; int u[100010],v[100010]; mint a[100010],b[100010],ans[100010]; void add_op(int x,int y,int id,mint c){ assert((x==v[id] && y==u[id]) || (x==u[id] || y==v[id])); a[x] += c; a[y] += c; deb_a[u[id]] += c; deb_a[v[id]] += c; ans[id] += c; } bool vis[100010]; void solve_dfs(int s,int p,int id){ if(vis[s]) return; vis[s] = true; for(auto [v,id]:G[s]){ if(vis[v]) continue; solve_dfs(v,s,id); } if(p!=-1 && id!=-1){ mint c = b[s] - a[s]; add_op(s,p,id,c); } } #include #include // (頂点,辺) pair,vector> get_path(int from,int to){ assert(from!=to); int a = from,b = to; vector v1,v2,e1,e2; v1.push_back(a); v2.push_back(b); while(a!=b){ if(d[a]>d[b]){ v1.push_back(par[a]); e1.push_back(par_id[a]); a = par[a]; }else{ v2.push_back(par[b]); e2.push_back(par_id[b]); b = par[b]; } } reverse(v2.begin(),v2.end()); reverse(e2.begin(),e2.end()); // lcaが被る v1.pop_back(); v1.insert(v1.end(),v2.begin(),v2.end()); e1.insert(e1.end(),e2.begin(),e2.end()); return {v1,e1}; } #include int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int i,n,m; cin >> n >> m; for(i=0;i> x; b[i] = x; } for(i=0;i> u[i] >> v[i]; u[i]--; v[i]--; G[u[i]].push_back({v[i],i}); G[v[i]].push_back({u[i],i}); } for(i=0;i> cc(n); for(i=0;i s; for(int v:ver) s.insert(v); for(int v:ver){ for(auto [u,id]:G[v]){ if(s.count(u)) continue; s.insert(u); solve_dfs(u,v,id); } } cerr << "DEBUG\n"; for(int x:ver) cerr << x << " "; cerr << "\n"; for(int id:ed) cerr << id << " "; cerr << "\n"; mint val = b[x] - a[x] + b[y] - a[y]; for(int id=1;id<(int)ver.size() - 1;id++){ if(id&1){ val -= b[ver[id]] - a[ver[id]]; }else{ val += b[ver[id]] - a[ver[id]]; } } cerr << "val == " << val.val() << "\n"; add_op(x,y,e,val/2); for(int u:ver) cerr << (b[u] - a[u]).val() << " "; cerr << "\n"; // x -> yのパスに沿って塗る // solve_dfsとは違う順番じゃないとダメ (verの順になる) while(ver.size()){ int z = ver.back(); ver.pop_back(); if(ver.size()){ mint c = b[z] - a[z]; cerr << "val == " << c.val() << "\n"; cerr << "z == " << z << " " << ver.back() << "\n"; add_op(z,ver.back(),ed.back(),c); for(int id=0;id