http://codeforces.com/contest/1343/problem/D
题意:
数组n,每个数 。现在要求变化最少的数,使得:
- 每个数
- 对于所有的 , 相同
解析:
对于每个 ,对 的位置贡献为0,假设可以一次到达的区间为 ,对 的位置贡献为1,其他位置为2。
最后求一个最小值。
解析:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<limits.h>
using namespace std;
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define lson (rt<<1)
#define rson ((rt<<1)|1)
#define mid (l+r>>1)
const int maxn=4e5+9;
int n;
//*********此模板(rt,l,r)==(1,1,n)******************
int trmin[maxn<<2];
int laz[maxn<<2];
void build(int rt,int l,int r){
trmin[rt]=laz[rt]=0;
if(l==r){return;}
build(lson,l,mid);
build(rson,mid+1,r);
}
void pushdown(int rt){
if(laz[rt]){
trmin[lson]+=laz[rt];
trmin[rson]+=laz[rt];
laz[lson]+=laz[rt];
laz[rson]+=laz[rt];
laz[rt]=0;
}
}
void update(int rt,int l,int r,int L,int R,int Val){
if(L<=l&&R>=r){
trmin[rt]+=Val;
laz[rt]+=Val;
return;
}
pushdown(rt);
if(L<=mid)update(lson,l,mid,L,R,Val);
if(R>mid) update(rson,mid+1,r,L,R,Val);
trmin[rt]=min(trmin[lson],trmin[rson]);
}
int a[maxn];
int main(){
int t;scanf("%d",&t);
while(t--){
int n,k;
scanf("%d%d",&n,&k);
rep(i,1,n){
scanf("%d",a+i);
}
build(1,1,2*k);
rep(i,1,n/2){
int op=a[i]+a[n-i+1];
int l=max(1,op-max(a[i]-1,a[n-i+1]-1));
int r=min(2*k,op+max(k-a[i],k-a[n-i+1]));
// printf("--%d %d %d\n",op,l,r);
update(1,1,2*k,1,2*k,2);
update(1,1,2*k,l,r,-1);
update(1,1,2*k,op,op,-1);
}
printf("%d\n",trmin[1]);
}
}
/*
1
6 6
5 2 6 1 3 4
*/