zoukankan      html  css  js  c++  java
  • P4374 [USACO18OPEN]Disruption P

    https://www.luogu.com.cn/problem/P4374

    洛谷这题一言难尽

    添加新边影响的边只有与新边成环的所有边,那就很简单了,树链剖分树上最大值就行了。。。很简单不知道为啥是紫题

    #include<iostream>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<algorithm>
    using namespace std;
    const int maxn = 2e5+11;
    const int INF = 1e9+111;
    
    vector<int>G[maxn];
    void add(int be,int en){
    	G[be].push_back(en);
    }
    
    
    int n,m;
    int top[maxn],id[maxn],cnt,dep[maxn],fa[maxn],siz[maxn],son[maxn];
    
    int dfs(int x,int f,int d) {
    	fa[x] = f;
    	dep[x] = d;
    	siz[x] = 1;
    	int s = 0;
    	
    	for(int i=0; i< G[x].size(); i++) {
    		int p = G[x][i];
    		if(p == f) continue;
    		
    		dfs(p,x,d+1);
    		siz[x] += siz[p];
    		if(s < siz[p]) {
    			s = siz[p];
    			son[x] = p;
    		}
    	}
    	return 0;
    }
    
    int dfs2(int x,int t) {
    	id[x] = ++cnt;
    	top[x] = t;
    	if(son[x] != 0) dfs2(son[x],t);
    	for(int i=0; i<G[x].size(); i++) {
    		int p =G[x][i];
    		if(p == son[x] || p == fa[x]) continue;
    		
    		dfs2(p,p);
    	}
    	return 0;
    }
    //建立线段树
    struct Node {
    	int ans,lazy;
    } tree[maxn*4];
    
    int bulit(int node,int be,int en) {
    	int mid =be+en>>1;
    	int l = node*2;
    	int r = node*2+1;
    	if(be == en) {
    		tree[node].ans = INF;
    		tree[node].lazy = INF;
    		return 0;
    	}
    
    	tree[node].ans = INF;
    	tree[node].lazy = INF;
    	bulit(l,be,mid);
    	bulit(r,mid+1,en);
    	return 0;
    }
    int push(int node,int be,int en) {
    	int mid = be +en >>1;
    	int l = node*2;
    	int r = node*2+1;
    	if(tree[node].lazy != INF) {
    		tree[l].ans = min(tree[l].ans , tree[node].lazy);
    		tree[r].ans = min(tree[r].ans , tree[node].lazy);
    
    		tree[l].lazy = min(tree[node].lazy,tree[l].lazy);
    		tree[r].lazy = min(tree[node].lazy,tree[r].lazy);
    		tree[node].lazy = INF;
    	}
    	return 0;
    }
    int update(int node,int be,int en,int LL,int RR,int val) {
    	if(LL > RR) return 0;
    	
    	int mid = be +en >>1;
    	int l = node*2;
    	int r = node*2+1;
    	if(LL <= be && en <= RR) {
    		tree[node].ans = min(tree[node].ans ,val);
    		if(tree[node].lazy != 0) tree[node].lazy = min(tree[node].lazy,val);
    
    		return 0;
    	}
    	push(node,be,en);
    	if(LL <= mid) update(l,be,mid,LL,RR,val);
    	if(RR > mid)  update(r,mid+1,en,LL,RR,val);
    	tree[node].ans = min(tree[l].ans,tree[r].ans);
    	return 0;
    }
    
    
    int ask(int node,int be,int en,int LL,int RR) {
    	if(LL > RR) return INF;
    	
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(LL <= be && en <= RR) {
    		return tree[node].ans;
    	}
    	int a = INF,b = INF;
    	push(node,be,en);
    	
    	if(LL <= mid) a = ask(l,be,mid,LL,RR);
    	if(RR > mid)  b = ask(r,mid+1,en,LL,RR);
    	return min(a,b);
    }
    
    
    int change(int x,int y,int val) {
    	int ans = INF;
    	while(top[x] != top[y]) {
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		update(1,1,n,id[top[x]],id[x],val);
    		x = fa[top[x]];
    	}
    	
    	if(dep[x] > dep[y]) swap(x,y);
    
    	update(1,1,n,id[x] + 1,id[y],val);
    	return 0;
    }
    
    
    
    vector<pair<int,int> >ins;
    vector<int>ans;
    
    int main() {
    //	freopen("in.in","r",stdin);
    //	freopen("out.out","w",stdout);
    	
    	scanf("%d %d",&n,&m);
    	for(int i=1; i<n; i++) {
    		int be,en;
    		scanf("%d%d",&be,&en);
    		ins.push_back(make_pair(be,en));
    		add(be,en);
    		add(en,be);
    	}
    	dfs(1,-1,1);
    	dfs2(1,1);
    	bulit(1,1,n);
    
    
    	while(m--) {
    		int x,y,w;
    		scanf("%d %d %d",&x,&y,&w);
    		change(x,y,w);
    	}
    	
    	for(int i=0;i<ins.size();i++){
    		int x = ins[i].first;
    		int y = ins[i].second;
    		if(dep[x] < dep[y]) swap(x,y);
    		
    		int a = ask(1,1,n,id[x],id[x]);
    		ans.push_back(a);
    	}
    	
    	for(int i=0;i<ans.size();i++){
    		if(ans[i] == INF) ans[i] = -1;
    		printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Ext.MessageBox.show的用法
    DecimalFormat很强大
    java根据模板导出excel和excel的一些知识
    数组分成若干个数组
    SQL SERVER 创建视图
    java 中怎么根据当前时间得到上周一和上周五的日期
    复选框提交后不合格还在选中状态
    sql语句的学习(2)
    sql语句的学习(1)
    利用LinkedList实现洗牌功能
  • 原文地址:https://www.cnblogs.com/lesning/p/14123879.html
Copyright © 2011-2022 走看看