第二段代码是正确地;
#include<iostream> #include<sstream> #include<algorithm> #include<cstdio> #include<string.h> #include<cctype> #include<string> #include<cmath> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; const int INF=15003; struct Tree { int left; int right; int mark; int Max; } tree[INF<<2]; int create(int root,int left,int right) { tree[root].left=left; tree[root].right=right; if(left==right) { return tree[root].Max=0; } int a,b,middle=(left+right)>>1; a=create(root<<1,left,middle); b=create(root<<1|1,middle+1,right); return tree[root].Max=max(a,b); } void update_mark(int root) { if(tree[root].mark) { tree[root].Max+=tree[root].mark; if(tree[root].left!=tree[root].right) { tree[root<<1].mark+=tree[root].mark; tree[root<<1|1].mark+=tree[root].mark; } tree[root].mark=0; } } int calculate(int root,int left ,int right) { update_mark(root); if(tree[root].left>right||tree[root].right<left) return 0; if(tree[root].left>=left&&tree[root].right<=right) { return tree[root].Max; } int a,b; a=calculate(root<<1,left,right); b=calculate(root<<1|1,left,right); return max(a,b); } int update(int root,int left,int right,int val) { update_mark(root); if(tree[root].left>right||tree[root].right<left) return tree[root].Max; if(tree[root].left>=left&&tree[root].right<=right) { tree[root].mark+=val; update_mark(root); return tree[root].Max; } int a=update(root<<1,left,right,val); int b=update(root<<1|1,left,right,val); return tree[root].Max=max(a,b); } int main() { int L; while(scanf("%d",&L)!=EOF) { create(1,0,L); int x,y,z; while(scanf("%d%d%d",&x,&y,&z)!=EOF) { if(x>y) swap(x,y); if(x!=-1) { update(1,x,y,z); } else break; } int k=calculate(1,0,L); int locl,locr; for(int i=0; i<=L;i++) { if(calculate(1,i,i)==k) { locl=i; break; } } for(int i=L;i>=0;i--) { if(calculate(1,i,i)==k) { locr=i; break; } } printf("%d,%d\n",locl,locr); } return 0; } /* 10 1 2 3 0 0 3 5 8 4 0 0 3 2 2 2 -1 1 3 */
</pre><pre name="code" class="cpp">正确 代码:
<pre name="code" class="cpp">#include<stdio.h> struct Tree { int left,right,cover; } tree[15000<<2]; int covered=0; void create(int root,int left,int right) { tree[root].left=left; tree[root].right=right; tree[root].cover=0; if(right==left) return ; int mid=(left+right)>>1; create(root<<1,left,mid); create(root<<1|1,mid+1,right); } void update(int root,int left,int right,int val) { if(left<=tree[root].left&&tree[root].right<=right) { tree[root].cover+=val; return ; } int m=(tree[root].left+tree[root].right)>>1; if(m>=left)update(root<<1,left,right,val); if(m<right)update(root<<1|1,left,right,val); } void calculate(int root,int x) { covered+=tree[root].cover; if(tree[root].left==tree[root].right) return ; int m=(tree[root].left+tree[root].right)>>1; if(m>=x) calculate(root<<1,x); else calculate(root<<1|1,x); } int main() { int L; while(scanf("%d",&L)!=EOF) { create(1,0,L); int x,y,z; while(scanf("%d%d%d",&x,&y,&z)) { if(x==-1) break; update(1,x,y,z); } int loc1, loc2,Max=0; for(int i=0; i<=L; i++) { covered=0; calculate(1,i); if(covered>Max) { Max=covered; loc1=i; } } for(int i=L,Max=0; i>=0; i--) { covered=0; calculate(1,i); if(covered>Max) { Max=covered; loc2=i; } } printf("%d %d\n",loc1,loc2); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
zoj 3573 Under Attack(线段树 标记法 最大覆盖数)
原文地址:http://blog.csdn.net/lsgqjh/article/details/46801867