LOJ3189 「ROI 2019 Day1」运输 20/19

Link
\(x\in[r,\frac p{p-1}r]\Leftrightarrow r\in[\frac {p-1}px,x]\Leftrightarrow pr\in[(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();
}
posted @ 2020-05-30 16:41  Shiina_Mashiro  阅读(264)  评论(1编辑  收藏  举报