http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=604&pid=1002
Accepts: 249
Submissions: 806
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
《4》http://acm.hdu.edu.cn/showproblem.php?pid=1754(简单题)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 200000+10; int num[MAXN]; struct Node { int l, r; int nMax; }segTree[MAXN*4]; void Build(int i, int l, int r) { segTree[i].l=l; segTree[i].r=r; if(l==r) { segTree[i].nMax=num[l]; return; } int mid=(segTree[i].l+segTree[i].r)>>1; Build(i<<1, l, mid); Build(i<<1|1, mid+1, r); segTree[i].nMax=max(segTree[i<<1].nMax, segTree[i<<1|1].nMax); } void Update(int i, int l, int r, int x) { if(segTree[i].l==l&&segTree[i].r==r) { segTree[i].nMax=x; return; } int mid=(segTree[i].l+segTree[i].r)>>1; if(r<=mid) Update(i<<1, l, r, x); else if(l>mid) Update(i<<1|1, l, r, x); else { Update(i<<1, l, mid, x); Update(i<<1|1, mid+1, r, x); } segTree[i].nMax=max(segTree[i<<1].nMax, segTree[i<<1|1].nMax); } int Query(int i, int l, int r) { if(segTree[i].l==l&&segTree[i].r==r) { return segTree[i].nMax; } int mid=(segTree[i].l+segTree[i].r)>>1; if(r<=mid) return Query(i<<1, l, r); else if(l>mid) return Query(i<<1|1, l, r); else return max(Query(i<<1, l, mid), Query(i<<1|1, mid+1, r)); } int main() { int n, m; while(scanf("%d%d", &n, &m)!=EOF) { int i, j, k, a, b; char s[2]; for(i=1; i<=n; i++) scanf("%d", &num[i]); Build(1, 1, n); for(i=0; i<m; i++) { scanf("%s%d%d", s, &a, &b); if(s[0]=='U') Update(1, a, a, b); else printf("%d\n", Query(1, a, b)); } } return 0; }
《5》http://acm.hdu.edu.cn/showproblem.php?pid=2795
线段树, 适用的范围还真广!!。 这个题看到别人能用线段树切, 也是非常的机智。
/*以墙的高度和广告数量的较小值建线段树 , 树中v表示该段中最大空余量,idid表示最大 空余量所在行 (从上开始记)。每次贴广告 先比较空余量, 从上到下,空余足够就贴, 再根据查找到的空余行进行点更新。。。 */ #include<cstdio> #include<algorithm> #include<iostream> using namespace std; const int MAXN = 200000+10; int h, v, n; struct Node { int l, r; int id; int v; }segTree[MAXN*4]; void Build(int i, int l, int r) { segTree[i].l = l; segTree[i].r = r; segTree[i].id = l; segTree[i].v = v; if(l==r) return; int mid=(l+r)>>1; Build(i<<1, l, mid); Build(i<<1|1, mid+1, r); } int Query(int i, int val) { if(segTree[i].v<val) return -1; if(segTree[i].l==segTree[i].r) return segTree[i].id; if(segTree[i<<1].v>=val) return Query(i<<1, val); else return Query(i<<1|1, val); } void Update(int i, int l, int r, int val) { if(segTree[i].l==l&&segTree[i].r==r) { segTree[i].v-=val; return; } int mid=(segTree[i].l+segTree[i].r)>>1; if(r<=mid) Update(i<<1, l, r, val); else if(l>mid) Update(i<<1|1, l, r, val); if(segTree[i<<1].v>segTree[i<<1|1].v) { segTree[i].v = segTree[i<<1].v; segTree[i].id = segTree[i<<1].id; } else { segTree[i].v = segTree[i<<1|1].v; segTree[i].id = segTree[i<<1|1].id; } } int main() { while(scanf("%d%d%d", &h, &v, &n)!=EOF) { int j, k; if(h>n) h = n; Build(1, 1, h); for(int q=0; q<n; q++) { scanf("%d", &k); int t; t = Query(1, k); printf("%d\n",t); if(t!=-1) Update(1, t, t, k); } } return 0; }