1. 程式人生 > >Educational Codeforces Round 44 (Rated for Div. 2)+E. Pencils and Boxes+樹狀數組

Educational Codeforces Round 44 (Rated for Div. 2)+E. Pencils and Boxes+樹狀數組

namespace 超過 closed .com 樹狀數組 最小 %d lse pre

題目鏈接:E. Pencils and Boxes

題意:N 個數,要求分成任意堆,要求每一堆只要有K個,同一堆中任意數之間差值不能超過d;

題解:用樹狀數組。排一下序然後從後面開始找,以當前數為最小值看能否成堆,要成堆的話要求i+k,到第一個大於a[i]+d的位置之間有能夠成堆的位置。(這裏判斷的時候樹狀數組一減看是否大於0就可以了)註意初始化時在n+1的位置加1.

技術分享圖片
 1 #include<bits/stdc++.h>
 2 #include <iostream>
 3 #include <string.h>
 4 #include <algorithm>
 5
#include <stdio.h> 6 #include <math.h> 7 #define ll long long 8 #define pb push_back 9 using namespace std; 10 const int N=800010; 11 const int INF=1<<30; 12 const int inf=0x3f3f3f3f; 13 const int maxn=5e5+10; 14 const int mod=1e9+7; 15 int n,k,d; 16 int lowbit(int x) 17 {
18 return x&(-x); 19 } 20 int a[maxn],b[maxn]; 21 bool v[maxn]; 22 int add(int x) 23 { 24 while(x<=n+1) 25 { 26 b[x]++;x+=lowbit(x); 27 } 28 } 29 int get(int x) 30 { 31 int ans=0; 32 while(x>0) 33 { 34 ans+=b[x];x-=lowbit(x); 35 }
36 return ans; 37 } 38 int main() 39 { 40 scanf("%d %d %d ",&n,&k,&d); 41 for(int i=1;i<=n;i++) 42 { 43 scanf("%d",&a[i]); 44 } 45 sort(a+1,a+1+n); 46 add(n+1); 47 for(int i=n-k+1;i>=1;i--) 48 { 49 int pos=upper_bound(a+1,a+1+n,a[i]+d)-a; 50 if(pos>=i+k-1&&get(pos)-get(i+k-1)>0) 51 { 52 v[i]=true;add(i); 53 } 54 } 55 if(v[1])printf("YES\n"); 56 else printf("NO\n"); 57 return 0; 58 }
View Code

Educational Codeforces Round 44 (Rated for Div. 2)+E. Pencils and Boxes+樹狀數組