zoukankan      html  css  js  c++  java
  • UOJ309 UNR #2 排兵布阵

    包含不小于$sqrt n$列的只有不大于$sqrt n$行,修改时这些行打标记,否则暴力更新,操作一列的时候暴力更新这些行。合并没啥影响直接搞就是了。更新需要访问位置,感觉必须用哈希表,并不是特别靠谱。平均复杂度$O(nsqrt n)$。

    #include<bits/stdc++.h>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/hash_policy.hpp>
    using namespace std;
    using namespace __gnu_pbds;
    int n2;
    inline void upd2(int&a,int b){
    	a<b?a=b:0;
    }
    struct vec{
    	int s,d;
    	gp_hash_table<int,int>w;
    	vec(){s=d=0;}
    	void ins(int i,int e){
    		auto j=w.find(i);
    		if(w.end()==j)w[i]=e-d;
    		else
    			upd2(j->second,e-d);
    		upd2(s,e);
    	}
    };
    gp_hash_table<int,vec>f[2];
    gp_hash_table<int,int>g[2];
    gp_hash_table<int,null_type>h[2];
    void dev(int k,int x){
    	auto&a=f[k][x];
    	for(int y:h[k^1]){
    		auto&b=f[k^1][y];
    		auto i=b.w.find(x);
    		if(b.w.end()!=i)
    			a.ins(y,i->second+b.d);
    	}
    }
    int sol5(int k,int x){
    	if(h[k].end()==h[k].find(x))
    		dev(k,x);
    	return f[k][x].s;
    }
    int ask(int k,int x){
    	return g[k].end()!=g[k].find(x)?sol5(k,g[k][x]):0;
    }
    void inc(int k,int x,int d){
    	auto&a=f[k][x];
    	if(h[k].end()==h[k].find(x)){
    		dev(k,x);
    		for(auto&e:a.w){
    			e.second+=d;
    			f[k^1][e.first].ins(x,e.second);
    		}
    	}else{
    		a.d+=d;
    		for(int y:h[k^1]){
    			auto&b=f[k^1][y];
    			auto i=b.w.find(x);
    			if(b.w.end()!=i){
    				i->second+=d;
    				upd2(b.s,i->second+b.d);
    			}
    		}
    	}
    	a.s+=d;
    }
    void sol4(int k,int x,int nx){
    	g[k][nx]=g[k][x];
    	g[k].erase(x);
    }
    void sol3(int k,int x,int nx){
    	auto&a=f[k][x],&b=f[k][nx];
    	if(h[k].end()==h[k].find(x))
    		dev(k,x);
    	for(auto e:a.w){
    		auto&c=f[k^1][e.first];
    		upd2(c.w[nx],e.second+a.d-c.d);
    		c.w.erase(x);
    		b.ins(e.first,e.second+a.d);
    	}
    	if(h[k].erase(x)||b.w.size()>n2){
    		h[k].insert(nx);
    		dev(k,nx);
    	}
    }
    void sol2(int k,int x,int nx){
    	sol3(k,g[k][x],g[k][nx]);
    	g[k].erase(x);
    }
    void sol1(int k,int x,int nx){
    	if(f[k][g[k][x]].w.size()<=f[k][g[k][nx]].w.size())
    		sol2(k,x,nx);
    	else{
    		sol2(k,nx,x);
    		sol4(k,x,nx);
    	}
    }
    void mov(int k,int x,int nx){
    	if(x!=nx)
    		(g[k].end()!=g[k].find(nx)?sol1:sol4)(k,x,nx);
    }
    int main(){
    	int n,m,x,y,d;
    	char o[8];
    	scanf("%d",&n);
    	n2=sqrt(n+.5);
    	while(n--){
    		scanf("%d%d%d",&x,&y,&d);
    		f[0][x].ins(y,d);
    		f[1][y].ins(x,d);
    		g[0][x]=x;
    		g[1][y]=y;
    	}
    	for(int k=0;k<2;++k)
    		for(auto&e:f[k])
    			if(e.second.w.size()>n2)
    				h[k].insert(e.first);
    	scanf("%d",&m);
    	while(m--){
    		scanf("%s%d",o,&x);
    		int k=*o=='Y';
    		if(o[1]=='Q')
    			printf("%d
    ",ask(k,x));
    		else{
    			scanf("%d",&d);
    			if(g[k].end()!=g[k].find(x))
    				o[1]=='M'?mov(k,x,x+d):inc(k,g[k][x],d);
    		}
    	}
    }
    
  • 相关阅读:
    navicat安装与激活
    MySQL 安装
    oracle中not in 和 in 的替代写法
    oracle中in和exists的区别
    oracle中nvarchar2()和varchar2()的区别
    oracle稳定执行计划(更改)的方法
    oracle显示转化字段类型
    oracle中varchar2(2)存不了一个汉字的原因
    oracle中索引快速全扫描和索引全扫描的区别
    oracle常见的执行计划
  • 原文地址:https://www.cnblogs.com/f321dd/p/7166171.html
Copyright © 2011-2022 走看看