zoukankan      html  css  js  c++  java
  • Codeforces Round #636 (Div. 3) A~D

    Codeforces Round #636 (Div. 3) A~D

    http://codeforces.com/contest/1343/

    A. Candies

    题意

    给定一个 (n) ,询问任意一个 (x) 满足 (x+2x+4x+⋯+2^{k−1}x=n,kgt1),题目保证存在至少一个 (x) 满足条件。

    解题

    等比数列求和 (1+2+2^2+...+2^{k-1} = 2^k-1),遍历寻找 (2^k-1)(n) 的因子的情况。

    for i in range(int(input())):	
        pow2 = 4;n=int(input())
        while pow2-1<=n:
            if(n%(pow2-1)==0):
                print(n//(pow2-1))
                break
            pow2 *= 2
    

    B. Balanced Array

    题意

    给定一个偶数 (n) ,求任意一个长度为 (n) 且满足下述条件的序列:

    • (n/2) 个元素是偶数
    • (n/2) 和元素是奇数
    • 所有的元素都是唯一的
    • 前半段和与后半段和相等

    如果序列不存在输出 “NO” ,存在输出 “YES” 并在第二行输出这个序列。

    解题

    分情况讨论,当 (n/2) 是奇数时,奇数个偶数相加为偶数,奇数个奇数相加为奇数,前后半段和不可能相等,所以此时不存在目标序列。

    (n/2) 是偶数时,前半段以 (2,4,6,...,2i-2,2i) 的形式填充,其和为 (sum_1 = i(i+1) = frac{n^2}{4}+frac{n}{2}) 。后半段以 (1,3,5,..,2i-5,2i-3,x) 的形式填充,其和为 (sum_2 = (frac{n}{2}-1)^2+x) ,前后两段和相等,可以求出 (x = frac{3}{2}n-1) 。这时序列满足条件。

    for t in range(int(input())):
        n = int(input())
        if((n/2)%2!=0):
            print("NO")
            continue
        else:
            print("YES")
            for i in range(1,n//2+1):
                print(2*i,end=' ')
            for i in range(1,n//2):
                print(2*i-1,end=' ')
            print(3*n//2-1)
    

    C. Alternating Subsequence

    题意

    给定一个序列(序列不含0),询问其最长正负交替子序列的最大和。

    解题

    贪心,从每个连续同符号子段中取出值最大的,组成的序列即为所求。

    for t in range(int(input())):
        n = int(input())
        l = 0;s = 0
        maxV = 0
        for a in list(map(int,input().split())):
            if(l==0 or maxV*a<0):
                s+=maxV
                l+=1
                maxV = a
            elif(maxV*a>0):
                maxV = max(maxV,a)
        print(s)
    

    D. Constant Palindrome Sum

    题意

    假设有一种正整数特殊序列,满足下列条件:

    • 所有的元素小于等于 (k) ,即 (a_ile k)
    • 任意的 (a_i+a_{n-i+1} = x)(x) 是某常数。

    给定一个正整数序列和 (k) ,询问将该序列变成上述特殊序列,最少需要替换多少个元素。

    解题

    起初以为确定 (x) 的值是关键,只需要找到使得替换次数最少的 (x) 的即可。但是这题数据 (On^2) 指定过不了,二分也没有明确的单调关系(头大

    可以先假设一下,如果我们已经确定了 (x) 的值。对于每一对元素,需要替换的个数 (d_i) 值为

    [p_{i} = min(a_i,a_{i+1}), q_{i} = max(a_i,a_{i+1}),\ d_i = left{ egin{array}{**lr**} 0 & p_i+q_{n-i+1} = x\ 1 & p_i+1le xle q_i+k, x e p_i+q_{n-i+1}\ 2 & p_i+1gt x lor q_i+klt x end{array} ight. ]

    ,设 (D_x) 为总替换次数,即 (D_x = sum_{i=1}^nd_i) 。从 ([2,2k]) 区间内的任何一个数都可以成为 (x) ,而且都有其对应的 (D_x)

    可以发现,每一对 (a_i,a_{n-i+1}) 的值都影响着一片区域内 (D_x) 的值,我们可以用线段树快速求出区间内的所有 (D_x) 。(见到区间就想线段树,已经没救了)

    • 初始化 (D_x = 0,x in [2,2k])
    • 遍历所有的元素对:
      • (p_{i} = min(a_i,a_{i+1}), q_{i} = max(a_i,a_{i+1}))
      • 区间 (xin [p_i+1,q_i+k]cap complement_u{p_i+q_i}) 内的 (D_x = D_x+1)
      • 区间 (xin [2,p_i+1)cup(q_i+k,2k]) 内的 (D_x = D_x+2)
    • 最后 (ans = min(D_x))

    复杂度 (O(nlogk)) 理论上是可以过题的,但是 Div.3 写线段树,简直是冤大头。

    再仔细思考下,我们对 (D) 序列只有一次查询,即最后的 (ans = min(D_x),xin [2,2k]) ,可以使用差分替代线段树。设 (m_x = D_{x} - D_{x-1},xgt 1) ,且 (m_1 = n) ,则 (D_x = sum_{i=1}^x m_i) 。每一对 (a_i,a_{n-i+1}) 仅仅影响着几个 (m_x) 值。

    • 初始化 (m_x = 0,xin [1,2k])
    • 遍历所有的元素对:
      • (p_{i} = min(a_i,a_{i+1}), q_{i} = max(a_i,a_{i+1}))
      • (m_{p_i+1} = m_{p_i+1}-1;)
      • (m_{p_i+q_i} = m_{p_i+q_i}-1;)
      • (m_{p_i+q_i+1} = m_{p_i+q_i+1}+1;)
      • (m_{q_i+k+1} = m_{q_i+k+1}+1;)
    • 最后 (ans = min(D_x) = min( sum_{i=1}^x m_i))

    复杂度 (O(n)),比线段树代码短几十行。

    def scanf():
        return list(map(int,input().split()))
    
    for t in range(int(input())):
        n,k = scanf()
        a = [0]+scanf()
        m = [0 for i in range(2*k+2)]
        m[1] = n
        
        for i in range(1,n//2+1):
            p = min(a[i],a[n-i+1])
            q = max(a[i],a[n-i+1])
            m[p+1]-=1
            m[p+q]-=1
            m[p+q+1]+=1
            m[q+k+1]+=1
        ans = 9e18; D=m[1]
        for mit in m[2:]:
            D += mit
            ans = min(ans,D)
        print(ans)
    
  • 相关阅读:
    utils04_搭建私有Git服务器
    utils03_clone远程仓库
    java 22
    java 22
    java 22
    java 22
    java 22
    java 22
    java 22
    java 22
  • 原文地址:https://www.cnblogs.com/DOEMsy/p/12771395.html
Copyright © 2011-2022 走看看