2022HDU-Multi-University Training Range Reachability Query

Range Reachability Query

题目链接:https://acm.hdu.edu.cn/showproblem.php?pid=7171

给定一张有向图,每次询问只经过编号在[l,r]范围的边的情况下,点对是否能够到达。

\(f[i][j]\)表示\(i\)点能否只经过\([l_j,r_j]\)区间的边走到应该到的目标点。

由于这张图是有顺序的,所以可以直接倒着转移。

由于转态数量比较多,所以我们对询问根号分治,这样bitset可以开的下了。

现在这个代码T了,但是懒得改了()

#include<bits/stdc++.h>
#define N 100009
using namespace std;
typedef long long ll;
const int bl=4000;
bitset<4001>f[50009],S[100009],ss;
int T,n,m,q,tag[N];
vector<int>vec[N],vec1[N],vec2[N];
inline ll rd(){
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
struct edge{
    int u,v;
}b[N];
struct qq{
    int u,v,l,r;
}c[N];
int main(){
//    freopen("1010.in","r",stdin);
//    freopen("1.out","w",stdout); 
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=m;++i){
            scanf("%d%d",&b[i].u,&b[i].v);
            vec[b[i].u].push_back(i);
        }
        for(int i=1;i<=q;++i){
            scanf("%d%d%d%d",&c[i].u,&c[i].v,&c[i].l,&c[i].r);
        }
        for(int i=1;i<=q;i+=bl){
            tag[0]=0;
            ss.reset();
            for(int j=1;j<=n;++j)f[j].reset();
            for(int j=i;j<=min(i+bl-1,q);++j){
                tag[j]=++tag[0];
                f[c[j].v][tag[j]]=1;
                vec1[c[j].l].push_back(j);
                vec2[c[j].r].push_back(j);
            }
            for(int j=1;j<=m;++j){
                for(int k=0;k<vec1[j].size();++k){
                    ss[tag[vec1[j][k]]]=1;
                }
                S[j]=ss;
                for(int k=0;k<vec2[j].size();++k){
                    ss[tag[vec2[j][k]]]=0;
                }
            }
            for(int j=n;j>=1;--j){
                for(int k=0;k<vec[j].size();++k){
                    f[j]|=f[b[vec[j][k]].v]&S[vec[j][k]];
                }
            }
            for(int j=1;j<=m;++j){
                vec1[j].clear();
                vec2[j].clear();
            }
            for(int j=i;j<=min(i+bl-1,q);++j){
                if(f[c[j].u][tag[j]])puts("YES");
                else puts("NO");
            }
        }
        for(int i=1;i<=n;++i){
            vec[i].clear();
        }
    } 
    return 0;
}
posted @ 2022-08-10 16:16  comld  阅读(46)  评论(0编辑  收藏  举报