• codeforces 1438 E. Yurii Can Do Everything (暴力)


    题目链接:https://codeforces.com/contest/1438/problem/E

    根据题目性质,答案不会太大

    枚举左端点 (l), 令 (k)(a_l) 的最高位,那么可能合法的右端点 (r) 一定在区间和小于 (2^{k + 1}) 的区间内,暴力寻找右端点 (r) 即可
    正着做完以后再反着来一遍,去重即可

    而每个右端点不会被扫描超过 (lg(a_r)) 次,因为对于每一位来说,如果这一位已经被扫到过了,那么如果又被扫到,区间和必定大于等于 (2^{k+1})

    于是时间复杂度位 (O(n*log(a_i)))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> P;
    
    const int maxn = 200010;
    
    int n;
    ll a[maxn], sum[maxn];
    
    map<P, bool> mp;
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	n = read();
    	for(int i = 1 ; i <= n ; ++i) a[i] = read(), sum[i] = sum[i - 1] + a[i];
    	
    	int ans = 0;
    	for(int i = 1 ; i <= n - 2 ; ++i){ // 枚举 l 
    		int k;
    		for(int j = 30 ; j >= 0 ; --j){ // 找到最高位 1 
    			if((a[i] >> j) & 1){
    				k = j;
    				break;
    			}
    		}
    		
    		for(int j = i + 2 ; j <= n ; ++j){
    			if(sum[j - 1] - sum[i] >= (1 << (k + 1))) break;
    			if(sum[j - 1] - sum[i] == (a[i] ^ a[j])) {
    //				printf("%d %d %lld %lld
    ", i, j, sum[j - 1] - sum[i], a[i] ^ a[j]); 
    				++ans;
    				mp[make_pair(i, j)] = true;
    			}
    		}
    	}
    //	printf("
    ", ans);
    
    //	for(int i = 1 ; i <= n ; ++i){
    //		for(int j = i + 2 ; j <= n ; ++j){
    //			if(mp.find(make_pair(i, j)) != mp.end()){
    //				printf("%d %d
    ", i, j);
    //			}
    //		}
    //	} 
    
    	// 倒着做 
    	for(int i = n ; i >= 3 ; --i){ // 枚举 l 
    		int k;
    		for(int j = 30 ; j >= 0 ; --j){ // 找到最高位 1 
    			if((a[i] >> j) & 1){
    				k = j;
    				break;
    			}
    		}
    		
    		for(int j = i - 2 ; j >= 1 ; --j){
    			if(sum[i - 1] - sum[j] >= (1 << (k + 1))) break;
    			if(sum[i - 1] - sum[j] == (a[i] ^ a[j]) && (mp.find(make_pair(j, i)) == mp.end())) { //
    //				printf("%d %d %lld %lld
    ", j, i, sum[i - 1] - sum[j], a[i] ^ a[j]); 
    				++ans;
    			}
    		}
    	}
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    CF710F String Set Queries AC自动机 二进制分组
    类欧几里得学习笔记
    P2053 [SCOI2007]修车 网络流
    螺旋方阵
    灯的排列问题
    编码问题
    论文阅读博客模板
    论文阅读框架模板
    动作识别论文20191104_Probabilistic selection of frames for early action recognition in videos
    剑指offer 57. 数字序列中某一位的数字
  • 原文地址:https://www.cnblogs.com/tuchen/p/14260121.html
Copyright © 2020-2023  润新知