CodeForces - 1343D Constant Palindrome Sum(思维+差分数组)
题目链接:点击查看
题目大意:给出 n 个数,保证 n 是偶数,且每个数的范围都在 [ 1 , k ] 之间,现在问我们至少需要给多少个数重新赋值,使得可以满足条件:
- 所有的数的值域都在 [ 1 , k ] 之间
- 对于 i ∈ [ 1 , n/2 ] ,满足 a[ i ] + a[ n - i + 1 ] = x ,且所有的 x 都相等
题目分析:不难看出是个贪心问题,但是如果真的以贪心的角度去想又有点难想,想过猜结论直接实现,直接WA了,又想过三分找最小值,打个表一看发现并没有单调性,最后比赛的时候也没做出这个题,菜炸了,赛后看了别人代码后才豁然开朗
首先对于每一对 a[ i ] 和 a[ n - i + 1 ] 来说都是独立的,所以我们只需要讨论一组即可,对于某一组 a[ i ] 和 a[ n - i + 1 ] 来说,不难看出:
- 改变 0 个数后的可达范围为 [ a[ i ] + a[ n - i + 1 ] , a[ i ] + a[ n - i + 1 ] ]
- 改变 1 个数后的可达范围为 [ min( a[ i ] , a[ n - i + 1 ] ) + 1 , max( a[ i ] , a[ n - i + 1 ] ) + k ]
- 改变 2 个数后的可达范围为 [ 2 , 2 * k ]
换句话说:
- 如果最后的 x 为 a[ i ] + a[ n - i + 1 ] 的话,那么这对数据的贡献为 0
- 如果最后的 x 在 [ min( a[ i ] , a[ n - i + 1 ] ) + 1 , max( a[ i ] , a[ n - i + 1 ] ) + k ] 这个范围内,那么这对数据的贡献为 1
- 否则贡献为 2
看到这里应该不难想到区间问题了,剩下的就可以直接用线段树解决了,需要用到线段树的区间更新,初始时建立以 [ 2 , 2 * k ] 为下标的线段树,用来记录值为 x 时的贡献值,对于每一对数据:
- [ 2 , 2 * k ] 内加二
- [ min( a[ i ] , a[ n - i + 1 ] ) + 1 , max( a[ i ] , a[ n - i + 1 ] ) + k ] 内减一
- [ a[ i ] + a[ n - i + 1 ] , a[ i ] + a[ n - i + 1 ] ] 内减一
最后维护一下最小值就是答案了,实现很简单,只是用到了线段树的区间维护和单点查询
不过这个题还有个更简单的办法,就是使用差分数组实现,原理和上面讲的没差别,就是换了一种实现方法,具体的看代码吧,比较清晰易懂
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;int a[N],cnt[N<<1];int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int w;cin>>w;while(w--){int n,k;scanf("%d%d",&n,&k);for(int i=1;i<=2*k;i++)cnt[i]=0;for(int i=1;i<=n;i++)scanf("%d",a+i);for(int i=1;i<=n/2;i++){cnt[1]+=2;cnt[min(a[i],a[n-i+1])+1]--;cnt[max(a[i],a[n-i+1])+k+1]++;cnt[a[i]+a[n-i+1]]--;cnt[a[i]+a[n-i+1]+1]++;}int ans=inf;for(int i=1;i<=2*k;i++){cnt[i]+=cnt[i-1];ans=min(ans,cnt[i]);}printf("%d\n",ans);}return 0;
}
CodeForces - 1343D Constant Palindrome Sum(思维+差分数组)相关推荐
- Codeforces Round #636 (Div. 3) D. Constant Palindrome Sum 思维 + 差分
传送门 文章目录 题意: 思路: 题意: 思路: 首先有一个显然的性质就是每组操作最多不会超过两次. 很容易想到一个很暴力的思路,就是枚举x∈[1,2∗k]x \in [1,2*k]x∈[1,2∗k] ...
- Codeforces Round #636 (Div. 3) D.Constant Palindrome Sum
Codeforces Round #636 (Div. 3) D.Constant Palindrome Sum 题目链接 You are given an array a consisting of ...
- D. Constant Palindrome Sum
题目:D. Constant Palindrome Sum 题解: 在题目中a[i]和a[n-i+1]的和总共会有n/2个,:判断这n/2个数 变成其他数字需要修改几次,然后利用差分在这一段区间同时加 ...
- Codeforces Round #636 (Div. 3)D. Constant Palindrome Sum
传送门-链接 题意:输入一个n和k,第二行输入一个长度为n的数组a,且保证了n为一个偶数,数组a中的每一个元素都不大于k,你可以修改多次,使得a[i]+a[n-i+1]=x(x为某个确定的值),你需要 ...
- Greg and Array CodeForces - 296C(差分数组+线段树)
Greg has an array a = a1, a2, -, an and m operations. Each operation looks as: li, ri, di, (1 ≤ li ≤ ...
- Codeforces Round #782 (Div. 2)-D. Reverse Sort Sum(树状数组)
题目链接:Problem - D - Codeforces 题意:给定一个 01 序列 ,对 区间分别进行递增排序,得到 个序列,现给定 序列, ,即所有序列第 位的和.求给定 序列所对应的原 ...
- C. Virus(差分数组,思维)
原题链接: There are nn houses numbered from 11 to nn on a circle. For each 1≤i≤n−11≤i≤n−1, house ii and ...
- 差分数组 and 树上差分
差分数组 定义 百度百科中的差分定义 //其实这完全和要讲的没关系 qwq 进去看了之后是不是觉得看不懂? 那我简单概括一下qwq 差分数组de定义:记录当前位置的数与上一位置的数的差值. 栗子 容易 ...
- Gym - 101775J Straight Master(差分数组)
题目链接:点击查看 题目大意:给出n种数,每种数有a[i]个,每3-5种连续的数都可以被消去,现在问给出的所有数字最后能否全部消去 题目分析:正难则反,题目问能否将数字全部消去,我们不妨设一开始的起点 ...
最新文章
- 人脸识别loss加强
- python 列表加入_加入python中的列表列表
- 微软在Build 2016开发者大会中发布 “认知服务”,牛津计划有正式名字啦!
- 梦想还是要有的,万一实现了呢
- 1.16 24点游戏
- markdown入门4--矩阵空格公式方程组
- 【BZOJ4660】Crazy Rabbit 结论+DP
- python人员管理系统_python实例_员工管理系统
- C#/VB.NET 合并PDF页面
- 股票实时行情接口如何获得快照历史数据?
- ubuntu ogv
- 如何快速实现西门子S7-200/300 PLC转Modbus-TCP协议与第三方数据对接
- 别再问什么是数据库分库分表了,看这里!
- 全志H3停产,A40I/T3更胜一筹--CoM-X40I核心模块来了
- 解决python爬虫出现的521问题
- java tcp 乱码_Java和C++通过Socket通信中文乱码的解决
- 利用宝塔搭建在线文件收取助手-easypicker2
- 主流 html5播放器,10 个最佳 HTML5 音频播放器推荐
- Vivado 综合后工程
- 全球富豪排行-国内富豪