zoukankan      html  css  js  c++  java
  • 「分块系列」数列分块入门8 解题报告

    数列分块入门8

    题意概括

    区间修改,区间计数。

    写在前面

    感叹~ 分块真是玄之又玄|( ̄0 ̄)

    正题

    跟分块7类似的是,这题也运用还原。

    v数组用来记录一个分块是否都为一个数,f数组来记录如果都为一个数,那么这个数是什么(实际上可以用只一个数组来记录QAQ)

    查询时,对于都为一个数的块,直接加上(如果这个数是c),顺便把f改为c,不是的话暴力计数,顺便把v改为1,f改为c。

    不完整的块稍微麻烦一点,如果v为1的话先还原(都变成f的值),然后再修改~

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 100005
    
    int n, d;
    int a[MAXN], b[MAXN], f[500];
    bool v[500];
    
    int FF( int x ){//取出x位置的值
    	return v[b[x]] ? f[b[x]] : a[x];
    }
    
    int fun( int l, int r, int c ){//计数&修改
    	int ans(0);
    	for ( int i = l; i <= r && i <= n; ++i ) ans += FF(i) == c, a[i] = c;
    	return ans;
    }
    
    int Get( int l, int r, int c ){
    	int ans(0);
    	if ( b[l] == b[r] ){
    		if ( v[b[l]] && f[b[l]] == c ) return r - l + 1;
    		
    		if ( v[b[l]] ){
    			fun( ( b[l] - 1 ) * d + 1, l - 1, f[b[l]] );
    			fun( r + 1, b[l] * d, f[b[l]] );
    		}
    		ans = fun( l, r, c );
    		v[b[l]] = 0;
    		return ans;
    	}
    	
    	if ( v[b[l]] ) fun( ( b[l] - 1 ) * d + 1, l - 1, f[b[l]] );
    	ans += fun( l, b[l] * d, c );
    	v[b[l]] = 0;
    	
    	
    	if ( v[b[r]] ) fun( r + 1, min( b[r] * d, n ), f[b[r]] );
    	ans += fun( ( b[r] - 1 ) * d + 1, r, c );
    	v[b[r]] = 0;
    	
    	for ( int i = b[l] + 1; i <= b[r] - 1; ++i ){
    		if ( !v[i] ){
    			for ( int j = ( i - 1 ) * d + 1; b[j] == i; ++j ) ans += a[j] == c, a[j] = c;
    			v[i] = 1; f[i] = c;
    		} else{
    			if ( f[i] == c ) ans += d;
    			else f[i] = c;
    		}
    	}
    	return ans;
    }
    
    int main(){
    	scanf( "%d", &n );
    	d = (int)sqrt(n);
    	for ( int i = 1; i <= n; ++i ){
    		scanf( "%d", &a[i] );
    		b[i] = ( i - 1 ) / d + 1;
    	}
    	for ( int i = 1; i <= n; ++i ){
    		int l, r, c;
    		scanf( "%d%d%d", &l ,&r, &c );
    		printf( "%d
    ", Get( l, r, c ) );
    	}
    	return 0;
    }
    

    总结

    分块大法好!(^分_块le^灵_活的暴力le^骗_分大法)

    数列分块系列目录

    数列分块入门1

    数列分块入门2

    数列分块入门3

    数列分块入门4

    数列分块入门5

    数列分块入门6

    数列分块入门7

    数列分块入门8 <-

    数列分块入门9

    蒲公英

    公主的朋友

  • 相关阅读:
    C++ 声明、定义、初始化、赋值
    skynet源码赏析
    python基础6函数 柒哥
    Python基础4数据类型详解下 柒哥
    Python基础1变量 柒哥
    Python基础2数据类型 柒哥
    Python基础3数据类型详解上 柒哥
    Python基础5条件分支与循环 柒哥
    PHP面试(A02)
    Envoy 配置
  • 原文地址:https://www.cnblogs.com/louhancheng/p/10051181.html
Copyright © 2011-2022 走看看