• 2019.10.22-蛤 (并查集)


    题目

    给出一张 N*M 的图,图中每个点有一个权值,代表这个点的高度,这个图
    因为下了雨,所以每秒钟海平面的高度会上升 1,所以在某些时间,一些点会被
    完全的淹没掉,现在给出 Q 个询问,每个询问给出一个时间 t,表示查询在时间
    t 时还没有被淹的点所组成的连通块个数.
    输入描述:
    第一行两个整数 N,M
    接下来 N 行,每行 M 个整数,分别表示第(i,j)点的高度.
    接下来一个整数 Q,表示询问个数
    接下来一行 Q 个整数 t[i],表示第 i 次询问时的时间
    输出描述:
    输出 Q 行,依次输出每个询问的答案.
    样例输入:
    4 5
    1 2 3 3 1
    1 3 2 2 1
    2 1 3 4 3
    1 2 2 2 2
    5
    1 2 3 4 5
    样例输出:
    2
    3
    1
    0
    0
    数据范围:
    60%的数据保证:1<=N,M<=1000,1<=Q<=10^5
    保证 1<=高度<=10^5 , 0<=t <= 10^5
    100%的数据保证:1<=N,M<=1000,1<=Q<=10^5
    保证 1<=高度<=10^9 ,0<= t <= 10^9

    时间排,高度排,上下左右突突突,没了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int a = (b); a <= (c); ++a)
    #define nR(a,b,c) for(register int a = (b); a >= (c); --a)
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
    
    #define ON_DEBUGG
    
    #ifdef ON_DEBUGG
    
    #define D_e_Line printf("-----------
    ")
    #define D_e(x) std::cout << (#x) << " : " <<x << "
    "
    #define FileOpen() freopen("in.txt", "r", stdin)
    #define FileSave() freopen("out.txt", "w", stdout)
    #define Pause() system("pause")
    #include <ctime>
    #define TIME() fprintf(stderr, "
    TIME : %.3lfms
    ", clock() * 1000.0 / CLOCKS_PER_SEC)
    
    #else
    
    #define D_e_Line ;
    #define D_e(x) ;
    #define FileOpen() ;
    #define FilSave ;
    #define Pause() ;
    #define TIME() ;
    
    #endif
    
    struct ios {
    	template<typename ATP> ios& operator >> (ATP &x) {
    		x = 0; int f = 1; char c;
    		for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
    		while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
    		x *= f;
    		return *this;
    	}
    }io;
    
    using namespace std;
    
    template<typename ATP> inline ATP Min(ATP a, ATP b) {
    	return a < b ? a : b;
    }
    template<typename ATP> inline ATP Max(ATP a, ATP b) {
    	return a > b ? a : b;
    }
    template<typename ATP> inline ATP Abs(ATP a) {
    	return a < 0 ? -a : a;
    }
    
    const int N = 1e3 + 7;
    const int M = 1e5 + 7;
    
    struct Ques {
    	int tim, id;
    	bool operator < (const Ques &com) const {
    		return tim > com.tim;
    	}
    } q[M];
    int ans[M];
    
    struct P {
    	int h, x, y;
    	bool operator < (const P &com) const {
    		return h > com.h;
    	}
    } a[N * N];
    //#define id(i,j) (((i) - 1) * (m) + (j))
    int n, m;
    inline int id(int x, int y) {
    	return (x - 1) * m + y;
    }
    int fa[N * N], siz[N * N];
    inline int Find(int x) {
    	return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    
    int tot;
    inline void Merge(int x, int y) {
    	x = Find(x), y = Find(y);
    	if(x == y) return;
    	if(siz[x] > siz[y]) Swap(x, y);
    	fa[x] = y;
    	siz[y] += siz[x];
    	--tot;
    }
    
    int vis[N][N];
    int main() {
    freopen("C.in", "r", stdin);
    freopen("C.out", "w", stdout);
    	io >> n >> m;
    	R(i,1,n){
    		R(j,1,m){
    			int x;
    			io >> x;
    			a[id(i, j)] = (P){ x, i, j};
    			fa[id(i, j)] = id(i, j);
    			siz[id(i, j)] = 1;
    		}
    	} 
    	int Q;
    	io >> Q;
    	R(i,1,Q){
    		io >> q[i].tim;
    		q[i].id = i;
    	}
    	sort(q + 1, q + Q + 1);
    	sort(a + 1, a  + n * m + 1);
    	int st = 1;
    	while(q[st].tim > a[1].h) ++st;
    	int j = 1;
    	R(i,st,Q){
    		while(a[j].h > q[i].tim){
    			int x = a[j].x, y = a[j].y;
    			vis[x][y] = true;
    			++tot;
    			if(vis[x - 1][y]) Merge(id(x, y), id(x - 1, y));
    			if(vis[x + 1][y]) Merge(id(x, y), id(x + 1, y));
    			if(vis[x][y - 1]) Merge(id(x, y), id(x, y - 1));
    			if(vis[x][y + 1]) Merge(id(x, y), id(x, y + 1));
    			++j;
    		}
    		ans[q[i].id] = tot;
    	}
    	
    	R(i,1,Q) printf("%d
    ", ans[i]);
    	return 0;
    }
    /*
    4 5 
    1 2 3 3 1 
    1 3 2 2 1 
    2 1 3 4 3 
    1 2 2 2 2 
    5 
    1 2 3 4 5 
    */
    

  • 相关阅读:
    状压DP入门
    二分图匹配(最大匹配:匈牙利算法)
    序列自动机入门
    Trie树入门+例题(字典树,前缀树)
    扩展KMP算法(Z-Algorithm)
    Oracle锁表查询和解锁方法
    oracle获取系统日期--当前时间+前一天+当前月+前一个月
    oracle获取年月日,两个日期相减
    oracle decode函数和 sign函数
    expdp、impdp数据泵导出导入数据
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11726799.html
Copyright © 2020-2023  润新知