zoukankan      html  css  js  c++  java
  • [bzoj4009] [HNOI2015]接水果

    Description

    风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果。

    由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本。首先有一个地图,是一棵由 n 个顶点、n-1 条边组成的树(例如图 1给出的树包含 8 个顶点、7 条边)。这颗树上有 P 个盘子,每个盘子实际上是一条路径(例如图 1 中顶点 6 到顶点 8 的路径),并且每个盘子还有一个权值。第 i 个盘子就是顶点a_i到顶点b_i的路径(由于是树,所以从a_i到b_i的路径是唯一的),权值为c_i。接下来依次会有Q个水果掉下来,每个水果本质上也是一条路径,第i 个水果是从顶点 u_i 到顶点v_i 的路径。幽香每次需要选择一个盘子去接当前的水果:一个盘子能接住一个水果,当且仅当盘子的路径是水果的路径的子路径(例如图1中从 3到7 的路径是从1到8的路径的子路径)。这里规定:从a 到b的路径与从b到 a的路径是同一条路径。当然为了提高难度,对于第 i 个水果,你需要选择能接住它的所有盘子中,权值第 k_i 小的那个盘子,每个盘子可重复使用(没有使用次数的上限:一个盘子接完一个水果后,后面还可继续接其他水果,只要它是水果路径的子路径)。幽香认为这个游戏很难,你能轻松解决给她看吗?

    img

    Input

    第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数。

    接下来n-1 行,每行两个数 a、b,表示树上的a和b 之间有一条边。树中顶点

    按1到 n标号。 接下来 P 行,每行三个数 a、b、c,表示路径为 a 到 b、权值为 c 的盘子,其

    中0≤c≤10^9,a不等于b。

    接下来Q行,每行三个数 u、v、k,表示路径为 u到 v的水果,其中 u不等于v,你需要选择第 k小的盘子,

    第k 小一定存在。

    Output

    对于每个果子,输出一行表示选择的盘子的权值。

    Solution

    超级码农题,,写了我一下午。。

    考虑盘子能影响到的水果构成了一个二维约束:

    • (lca)不是两点中任意一个,则两个点的子树分别是两维约束。
    • 否则全集减去(lca)的子树为第一维约束,剩下那个点的子树为第二维约束

    这两维约束形成了若干个矩阵,而水果则可以看做是平面上的一个点。

    那么做法就很显然了:

    用扫描线把两维变一维,然后类似k大数查询那样维护扫描线那一维,对于水果按(x)坐标(sort)一遍顺便求出答案就好了。

    注意对于一个矩阵,其实两维反过来也会被它影响到,所以对于每一个矩阵把它和(y=x)对称的矩阵也加进去。

    内层线段树记得标记永久化,不然稳炸。

    剩下细节问题自己考虑

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
     
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    const int maxn = 1e5+10;
    
    int dfn[maxn],n,m,q,f[maxn][20],dep[maxn],sz[maxn];
    
    struct Input_Tree {
    	int head[maxn],tot,dfn_cnt;
    	struct edge{int to,nxt;}e[maxn<<1];
    
    	void add(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}
    	void ins(int u,int v) {add(u,v),add(v,u);}
    	
    	void dfs(int x,int fa) {
    		f[x][0]=fa,dep[x]=dep[fa]+1,dfn[x]=++dfn_cnt,sz[x]=1;
    		for(int i=1;i<=16;i++) f[x][i]=f[f[x][i-1]][i-1];
    		for(int i=head[x];i;i=e[i].nxt)
    			if(e[i].to!=fa) dfs(e[i].to,x),sz[x]+=sz[e[i].to];
    	}
    
    	int lca(int x,int y) {
    		if(dep[x]<dep[y]) swap(x,y);
    		for(int i=16;~i;i--) if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    		if(x==y) return x;
    		for(int i=16;~i;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    		return f[x][0];
    	}
    }T;
    
    int cnt,inx[maxn],iny[maxn],inz[maxn];
    
    struct query {
    	int x,y,k,ans,id;
    	bool operator < (const query &rhs) const {return x<rhs.x;}
    }a[maxn];
    
    int cmp(query A,query b) {return A.id<b.id;}
    
    int ls[maxn*200],rs[maxn*200],sum[maxn*200],tag[maxn*200],seg;
    
    #define mid ((l+r)>>1)
    
    struct Pos_Seg_Tree {
    	int rt;
    	void modify(int &p,int l,int r,int x,int y,int z) {
    		if(!p) p=++seg;
    		if(x<=l&&r<=y) return sum[p]+=z,void();
    		if(x<=mid) modify(ls[p],l,mid,x,y,z);
    		if(y>mid) modify(rs[p],mid+1,r,x,y,z);
    	}
    	int query(int p,int l,int r,int x) {
    		if(!p) return 0;
    		if(l==r) return sum[p];
    		if(x<=mid) return query(ls[p],l,mid,x)+sum[p];
    		else return query(rs[p],mid+1,r,x)+sum[p];
    	}
    };
    
    #define ls p<<1
    #define rs p<<1|1
    
    struct Val_Seg_Tree {
    	Pos_Seg_Tree t[maxn<<2];
    	void modify(int p,int l,int r,int x,int A,int b,int op) {
    		t[p].modify(t[p].rt,1,n,A,b,op);
    		if(l==r) return ;
    		if(x<=mid) modify(ls,l,mid,x,A,b,op);
    		else modify(rs,mid+1,r,x,A,b,op);
    	}
    	int query(int p,int l,int r,int x,int k) {
    		if(l==r) return l;
    		int s=t[ls].query(t[ls].rt,1,n,x);
    		if(s>=k) return query(ls,l,mid,x,k);
    		else return query(rs,mid+1,r,x,k-s);
    	}
    }SGT;
    
    #undef ls
    #undef rs
    #undef mid 
    
    struct line {
    	int up,down,val,op,x;
    	bool operator < (const line &rhs) const {return x<rhs.x;}
    }l[maxn*20];
    
    int r[maxn];
    
    int main() {
    	read(n),read(m),read(q);
    
    	for(int i=1,x,y;i<n;i++) read(x),read(y),T.ins(x,y);
    	T.dfs(1,0);
    
    	for(int i=1;i<=m;i++) read(inx[i]),read(iny[i]),read(inz[i]),r[i]=inz[i];
    	sort(r+1,r+m+1);int M=unique(r+1,r+m+1)-r-1;
    	for(int i=1;i<=m;i++) inz[i]=lower_bound(r+1,r+M+1,inz[i])-r;
    	
    	for(int i=1;i<=m;i++) {
    		int x=inx[i],y=iny[i],z=inz[i];
    		int t=T.lca(x,y);if(dep[x]>dep[y]) swap(x,y);
    		if(x==t) {
    			int son=y;
    			for(int j=16;~j;j--) if(dep[f[son][j]]>dep[x]) son=f[son][j];
    			l[++cnt]=(line){dfn[son]-1,1,z,1,dfn[y]};
    			l[++cnt]=(line){dfn[son]-1,1,z,-1,dfn[y]+sz[y]-1};
    			if(dfn[son]+sz[son]<=n) {
    				l[++cnt]=(line){n,dfn[son]+sz[son],z,1,dfn[y]};
    				l[++cnt]=(line){n,dfn[son]+sz[son],z,-1,dfn[y]+sz[y]-1};
    			}
    		} else {
    			if(dfn[x]>dfn[y]) swap(x,y);
    			l[++cnt]=(line){dfn[x]+sz[x]-1,dfn[x],z,1,dfn[y]};
    			l[++cnt]=(line){dfn[x]+sz[x]-1,dfn[x],z,-1,dfn[y]+sz[y]-1};
    		}
    	}
    
    	int c=cnt;
    	for(int i=1;i<=c;i+=2) {
    		int ldy=l[i].down,ldx=l[i].x,rux=l[i+1].x,ruy=l[i+1].up;
        	swap(ldx,ldy),swap(rux,ruy);
    		l[++cnt]=(line){ruy,ldy,l[i].val,1,ldx};
    		l[++cnt]=(line){ruy,ldy,l[i].val,-1,rux};
    	}
    	
    	for(int i=1;i<=cnt;i++) if(l[i].op==-1) l[i].x++;
    	
    	sort(l+1,l+cnt+1);
    	
    	for(int i=1;i<=q;i++) {
    		read(a[i].x),read(a[i].y),read(a[i].k);a[i].id=i;
    		a[i].x=dfn[a[i].x],a[i].y=dfn[a[i].y];
    	}
    	sort(a+1,a+q+1);
    	
    	int p=1;
    	for(int i=1;i<=cnt;i++) {
    		while(l[i].x>a[p].x&&p<=q) a[p].ans=SGT.query(1,1,n,a[p].y,a[p].k),p++;
    		SGT.modify(1,1,n,l[i].val,l[i].down,l[i].up,l[i].op);
    	}
    	
    	sort(a+1,a+q+1,cmp);
    	for(int i=1;i<=q;i++) write(r[a[i].ans]);
    	return 0;
    }
    
  • 相关阅读:
    kickstart-G
    some advice in work
    Java Applet:练习TextField类和TextArea类的文本事件
    jquery带下拉菜单和焦点图
    炫酷的CSS3抖动样式:CSS Shake
    CSS: iPhone Custom CSS
    css sprite技巧详解
    CSS缎带效果
    css 采集下载
    CSS控制表格嵌套
  • 原文地址:https://www.cnblogs.com/hbyer/p/10239713.html
Copyright © 2011-2022 走看看