• acwing 2154. 梦幻布丁


    给一个区间,有(n)数,每个数有一个颜色。
    (2)种操作

    • 把所有的(x)都修改为(y)
    • 求有几个颜色段

    可以知道计算出最开始有几个颜色段后,对于某个数字的修改,主需要查看这个数字的左边和右边值是否是(y)即可。
    那么,进行启发式合并,把一个set的值合并到另一个set里面

    #include <bits/stdc++.h>
    #define ll long long
    #define ld long double
    #define CASE int Kase = 0; cin >> Kase; for(int kase = 1; kase <= Kase; kase++)
    using namespace std;
    template<typename T = long long> inline T read() {
        T s = 0, f = 1; char ch = getchar();
        while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
        while(isdigit(ch)) {s = (s << 3) + (s << 1) + ch - 48; ch = getchar();} 
        return s * f;
    }
    #ifdef ONLINE_JUDGE
    #define qaq(...) ;
    #define qwq(c) ;
    #else
    #define qwq(a, b) for_each(a, b, [=](int x){cerr << x << " ";}), cerr << std::endl
    template <typename... T> void qaq(const T &...args) {
        auto &os = std::cerr;
        (void)(int[]){(os << args << " ", 0)...};
        os << std::endl;
    }
    #endif
    const int N = 1e5 + 5, M = 1e6 + 5, MOD = 1e9 + 7, CM = 998244353, INF = 0x3f3f3f3f; const ll linf = 0x7f7f7f7f7f7f7f7f;
    set<int> s[M];
    int fa[M], a[N], ans = 0;
    void merge(int x, int y) {
    	for(set<int>::iterator it = s[x].begin(); it != s[x].end(); it++) {
    		ans -= (a[*it - 1] == y) + (a[*it + 1] == y);
    		s[y].insert(*it);	
    	}
    	for(set<int>::iterator it = s[x].begin(); it != s[x].end(); it++) {
    		a[*it] = y;
    	}
    	s[x].clear();
    }
    void solve(int kase){
    	int n = read(), m = read();
    	for(int i = 1; i <= n; i++) {
    		a[i] = read(); 
    		s[a[i]].insert(i);
    		fa[a[i]] = a[i]; ans += a[i] != a[i - 1];
    	}
    	for(int i = 1; i <= m; i++) {
    		int op = read();
    		if(op == 1) {
    			int u = read(), v = read();
    			if(u == v) continue;
    			if(s[fa[u]].size() > s[fa[v]].size()) swap(fa[v], fa[u]);
    			merge(fa[u], fa[v]);
    		}else printf("%d
    ", ans);
    	}
    }
    const bool ISFILE = 0, DUO = 0;
    int main(){
    	srand(time(NULL));
        clock_t start, finish; double totaltime; start = clock();
        if(ISFILE) freopen("/Users/i/Desktop/practice/in.txt", "r", stdin);
        if(DUO) {CASE solve(kase);} else solve(1);
        finish = clock(); 
        qaq("
    Time:", (double)(finish - start) / CLOCKS_PER_SEC * 1000, "ms
    ");
        return 0;
    }
    
    I‘m Stein, welcome to my blog
  • 相关阅读:
    洛谷#P5652#基础博弈练习题
    hgoi#20191112
    hgoi#20191111
    hgoi#20191109
    洛谷#P3674#小清新人渣的本愿
    hgoi#20191108
    hgoi#20191107
    树上差分
    树链剖分(树剖)
    LCA(最近公共祖先)问题
  • 原文地址:https://www.cnblogs.com/Emcikem/p/14551235.html
Copyright © 2020-2023  润新知