本蒟蒻本来用莫队拿了六十分,然后来写线段树的版本,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 ;
}