Link
(xin[r,frac p{p-1}r]Leftrightarrow rin[frac {p-1}px,x]Leftrightarrow prin[(p-1)x,px])
对于每个点维护其合法的(pr)区间即可。
#include<cctype>
#include<cstdio>
#include<vector>
#include<utility>
#include<algorithm>
using i64=long long;
const int N=500007;
char ibuf[1<<25|1],*iS=ibuf;int n,m,p,q;
std::vector<std::pair<int,i64>>e[N];std::vector<std::pair<i64,i64>>vec[N];
i64 read(){i64 x=0;while(isspace(*iS))++iS;while(isdigit(*iS))(x*=10)+=*iS++&15;return x;}
void merge(int u,int v,i64 w)
{
std::vector<std::pair<i64,i64>>now;i64 l,r;
for(auto i=vec[u].begin(),j=vec[v].begin();i!=vec[u].end()||j!=vec[v].end();)
{
if(i!=vec[u].end()&&(j==vec[v].end()||i->first<j->first+w*(p-1))) l=i->first,r=i++->second; else l=j->first+w*(p-1),r=j++->second+w*p;
if(!now.size()||l>now.back().second) now.emplace_back(l,r); else now.back().second=std::max(now.back().second,r);
}
vec[u].swap(now);
}
void query()
{
int f=read();i64 x=read()*p;
auto it=std::upper_bound(vec[f].begin(),vec[f].end(),std::make_pair(x,1ll<<62));
putchar(it==vec[f].begin()||prev(it)->second<x? '0':'1');
}
void solve()
{
n=read(),m=read(),q=read(),p=read();
for(int i=1;i<=n;++i) e[i].clear(),vec[i].clear();
for(int i=1,u,v;i<=m;++i) u=read(),v=read(),e[v].emplace_back(u,read());
vec[1].emplace_back(0,0);
for(int u=2;u<=n;++u) for(auto v:e[u]) merge(u,v.first,v.second);
while(q--) query();
puts("");
}
int main()
{
fread(ibuf,1,1<<25,stdin);
for(int t=read();t;--t) solve();
}