zoukankan      html  css  js  c++  java
  • HDU 5997 rausen loves cakes(启发式合并 + 树状数组统计答案)

    题目链接  rausen loves cakes

    题意  给出一个序列和若干次修改和查询。修改为把序列中所有颜色为$x$的修改为$y$,

             查询为询问当前$[x, y]$对应的区间中有多少连续颜色段。

        序列长度为$n$,总操作数为$q$,满足$1 <= n <= 10^{5}, 1 <= q <= 10^{5}$

     

    初始化的时候若当前颜色和前一个位置的颜色不相等的时候则在这个位置的树状数组中打标记。

    修改的时候,颜色权值数小的往大的合并,这样满足总合并复杂度为$O(nlogn)$,

    若当前位置经过修改之后和前一个位置颜色相等则取消当前位置的标记,

    若当前位置经过修改之后和后一个位置颜色相等则取消当前位置的后一个位置的标记,

    注意最后统计答案的时候第要对第一个位置特判。

    因为用到了set,所以总时间复杂度$O(nlog^{2}n)$

     

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    const int M = 1e6 + 10;
    
    int T;
    int ans;
    int n, m;
    int a[N], f[M];
    int c[N];
    set <int> s[M];
    
    void update(int x, int val){
    	for (; x <= n; x += x & -x) c[x] += val;
    }
    
    int query(int x){
    	if (x < 1) return 0;
    	int ret = 0;
    	for (; x; x -= x & -x) ret += c[x];
    	return ret;
    }
    
    void solve(int x, int y){
    	for (auto u : s[x]){
    		if (a[u - 1] == y) update(u, -1);
    		if (a[u + 1] == y) update(u + 1, -1);
    		s[y].insert(u);
    	}
    
    	for (auto u : s[x]) a[u] = y;
    	s[x].clear();
    }
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d", &n, &m);
    		rep(i, 1, n) scanf("%d", a + i);
    		memset(f, 0, sizeof f);
    		memset(c, 0, sizeof c);
    		rep(i, 0, 1e6 + 1) s[i].clear();
    		rep(i, 1, n){
    			f[a[i]] = a[i];
    			if (a[i] ^ a[i - 1]) update(i, 1);
    			s[a[i]].insert(i);
    		}
    
    		rep(i, 1, m){
    			int op, x, y;
    			scanf("%d", &op);
    			if (op == 1){
    				int x, y;
    				scanf("%d%d", &x, &y);
    				if (x == y) continue;
    				if (s[f[x]].size() > s[f[y]].size()) swap(f[x], f[y]);
    				x = f[x], y = f[y];
    				solve(x, y);
    			}
    			else{
    				int x, y;
    				scanf("%d%d", &x, &y);
    				printf("%d
    ", query(y) - query(x - 1) + (a[x] == a[x - 1]));
    			}
    		}
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    Cocos2d-js 开发记录:图片数据资源等的异步加载
    Cocos2d-js 开发记录:声音播放
    Cocos2d-js 开发记录-初始
    PAT 1064 Complete Binary Search Tree
    python 对象属性与 getattr & setattr
    LeetCode Text Justification
    LeetCode Valid Number
    LeetCode String to Integer (atoi)
    struts2--标签取值
    java--Hibernate实现分页查询
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8401859.html
Copyright © 2011-2022 走看看