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;
}