• 题解——A君的问题(a)(值域线段树)


    题解——A君的问题(a)

    这道题很水,但不要问ssw02为什么要在这时做一道B层的题
    因为ssw02再换板子,而这道题就是二分值域线段树的裸题
    感谢神犇SXK提供优质的模板参考


    题目搬运

    【题目描述】

    A君来到了一个蛋糕店,蛋糕店有n个位置顺次摆放着若干蛋糕,从左到右位置编号依次递增。当有客人来的时候服务生会把有些位置的蛋糕打包给客人,也可能会在某个没有蛋糕的空位放上一个蛋糕。A君想知道在某一时刻从左数第k个蛋糕的位置。

    【输入数据】

    第一行一个正整数n,m,其中n表示位置数量,m表示客人的数量。第二行n个数为0或1,第i个数表示开始时没有蛋糕(0)或者有蛋糕(1)。接下来共m行每行俩个数p,k,其中k如上文,p表示第p个位置有无蛋糕的情况发生了变化。

    【输出数据】

    m行,每行一个数表示询问的结果,若不存在k个蛋糕则输出”-1”(不含引号)。

    解题思路

    没有思路,单点修改+单点查询(查询二分当前区间个数就可以了)

    我只是想把它当个板子记一下而已(以前的太丑了)

    AC code

    #include<bits/stdc++.h>
    using namespace std; 
    const  int  MAXN = 500005 ;
    int N , M , num , sum[ MAXN<<2 ] , a[ MAXN ] ;
    inline int read(){
    	int s=0 ; char g=getchar() ;while(g>'9'||g<'0')g=getchar() ;
    	while(g>='0'&&g<='9')s=s*10+g-'0',g=getchar();return s ;
    }
    void build( int p , int l , int r ){
    	if( l == r ){
    		sum[ p ] = a[ l ] ; return ;
    	}
    	int  mid = (l+r)>>1 ; 
    	build( p<<1 , l , mid ) ;
    	build( p<<1|1 , mid+1 , r ) ;
    	sum[ p ] = sum[ p<<1 ] + sum[ p<<1 | 1 ] ;
    }
    void  change_a( int p , int  l , int r , int x , int v ){//和普通线段树没有区别
    	sum[ p ] += v ;
    	if( l==r )return ;
    	int  mid = (l+r)>>1 ;
    	if( x <= mid )change_a( p<<1 , l , mid , x , v ) ;
    	else change_a( p<<1|1 , mid+1 , r , x , v ) ;
    	sum[ p ] = sum[ p<<1 ]+sum[ p<<1|1 ] ;
    }
    int  ask( int p , int l , int r , int k ){
    	if( l == r )return l ;
    	int  mid = (l+r)>>1 ;//二分个数,判断位置
    	if( sum[ p<<1 ] >= k )return ask( p<<1 , l , mid , k );
    	else return ask( p<<1|1 , mid+1 , r , k-sum[p<<1] );
    }
    int main(){
    	N = read() , M = read() ;
    	for( register int i = 1 ; i <= N ; ++i )
    	a[ i ] = read() , num += a[ i ] ; 
    	build( 1 , 1 , N ) ; 
    	while( M-- ){
    		int  m1 = read() , m2 = read() ;
    		if( a[ m1 ] )
    		    change_a( 1 , 1 , N , m1 , -1 ),a[m1]=0,num-- ;
    		else change_a( 1 , 1 , N , m1 , 1 ),a[m1]=1,num++ ;
    		if( m2 > num )printf("-1
    ") ;
    		else printf("%d
    ",ask( 1 , 1 , N , m2 ) ) ;
    	}
    	return 0 ;
    }
    

    它就是个板子,ssw02还要改动态区间第K大,先溜了。(本博客无任何价值)

  • 相关阅读:
    NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程?
    Groovy split竖杆注意
    使用Flask-Migrate进行管理数据库升级
    Fabric自动部署太方便了
    程序员的复仇:11行代码如何让Node.js社区鸡飞狗跳
    grails 私有库相关设置
    A successful Git branching model
    String to Date 多种格式转换
    C#搭建CEF(CEFGLUE) 环境。
    使用Win PE修改其他硬盘中的系统注册表
  • 原文地址:https://www.cnblogs.com/ssw02/p/11240582.html
Copyright © 2020-2023  润新知