Starry Sky Tree
StarrySkyを解こうとしました.
枝刈りしていないので半分ぐらいTLEします.
#include <cstdio> #include <string.h> #include <algorithm> #define X first #define Y second using namespace std; const int MAXN = 4096; typedef pair<int, int> P; typedef pair<P, int> STAR; int N; int cx[MAXN], cy[MAXN], cl[MAXN]; STAR stars[MAXN]; const int INF = 1 << 29; int sst[MAXN * 2 - 1]; int adt[MAXN * 2 - 1]; void init(){ fill(sst,sst+MAXN*2-1,0); fill(adt,adt+MAXN*2-1,0); } //区間[p,q)に値xを加算 void add(int p, int q, int x, int k, int l, int r){ if(r <= p || q <= l) return; if(p <= l && r <= q){ adt[k] += x; return; } add(p, q, x, 2*k+1, l, (l+r)/2); add(p, q, x, 2*k+2, (l+r)/2, r); sst[k]=max(sst[2*k+1]+adt[2*k+1],sst[2*k+2]+adt[2*k+2]); } int get_max(int p, int q, int k, int l, int r){ if(r <= p || q <= l) return -INF; if(p <= l && r <= q) return sst[k]+adt[k]; int m1, m2; m1 = get_max(p,q,2*k+1,l,(l+r)/2); m2 = get_max(p,q,2*k+2,(l+r)/2,r); return max(m1,m2)+adt[k]; } int conv(int v, int c[MAXN]){ return distance(c,lower_bound(c,c+N,v)); } int main(){ scanf("%d", &N); for(int i = 0; i < N; i++){ int x, y, l; scanf("%d %d %d", &x, &y, &l); stars[i] = STAR(P(x,y),l); cx[i] = x; cy[i] = y; cl[i] = l; } sort(cx,cx+N); sort(cy,cy+N); sort(cl,cl+N); sort(stars, stars+N); int ans = 0; for(int L = 0; L < N; L++){ int lx = 0, rx = 0; init(); for(; rx<N; rx++){ if(cl[L] <= stars[rx].second){ int ry = conv(stars[rx].first.Y, cy) + 1; int ly = conv(stars[rx].first.Y - cl[L], cy); add(ly, ry, 1, 0, 0, MAXN); } for(; cx[rx]-cx[lx] > cl[L]; lx++){ if(cl[L] <= stars[lx].second){ int ry = conv(stars[lx].first.Y, cy) + 1; int ly = conv(stars[lx].first.Y - cl[L], cy); add(ly, ry, -1, 0, 0, MAXN); } } ans = max(ans, get_max(0,MAXN,0,0,MAXN)); } } printf("%d\n", ans); }