結果
| 問題 |
No.2588 Increasing Record
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-12-16 00:59:56 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 507 ms / 3,000 ms |
| コード長 | 3,854 bytes |
| コンパイル時間 | 14,013 ms |
| コンパイル使用メモリ | 246,140 KB |
| 最終ジャッジ日時 | 2025-02-18 11:45:12 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 44 |
ソースコード
// -fsanitize=undefined,
// #define _GLIBCXX_DEBUG
#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>
#include <stdio.h>
#include <fstream>
#include <functional>
#include <cassert>
#include <unordered_map>
#include <bitset>
#include <chrono>
#include <atcoder/modint>
#include <atcoder/convolution>
using namespace std;
using namespace atcoder;
#define rep(i,n) for (int i=0;i<n;i+=1)
#define rrep(i,n) for (int i=n-1;i>-1;i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << " )\n";
template<class T>
using vec = vector<T>;
template<class T>
using vvec = vec<vec<T>>;
template<class T>
using vvvec = vec<vvec<T>>;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
template<class T>
bool chmin(T &a, T b){
if (a>b){
a = b;
return true;
}
return false;
}
template<class T>
bool chmax(T &a, T b){
if (a<b){
a = b;
return true;
}
return false;
}
template<class T>
T sum(vec<T> x){
T res=0;
for (auto e:x){
res += e;
}
return res;
}
template<class T>
void printv(vec<T> x){
for (auto e:x){
cout<<e<<" ";
}
cout<<endl;
}
template<class T,class U>
ostream& operator<<(ostream& os, const pair<T,U>& A){
os << "(" << A.first <<", " << A.second << ")";
return os;
}
template<class T>
ostream& operator<<(ostream& os, const set<T>& S){
os << "set{";
for (auto a:S){
os << a;
auto it = S.find(a);
it++;
if (it!=S.end()){
os << ", ";
}
}
os << "}";
return os;
}
using mint = modint998244353;
ostream& operator<<(ostream& os, const mint& a){
os << a.val();
return os;
}
template<class T>
ostream& operator<<(ostream& os, const vec<T>& A){
os << "[";
rep(i,A.size()){
os << A[i];
if (i!=A.size()-1){
os << ", ";
}
}
os << "]" ;
return os;
}
template <typename T> vector<T>& operator+=(vector<T>& a, const vector<T>& b) {
if (a.size() < b.size()) {
a.resize(b.size());
}
for (int i = 0; i < (int)b.size(); i++) {
a[i] += b[i];
}
return a;
}
template <typename T> vector<T> operator+(const vector<T>& a, const vector<T>& b) {
vector<T> c = a;
return c += b;
}
int main(){
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int N,M;
cin>>N>>M;
vec<vec<int>> edge(N);
vec<set<int>> to_big(N);
rep(i,M){
int u,v;
cin>>u>>v;
u--; v--;
edge[max(u,v)].push_back(min(u,v));
to_big[min(u,v)].insert(max(u,v));
}
vector<mint> dp(N,1);
vector<mint> lazy_add(N,0);
vector<int> root(N,-1);
vector<vector<int>> G(N);
vector<map<int,mint>> add_to_big(N);
rep(i,N){
root[i] = i;
G[i].push_back(i);
}
auto merge = [&](int u,int v){
u = root[u];
v = root[v];
if (u == v) return ;
if (G[u].size() > G[v].size()) swap(u,v);
for (auto x:G[u]){
root[x] = v;
G[v].push_back(x);
}
G[u].clear();
for (auto [big,val]:add_to_big[u]){
if (!add_to_big[v].count(big)){
add_to_big[v][big] = -lazy_add[v];
}
add_to_big[v][big] += lazy_add[u] + val;
}
};
for (int i=0;i<N;i++){
set<int> done;
for (auto nv:edge[i]){
int r = root[nv];
if (done.count(r)) continue;
if (add_to_big[r].count(i)){
dp[i] += add_to_big[r][i] + lazy_add[r];
add_to_big[r].erase(i);
}
}
for (auto nv:to_big[i]){
add_to_big[i][nv] = 0;
}
for (auto nv:edge[i]){
merge(nv,i);
}
lazy_add[root[i]] += dp[i];
}
mint ans = accumulate(all(dp),mint(0));
//debug(dp);
cout << ans << endl;
}