1. 程式人生 > >【POJ 2482】Stars in your window

【POJ 2482】Stars in your window

click turn sca 變化 file char 亮度 算法 mes

【原題題面】傳送門

【題面大意】

給出每顆星星的坐標和亮度,在h,w的矩形範圍內,內圈住的星星的最大亮度和。(邊界上的星星不算)

【題解大意】

如何轉化成掃描線問題?
將每個星星能夠產生貢獻的範圍設為矩形
星星位於產生貢獻的矩形的某個固定位置
這樣產生貢獻的計算才不重不漏。

具體操作:

同樣將每顆星星的用結構體(四元體)記錄。

每顆星星照例要用兩個四元組儲存,分別記錄正貢獻和負貢獻

線段樹記錄縱坐標的c值。

查詢任意區間長度為H,[i,i+H-1]中的和的最大值得出答案。

【code】

技術分享圖片
#include <iostream>
#include <cstdio>
#include 
<cstring> #include <algorithm> using namespace std; #define File "stars" #define ll long long inline void file(){ freopen(File".in","r",stdin); freopen(File".out","w",stdout); } inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<0||ch>9){if(ch==
-)f=-1; ch=getchar();} while(ch>=0&&ch<=9){x=(x<<1)+(x<<3)+ch-0; ch=getchar();} return x*f; } const int mxn = 1e4+5; int n,W,H; struct T{ int l,r,dat,tg; }tr[mxn<<3]; struct P{ int x,y1,y2,c; bool operator <(const P t) const {
return x == t.x ? c < t.c : x < t.x; } }p[mxn<<1]; int a[mxn<<1]; #define ls p<<1 #define rs p<<1|1 inline void B(int p,int l,int r){ tr[p].l = l,tr[p].r = r; tr[p].dat = tr[p].tg = 0; if(l == r) return; int mid = l+r >>1; B(ls,l,mid),B(rs,mid+1,r);//!!! } inline void push(int p){ int tg = tr[p].tg; if(tg){ tr[ls].tg += tg; tr[rs].tg += tg; tr[ls].dat += tg; tr[rs].dat += tg; tr[p].tg = 0; } } inline void U(int p,int l,int r,int c){ if(l <= tr[p].l && tr[p].r <= r){ tr[p].dat += c; tr[p].tg += c; return; } push(p); int mid = tr[p].l+tr[p].r >>1; if(l <= mid) U(ls,l,r,c); if(r > mid) U(rs,l,r,c); tr[p].dat = max(tr[ls].dat,tr[rs].dat); } int main(){ // file(); while(~scanf("%d%d%d",&n,&W,&H)){ // n = read(),W = read(),H = read(); for(int i = 1;i <= n; ++i){ int x,y,c; x = read(),y = read(),c = read(); // double x,y; int c; // scanf("%lf %lf %d",&x,&y,&c); int id = i<<1; a[id-1] = y,a[id] = y+H-1; //儲存y值 p[id-1].x = x,p[id].x = x+W; p[id-1].y1 = p[id].y1 = y; p[id-1].y2 = p[id].y2 = y+H-1; p[id-1].c = c,p[id].c = -c; } n <<= 1; sort(a+1,a+n+1);//按y值排序,離散化 int m = unique(a+1,a+n+1)-(a+1); for(int i = 1;i <= n; ++i){ p[i].y1 = lower_bound(a+1,a+m+1,p[i].y1)-a; p[i].y2 = lower_bound(a+1,a+m+1,p[i].y2)-a; } sort(p+1,p+n+1); B(1,1,m); int ans = 0; for(int i = 1;i <= n; ++i){ int y1 = p[i].y1,y2 = p[i].y2,c = p[i].c; U(1,y1,y2,c); ans = max(ans,tr[1].dat); } cout << ans << endl; } return 0; } /* 3 5 4 1 2 3 2 3 2 6 3 1 3 5 4 1 2 3 2 3 2 5 3 1 */ /* 小數據點過了但大數據點沒過 可能是: 1.沒開ll或double爆精度 2.算法本身有bug 3.tle變成了wa 4.mle變成了wa 5.數組邊界和更新 6.變量的初值和變化 */
View Code

【POJ 2482】Stars in your window