• [洛谷P5166]xtq的口令


    题目大意:给出一张有向图,保证任何时候边都是从编号大的向编号小连。两个操作:

    1. $1;l;r:$表示若编号在区间$[l,r]$内的点被染色了,问至少还需要染多少个点才可以使得整张图被染色。一个点会被染色的要求是:要么直接被染色,要么它所连向的点中至少一个被染色
    2. $2;l;r;x:$表示编号在区间$[l,r]$中的所有点都向$x$连一条边,保证$x<l$

    题解:发现这张图是一个$DAG$,然后只要把所有出度为$0$的点染色就一定可以把所有点染色。

    于是就记录每个点是否出度为$0$,询问是区间$[1,l)cup(r,n]$中出度为$0$的点的个数,修改就把区间$[l,r]$中出度为$0$的点改为非$0$。可以用线段树维护

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cctype>
    namespace std {
    	struct istream {
    #define M (1 << 24 | 3)
    		char buf[M], *ch = buf - 1;
    		inline istream() {
    #ifndef ONLINE_JUDGE
    			freopen("input.txt", "r", stdin);
    #endif
    			fread(buf, 1, M, stdin);
    		}
    		inline istream& operator >> (int &x) {
    			while (isspace(*++ch));
    			for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
    			return *this;
    		}
    #undef M
    	} cin;
    	struct ostream {
    #define M (1 << 23 | 3)
    		char buf[M], *ch = buf - 1;
    		inline ostream& operator << (int x) {
    			if (!x) {
    				*++ch = '0';
    				return *this;
    			}
    			static int S[20], *top; top = S;
    			while (x) {
    				*++top = x % 10 ^ 48;
    				x /= 10;
    			}
    			for (; top != S; --top) *++ch = *top;
    			return *this;
    		}
    		inline ostream& operator << (const char x) { *++ch = x; return *this; }
    		inline ~ostream() {
    #ifndef ONLINE_JUDGE
    			freopen("output.txt", "w", stdout);
    #endif
    			fwrite(buf, 1, ch - buf + 1, stdout);
    		}
    #undef M
    	} cout;
    }
    
    #define maxn 300010
    int n, m;
    bool notice[maxn];
    
    namespace SgT {
    	bool tg[maxn << 2];
    	int V[maxn << 2];
    	void build(int rt, int l, int r) {
    		if (l == r) {
    			V[rt] = !notice[l];
    			return ;
    		}
    		int mid = l + r >> 1;
    		build(rt << 1, l, mid), build(rt << 1 | 1, mid + 1, r);
    		V[rt] = V[rt << 1] + V[rt << 1 | 1];
    	}
    
    	int L, R;
    	inline void pushdown(int rt) {
    		V[rt << 1] = V[rt << 1 | 1] = 0;
    		tg[rt << 1] = tg[rt << 1 | 1] = true;
    		tg[rt] = false;
    	}
    	void __modify(const int rt, const int l, const int r) {
    		if (L <= l && R >= r) {
    			V[rt] = 0;
    			tg[rt] = true;
    			return ;
    		}
    		if (tg[rt]) pushdown(rt);
    		const int mid = l + r >> 1;
    		if (L <= mid) __modify(rt << 1, l, mid);
    		if (R > mid) __modify(rt << 1 | 1, mid + 1, r);
    		V[rt] = V[rt << 1] + V[rt << 1 | 1];
    	}
    	void modify(const int __L, const int __R) {
    		L = __L, R = __R;
    		__modify(1, 1, n);
    	}
    
    	int res;
    	void __query(const int rt, const int l, const int r) {
    		if (L <= l && R >= r) {
    			res += V[rt];
    			return ;
    		}
    		if (tg[rt]) pushdown(rt);
    		const int mid = l + r >> 1;
    		if (L <= mid) __query(rt << 1, l, mid);
    		if (R > mid) __query(rt << 1 | 1, mid + 1, r);
    	}
    	int query(const int __L, const int __R) {
    		if (__L > __R) return 0;
    		L = __L, R = __R, res = 0;
    		__query(1, 1, n);
    		return res;
    	}
    }
    
    int main() {
    	std::cin >> n >> m;
    	for (int i = 1, k; i <= n; ++i) {
    		std::cin >> k;
    		for (int j = 0, x; j < k; ++j) std::cin >> x, notice[x] = true;
    	}
    	SgT::build(1, 1, n);
    	while (m --> 0) {
    		static int op, l, r, x;
    		std::cin >> op >> l >> r;
    		if (op == 1) std::cout << SgT::query(1, l - 1) + SgT::query(r + 1, n) << '
    ';
    		else std::cin >> x, SgT::modify(l, r);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    MvcScaffolding: OnetoMany Relationships
    未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载
    MVC中使用Scaffold生成代码
    项目开发的三个阶段 我的一点体会
    在Eclipse工作空间中创建新项目的方法
    Visual Studio 使用常见问题
    Matlab代码:为图像添加信噪比为SNR db的高斯噪声
    《Ogre 3D 游戏开发框架指南》配套光盘的一个小瑕疵
    如何阅读C++源代码
    在Eclipse工作空间中移除再添加项目的方法
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10249921.html
Copyright © 2020-2023  润新知