zoukankan      html  css  js  c++  java
  • 洛谷P1196 [NOI2002]银河英雄传说

    (Large extbf{Description: } large{30000个战舰,有两种操作,共k次(k leq 500005):}\)
    (quadquadlarge{M(i,j):把以i战舰为首的舰队接到j号战舰所在舰队尾部。\})
    (quadquadlarge{C(i,j):如果战舰i与战舰j在一个舰队,则输出他们间的战舰数;否则,输出-1。\})

    (Large extbf{Solution: } large{对于第一个操作,我们可以想到用并查集维护。\对于第二个操作,考虑到询问次数很多,我们发现可以用前缀和做到O(1)查询,\用top数组维护每个战舰与舰首之间的战舰数,那么ans = abs(top[i] - top[j]) - 1。\考虑如何维护前缀和,因为每次移动都是整个舰队移动,所以舰队中每艘战舰与舰首之间的战舰数不变。如果i与j本来就在一个舰队,那么对我们的top没影响。\如果一开始i与j并不在一个舰队里呢?对于一个i我们发现在find函数中可以顺便维护他的top数组,其余的战舰对结果没影响,我们不用处理。\})

    (Large extbf{Code: })

    #include <cmath>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define gc() getchar()
    #define rep(i, a, b) for (int i = (a); i <= (b); ++i)
    using namespace std;
    const int N = 3e4 + 5;
    int n, f[N], size[N], top[N];
    
    inline int read() {
    	char ch = gc();
    	int ans = 0;
    	while (ch > '9' || ch < '0') ch = gc();
    	while (ch >= '0' && ch <= '9') ans = (ans << 1) + (ans << 3) + ch - '0', ch = gc();
    	return ans;	
    }
    
    inline int find(int x) {
    	if (f[x] == x) return f[x];
    	int ff = find(f[x]);
    	top[x] += top[f[x]];
    	return f[x] = ff;	
    }
    
    int main() {
    	n = read();		
    	rep(i, 1, N) f[i] = i, size[i] = 1, top[i] = 0;
    	char s;
    	int x, y, no = -1;
    	while (n--) {
    		cin >> s;
    		x = read(), y = read();
    		int fx = find(x), fy = find(y);
    		if (s == 'M') {
    			top[fx] += size[fy]; 
    			size[fy] += size[fx];
    			f[fx] = fy;
    			size[fx] = 0;
    		}
    		else {
    			if (fx != fy) printf("-1
    ");
    			else printf("%d
    ", abs(top[x] - top[y]) - 1);
    		}	
    	}
    	return 0;
    }
    
  • 相关阅读:
    PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
    thinkphp整合系列之微信公众号支付
    JS之变量的运算
    (php)thinkphp3.2配置sql_server
    jyd数据结构
    mac终端下svn常用命令
    项目学习
    抛错
    phpunit
    Python
  • 原文地址:https://www.cnblogs.com/Miraclys/p/12356336.html
Copyright © 2011-2022 走看看