尺取法Codeforces 985E Pencils and Boxes (複習一下尺取法)再次開啓咕咕咕之旅

去吧皮卡丘
Educational Codeforces Round 44 (Rated for Div. 2)
題意:給定n,k,d,表示給你n支鉛筆,每支有一個權值v。現在讓你把n支筆放入一些盒子中(盒子數量可以無窮大),每個盒子中至少有k支筆,而且每個盒子中的最大筆的值與最小筆的值不超過d。問你能否找到一個合法的放法,可以輸出"YES",否則輸出"NO"。
思路:排序是不可能的啦,這輩子都不可能排序的(纔怪),因爲有最大值和最小值差值的關係,肯定是要排序的(真香)。這個題有三個要點1.每個箱子裏能放的筆越多越好,所以在尺取法的時候,對於每一個起點終點越靠後越好,2.而維護過的終點不需要維護第二遍,所以設定一個指針讓他持續++就可以了3.當一個終點符合的時候下一個點可以作爲起點。
瞭解這三個要點就可以愉快的寫題題啦(嘔)
(浙江省賽真的已經在補了,別打了,別打了,主要是權值線段樹還在學,啊啊,我知道我弱了,別打了,再打就鞭屍了,對對還有矩陣快速冪一直都這麼垃圾,“上次林大題你瞅你那死出” 落寞的哭泣ing,,,): (😭

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define pb push_back
#define fi first
#define se second
#define yes puts("YES")
#define no puts("NO")
#define ios ios::sync_with_stdio(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const LL N = 5e5+9,M=5e4;
const LL inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
LL qp(LL x,LL y){LL ans=1;x%=mod;while(y){if(y&1)ans=ans*x%mod;x=x*x%mod;y>>=1;}return ans;}
LL inv(LL x){return qp(x,mod-2);}
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
///head
int n, k, d;
int a[N], ac[N], st[N];
int main() {
    while(~scanf("%d %d %d",&n , &k, &d)){
        memset(st , 0 , sizeof st);
        memset(ac , 0 , sizeof st);
        for(int i = 1 ;i <= n ;i ++){
            scanf("%d", &a[i]);
        }
        sort(a + 1 , a + n + 1);
        st[1] = 1;
        ac[0] = 1;
        int e = 1;
        for(int i = 1 ; i <= n ; i ++){
            if(st[i]){
                while(a[e] - a[i] <= d && e <= n){
                    if(e - i + 1 >= k){
                        ac[e] = 1;
                        st[e + 1] = 1;
                    }
                    e ++;
                }
            }
        }
        if(ac[n]) yes;
        else no;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章