zoukankan      html  css  js  c++  java
  • [qbzt寒假]线段树和树状数组

    树状数组

    (lowbit(x)=x&(-x))

    二维树状数组

    修改某个点,查询(1,1)到(n,m)的前缀和(树状数组要从1开始)

    HDU2642 Stars

    (YFF)是个浪漫的人,他喜欢数天上的星星。

    为了解决这个问题,我们考虑到天空是一个二维平面,有时星星会很亮,有时星星会很暗。首先,天空中没有明亮的星星,然后一些信息会被给出为“(B) (x) (y)”,其中“(B)”表示明亮,(x)表示(x)坐标,(y)表示在((x,y))星星是明亮的,而“(D) (x) (y)”中的“(D)”表示((x,y))处的恒星是暗淡的。当查询到“(Q) (X1) (X2) (Y1)(Y2)”时,您应该告诉(YFF)该区域有多少明亮的恒星对应于(X1)(X2)(Y1)(Y2)这个四边形区域。

    (X,Y (0 <=X,Y<= 1000))

    二维树状数组模板

    #include<cstdio>
    #include<algorithm>
    #define N 1010
    using namespace std;
    
    int c[N][N];
    int f[N][N];
    int m;
    
    int lowbit(int x){
    	return x&(-x);
    }
    
    void modify(int x,int y,int z){
    	for(int i=x;i<N;i+=lowbit(i)){
    		for(int j=y;j<N;j+=lowbit(j)){
    			c[i][j]+=z;
    		}
    	}
    }
    
    int query(int x,int y){
    	int ret=0;
    	for(int i=x;i;i-=lowbit(i)){
    		for(int j=y;j;j-=lowbit(j)){
    			ret+=c[i][j];
    		}
    	}
    	return ret;
    }
    
    int main(){
    	scanf("%d",&m);
    	while(m--){
    		char opt[10];
    		int x,y,a,b;
    		scanf("%s",opt);
    		if(opt[0]=='B'){
    			scanf("%d%d",&x,&y);
    			x++;y++;
    			if(f[x][y]) continue;
    			f[x][y]=1;
    			modify(x,y,1);
    		}
    		if(opt[0]=='D'){
    			scanf("%d%d",&x,&y);
    			x++;y++;
    			if(f[x][y]==0) continue;
    			f[x][y]=0;
    			modify(x,y,-1);
    		}
    		if(opt[0]=='Q'){
    			scanf("%d%d%d%d",&x,&a,&y,&b);
    			x++;y++;a++;b++;
    			if(x<a) swap(x,a);
    			if(y<b) swap(y,b);
    			int ans=query(x,y)-query(x,b-1)-query(a-1,y)+query(a-1,b-1);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    

    POJ 2299

    先离散化,开一个权值树状数组

    POJ 2352

    在坐标上有(n)个星星,如果某个星星坐标为((x, y)), 它的左下位置为:((x0,y0),x0<=x)(y0<=y)。如果左下位置有(a)个星星,就表示这个星星属于(level x)

    按照(y)递增,如果(y)相同则(x)递增的顺序给出(n)个星星,求出所有(level)水平的数量。

    (x)为第一关键字升序排序,(y)为第二关键字升序排序

    计数:排序后,将(y)的值一个一个加入树状数组中,加入前维护小于等于这个(y)的前缀和,得到的就是(level)

    CF GYM 100741A Queries

    开十个树状数组,分别表示模m=0,1,……的数的个数

    每次加减的时候就找到单点修改

    BZOJ 3289

    树状数组维护区间逆序对

    线段树

    POJ 3488

    裸题

    LIS

    (f_i=max{f_j+1})

    线段树优化:1.离散化2.建立线段树,下标代表权值:对于所有$a_k=下标 (,最大的)f_k$是多少(线段树维护区间最大值)

    BZOJ 1588

    (1.Multiset)

    (2.)建立一个权值线段树,对一个值(x),二分查找(对下标进行二分查找,寻找下标最大的(leq x)的权值不为(0)的点,下标最小的(geq x)的权值不为(0)的点,比较差值,取差值较小的)

    BZOJ 3211

    线段树维护区间和,每次修改暴力分治,如果出现一个区间都是(0)(1),打(tag),不再修改

    Codeforces 718C

    操作1:对([l,r])每个矩阵(*T^x)

    操作2:对([l,r])中的矩阵求和,再(*[1,1])

    (T)是斐波那契数列数列矩阵加速公式

    Codeforces 85D

    乍一看与线段树并无关系

    1.离散化

    2.建立权值线段树

    3:

    滚动合并:

    BZOJ 3339

    给出一个序列(A,Q)次询问,每次询问在([Li, Ri])(mex)是多少.
    (N, Q ≤ 100000.)

    将所有询问离线下来,按照(L)从小到大排序。提前处理好(1->i)的前缀(mex)

      for(int i=1;i<=n;i++){
            c[a[i]]=1;
            while(c[now]) now++;
            mex[i]=now;
        }
    

    (next[i])表示下标为(i)的数下一次出现在哪个下标:

    for(int i=n;i>=1;i--){
            next[i]=last[a[i]];
            if(next[i]==0) next[i]=n+1;
            last[a[i]]=i;
        }
    

    (L)右移一,会将所有(L+1->next[i]-1)(>A[L])(mex)变为(A[L])

    然后移动左端点,按照上面进行修改,对右端点进行查询(区间(mex)等于最右侧)

    BZOJ 2124

    给一个(1)(N)的排列({Ai}),询问是否存在(1<=p_1<p_2<p_3<p_4<p_5<…<p_{Len}<=N (Len>=3)),使得(A_{p1},A_{p2},A_{p3},…A_{pLen})是一个等差序列。

    实质上问是否存在三元组((i,j,k)),满足(i<j<k)(A_k-A_j=A_j-A_i)

    用二进制表示一个数是否已经选了,在某个位置的数若是(A[i]),若其向左数的(hash)不等于向右数的(hash),说明一定有(A[i]+x和A[i]-x)分别在(A[i])所在位置的两边,也就是有解.

    ↑上面这行目测看不懂,举个例子:

    3
    3 2 1

    这是题目中的数据。我们用(01)串表示(1、2、3)这三个数选了没有,初始时是(“0 0 0”)

    从左开始扫描,先选定(3),此时(01)串表示为("0 0 1")(3)的位置在串最右(原数集中(3)最大),左右不可能有数和它构成等差序列。

    然后选定(2),此时(01)串表示为“(0 1 1)”,以(2)的位置为中心向左数,得到(0);向右数,在对称位置得到(1),这说明“比(2)(1)的数”和“比(2)(1)的数”一个选了(在左边)一个没选(在右边),那么它们就能构成等差序列了。

    存储(hash)以判断(01)串是否相等,用线段树维护区间(hash)以方便查找,就大功告成了。

    注意:由于是要判断一个位置左右“对称位置”是否不等,所以要存正序和逆序的(hash)。再举个例子:

    (01)串:0 1 0 1 [1] 0 1 1 0 1,从中心位置向左数得到的串是“1 0 1 0”,向右数得到的是“0 1 1 0”(两边长度要保持等于最短的一边的长度)。

    此处引用Bzoj2124 等差子序列

    Luogu 2221

    丢一篇题解

  • 相关阅读:
    Windows下安装并设置Redis
    Android平台相机接口的应用
    Struts(十五):主题
    Struts(十四):通用标签-form表单
    Struts(十三):通用标签
    Struts(十二):异常处理:exception-mapping元素
    Struts(十一):OGNL表达式(二)
    Struts(十):OGNL表达式(一)
    A*算法
    Centos:如何查找安装的jdk的目录
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/12267051.html
Copyright © 2011-2022 走看看