UVALive 6678 Judging Troubles

题意是:给你一组数组,求出存在多少个区间,满足区间内的数的xor值和and值是相等的。

我的想法是:先枚举区间左端点(假设为第 L 行),由于and的特性,从L开始,可以将[L,n)划分成32段,从L到第1段的某行的and值是全1,到第2段的某行的and值是有1个0,以此类推。那么就可以一段一段处理,而对于某一段,and值已经确定了,[a行,b行]的xor值 = [1,a] ^[1,b],可以预处理第1行到第i行的xor值,于是,可以转化成求这段区间(and值) ^ (0~L-1行的异或值)的个数,这个又可以化成两个前缀区间相减。


#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #include 
             
               #include 
              
                #include 
               
                 #include 
                
                  #include 
                  using namespace std; #define rep(i,n) for(int i=0; i 
                  
                    > mp; int Find(int l,int r,int v) { return upper_bound(mp[v].begin(),mp[v].end(),r) - lower_bound(mp[v].begin(),mp[v].end(),l); } int Log(int x) { int res = 1,cnt = 0; while(res < x) { cnt++; res <<= 1; } return cnt; } int main() { //freopen("out.txt","w",stdout); while(~scanf("%d",&n)) { rep(i,n) { //A[i] = (rand() % (1LL<<31-1)); scanf("%d",A+i); } rep(i,31) R[n][i] = n; for(int i=n-1; i>=0; i--) { rep(j,31) { if((A[i]>>j)&1) R[i][j] = R[i+1][j]; else R[i][j] = i; } } mp.clear(); repe(i,n-1) { V[i] = V[i-1] ^ A[i - 1]; mp[V[i]].push_back(i-1); } mp[V[n-1] ^ A[n-1]].push_back(n-1); ll ans = 0; rep(i,n) { rep(j,31) node[j] = Node(R[i][j],j); sort(node,node+31); int Xor = (1LL<<31) - 1 - V[i]; rep(j,31) { int l = (j ? node[j-1].r : i); if(node[j].r != l) ans += Find(l,node[j].r-1,Xor); Xor ^= (1< 
                    
                   
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值