您的位置:首页 > 其它

【bzoj3476-懒惰的奶牛】线段树

2016-11-01 21:10 127 查看


题解:

感觉这题和别人的做法不一样。。。呵呵呵。。。调了一百年。。

设家坐标为(a,b),对于每个点(x,y),可以转化为|a-x|+|b-y|<=k

对于每个点,它的影响范围是一个菱形(也就是一个正方形啦。。),也就是一个图上有若干个正方形。



然后我就把这个坐标轴选择了45度。

好难画不画了,正交分解一下就可以了。

然后题目就转化成正方形各种交里的最大值。



正方形有x和y两个元素,但是很明显我们只能维护一个。。

所以我以x轴建立线段树,对于每个正方形按照y从小到大排序。

维护一个指针j,表示当前前j个正方形已经和现在在处理的第i个正方形没有交集。每次都要先把j更新(看看它是否能后移)。

然后我们在当前正方形的两端a[i].x~a[i].y这一段+a[i].d

每个点维护当前的和d以及该区间的最大值mx。每次做完之后,用t[1].mx更新答案。

1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<ctime>
6 #include<queue>
7 #include<algorithm>
8 using namespace std;
9
10 const int N=1001000,INF=(int)1e9;
11 int n,K,L,tl,ans;
12 struct trnode{
13     int l,r,lc,rc,d,mx,lazy;
14 }t[4*N];
15 struct node{
16     int x,y,d;
17 }a
;
18
19 bool cmp(node x,node y){return x.y<y.y;}
20 int maxx(int x,int y){return x>y ? x:y;}
21 int minn(int x,int y){return x<y ? x:y;}
22
23 int read()
24 {
25     int x=0,f=1; char ch=getchar();
26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
27     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
28     return x*f;
29 }
30
31 int bt(int l,int r)
32 {
33     int x=++tl;
34     t[x].l=l;t[x].r=r;
35     t[x].lc=t[x].rc=0;
36     t[x].mx=0;t[x].d=0;
37     t[x].lazy=0;
38     if(l<r)
39     {
40         int mid=(l+r)/2;
41         t[x].lc=bt(l,mid);
42         t[x].rc=bt(mid+1,r);
43     }
44     return x;
45 }
46
47 void pd(int x)
48 {
49     if(t[x].lazy==0) return ;
50     int d=t[x].lazy,lc=t[x].lc,rc=t[x].rc;
51     t[x].lazy=0;
52     t[x].d+=d;
53     t[x].mx+=d;
54     if(lc) t[lc].lazy+=d;
55     if(rc) t[rc].lazy+=d;
56 }
57
58 void change(int x,int l,int r,int d)
59 {
60     pd(x);
61     if(t[x].l==l && t[x].r==r)
62     {
63         t[x].lazy+=d;
64         pd(x);
65         return ;
66     }
67     int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2;
68     if(r<=mid) change(lc,l,r,d);
69     else if(l>mid) change(rc,l,r,d);
70     else
71     {
72         change(lc,l,mid,d);
73         change(rc,mid+1,r,d);
74     }
75     pd(x);pd(lc);pd(rc);
76     t[x].mx=maxx(t[lc].mx,t[rc].mx);
77 }
78
79 int main()
80 {
81     // freopen("a.in","r",stdin);
82     // freopen("me.out","w",stdout);
83     freopen("lazy.in","r",stdin);
84     freopen("lazy.out","w",stdout);
85     n=read();K=read();
86     // scanf("%d%d",&n,&K);
87     int x,y,tx,ty,nx=INF,ny=INF,mx=0;tl=0;L=2*K;
88     for(int i=1;i<=n;i++)
89     {
90         a[i].d=read();x=read();y=read();
91         // scanf("%d%d%d",&a[i].d,&x,&y);
92         tx=x,ty=y+K;
93         a[i].x=tx-ty;
94         a[i].y=tx+ty;
95
96         nx=minn(nx,a[i].x);
97         ny=minn(ny,a[i].y);
98     }
99     for(int i=1;i<=n;i++)
100     {
101         a[i].x-=nx-1;
102         a[i].y-=ny-1;
103         mx=maxx(mx,a[i].x);
104     }
105     mx+=10;ans=0;
106     sort(a+1,a+1+n,cmp);
107     bt(1,mx);
108     int j=1;
109     change(1,a[1].x,minn(mx,a[1].x+L),a[1].d);
110     ans=maxx(ans,t[1].mx);
111     for(int i=2;i<=n;i++)
112     {
113         while(j<i && a[i].y-L>a[j].y)
114         {
115             change(1,a[j].x,minn(mx,a[j].x+L),-a[j].d);
116             ans=maxx(ans,t[1].mx);
117             j++;
118         }
119         change(1,a[i].x,minn(mx,a[i].x+L),a[i].d);
120         ans=maxx(ans,t[1].mx);
121     }
122     printf("%d\n",ans);
123     return 0;
124 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: