2B错误,线段树开了2倍空间, 检查到死,改成4倍空间直接AC,太伤了,线段树太弱了。
线段树:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define Mid int m = (l+r) >> 1; const int maxn = 100005; const int inf = 1e9; int n, k; int a[maxn]; int dp[maxn]; struct segtree { int sum[maxn<<2]; void pushUp(int rt) { sum[rt] = min(sum[rt<<1], sum[rt<<1|1]); } void build(int l = 0, int r = n, int rt = 1) { sum[rt] = inf; if(l == r) { if(l == 0) sum[rt] = 0; return; } Mid; build(lson); build(rson); pushUp(rt); } void insert(int p, int v, int l = 0, int r = n, int rt = 1) { if(l == r) { sum[rt] = min(sum[rt], v); return; } Mid; if(p <= m) insert(p, v, lson); else insert(p, v, rson); pushUp(rt); } int query(int L, int R, int l = 0, int r = n, int rt = 1) { if(L <= l && r <= R) return sum[rt]; Mid; int ret = inf; if(L <= m) ret = min(ret, query(L, R, lson)); if(R > m) ret = min(ret, query(L, R, rson)); return ret; } void print(int l = 0, int r = n, int rt = 1) { if(l ==r) { printf("%d ", sum[rt]); return; } Mid; print(lson); print(rson); } }T; int main() { // freopen("int.txt", "r", stdin); int i, j, d, cas; scanf("%d", &cas); for(int ca = 1; ca <= cas; ca++) { scanf("%d%d", &n, &k); for(i = 1; i <= n; i++) { scanf("%d", &a[i]); dp[i] = inf; } T.build(); dp[0] = 0; sort(a+1, a+n+1); for(i = 1; i <= n; i++) { j = lower_bound(a+1, a+i+1, a[i]-(k<<1))-a; //printf("i = %d j = %d\n", i, j); if(i-j+1 >= 3) { // puts("YES"); dp[i] = min(dp[i], T.query(j-1, i-3) + 1); T.insert(i, dp[i]); } } if(dp[n] >= inf) dp[n] = -1; printf("Case %d: %d\n", ca, dp[n]); } return 0; }
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define Mid int m = (l+r) >> 1; const int maxn = 100005; const int inf = 1e9; int n, k; int a[maxn]; int dp[maxn]; int Q[maxn]; int main() { // freopen("int.txt", "r", stdin); int i, j, d, cas; scanf("%d", &cas); for(int ca = 1; ca <= cas; ca++) { scanf("%d%d", &n, &k); for(i = 1; i <= n; i++) { scanf("%d", &a[i]); dp[i] = -1; } sort(a+1, a+n+1); dp[0] = 0; int len = k<<1; int s = 0, e = 0; for(i = 1; i <= n; i++) { int t = i-3; if(t >= 0 && ~dp[t]) { while(s < e && dp[Q[e-1]] > dp[t]) e--; Q[e++] = t; } while(s < e && a[Q[s]+1] + len < a[i]) s++; if(s != e) dp[i] = dp[Q[s]]+1; } printf("Case %d: %d\n", ca, dp[n]); } return 0; }