zoukankan      html  css  js  c++  java
  • 「分块 * 莫队 」题目解析

    分块入门9题

    T1:

    入门题,不写了

    T2:区间加,区间求小于某数的元素个数

    修改:大块打标记,小块先把块标记下传,然后再加,最后排序

    查询:由于块内是排完序的,大块二分,小块暴力统计

    T3:区间加,查前驱

    两种写法

    第一种:同2,排序+二分

    修改:同2

    查询:二分

    第二种:用set维护

    修改:大块标记,小块拿出来修改,注意删除操作要先查迭代器再删,以免直接删除一个值将所有的同值的所有数删除

    查询:二分

    T4:区间加,区间求和

    非分块:线段树

    分块:

    整体跟1没区别

    修改:同1

    查询:大块直接加维护的数组,小块暴力加

    T5:区间开根,区间查询

    性质:发现 (1e9) 开五次就到了1,所以暴力下压的

    非分块:线段树

    分块:

    修改:前几次暴力下压,直到块内都为1

    查询:乱搞,有 (tag=1) 块贡献为块的 (size) ,否则暴力统计

    带修的以后再补

    T6:单点插值,单点查询

    非分块:用链表直接搞

    暴力分块:每个块开个vector,二分插入,能A

    正解分块貌似是每查一个值调整每个块的左右边界

    T7:区间乘区间加单点查

    非分块:线段树

    分块:区间加加强版,调起来比较费劲

    开两个标记,乘和加都是大块都是打标记,小块要把所有标记下传

    inline void Build(){
    	int maxe=sqrt(n+0.5);
    	for(register int i=1;i<=n;++i){
    		belong[i]=(i-1)/maxe+1;
    		if(!L[belong[i]])L[belong[i]]=i;
    		R[belong[i]]=i;sum[belong[i]]+=a[i];sum[belong[i]]%=mol;
    		size[belong[i]]++;
    		mul[belong[i]]=1;
    		maxs=max(maxs,belong[i]);
    	}
    }
    inline void modify1(int s,int t,int w){//mul
    	if(belong[s]!=belong[t]){
    		modify1(s,R[belong[s]],w),modify1(L[belong[t]],t,w);
    		for(int i=belong[s]+1;i<belong[t];i++){
    			sum[i]*=w,add[i]*=w,mul[i]*=w;
    			sum[i]%=mol,add[i]%=mol,mul[i]%=mol;
    		}
    	}else{
    		for(int i=L[belong[s]];i<=R[belong[s]];i++)a[i]=(1LL*a[i]*mul[belong[i]]%mol+add[belong[i]])%mol;
    		add[belong[s]]=0;mul[belong[s]]=1;
    		for(int i=s;i<=t;i++){
    			sum[belong[s]]-=a[i];a[i]*=w;sum[belong[s]]+=a[i];a[i]%=mol;
    		}
    	}
    }
    inline void modify2(int s,int t,int w){//add
    	if(belong[s]!=belong[t]){
    		modify2(s,R[belong[s]],w),modify2(L[belong[t]],t,w);
    		for(int i=belong[s]+1;i<belong[t];i++){
    			sum[i]+=w*size[i]%mol,add[i]+=w;
    			sum[i]%=mol;add[i]%=mol;
    		}
    	}else{
    		for(int i=L[belong[s]];i<=R[belong[s]];i++)a[i]=(1LL*a[i]*mul[belong[i]]%mol+add[belong[i]])%mol;
    		add[belong[s]]=0;mul[belong[s]]=1;
    		for(int i=s;i<=t;i++){
    			sum[belong[s]]-=a[i];a[i]+=w;sum[belong[s]]+=a[i];a[i]%=mol;
    		}
    	}
    }
    inline void query(register int s){
    	ans=(a[s]*mul[belong[s]]%mol+add[belong[s]])%mol;
    }
    

    T8:区间覆盖查元素个数

    非分块:珂朵莉处理区间推平

    分块:

    暴力思路:对每个块开桶打标记,发现unorderedmap都只有三十分

    正解:看题解了,暴力下压,时间复杂度是对的

    ——待续——

  • 相关阅读:
    c++ 中的substr
    c++ 中将数字字符串转换成int输出的stoi() 和 atoi()
    c++ 四舍五入函数 round
    stddef.h----常用函数
    local.h-----地区函数
    errno.h-----定义出错代码
    signal.h-----信号函数
    stdio.h----标准的输入输出函数
    time.h-------日期与时间函数
    math.h--------数学函数
  • 原文地址:https://www.cnblogs.com/614685877--aakennes/p/14043743.html
Copyright © 2011-2022 走看看