zoukankan      html  css  js  c++  java
  • CTSC2016 时空旅行

    时空旅行

    题面有点长,放链接了。
    LOJ 题面

    题解

    显然 y,z 没有用。那么要求就是最小化 (x0-xi)2+ci

    一看到二次函数形式就应该想到维护凸包。考虑这个问题的凸包要怎么维护,显然可持久化动态凸包是可行的

    由于每个节点的操作对子树生效,而子树的 DFS 序是连续的,所以可以对 DFS 序做线段树分治。区间修改操作可以在 DFS 的同时解决,主要就是递归和回溯之前的操作,具体见代码。

    然后由于修改互相独立,所以可以先对线段树节点建出凸包。询问先在外层排序后再放进线段树里查询,这样就不用写二分了。

    时间复杂度 O(n log2 n)。

    #include<bits/stdc++.h>
    using namespace std;
    template<class T> T read(){
        T x=0,w=1;char c=getchar();
        for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*w;
    }
    template<class T> T read(T&x){
        return x=read<T>();
    }
    #define co const
    #define il inline
    typedef long long LL;
    
    struct Vector {LL x,y;};
    il bool operator<(co Vector&a,co Vector&b){
    	return a.x!=b.x?a.x<b.x:a.y<b.y;
    }
    il Vector operator-(co Vector&a,co Vector&b){
    	return (Vector){a.x-b.x,a.y-b.y};
    }
    il LL cross(co Vector&a,co Vector&b){
    	return a.x*b.y-a.y*b.x;
    }
    il LL calc(co Vector&a,int x){
    	return (LL)x*x-a.x*x+a.y;
    }
    
    co int N=500000+10;
    int n,m;
    LL X[N],C[N];
    int id[N],to[N],next[N];
    int pos[N],dfn,last[N];
    
    vector<Vector> tree[N<<2];
    int pl[N<<2]; // edit 3: N<<2
    #define lc (x<<1)
    #define rc (x<<1|1)
    void insert(int x,int l,int r,int ql,int qr,co Vector&v){
    //	if(x==1) cerr<<"ins "<<ql<<" "<<qr<<" "<<v.x<<" "<<v.y<<endl;
    	if(ql<=l and r<=qr)
    		return tree[x].push_back(v);
    	int mid=(l+r)>>1;
    	if(ql<=mid) insert(lc,l,mid,ql,qr,v);
    	if(qr>mid) insert(rc,mid+1,r,ql,qr,v);
    }
    void dfs(int x){
    	pos[x]=++dfn;
    	if(id[x]>0) last[id[x]]=dfn;
    	else{
    		int p=-id[x];
    		if(last[p]<=dfn-1)
    			insert(1,1,n,last[p],dfn-1,(Vector){2*X[p],X[p]*X[p]+C[p]});
    		last[p]=0;
    	}
    	for(int y=to[x];y;y=next[y]) dfs(y);
    	if(id[x]<0) last[-id[x]]=dfn+1;
    	else{
    		int p=id[x];
    		if(last[p]<=dfn)
    			insert(1,1,n,last[p],dfn,(Vector){2*X[p],X[p]*X[p]+C[p]});
    		last[p]=0;
    	}
    }
    void build(int x,int l,int r){
    	sort(tree[x].begin(),tree[x].end());
    	static Vector st[N];
    	int top=0;
    	for(int i=0;i<(int)tree[x].size();++i){
    		while(top>=2 and cross(tree[x][i]-st[top-1],st[top]-st[top-1])>=0) --top;
    		st[++top]=tree[x][i];
    	}
    	tree[x].assign(st+1,st+top+1);
    	if(l==r) return;
    	int mid=(l+r)>>1;
    	build(lc,l,mid),build(rc,mid+1,r);
    }
    
    struct ask {int s,x,id;}q[N];
    il bool operator<(co ask&a,co ask&b){
    	return a.x<b.x;
    }
    LL ans[N];
    
    void query(int x,int l,int r,co ask&q){
    //	if(x==1) cerr<<"qry "<<q.s<<" "<<q.x<<" "<<q.id<<endl;
    	if(tree[x].size()){
    		while(pl[x]<(int)tree[x].size()-1 and calc(tree[x][pl[x]+1],q.x)<=calc(tree[x][pl[x]],q.x)) ++pl[x]; // edit 1:<=
    		ans[q.id]=min(ans[q.id],calc(tree[x][pl[x]],q.x));
    	}
    	if(l==r) return;
    	int mid=(l+r)>>1;
    	if(q.s<=mid) query(lc,l,mid,q);
    	else query(rc,mid+1,r,q);
    }
    
    int main(){
    	freopen("travel.in","r",stdin),freopen("travel.out","w",stdout); // travel
    	read(n),read(m),read(C[1]);
    	id[1]=1;
    	for(int i=2;i<=n;++i){
    		int opt=read<int>(),fa=read<int>()+1;
    		next[i]=to[fa],to[fa]=i,id[i]=read<int>()+1;
    		if(!opt) read(X[id[i]]),read<int>(),read<int>(),read(C[id[i]]); // edit 2:id
    		else id[i]=-id[i];
    	}
    	dfs(1),build(1,1,n);
    	for(int i=1;i<=m;++i){
    		int s=read<int>()+1,x=read<int>();
    		q[i]=(ask){pos[s],x,i};
    	}
    	sort(q+1,q+m+1);
    	for(int i=1;i<=m;++i) ans[q[i].id]=1e18,query(1,1,n,q[i]);
    	for(int i=1;i<=m;++i) printf("%lld
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    服务器与本地时间的倒计时
    没有花括号(大括号)的for循环也能正确执行
    js瀑布流效果
    AQS详解(AbstractQueuedSynchronizer)
    SimpleDateFormat的线程安全问题与解决方案
    jvm不打印异常栈
    Java中的序列化Serialable高级详解
    java梳理-序列化与反序列化
    AQS详解
    对ConditionQueue和锁的理解
  • 原文地址:https://www.cnblogs.com/autoint/p/11495318.html
Copyright © 2011-2022 走看看