zoukankan      html  css  js  c++  java
  • 【LOJ 6277】数列分块入门 1

    题目


    这是一道能用许多数据结构优化的经典题,可以用于不同数据结构训练。

    数列分块就是把数列中每(m)个元素打包起来,达到优化算法的目的。

    以此题为例,如果我们把每(m)个元素分为一块,共有(n/m)块,每次区间加的操作会涉及(O(n/m))个整块,以及区间两侧两个不完整的块中至多(2m)个元素。

    我们给每个块设置一个加法标记(就是记录这个块中元素一起加了多少),每次操作对每个整块直接(O(1))标记,而不完整的块由于元素比较少,暴力修改元素的值。

    每次询问时返回元素的值加上其所在块的加法标记。

    这样每次操作的复杂度是(O(n/m)+O(m)),根据均值不等式,当(m)(sqrt(n))时总复杂度最低。


    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=50005;
    int a[N],tag[N],L[N],R[N],pos[N];
    inline void add(int l,int r,int d) {
    	int p=pos[l],q=pos[r];
    	if(p==q) {
    		for(int i=l; i<=r; i++) {
    			a[i]+=d;
    		}
    	} else {
    		for(int i=p+1; i<q; i++) {
    			tag[i]+=d;
    		}
    		for(int i=l; i<=R[p]; i++) {
    			a[i]+=d;
    		}
    		for(int i=L[q]; i<=r; i++) {
    			a[i]+=d;
    		}
    	}
    }
    int main() {
    	int n;
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++) {
    		scanf("%d",a+i);
    	}
    	int t=sqrt(n*1.0);
    	for(int i=1; i<=t; i++) {
    		L[i]=(i-1)*t+1,R[i]=i*t;
    	}
    	if(R[t]<n) {
    		t++,L[t]=R[t-1]+1,R[t]=n;
    	}
    	for(int i=1; i<=t; i++) {
    		for(int j=L[i]; j<=R[i]; j++) {
    			pos[j]=i;
    		}
    	}
    	for(int i=1,opt,l,r,c; i<=n; i++) {
    		scanf("%d %d %d %d",&opt,&l,&r,&c);
    		if(!opt) {
    			add(l,r,c);
    		} else {
    			printf("%d
    ",a[r]+tag[pos[r]]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    net use命令详解(转)
    SQL Server架构SQL Server的执行模式和SQLOS
    SQL Server架构SQL Server的执行模式和SQLOS
    利用xcopy命令实现本地文件复制到远程服务器的方法
    利用xcopy命令实现本地文件复制到远程服务器的方法
    xcopy部署
    xcopy部署
    css样式—字体垂直、水平居中
    音视频&流媒体
    分布式编译工具
  • 原文地址:https://www.cnblogs.com/Sam2007/p/13160031.html
Copyright © 2011-2022 走看看