HDU 3874 Necklace

HDU 3874 Necklace
树状数组的应用。
采用离线算法:先按询问的右端点排序,然后依次把数字插入到树状数组里面,pos[i]记录数字i上一次在数组里面出现的位置,如果i已经出现过,删除之前的,添加到当前的位置。遇到可以处理的询问则处理,同时存储结果。
以下是我的代码:
#include < iostream >
#include
< algorithm >
#include
< cstdio >
#include
< cstring >
#define  lowbit(x) ((x)&(-(x)))
using   namespace  std;
const   int  kMaxn( 50007 );
const   int  kMaxm( 200007 );
const   int  kMaxv( 1000007 );

struct  Interval
{
    
int  a,b;
    
int  id;
};
bool   operator < ( const  Interval  & a, const  Interval  & b)
{
    
return  (a.b < b.b);
}

int  n,m,r[kMaxn];
Interval query[kMaxm];
long   long  bit[kMaxn],ans[kMaxm];
int  pos[kMaxv];

void  Add( int  x, int  delta)
{
    
for ( int  i = x;i <= n;i += lowbit(i))
        bit[i]
+= delta;
}

long   long  Sum( int  x)
{
    
long   long  re( 0 );
    
for ( int  i = x;i > 0 ;i -= lowbit(i))
        re
+= bit[i];
    
return  re;
}

int  main()
{
    
// freopen("data.in","r",stdin);

    
int  T;
    scanf(
" %d " , & T);
    
while (T -- )
    {
        scanf(
" %d " , & n);
        
for ( int  i = 1 ;i <= n;i ++ )
            scanf(
" %d " , & r[i]);
        scanf(
" %d " , & m);
        
for ( int  i = 1 ;i <= m;i ++ )
        {
            scanf(
" %d%d " , & query[i].a, & query[i].b);
            query[i].id
= i;
        }

        
//   Input

        sort(query
+ 1 ,query + m + 1 );
        memset(bit,
0 , sizeof (bit));
        memset(pos,
- 1 , sizeof (pos));

        
for ( int  i = 1 ,j = 1 ;i <= &&  j <= m;i ++ )
        {
            Add(i,r[i]);
            
if (pos[r[i]] !=- 1 )
                Add(pos[r[i]],
- r[i]);
            pos[r[i]]
= i;

            
while (i == query[j].b)
            {
                ans[query[j].id]
= Sum(query[j].b) - Sum(query[j].a - 1 );
                j
++ ;
            }
        }

        
for ( int  i = 1 ;i <= m;i ++ )
            printf(
" %I64d\n " ,ans[i]);
    }

    
return   0 ;
}

你可能感兴趣的:(HDU 3874 Necklace)