ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「ROI 2019 Day1」运输 20/19

2021-02-16 10:02:06  阅读:90  来源: 互联网

标签:ROI 20 log 19 ll int frac dp const


「ROI 2019 Day1」运输 20/19

题目大意:

给定一个带权\(DAG\),\(1\)为起始点,给定小常数\(p\)

每次查询一个点\(u\),一个权值\(r\),问是否存在一条路径\(1\ldots u\),其长度\(x\)满足\(r\leq x\leq \frac{p}{p-1}\cdot r\)

转换一下,\(dp\)每个点是否存在\(r\),那么对于路径的权值\(x\),合法的\(r\)即为\([\frac{p-1}{p}\cdot x,x]\)

对于任意两个区间,如果其相交,则可以合并,并且用两个区间中最小和最大的\(x\)来表示这个区间

而不相交的区间最多只有\(\log_{\frac{p}{p-1}} w\)段,大概\(700\)段

任意时刻,每个点的\(dp\)情况可以用\(700\)段不交的区间表示,转移可以归并数组进行

因此维护\(dp\)复杂度为\(O(m\log_{\frac{p}{p-1}} w)\)常数极小,单次查询复杂度为\(O(\log \log_{\frac{p}{p-1}} w)\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
char IO;
template <class T=int> T rd(){
	T s=0; int f=0;
	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
	do s=(s<<1)+(s<<3)+(IO^'0');
	while(isdigit(IO=getchar()));
	return f?-s:s;
}

const int N=5e5+10;

int n,m,q,p;
struct Interval{
	ll l,r,x,y;
	Interval(ll a,ll b){ 
		x=a,y=b;
		l=(x*(p-1)+p-1)/p,r=y;
	}
	void Add(ll c){
		x+=c,y+=c;
		l=(x*(p-1)+p-1)/p,r=y;
	}
	bool operator & (const Interval &__) const { return min(r,__.r)>=max(l,__.l)-1; }
	Interval operator + (const Interval &__) const { return Interval(min(x,__.x),max(y,__.y)); }
	bool operator < (const ll &x) const {
		return r<x;
	}
};
vector <Interval> dp[N];

struct Edge{
	int to,nxt; ll w;
} e[N];
int head[N],ecnt;
void AddEdge(int u,int v,ll w){
	e[++ecnt]=(Edge){v,head[u],w};
	head[u]=ecnt;
}
void Trans(vector <Interval> &x,vector <Interval> y,ll c){
	for(auto &i:y) i.Add(c);
	vector <Interval> res;
	int p1=0,p2=0,s1=x.size(),s2=y.size();
	while(p1<s1 || p2<s2) {
		if(p1<s1 && (p2==s2 || x[p1].l<=y[p2].l)) {
			if(res.size() && *res.rbegin()&x[p1]) res[res.size()-1]=*res.rbegin()+x[p1++];
			else res.pb(x[p1++]);
		} else {
			if(res.size() && *res.rbegin()&y[p2]) res[res.size()-1]=*res.rbegin()+y[p2++];
			else res.pb(y[p2++]);
		}
	}
	x=res;
}

int main(){
	rep(kase,1,rd()) {
		n=rd(),m=rd(),q=rd(),p=rd();
		rep(i,1,n) head[i]=ecnt=0;
		rep(i,1,m){
			int u=rd(),v=rd(); ll w=rd<ll>();
			AddEdge(u,v,w);
		}
		rep(i,1,n) dp[i].clear();
		dp[1].pb(Interval(0,0));
		rep(u,1,n) {
			for(int i=head[u];i;i=e[i].nxt) {
				Trans(dp[e[i].to],dp[u],e[i].w);
			}
		}
		while(q--){
			int x=rd(); ll y=rd<ll>();
			auto p=lower_bound(dp[x].begin(),dp[x].end(),y);
			if(p!=dp[x].end() && p->l<=y) putchar('1');
			else putchar('0');
		}
		puts("");
	}
}

标签:ROI,20,log,19,ll,int,frac,dp,const
来源: https://www.cnblogs.com/chasedeath/p/14406118.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有