[BZOJ2794][Poi2012]Cloakroom

2794: [Poi2012]Cloakroom

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 167  Solved: 119
[Submit][Status][Discuss]

Description

有n件物品,每件物品有三个属性a[i], b[i], c[i] (a[i]<b[i])。
再给出q个询问,每个询问由非负整数m, k, s组成,问是否能够选出某些物品使得:
1. 对于每个选的物品i,满足a[i]<=m且b[i]>m+s。
2. 所有选出物品的c[i]的和正好是k。

 

Input

第一行一个正整数n (n<=1,000),接下来n行每行三个正整数,分别表示c[i], a[i], b[i] (c[i]<=1,000, 1<=a[i]<b[i]<=10^9)。
下面一行一个正整数q (q<=1,000,000),接下来q行每行三个非负整数m, k, s (1<=m<=10^9, 1<=k<=100,000, 0<=s<=10^9)。

 

Output


输出q行,每行为TAK (yes)或NIE (no),第i行对应第i此询问的答案。

Sample Input

5

6 2 7

5 4 9

1 2 4

2 5 8

1 3 9

5

2 7 1

2 7 2

3 2 0

5 7 2

4 1 5

Sample Output

TAK

NIE

TAK

TAK

NIE

HINT

 

Source

[Submit][Status][Discuss]


先看数据范围,发现q非常的大,所以想到离线处理。

如果离线处理,可以把a的这个条件直接去掉,只需用b和c来DP。

然后就非常简单了。时间复杂度$O(qlogq+nk)$

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 1005
 4 #define M 100010
 5 #define Q 1000100
 6 using namespace std;
 7 inline int read()
 8 {
 9     int x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 int n,q,f[M]={1e9},ans[Q],maxn;
15 struct node{int a,b,c,id;}a[N],b[Q];
16 bool operator<(node x,node y){return x.a<y.a;}
17 int main()
18 {
19     n=read();
20     for(int i=1;i<=n;i++)
21     a[i].c=read(),a[i].a=read(),a[i].b=read();
22     sort(a+1,a+n+1);
23     q=read();
24     for(int i=1;i<=q;i++)
25     b[i].a=read(),b[i].c=read(),b[i].b=read(),
26     b[i].id=i,maxn=max(maxn,b[i].c);
27     sort(b+1,b+q+1);
28     for(int i=1,j=1;i<=q;i++)
29     {
30         while(j<=n&&a[j].a<=b[i].a)
31         {
32             for(int k=maxn;k>=a[j].c;k--)
33             f[k]=max(f[k],min(f[k-a[j].c],a[j].b));
34             j++;
35         }
36         ans[b[i].id]=(f[b[i].c]>b[i].a+b[i].b);
37     }
38     for(int i=1;i<=q;i++)
39     puts(ans[i]?"TAK":"NIE");
40 }
View Code

 

posted @ 2016-02-14 19:52  xuruifan  阅读(544)  评论(0编辑  收藏  举报