FZU 1608 Huge Mission

64 篇文章 0 订阅
54 篇文章 0 订阅

http://acm.fzu.edu.cn/problem.php?pid=1608
题目的意思很简单,就是问在所给的时间段内的最大的工作量,考察的是线段树,下面是偶写的不怎么样的Pascal代码
跑了3S+...无语,C++ 1S内..寒~
插入的时候完全覆盖才插入,最后来次dfs更新,统计元区间的值就OK
  1. type Segment=record
  2.     L,R,tLen:longint;
  3. end;
  4. var
  5. ans:longint;
  6. flag:array [0..1000001of boolean;
  7. seg:array [0..1000001of Segment;
  8. procedure mkseg(L,r,node:longint);
  9. var
  10. mid:longint;
  11. begin
  12.     Mid:=(L+R) div 2;
  13.     flag[node]:=true;
  14.     seg[node].L:=L;
  15.     seg[node].R:=R;
  16.     seg[node].tLen:=0;
  17.     if(Mid-L>=1)then mkseg(L,Mid,2*node);
  18.     if((R-Mid>=1)and(Mid<>L))then mkseg(Mid,R,2*node+1);    
  19. end;
  20. procedure ins(node,L,R,val:longint);
  21. var 
  22. tm:longint;
  23. begin
  24.     if((flag[node]=false)or(seg[node].tLen>=val))then exit;
  25.     if((L<=seg[node].L)and(seg[node].R<=R)) then begin
  26.      if(val>seg[node].tLen)then seg[node].tLen:=val;
  27.         exit;
  28.     end;
  29.     tM:=(seg[node].L+seg[node].R) div 2;
  30.     if(R<=tM) then
  31.         ins(2*node,L,R,val)
  32.     else
  33.     if(L>=tM) then
  34.         ins(2*node+1,L,R,val)
  35.     else
  36.         begin 
  37.             ins(2*node,L,tM,val);ins(2*node+1,tM,R,val);
  38.         end;
  39. end;
  40. procedure update(node:longint);
  41. begin
  42.     if(seg[node].R=seg[node].L+1)then
  43.         inc(ans,seg[node].tLen)
  44.     else
  45.         begin
  46.             if(flag[2*node]=true)then begin
  47.                 if(seg[node].tLen>seg[2*node].tLen)then
  48.                         seg[2*node].tLen:=seg[node].tLen;
  49.                     update(2*node);
  50.                 end;
  51.             if(flag[2*node+1]=true)then begin
  52.                     if(seg[node].tLen>seg[2*node+1].tLen)then
  53.                         seg[2*node+1].tLen:=seg[node].tLen;
  54.                     update(2*node+1);
  55.             end;
  56.         end;
  57. end;
  58. var
  59. n,k,l,r,val,i:longint;
  60. begin
  61.     while not eof do begin
  62.     readln(n,k);
  63.         fillchar(flag,sizeof(flag),false);
  64.             mkseg(0,n,1);
  65.             for i:=1 to k do begin
  66.                 readln(l,r,val);
  67.                 ins(1,l,r,val);
  68.             end;
  69.             ans:=0;
  70.             update(1);
  71.             writeln(ans);
  72.     end;
  73. end.

如果上面的代码看的还是很别扭那下面是C++的

  1. #include <iostream>
  2. using namespace std;
  3. int ans;
  4. bool flag[1000001];
  5. struct Segment
  6. {
  7.     int L,R,tLen;
  8. }seg[1000001];
  9. inline void make(int L,int R,int node)
  10. {
  11.     int Mid=(L+R)/2;
  12.     flag[node]=true;
  13.     seg[node].L=L;
  14.     seg[node].R=R;
  15.     seg[node].tLen=0;
  16.     if(Mid-L>=1)make(L,Mid,2*node);
  17.     if(R-Mid>=1&&Mid!=L)make(Mid,R,2*node+1);   
  18. }
  19. inline void insert(int node,int L,int R,int val)
  20. {
  21.     if(!flag[node]||seg[node].tLen>=val)return;
  22.     if(L<=seg[node].L&&seg[node].R<=R)//完全覆盖
  23.     {
  24.         if(val>seg[node].tLen)seg[node].tLen=val;
  25.         return;
  26.     }
  27.     int tM=(seg[node].L+seg[node].R)/2;
  28.     if(R<=tM)
  29.         insert(2*node,L,R,val);
  30.     else
  31.     if(L>=tM)
  32.         insert(2*node+1,L,R,val);
  33.     else
  34.         insert(2*node,L,tM,val),insert(2*node+1,tM,R,val);
  35. }
  36. inline void update(int node)
  37. {
  38.     if(seg[node].R==seg[node].L+1)
  39.         ans+=seg[node].tLen;
  40.     else
  41.         {
  42.             if(flag[2*node])
  43.                 {
  44.                     if(seg[node].tLen>seg[2*node].tLen)
  45.                         seg[2*node].tLen=seg[node].tLen;
  46.                 }
  47.             if(flag[2*node+1])
  48.                 {
  49.                     if(seg[node].tLen>seg[2*node+1].tLen)
  50.                         seg[2*node+1].tLen=seg[node].tLen;
  51.                 }
  52.             if(flag[2*node])update(2*node);
  53.             if(flag[2*node+1])update(2*node+1);
  54.         }
  55. }
  56. int main()
  57. {
  58.     int n,k,l,r,val;
  59.     //OPEN
  60.     while(scanf("%d%d",&n,&k)!=EOF)
  61.         {
  62.             memset(flag,false,sizeof(flag));
  63.             make(0,n,1);
  64.             while(k--)
  65.                 {
  66.                     scanf("%d%d%d",&l,&r,&val);
  67.                     insert(1,l,r,val);//insert datas;
  68.                 }
  69.             ans=0;
  70.             update(1);
  71.             printf("%d/n",ans);
  72.         }
  73.     return 0;
  74. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值