[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
",ans[i]);
157     return 0;
158 }
原文地址:https://www.cnblogs.com/--HPY-7m/p/12767009.html