zoukankan      html  css  js  c++  java
  • 【GDOI2013模拟1】删数字

    这题我们发现,只有在剩下的数是一段连续的数的时候才是最优的。

    所以,这题我们用桶来做。
    之前用线段树来做,结果T︿( ̄︶ ̄)︿了。。。
    我们用桶维护区间最小值,然后在记录一下这个差值的位置。
    不断地搞这东东就可以了。
    上标:

    #include<cstdio>
    #include<algorithm>
    #define N 1000010
    using namespace std;
    int n,K,a[N],d[N],fr[N],ans=(1<<30),tot=0;
    
    inline int read()
    {
    	int x=0,f=0; char c=getchar();
    	while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return f ? -x:x;
    }
    
    void up(int x)
    {
    	while (x>1 && d[x]<d[x>>1])
    		swap(d[x],d[x>>1]),swap(fr[x],fr[x>>1]),x>>=1;
    }
    
    void down()
    {
    	int x=1,t=x<<1;
    	if (d[t]>d[t+1] && t<tot) t++;
    	while (t<=tot)
    	{
    		if (d[t]<d[x]) 
    			swap(d[t],d[x]),swap(fr[t],fr[x]),x=t;
    		else break;
    		t=x<<1;
    		if (d[t]>d[t+1] && t<tot) t++;
    	}
    }
    
    int main()
    {
    	n=read(),K=n-read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	sort(a+1,a+n+1);
    	for (int i=2;i<=K;i++)
    		d[++tot]=a[i]-a[i-1],fr[tot]=i,up(tot);
    	ans=a[K]-a[1]+d[1];
    	for (int i=K+1;i<=n;i++)
    	{
    		d[++tot]=a[i]-a[i-1],fr[tot]=i,up(tot);
    		while (fr[1]<=i-K+1) d[1]=d[tot],fr[1]=fr[tot],tot--,down();
    		if (d[1]+a[i]-a[i-K+1]<ans) ans=d[1]+a[i]-a[i-K+1];
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    MytBatis错题分析
    Spring核心概念
    延迟与缓存
    MyBatis的关联查询
    Mabatis注解
    [leetcode]226. Invert Binary Tree翻转二叉树
    [leetcode]633. Sum of Square Numbers平方数之和
    [leetcode]296. Best Meeting Point最佳见面地点
    [leetcode]412. Fizz Buzz报数
    [leetcode]142. Linked List Cycle II找出循环链表的入口
  • 原文地址:https://www.cnblogs.com/jz929/p/11817572.html
Copyright © 2011-2022 走看看