博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5861 Road(线段树 区间修改 单点查询)
阅读量:6617 次
发布时间:2019-06-25

本文共 3298 字,大约阅读时间需要 10 分钟。

Road

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1132    Accepted Submission(s): 309

Problem Description
There are n villages along a high way, and divided the high way into n-1 segments. Each segment would charge a certain amount of money for being open for one day, and you can open or close an arbitrary segment in an arbitrary day, but you can open or close the segment for just one time, because the workers would be angry if you told them to work multiple period.
We know the transport plan in the next m days, each day there is one cargo need to transport from village 
ai to village bi, and you need to guarantee that the segments between ai and bi are open in the i-th day. Your boss wants to minimize the total cost of the next m days, and you need to tell him the charge for each day.
(At the beginning, all the segments are closed.)
Input
Multiple test case. For each test case, begins with two integers n, m(1<=n,m<=200000), next line contains n-1 integers. The i-th integer 
wi(1<=wi<=1000) indicates the charge for the segment between village i and village i+1 being open for one day. Next m lines, each line contains two integers ai,bi(1ai,bi<=n,ai!=bi).
Output
For each test case, output m lines, each line contains the charge for the i-th day.
Sample Input
4 3 1 2 3 1 3 3 4 2 4
Sample Output
3 5 5
Author
BUPT
Source
【题意】n个点将一条线段分成n-1份,点的编号从左往右1~n,每条路你只能打开一次,打开后每天都收费,当然打开后你也可以选择关上,但是关上后这条路就再也不能打开了。每条线段有一个Cost值,然后Q次询问,没次询问给出两个点U,V,表示从U,到V,你必须保证U->V上的线段都打开才能过去,然后问你在保证你能过去的情况下,每天的最小花费。
【分析】要想避免无用的花费,那么我们可以对于每条路,他第一次使用就把它打开,他最后一条使用完过后就把它关了,因为这条路再也不用了。那么我们可以先找到每条路的打开时间和关闭时间,这个类似于区间覆盖,所以我们可以用线段树来维护,复杂度NlogN。然后就是要找到当前天,有多少路是打开的,这个我们可以用一个类似于莫队的做法,假设对于前一天我们已经知道了答案,那么对于今天,我们只要知道有多少条路是今天打开的和关闭的,那么我们今天就可以根据前一天的来推,复杂度O(M);
#include 
#define mp make_pair#define pb push_back#define met(a,b) memset(a,b,sizeof a)#define inf 10000000using namespace std;typedef long long ll;typedef pair
pii;const int N = 4e5+5;const double eps = 1e-8;int n,sum[2*N],m;int lazy[2*N],a[N],mi[N*2],ma[N*2];vector
st[N],en[N];struct man{ int u,v;}q[N];void init(){ for(int i=0;i
=L&&r<=R) { mi[pos]=min(mi[pos],val); ma[pos]=max(ma[pos],val); return; } int mid=(l+r)>>1; pushDown(pos); if(L<=mid) update(L,R,val,l,mid,pos<<1); if(mid
<<1|1);}void query(int l,int r,int pos) { if(l==r){ if(mi[pos]!=inf)st[mi[pos]].pb(l); if(ma[pos]!=0)en[ma[pos]+1].pb(l); return; } int mid=(l+r)>>1; pushDown(pos); query(l,mid,pos<<1); query(mid+1,r,pos<<1|1); return;}void build(int l,int r,int pos){ mi[pos]=inf; ma[pos]=0; if(l==r){ return; } int mid=(l+r)/2; build(l,mid,pos*2); build(mid+1,r,pos*2+1);}int main() { int ll,rr,cnt=0; while(~scanf("%d%d",&n,&m)){ init(); build(1,n-1,1); for(int i=1;i
q[i].v)swap(q[i].u,q[i].v); update(q[i].u,q[i].v-1,i,1,n-1,1); } query(1,n-1,1); int ans=0; for(int i=1;i<=m;i++){ for(int x:st[i]){ ans+=a[x]; } for(int x:en[i]){ ans-=a[x]; } printf("%d\n",ans); } } return 0;}

 

转载于:https://www.cnblogs.com/jianrenfang/p/6784446.html

你可能感兴趣的文章
批量操作Windows域用户
查看>>
shell脚本 接受用户参数 记录一下
查看>>
健脾祛湿的中成药有哪些?
查看>>
mongodb Index(2)
查看>>
IIS下支持下载.exe文件
查看>>
桌面快捷方式打不开怎么办?用金山网盾可修复
查看>>
CXF WebService Hello World
查看>>
市场调研报告:企业级信息防泄漏大趋势
查看>>
济南企业短信平台的价格如何?
查看>>
requirejs
查看>>
远程控制工具VNC的安装使用
查看>>
安装vmware tools错误解决办法
查看>>
Centos版的安装docker-registry私有仓库
查看>>
redis故障处理 process is already running or crashed
查看>>
find命令详解
查看>>
cxf 学习总结
查看>>
Linux之sysctl.conf与limits.conf优化配置
查看>>
《Android 4游戏高级编程(第2版)》书评
查看>>
min-width与max-width
查看>>
jdbc oracle clob blob long类型数据
查看>>