zoukankan      html  css  js  c++  java
  • [bzoj3747][POI2015]Kinoman_线段树

    Kinoman bzoj-3747 POI-2015

    题目大意:有m部电影,第i部电影的好看值为w[i]。现在放了n天电影,请你选择一段区间l~r使得l到r之间的好看值总和最大。特别地,如果同一种电影放了两遍及以上,那么这种电影的好看值将不会被获得。

    注释:$1le m le n le 10^6$。

    想法:和rmq problem类似的,我们处理出每一个位置pos右边第一个和pos上电影种类相同的位置nxt[pos]。然后,我从1-n扫一遍,每次讲l+1到nxt[l]-1之间的值加上w[a[l]],这个过程可以用线段树维护。

    最后,附上丑陋的代码... ...

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1000050
    #define lson pos<<1
    #define rson pos<<1|1
    typedef long long ll;
    ll t[N<<2],lazy[N<<2];
    int f[N],w[N],nxt[N],n,m,now[N];
    char nc()
    {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd()
    {
        register int x=0;
        register char s=nc();
        while(s<'0'||s>'9')s=nc();
        while(s>='0'&&s<='9')x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    void pushdown(int pos)
    {
    	if(!lazy[pos]) return;
    	ll d=lazy[pos];
    	lazy[lson]+=d; lazy[rson]+=d;
    	t[lson]+=d; t[rson]+=d;
    	lazy[pos]=0;
    }
    void update(int l,int r,int x,int y,ll v,int pos)
    {
    	if(x<=l&&y>=r)
    	{
    		t[pos]+=v; lazy[pos]+=v;
    		return;
    	}
    	pushdown(pos);
    	int mid=(l+r)>>1;
    	if(x<=mid) update(l,mid,x,y,v,lson);
    	if(y>mid) update(mid+1,r,x,y,v,rson);
    	t[pos]=max(t[lson],t[rson]);
    }
    int main()
    {
    	n=rd(),m=rd();
    	for(int i=1;i<=n;i++)
    	{
    		f[i]=rd();
    	}
    	for(int i=1;i<=m;i++)
    	{
    		w[i]=rd();
    	}
    	for(int i=n;i;i--)
    	{
    		nxt[i]=now[f[i]];
    		now[f[i]]=i;
    	}
    	for(int i=1;i<=m;i++)
    	{
    		if(now[i])
    		{
    			if(!nxt[now[i]]) update(1,n,now[i],n,w[i],1);
    			else update(1,n,now[i],nxt[now[i]]-1,w[i],1);
    		}
    	}
    	ll ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		ans=max(ans,t[1]);
    		if(nxt[i])
    		{
    			update(1,n,i,nxt[i]-1,-w[f[i]],1);
    			if(nxt[nxt[i]]) update(1,n,nxt[i],nxt[nxt[i]]-1,w[f[i]],1);
    			else update(1,n,nxt[i],n,w[f[i]],1);
    		}
    		else update(1,n,i,n,-w[f[i]],1);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }

    小结:线段树能干好多事情啊qwq

  • 相关阅读:
    生产者消费者模型
    进程对象及其他方法、僵尸进程与孤儿进程(了解)、互斥锁、进程间通信、IPC机制、生产者消费者模型
    并发编程总结
    京东618一元抢宝系统的架构优化读后感
    阿里游戏高可用架构设计实践 ------读后感
    以《淘宝网》为例,描绘质量属性的六个常见属性场景
    余额宝技术架构及演进-----读后感
    《架构漫谈》---读后感
    心理小程序开发进度七
    心理小程序开发进度九
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9085045.html
Copyright © 2011-2022 走看看