[CTSC2016]时空旅行 (线段树分治+凸壳
题意:http://uoj.ac/problem/198
这题看懂了差不多就行,
我就差对每个星球的插入删除区间的维护了,因为不是很懂题目会不会添加了一个星球后来删除了,然后又添加了这种情况
所以我不想写了,对。。。
其他部分我都写好了
1 const int N=(int)5e5+10; 2 3 int dfn[N],sz[N],tot; 4 struct node 5 { 6 int op; 7 int fr,cang,x,c,s; 8 friend bool operator<(node a,node b) 9 { 10 return a.x==b.x?a.x*a.x+a.c<b.x*b.x+b.c:-2*a.x>-2*b.x; 11 } 12 }a[N]; 13 int K(int x){ 14 return -2*a[x].x; 15 } 16 int B(int x){ 17 return a[x].x*a[x].x+a[x].c; 18 } 19 bool Check(int x,int y,int z){//p(l_a&l_b) is on the left of p'(l_b&l_c) 20 return 1ll*(B(x)-B(y))*(K(z)-K(y))<=1ll*(B(y)-B(z))*(K(y)-K(x)); 21 } 22 ll cal(int x,int x0,int c0) 23 { 24 return (x-x0)*(x-x0)+c0; 25 } 26 struct nodeask 27 { 28 int s,x,id; 29 friend bool operator<(nodeask a,nodeask b) 30 { 31 return a.s<b.s; 32 } 33 }q[N]; 34 vector<vector<int> >G(N); 35 void dfs(int x,int fa) 36 { 37 dfn[x]=++tot; 38 sz[x]=1; 39 for(int i=0,SZ=G[x].size();i<SZ;++i) 40 { 41 int to=G[x][i]; 42 if(to==fa)continue; 43 dfs(to,x); 44 sz[x]+=sz[to]; 45 } 46 } 47 48 vector<vector<int> >Seg(N<<2); 49 void update(int L,int R,int val,int l,int r,int rt)//查询区间和 50 { 51 if(L>R)return; 52 if(L<=l&&r<=R){Seg[rt].push_back(val);return;} 53 int mid=(l+r)>>1; 54 if(L<=mid)update(L,R,val,l,mid,ls); 55 if(R> mid)update(L,R,val,mid+1,r,rs); 56 } 57 int is[N]; 58 int line[N],cl; 59 int ask[N],ck; 60 int sk[N],top; 61 int Ans[N]; 62 ll ans[N]; 63 void get() 64 { 65 if(cl<=0||ck<=0)return; 66 sk[top=1]=1; 67 for(int i=2;i<=cl;++i) 68 { 69 if(K(line[i])==K(line[i-1]))continue; 70 while(top>1&&Check(i,sk[top],sk[top-1]))--top; 71 sk[++top]=i; 72 } 73 for(int i=1;i<=top;++i)Ans[i]=line[sk[i]]; 74 for(int i=1,j=1;i<=ck;++i) 75 { 76 if(j==cl) 77 { 78 cout<<cal(q[ask[i]].x,a[line[j]].x,a[line[j]].c)<<endl; 79 ans[q[ask[i]].id]=min(ans[q[ask[i]].id],cal(q[ask[i]].x,a[line[j]].x,a[line[j]].c)); 80 continue; 81 } 82 if(1ll*(-K(ask[i])+K(ask[i+1]))*q[ask[i]].x<=-B(ask[i+1])+B(ask[i])) 83 { 84 cout<<cal(q[ask[i]].x,a[line[j]].x,a[line[j]].c)<<endl; 85 ans[q[ask[i]].id]=min(ans[q[ask[i]].id],cal(q[ask[i]].x,a[line[j]].x,a[line[j]].c)); 86 } 87 else 88 j++; 89 } 90 } 91 92 //nodeask t1[N],t2[N]; 93 void solve(int L,int R,int l,int r,int rt) 94 { 95 if(L>R||l>r)return; 96 for(int i=0,SZ=Seg[rt].size();i<SZ;++i) 97 { 98 int to=Seg[rt][i]; 99 if(a[to].op==0)is[a[to].cang]++; 100 else is[a[to].cang]--; 101 } 102 cl=ck=0; 103 for(int i=0,SZ=Seg[rt].size();i<SZ;++i) 104 { 105 int to=Seg[rt][i]; 106 if(is[a[to].cang]) 107 line[++cl]=to; 108 } 109 for(int i=L;i<=R;++i)ask[++ck]=i; 110 get(); 111 for(int i=0,SZ=Seg[rt].size();i<SZ;++i) 112 { 113 int to=Seg[rt][i]; 114 is[a[to].cang]=0; 115 } 116 if(l==r)return; 117 int mid=l+r>>1; 118 int c1=0,c2=0; 119 for(int i=L;i<=R;++i) 120 { 121 if(q[i].s<=mid)c1++; 122 else c2++; 123 } 124 solve(L,L+c1-1,l,mid,ls); 125 solve(R-c2+1,R,mid+1,r,rs); 126 } 127 128 int plant[N]; 129 int main() 130 { 131 int n,m,c0; 132 sc("%d%d%d",&n,&m,&c0); 133 a[1].op=0; 134 a[1].c=c0; 135 a[1].s=1; 136 for(int i=2;i<=n;++i) 137 { 138 sc("%d",&a[i].op); 139 if(a[i].op==0)sc("%d%d%d%d%d%d",&a[i].fr,&a[i].cang,&a[i].x,&a[i].c,&a[i].c,&a[i].c); 140 else sc("%d%d",&a[i].fr,&a[i].cang); 141 a[i].fr++; 142 a[i].s=i; 143 if(a[i].op==0)plant[a[i].cang]=i; 144 if(a[i].op==1)a[i].x=a[plant[a[i].cang]].x,a[i].c=a[plant[a[i].cang]].c; 145 G[a[i].fr].push_back(i); 146 G[i].push_back(a[i].fr); 147 } 148 for(int i=1;i<=m;++i)sc("%d%d",&q[i].s,&q[i].x),q[i].id=i,q[i].s++; 149 dfs(1,-1); 150 sort(a+1,a+1+n); 151 sort(q+1,q+1+m); 152 for(int i=1;i<=n;++i) 153 update(dfn[a[i].s],dfn[a[i].s]+sz[a[i].s]-1,i,1,n,1); 154 for(int i=0;i<=n;++i)ans[i]=INF; 155 solve(1,m,1,n,1); 156 for(int i=1;i<=n;++i)pr("%lld\n",ans[i]); 157 return 0; 158 }