蒟蒻玄关线段树有详细注释求调
查看原帖
蒟蒻玄关线段树有详细注释求调
950927
_luo_gu楼主2024/8/17 17:07

本蒟蒻本来用莫队拿了六十分,然后来写线段树的版本,TLE倒没有,但是全WA了。

样例完全没有问题。思路和题解区的第一篇题解一样。

以下是代码

#include <bits/stdc++.h>
#define lson ( pos << 1 )
#define rson ( pos << 1 | 1 )
using namespace std ;
struct SegTree{
	int sum ;
}tre[4000006];
//上传 
void pushup( int pos ){
	tre[pos].sum = tre[lson].sum + tre[rson].sum ;
	return ; 
}
//函数中的pos是该节点,l与r对应该节点的左边界和右边界。定义了lson是左侧儿子,rson是右侧儿子 
//单点更改 将下标为	q的元素的值更改为x 
void update( int pos , int l , int r , int q , int x ){
	if( l == r ){//如果是叶子节点,赋值然后返回 
		tre[pos].sum = x ;
		return ;
	}
	int mid = ( l + r ) >> 1 ;
	if( q <= mid ){
		update( lson , l , mid , q , x );
	} else {
		update( rson , mid+1 , r , q , x );
	}
	pushup( pos );
	return ;
}
//区间查询 从ql到qr之间的和 
int query( int pos , int l , int r , int ql , int qr ){
	if( ql <= l && qr >= r ){
		return tre[pos].sum ;
	}
	int mid = ( l + r ) >> 1 ;
	int ans = 0 ;
	if( ql <= mid ){
		ans += query( lson , l , mid , ql , qr );
	}
	if( qr > mid ){
		ans += query( rson , mid+1 , r , ql ,qr );
	}
	return ans ;
}
///快读 
int read(){
	int x = 0 , f = 1 ; 
	char c = getchar() ;
	while( c <'0' || c > '9' ){
		if( c == '-' ){
			f = -1 ;
		}
		c = getchar() ;
	}
	while( c >= '0' && c <= '9' ){
		x = ( x << 3 ) + ( x << 1 ) + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
//front对于前一个相同点位置的记录 
struct Node {
	int front ;
}node[1000006];
//ques记录询问的信息,方便排序 
struct Ques{
	int l ;
	int r ;
	int id ;
}ques[1000006] ;
//按照右侧节点顺序排序 
bool cmp ( Ques a , Ques b ){
	return a.r < b.r ; 
}
//loc记录上一个点出现的位置,ans为答案 
int n , loc[1000006] , ans[1000006], m ;
int main(){
	n = read();
	int in ;
	for( int i = 1 ; i <= n ; ++ i ){
		//输入 
		in = read();
		//83行表示下标为i的点的前一个相同的数的位置 
		node[i].front = loc[in] ;
		//loc【i】记录i这个数上一次出现的位置 
		loc[in] = i ;//更新位置的记录 
	}
	m = read() ;
	//记录 
	for( int i = 1 ; i <= m ; ++ i ){
		ques[i].l = read() ;
		ques[i].r = read() ;
		ques[i].id = i ;
	}
	int j = 1 ;
	for( int i = 0 ; i <= n ; ++ i ){
		update( 1 , 1 , n , i , 1 );//将最右侧的点加入线段树进行记录 
		if( node[i].front != 0 ){
			//此处的判断是因为初始化时的问题
			//我写的代码导致如果强行对于0为下标的点访问会访问至下标为1的点 
			update( 1 , 1 , n , node[i].front , 0 );//将上一个相同的点的位置覆盖为0 
		}
		while( ques[j].r == i ){
			//记录答案 
			ans[ques[j].id] += query( 1 , 1 , n , ques[j].l , i ); 
			j ++ ;
		}	
	}
	//输出 
	for( int i = 1 ; i <= m ; ++ i ){
		printf("%d\n",ans[i]);
	}
	return 0 ;
}
2024/8/17 17:07
加载中...