AT_abc450_f ABC450F Strongly Connected 2 Sol

题目链接

到现在连这种题都做不出来是不是可以退役了。

不难发现本题的问题实际上为选出若干条边,使得可以从 1 走到 n

开题的时候尝试了容斥,思考后发现难以解决。

实际上本题的正解是使用线段树优化 DP。记 \(f_{i,j}\) 表示考虑到第 \(i\) 条边,最远能够走到 \(j\)。要记录的是最远是显然的,走的更远一定更优。尝试转移。假设所选区间为 \([l,r]\),则 \([1,l-1]\) 不受影响,为 \(f_{i,j} = f_{i-1,j} \times 2\)\([r+1,n]\) 也不受影响,转移同理。在 \([l,r-1]\) 区间中的点都可以到 \(r\),而不会留在原地,所以有 \(f_{i,j} = f_{i-1,j}\),而对于 \(r\),则为 \(f_{i,j} = \sum\limits_{j=l}^{r} f_{i-1,j}\)。这个显然是能使用线段树维护的。

Code

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define File(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define LL long long
#define fi first
#define se second
const LL mod = 998244353;
const int N = 2e5 + 10;
class Modint{
static constexpr LL mod = (LL)(998244353);
LL val;
public:
	Modint(long long v = 0) : val(v % mod){
		if(val < 0) val += mod;
	}
	long long value() const {return val;}
	Modint& operator = (long long v){
		val = (v % mod + mod) % mod;
		return *this;
	}

	Modint operator + (const Modint &o) const{
		return Modint(val + o.val);
	}
	Modint& operator += (const Modint &o){
		val = (val + o.val) % mod;
		return *this;
	}

	Modint operator - (const Modint &o) const{
		return Modint(val - o.val);
	}
	Modint& operator -= (const Modint &o){
		val = (val - o.val + mod) % mod;
		return *this;
	}
	Modint operator*(const Modint& o) const {
		return Modint(val * o.val);
    }
    Modint& operator*=(const Modint& o){
    	val = val * o.val % mod;
    	return *this;
    }
    static LL qpow(LL a,LL b = mod-2){
    	if(b == 0) return 1;
    	if(b == 1) return a;
    	LL res = qpow(a,b/2);
    	res = res * res % mod;
    	if(b & 1ll) res *= a;
    	return res % mod;
    }
    static LL inv(LL a){
    	return qpow(a);
    }
    Modint operator / (const Modint& o) const{
    	return Modint(val * inv(o.val));
    }
    Modint& operator /= (const Modint& o){
    	val = val * inv(o.val) % mod;
    	return *this;
    }
    bool operator == (const Modint &other) const{return val == other.val;}
    bool operator != (const Modint &other) const{return val != other.val;}
    friend ostream& operator <<(ostream& os ,const Modint &m){
    	return os << m.val;
    }
    friend istream& operator >>(istream& is,Modint &m){
    	long long v;
    	is >> v;
    	m = Modint(v);
    	return is;
    }
};

// <=== Modint Above ===>
struct segment_tree{
	Modint tre[N << 2],lzy[N << 2];
	void pushup(int p){tre[p] = tre[p*2] + tre[p*2+1];}
	void pushdown(int p){
		if(lzy[p] == 1) return ;
		tre[p*2]  *= lzy[p];tre[p*2+1] *= lzy[p];
		lzy[p*2] *= lzy[p];lzy[p*2+1] *= lzy[p];
		lzy[p] = 1;
		return ;
	}
	void add(int pl,int pr,int p,int x,Modint k){
		if(pl == pr){
			tre[p] += k;
			lzy[p] = 1;
			return ;
		}
		pushdown(p);
		int mid = pl + pr >> 1;
		if(x <= mid) add(pl,mid,p*2,x,k);
		if(x > mid) add(mid+1,pr,p*2+1,x,k);
		pushup(p);
	}
	void build(int pl,int pr,int p){
		tre[p] = 0,lzy[p] = 1;
		if(pl == pr){
			return ;
		}
		int mid = pl + pr >> 1;
		build(pl,mid,p*2);
		build(mid+1,pr,p*2+1);
		return ;
	}
	void mul(int L,int R,int pl,int pr,int p,LL k){
		if(L > R) return ;
		if(L <= pl && pr <= R){
			tre[p] *= k;
			lzy[p] *= k;
			return ;
		}
		pushdown(p);
		int mid = pl + pr >> 1;
		if(L <= mid) mul(L,R,pl,mid,p*2,k);
		if(R > mid) mul(L,R,mid+1,pr,p*2+1,k);
		pushup(p);
	}
	Modint query(int L,int R,int pl,int pr,int p){
		if(L > R) return 0;
		if(L <= pl && pr <= R) return tre[p];
		pushdown(p);
		int mid = pl + pr >> 1;
		Modint res = 0;
		if(L <= mid) res += query(L,R,pl,mid,p*2);
		if(R > mid) res += query(L,R,mid+1,pr,p*2+1);
		return res;
	}
}sgt;
int n,m;
pair<int,int> edge[N];
int main(){
	IOS;
	cin >> n >> m;
	for(int i=1;i<=m;i++)
		cin >> edge[i].fi >> edge[i].se;
	sort(edge+1,edge+1+m);
	sgt.build(1,n,1);
	sgt.add(1,n,1,1,1);
	for(int i=1;i<=m;i++){
		int l,r;
		l = edge[i].fi,r = edge[i].se;
		if(l > r){
			sgt.mul(1,n,1,n,1,2);
			continue;
		}
		sgt.mul(1,l-1,1,n,1,2);
		sgt.mul(r+1,n,1,n,1,2);
		sgt.add(1,n,1,r,sgt.query(l,r,1,n,1));
	}
	cout << sgt.query(n,n,1,n,1);
	return 0;
}
posted @ 2026-05-21 09:51  WinterXorSnow  阅读(7)  评论(0)    收藏  举报