[USACO Jan08] 化装晚会

万圣节又到了!Farmer John打算带他的奶牛去参加一个化装晚会,但是,FJ只做了一套能容 下两头总长不超过S(1 <= S <= 1,000,000)的牛的恐怖服装。FJ养了N(2 <= N <= 20,000)头按1..N顺序编号的奶牛,编号为i的奶牛的长度为L_i(1 <= L_i <= 1,000,000)。如果两头奶牛的总长度不超过S,那么她们就能穿下这套服装。

FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。

程序名: costume

输入格式:

  • 第1行: 2个用空格隔开的整数:N 和 S
  • 第2..N+1行: 第i+1为1个整数:L_i

输入样例 (costume.in):

4 6
3
5
2
1


输出格式:

  • 第1行: 输出1个整数,表示FJ可选择的所有方案数。注意奶牛顺序不同的两种方案是被视为相同的

输出样例 (costume.out):

4

输出说明:

4种选择分别为:奶牛1和奶牛3;奶牛1和奶牛4;奶牛2和奶牛4;奶牛3和奶牛4。

 

 

简单的单调队列。

 1 #include<iostream>
 2 #include<fstream>
 3 using namespace std;
 4 ifstream fin("costume.in");
 5 ofstream fout("costume.out");
 6 
 7 int n,s,h[20005],tot[20005]={0};
 8 
 9 void Quick(int l,int r){
10      if(l>=r) return ;
11      int i=l,j=r,mid=h[(l+r)/2];
12      while(i<=j)
13      {
14        while(h[i]<mid) i++;
15        while(h[j]>mid) j--;
16        if(i<=j) {swap(h[i],h[j]);i++;j--;}
17                 }
18      Quick(l,j);
19      Quick(i,r);
20      }
21 
22 int main()
23 {
24     fin>>n>>s;
25     
26     for(int i=1;i<=n;++i) fin>>h[i];
27     
28     Quick(1,n);
29     
30     int l=1,r=2;
31     while(h[l]+h[r]<=s&&r<=n) tot[l]++,r++;
32     r--;
33     l=2;
34     while(l<r&&r<=n)
35     {
36       tot[l]+=tot[l-1]-1;
37       while(h[l]+h[r]>s&&r>l) {tot[l]--;r--;}
38       l++;
39                }
40     
41     int ans=0;
42     for(int i=1;i<=n;++i)
43     ans+=tot[i];
44     
45     fout<<ans<<endl;
46     
47     return 0;
48     
49     }
posted on 2012-10-29 19:51  怡红公子  阅读(937)  评论(0编辑  收藏  举报