hdu2795billboard线段树

题目链接:http://icpc.njust.edu.cn/Problem/Hdu/2795/

题目大意:有一块长方形木板,从上到下被分成h*w的区域,现要将n个长条放进这些区域中,要求从上到下只要后面空余位置够就放,紧贴最左侧放置。由于给出长度为C的长条之后只要一个区间[l,r]的最大值大于等于C我们就可以放置,所以考虑用线段树维护区间的最大值。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define dbg(args) cout<<#args<<":"<<args<<endl;
17 #define pb(i) push_back(i)
18 #define ppb(x) pop_back(x)
19 #define inf 0x3f3f3f3f
20 #define maxn 200005
21 int n,m,h,w;
22 int t[maxn<<2];
23 void build(int l,int r,int rt)
24 {
25     if(l==r){
26         t[rt]=w;//初始最大值都是栏的长度 
27         return;
28     }
29     int mid =l+r>>1;
30     build(lson);
31     build(rson);
32     t[rt]=max(t[rt<<1],t[rt<<1|1]);
33  } 
34  void update(int l,int r,int rt,int C)
35  {
36      if(l==r)
37      {
38          t[rt]-=C;
39          pf("%d\n",l);
40          return;
41      }
42      int mid=l+r>>1;
43      if(C<=t[rt<<1]) update(lson,C);//优先往左子树走,保证最终放在一个区间最大值比C大的区间的最左端 
44      else update(rson,C);
45      t[rt]=max(t[rt<<1],t[rt<<1|1]);
46  }
47 int main()
48 {
49     //freopen("input.txt","r",stdin);
50     //freopen("output.txt","w",stdout);
51     std::ios::sync_with_stdio(false);
52     while(scanf("%d%d%d",&h,&w,&n)==3)
53     {
54         if(h>n)h=n;//最多粘贴n行
55         build(1,h,1);
56     //    dbg(t[1]);
57         int x; 
58         while(n--)
59         {
60             scan(x);
61             if(x>t[1])pf("-1\n");//最大的位置容不下它
62             else update(1,h,1,x);
63         }    
64     }
65     
66  } 

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/12442705.html
今日推荐