• 【POJ Challenge】生日礼物 加强m子段和


    还是链表跟二叉堆的双映射
    //#include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>                    
    #include<stack>
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip> 
    #include<bitset>
    using namespace std;         //
    
    #define ll long long  
    #define ull unsigned long long
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++) 
    #define sqr(a) (a)*(a)
    #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    ll qp(ll a,ll b,ll mod){
    	ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
    }
    struct DOT{ll x;ll y;};
    inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} 
    const int dx[4]={0,0,-1,1};
    const int dy[4]={1,-1,0,0};
    const int inf=0x3f3f3f3f; 
    const ll Linf=0x3f3f3f3f3f3f3f3f;
    
    const ll mod=1e9+7;;
    const int maxn=2e5+3;
    
    int ans;
    
    struct heap{
    	int v,x,av;
    }h[maxn];int sz;
    int n,m,a[maxn];//read
    int cnt,v[maxn];//正块个数
    int tot;		//选择数
    
    int pre[maxn],nxt[maxn],pos[maxn];
    
    void pushup(int x){
    	while(h[x].av<h[x>>1].av){
    		pos[h[x>>1].x]=x;
    		swap(h[x],h[x>>1]);
    		x=x>>1;
    	}
    	pos[h[x].x]=x;
    }
    void push(int v,int x){
    	sz++;h[sz].v=v;h[sz].x=x;h[sz].av=abs(v);
    	pos[x]=sz;
    	pushup(sz);
    }
    void pushdown(int x){
    	int to;
    	while((x<<1)<=sz){
    		to=(x<<1);
    		if(to<sz && h[to].av>h[to+1].av)to++;
    		if(h[x].av>h[to].av){
    			pos[h[to].x]=x;
    			swap(h[to],h[x]);
    			x=to;
    		}else break;
    	}
    	pos[h[x].x]=x;
    }
    void del(int x){
    	h[x].av=inf;
    	pushdown(x);
    }
    
    void solve(){
    	int a,b;heap k;
    	for(int i=1;i<=cnt;i++)push(v[i],i);
    	while(tot>m){
    		tot--;
    		k=h[1];
    		if(pre[k.x]==-1){
    			if(k.v>0){ans-=k.v;del(1);}
    			else{del(1);tot++;}
    			pre[nxt[k.x]]=-1;
    		}else if(nxt[k.x]==-1){
    			if(k.v>0){ans-=k.v;del(1);}
    			else{del(1);tot++;}
    			nxt[pre[k.x]]=-1;
    		}else{
    			ans-=k.av;
    			a=nxt[k.x];b=pre[k.x];
    			pre[k.x]=pre[b];nxt[pre[b]]=k.x;
    			nxt[k.x]=nxt[a];pre[nxt[a]]=k.x;
    			h[1].av=h[pos[a]].av+h[pos[b]].av-h[1].av;
    			h[1].v+=h[pos[a]].v+h[pos[b]].v;
    			pushdown(1);
    			del(pos[a]);del(pos[b]);
    		}
    	}
    	printf("%d
    ",ans);
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	int tmp=0;
    	for(int i=1;i<=n;i++){
    		int x;scanf("%d",&x);
    		a[++tmp]=x;
    		if(a[tmp]==0)tmp--;
    	}
    	v[++cnt]=a[1];
    	for(int i=2;i<=tmp;i++){
    		if(a[i]*a[i-1]>0)v[cnt]+=a[i];
    		else v[++cnt]=a[i];
    	}
    	for(int i=1;i<=cnt;i++)if(v[i]>0){ans+=v[i];tot++;}
    	for(int i=1;i<=cnt;i++){nxt[i]=i+1;pre[i]=i-1;}
    	nxt[cnt]=-1;pre[1]=-1;
    	solve();
    }

  • 相关阅读:
    主流浏览器的内核私有属性css前缀
    判断一个js对象是否是Array,最准确的方法
    JavaScript的void运算符
    js闭包面试题
    请问何为混合应用 (Hybrid APP) ,与原生 Native 应用相比它的优劣势
    将闭包返回赋值给两个变量,执行这两个闭包变量
    js操作符“+”前后的类型转换
    js基本类型和基本包装类型的区别
    只能输入零和非零开头的数字的正则表达式
    将一个非匿名函数赋值给变量再执行这个非匿名函数会如何
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611194.html
Copyright © 2020-2023  润新知