标签:contain get acm ram 离散化 大学 scan push 数据
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1258 Accepted Submission(s): 445
#include<bits/stdc++.h> #define lson l,m,k<<1 #define rson m+1,r,k<<1|1 using namespace std; #define maxn 200010 int tree[maxn<<2]; void pushup(int k) { tree[k]=max(tree[k<<1],tree[k<<1|1]); } void build(int l,int r,int k) { if(l==r) { tree[k]=0; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(k); } int query_getmax(int x,int y,int l,int r,int k)//这里是求出最大值 { if(x<=l&&r<=y) return tree[k]; int m=(l+r)>>1; int ans=0; if(x<=m) ans=max(ans,query_getmax(x,y,lson)); if(y>m) ans=max(ans,query_getmax(x,y,rson)); return ans; } void update(int p,int c,int l,int r,int k) { if(l==r) { tree[k]=c; return; } int m=(l+r)>>1; if(p<=m) update(p,c,lson); else update(p,c,rson); pushup(k); } struct point{ int x,y,w; int ha_x,ha_y;//记录离散后的坐标 }a[100005]; bool cmp1(point a,point b) { return a.x<b.x; } bool cmp2(point a,point b) { return a.y<b.y; } bool cmp3(point a,point b) { if(a.x==b.x) return a.y>b.y; return a.x<b.x; } int main() { int n,m; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); int ha=0; build(1,n,1); for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); sort(a+1,a+1+n,cmp1); int haxx=1; for(int i=1;i<=n;i++)//对x坐标得点进行离散化 { a[i].ha_x=haxx; if(a[i+1].x!=a[i].x)haxx++; } int hayy=1; sort(a+1,a+1+n,cmp2); for(int i=1;i<=n;i++)//对y坐标进行离散化 { a[i].ha_y=hayy; if(a[i+1].y!=a[i].y)hayy++; } sort(a+1,a+1+n,cmp3); haxx--,hayy--; for(int i=1;i<=n;i++)//跟一维01背包的更新可像 { if(a[i].ha_y==1) update(a[i].ha_y,a[i].w,1,n,1);//到了最下面,在1的线段树出更新 else { int t=query_getmax(1,a[i].ha_y-1,1,n,1)+a[i].w;//从1到a[i].ha_y 这个区间求出最大值 update(a[i].ha_y,t,1,n,1);//把这个点的最优值储存在a[i].ha_y上 } } cout<<query_getmax(1,n,1,n,1)<<endl; } return 0; }
标签:contain get acm ram 离散化 大学 scan push 数据
原文地址:https://www.cnblogs.com/wpbing/p/9542378.html