bzoj 4240: 有趣的家庭菜园【树状数组+贪心】
2018-09-25 08:59
316 查看
以为是逆序对数……
实际上,原数组移动若干次后我们会得到一个新的下标序列,需要的移动次数是这个新下标序列的逆序对数
然后我们要让这个最小,考虑贪心先按h把下标排一遍序,然后每次询问到一种值的时候,对每个下标查询一下逆序对数,然后在满足1条件和满足2条件中取个min,最后这些值相同的下标再一起update
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=300005; int n,t ; long long ans; struct qwe { int v,id; }a ; bool cmp(const qwe &a,const qwe &b) { return a.v>b.v; } int read() { int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f; } int ques(int x) { int r=0; for(int i=x;i>=1;i-=(i&(-i))) r+=t[i]; return r; } void update(int x,int v) { for(int i=x;i<=n;i+=(i&(-i))) t[i]+=v; } int main() { n=read(); for(int i=1;i<=n;i++) a[i].v=read(),a[i].id=i; sort(a+1,a+1+n,cmp); for(int i=1;i<=n;) { int j=i; for(;a[j].v==a[i].v;j++) { int nw=ques(a[j].id); ans+=min(nw,i-1-nw); } for(;i<j;i++) update(a[i].id,1); } printf("%lld\n",ans); return 0; }
相关文章推荐
- 【bzoj4240】有趣的家庭菜园 贪心+树状数组
- 【BZOJ4240】有趣的家庭菜园 树状数组+贪心
- bzoj 4240: 有趣的家庭菜园 树状数组+贪心
- [BZOJ]4240: 有趣的家庭菜园 贪心+树状数组
- BZOJ4240 有趣的家庭菜园(贪心+树状数组)
- [BZOJ4240]有趣的家庭菜园(贪心+树状数组)
- bzoj4240 有趣的家庭菜园 树状数组
- [bzoj4240] 有趣的家庭菜园
- BZOJ4240: 有趣的家庭菜园
- [树状数组] BZOJ 4240 有趣的家庭菜园
- 【bzoj4240】有趣的家庭菜园
- BZOJ 4240 有趣的家庭菜园
- bzoj 4240: 有趣的家庭菜园
- 4240: 有趣的家庭菜园
- 【OI做题记录】【BZOJ】有趣的家庭菜园
- JOI 有趣的有趣的家庭菜园Fgarden
- [JZOJ4296]有趣的有趣的家庭菜园
- 【NOIP2015模拟11.2】有趣的有趣的家庭菜园
- 【有趣的有趣的家庭菜园】题解
- 有趣的有趣的家庭菜园