zoukankan      html  css  js  c++  java
  • BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)

    1367: [Baltic2004]sequence

    Time Limit: 20 Sec   Memory Limit: 64 MB
    Submit: 521   Solved: 159
    [ Submit][ Status]

    Description

    Input

    Output

    一个整数R

    Sample Input

    7
    9
    4
    8
    20
    14
    15
    18

    Sample Output

    13

    HINT

    所求的Z序列为6,7,8,13,14,15,18.
    R=13


    左偏树+1

    这题裸裸的左偏树,我却各种WA。。。。

    结果发现 左偏树合并 a*b==0 会乘爆掉。。。掉节操。。。。。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<functional>
    #include<iostream>
    #include<cmath>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Fork(i,k,n) for(int i=k;i<=n;i++)
    #define Rep(i,n) for(int i=0;i<n;i++)
    #define ForD(i,n) for(int i=n;i;i--)
    #define RepD(i,n) for(int i=n;i>=0;i--)
    #define Forp(x) for(int p=pre[x];p;p=next[p])
    #define Lson (x<<1)
    #define Rson ((x<<1)+1)
    #define MEM(a) memset(a,0,sizeof(a));
    #define MEMI(a) memset(a,127,sizeof(a));
    #define MEMi(a) memset(a,128,sizeof(a));
    #define INF (2139062143)
    #define F (100000007)
    #define MAXN (1300000+10)
    long long mul(long long a,long long b){return (a*b)%F;}
    long long add(long long a,long long b){return (a+b)%F;}
    long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
    typedef long long ll;
    int father[MAXN];
    int getfather(int x)
    {
    	if (father[x]==x) return x;
    	father[x]=getfather(father[x]);
    	return father[x];
    }
    struct node
    {
    	ll v;
    	int dis,ch[2];
    	node():v(0),dis(0){ch[0]=ch[1]=0;}
    	node(ll _v):v(_v),dis(0){ch[0]=ch[1]=0;}
    }q[MAXN];
    int merge(int a,int b)
    {
    	if (a==0||b==0) return a+b;
    	if (q[a].v<q[b].v) swap(a,b);
    	q[a].ch[1]=merge(q[a].ch[1],b);
    	if (q[q[a].ch[0]].dis<q[q[a].ch[1]].dis) swap(q[a].ch[0],q[a].ch[1]);
    	if (q[a].ch[1]) q[a].dis=q[q[a].ch[1]].dis+1;else q[a].dis=0;
    	return a;
    }
    int root[MAXN],tot=0;
    int pop(int a)
    {
    	int p=merge(q[a].ch[0],q[a].ch[1]);
    	return p;
    }
    int n,siz[MAXN],l[MAXN],r[MAXN];
    ll a[MAXN];
    ll abs2(ll a,ll b){return a-b>0?a-b:b-a;}
    int main()
    {
    //	freopen("bzoj1367.in","r",stdin);
    	scanf("%d",&n);
    	For(i,n) scanf("%lld",&a[i]),a[i]-=(long long)i,father[i]=i,q[i].v=a[i];
    	For(i,n)
    	{
    		siz[++tot]=1;root[tot]=i;l[tot]=r[tot]=i;
    		while (tot>1&&q[root[tot]].v<=q[root[tot-1]].v)
    		{
    			int ru=root[tot-1],rv=root[tot];
    			Fork(j,l[tot],r[tot])
    			{
    				q[j]=node(a[j]);
    				ru=merge(ru,j);
    			}
    			siz[tot-1]+=r[tot]-l[tot]+1;r[tot-1]=r[tot];tot--;
    			while (siz[tot]>(r[tot]-l[tot]+2)/2) ru=pop(ru),siz[tot]--;
    			root[tot]=ru;			
    		}
    //		For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;	cout<<endl;
    	}
    	//For(i,n) cout<<a[i]<<' ';cout<<endl;
    	//For(i,tot) cout<<siz[i]<<' ';cout<<endl;
    	
    	//For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;	
    	
    	ll ans=0;
    	For(i,tot)
    	{
    		Fork(j,l[i],r[i]) ans+=abs2(q[root[i]].v,a[j]);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    


    第二Sol-贪心:

    假想有2数列A,B

    A的中位数<B的中位数 

    A的中位数>(B+C)的中位数 

    则(A+B+C)的中位数≤A的中位数<B的中位数

    所以A中位数,B中位数往上的部分去掉,不影响结果


    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<functional>
    #include<iostream>
    #include<cmath>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Fork(i,k,n) for(int i=k;i<=n;i++)
    #define Rep(i,n) for(int i=0;i<n;i++)
    #define ForD(i,n) for(int i=n;i;i--)
    #define RepD(i,n) for(int i=n;i>=0;i--)
    #define Forp(x) for(int p=pre[x];p;p=next[p])
    #define Lson (x<<1)
    #define Rson ((x<<1)+1)
    #define MEM(a) memset(a,0,sizeof(a));
    #define MEMI(a) memset(a,127,sizeof(a));
    #define MEMi(a) memset(a,128,sizeof(a));
    #define INF (2139062143)
    #define MAXN (1000000+10)
    typedef long long ll;
    struct node
    {
    	int v,dis,ch[2];
    	node():v(0),dis(0){ch[0]=ch[1]=0;}
    	node(int _v):v(_v),dis(0){ch[0]=ch[1]=0;}
    }q[MAXN];
    int merge(int a,int b)
    {
    	if (a==0||b==0) return a+b;
    	if (q[a].v<q[b].v) swap(a,b);
    	q[a].ch[1]=merge(q[a].ch[1],b);
    	if (q[q[a].ch[0]].dis<q[q[a].ch[1]].dis) swap(q[a].ch[0],q[a].ch[1]);
    	q[a].dis=q[q[a].ch[1]].dis+1;
    	return a;
    }
    int root[MAXN],tot=0;
    int pop(int a)
    {
    	int p=merge(q[a].ch[0],q[a].ch[1]);
    	return p;
    }
    int n,siz[MAXN]={0},l[MAXN]={0},r[MAXN]={0};
    int a[MAXN]={0};
    ll abs2(ll a,ll b){return a-b>0?a-b:b-a;}
    int main()
    {
    	freopen("bzoj1367.in","r",stdin);
    	scanf("%d",&n);
    	For(i,n)
    	{
    		scanf("%d",&a[i]),a[i]-=i;q[i].v=a[i];
    	}
    	For(i,n)
    	{
    		siz[++tot]=1;root[tot]=i;l[tot]=r[tot]=i;
    		while (tot>1&&q[root[tot-1]].v>q[root[tot]].v)
    		{
    			int ru=root[tot-1],rv=root[tot];
    			/*
    			Fork(j,l[tot],r[tot])
    			{
    				q[j]=node(a[j]);
    				ru=merge(ru,j);
    			}*/
    			ru=merge(ru,rv);int b=((r[tot-1]-l[tot-1]+1)%2)+((r[tot]-l[tot]+1)%2);
    			siz[tot-1]+=siz[tot];r[tot-1]=r[tot];tot--;
    			if (b==2) ru=pop(ru),siz[tot]--;
    			root[tot]=ru;			
    //		For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;	cout<<endl;
    		}
    	}
    //	For(i,n) cout<<a[i]<<' ';cout<<endl;
    //	For(i,tot) cout<<siz[i]<<' ';cout<<endl;
    	
    //	For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;	
    	
    	ll ans=0;
    	For(i,tot)
    	{
    		Fork(j,l[i],r[i]) ans+=abs2(q[root[i]].v,a[j]);
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    





  • 相关阅读:
    vs code插件
    各大厂RTSP取流的URI
    关于VLC无法播放rtsp的问题分析
    VLC查看日志的方法
    wireshark的过滤命令
    vs编译完提示不支持尝试的执行操作
    vs2015的密钥
    VS制作dll、def文件的使用、dll加入工程使用
    python之NLP数据清洗
    python 生成词云
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3188498.html
Copyright © 2011-2022 走看看