zoukankan      html  css  js  c++  java
  • 【LOJ】#2508. 「AHOI / HNOI2018」游戏

    题解

    把没有门的点缩成一个点

    如果(i->i + 1)的钥匙大于(i),那么(i)不可以到(i + 1),连一条(i)(i + 1)的边
    如果(i->i + 1)的钥匙小于(i),那么(i + 1)不可以到(i),连一条(i + 1)(i)的边
    按照拓扑序计算,每次暴力向左和向右扩张,每次扩张碰到的区间和当前这个点扩张的区间没有重叠的部分,于是复杂度就相当于把一条链相邻两个点一个个合并起来,是(O(n))

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define MAXN 1000005
    #define eps 1e-8
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    struct node {
        int to,next;
    }E[MAXN];
    int N,M,P;
    int a[MAXN],head[MAXN],sumE,L[MAXN],R[MAXN],id[MAXN],tot,deg[MAXN];
    void add(int u,int v) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        head[u] = sumE;
    }
    queue<int> Q;
    void BFS() {
        for(int i = 1 ; i <= tot ; ++i) {
    	if(!deg[i]) Q.push(i);
        }
        while(!Q.empty()) {
    	int u = Q.front();Q.pop();
    	while(1) {
    	    bool flag = 0;
    	    while(L[u] != 1 && a[L[u] - 1] >= L[u] && a[L[u] - 1] <= R[u]) {flag = 1;L[u] = L[id[L[u]] - 1];}
    	    while(R[u] != N && a[R[u]] >= L[u] && a[R[u]] <= R[u]) {flag = 1;R[u] = R[id[R[u]] + 1];}
    	    if(!flag) break;
    	}
    	for(int i = head[u] ; i ; i = E[i].next) {
    	    int v = E[i].to;
    	    if(!(--deg[v])) {
    		Q.push(v);
    	    }
    
    	}
        }
    }
    void Solve() {
        read(N);read(M);read(P);
        int x,y;
        for(int i = 1 ; i <= M ; ++i) {
    	read(x);read(y);
    	a[x] = y;
        }
        int p = 1;
        while(p <= N) {
    	id[p] = ++tot;L[tot] = p;
    	while(p != N && !a[p]) {++p;id[p] = tot;}
    	R[tot] = p;
    	++p;
        }
        for(int i = 1 ; i <= N ; ++i) {
    	if(!a[i]) continue;
    	if(a[i] > i) {add(id[i],id[i + 1]);deg[id[i + 1]]++;}
    	else {add(id[i + 1],id[i]);deg[id[i]]++;}
        }
        BFS();
        int s,t;
        for(int i = 1 ; i <= P ; ++i) {
    	read(s);read(t);
    	if(t >= L[id[s]] && t <= R[id[s]]) puts("YES");
    	else puts("NO");
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Maximum Depth of Binary Tree
    Sharepoint 2013 创建TimeJob 自动发送邮件
    IE8 不能够在Sharepoint平台上在线打开Office文档解决方案
    TFS安装与管理
    局域网通过IP查看对方计算机名,通过计算机名查看对方IP以及查看在线所有电脑IP
    JS 隐藏Sharepoint中List Item View页面的某一个字段
    SharePoint Calculated Column Formulas & Functions
    JS 两个一组数组转二维数组
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9953517.html
Copyright © 2011-2022 走看看