zoukankan      html  css  js  c++  java
  • 【HNOI2018】游戏

    题面

    题解

    这道题目到底有没有靠谱一点的解法啊。。。

    有很多种(color{green}{mathrm{AC}})的方法,设(L[i],R[i])表示点(i)最左边和最右边能够到达的位置

    于是就有正着推(20)分,反着推(color{green}{mathrm{AC}})

    还可以拓扑排序,正着加点(color{#001277}{mathrm{TLE}}),反着加点(color{green}{mathrm{AC}})

    所以也没有什么好讲的了。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define clear(x, y) memset(x, y, sizeof(x))
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while(ch != '-' && (!isdigit(ch))) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(1e6 + 10);
    struct edge { int next, to; } e[maxn];
    int head[maxn], e_num, deg[maxn];
    
    inline void add_edge(int from, int to)
    {
    	e[++e_num] = (edge) {head[from], to};
    	head[from] = e_num; ++deg[to];
    }
    
    int n, m, Q, p[maxn], cnt, key[maxn], L[maxn], R[maxn];
    void TopSort()
    {
    	std::queue<int> Q;
    	for(RG int i = n; i; i--) if(!deg[i]) Q.push(i);
    	while(!Q.empty())
    	{
    		int x = Q.front(); Q.pop(); p[++cnt] = x;
    		for(RG int i = head[x]; i; i = e[i].next)
    			if(!--deg[e[i].to]) Q.push(e[i].to);
    	}
    }
    
    void calc(int x)
    {
    	int l = x, r = x;
    	while(1)
    	{
    		int pl = l, pr = r;
    		while(l > 1 && (!key[l - 1] || (l <= key[l - 1] && key[l - 1] <= r)))
    			l = L[l - 1];
    		while(r < n && (!key[r] || (l <= key[r] && key[r] <= r))) r = R[r + 1];
    		if(pl == l && pr == r) break;
    	}
    	L[x] = l, R[x] = r;
    }
    
    int main()
    {
    	n = read(), m = read(), Q = read();
    	for(RG int i = 1, x, y; i <= m; i++)
    	{
    		x = read(), y = read(), key[x] = y;
    		if(y <= x) add_edge(x + 1, x);
    		else add_edge(x, x + 1);
    	}
    	TopSort();
    	for(RG int i = 1; i <= n; i++) L[i] = R[i] = i;
    	for(RG int i = 1; i <= n; i++) calc(p[i]);
    	while(Q--)
    	{
    		int S = read(), T = read();
    		puts(L[S] <= T && T <= R[S] ? "YES" : "NO");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Windows解决端口占用
    Oracle数字格式化
    Windows生成项目目录结构
    IDEA激活教程
    Windows搭建SMB服务
    在右键新建菜单中添加新项目
    Fastjson1.2.47反序列化+环境搭建+漏洞复现
    nmap常用命令及端口
    Shiro反序列化复现
    CVE-2020-0796漏洞复现
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10451786.html
Copyright © 2011-2022 走看看