zoukankan      html  css  js  c++  java
  • BZOJ 3747 POI2015 Kinoman 段树

    标题效果:有m点,每个点都有一个权值。现在我们有这个m为点的长度n该序列,寻求区间,它仅出现一次在正确的点区间内值和最大

    想了很久,甚至神标题,奔说是水的问题……我醉了

    枚举左点 对于每个请求留点右键点 树维护最大值

    考虑每一个数对答案的贡献 记录一个数组next表示这个位置上的点下一次出现的位置 那么这个点贡献的作用范围就是[i,next[i]-1] 假设没有next就是[i,n]

    于是我们先把全部第一个出现的数对答案的贡献增加线段树 然后从左到右扫一遍 每次统计完答案之后把i对答案的贡献去除 然后把next[i]对答案的贡献增加线段树

    这常数我也是醉了……速度倒数第二啥的 正解一定不是这种……

    此外POI2015是我穿错年代了?

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define M 1001001
    using namespace std;
    struct Segtree{
    	Segtree *ls,*rs;
    	long long num,mark;
    	void Build_Tree(int x,int y);
    	void Update(int x,int y,int l,int r,long long val);
    	long long Get_Ans(int x,int y,int l,int r);
    }*root=new Segtree,mempool[M<<1],*C=mempool;
    int n,m;
    int a[M],w[M],next[M],last[M];
    bool v[M];
    long long ans;
    void Segtree :: Build_Tree(int x,int y)
    {
    	int mid=x+y>>1;
    	num=0;mark=0;
    	if(x==y) return ;
    	ls=C++;rs=C++;
    	ls->Build_Tree(x,mid);
    	rs->Build_Tree(mid+1,y);
    }
    void Segtree :: Update(int x,int y,int l,int r,long long val)
    {
    	int mid=x+y>>1;
    	if(x==l&&y==r)
    	{
    		num+=val;
    		mark+=val;
    		return ;
    	}
    	if(mark)
    	{
    		ls->num+=mark;
    		rs->num+=mark;
    		ls->mark+=mark;
    		rs->mark+=mark;
    		mark=0;
    	}
    	if(r<=mid) ls->Update(x,mid,l,r,val);
    	else if(l>mid) rs->Update(mid+1,y,l,r,val);
    	else ls->Update(x,mid,l,mid,val),rs->Update(mid+1,y,mid+1,r,val);
    	num=max(ls->num,rs->num);
    }
    long long Segtree ::  Get_Ans(int x,int y,int l,int r)
    {
    	int mid=x+y>>1;
    	if(x==l&&y==r)
    		return num;
    	if(mark)
    	{
    		ls->num+=mark;
    		rs->num+=mark;
    		ls->mark+=mark;
    		rs->mark+=mark;
    		mark=0;
    	}
    	if(r<=mid) return ls->Get_Ans(x,mid,l,r);
    	if(l> mid) return rs->Get_Ans(mid+1,y,l,r);
    	return max( ls->Get_Ans(x,mid,l,mid) , rs->Get_Ans(mid+1,y,mid+1,r) );
    }
    int main()
    {
    	int i;
    	cin>>n>>m;
    	for(i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for(i=1;i<=m;i++)
    		scanf("%d",&w[i]);
    	for(i=1;i<=n;i++)
    	{
    		if(last[a[i]])
    			next[last[a[i]]]=i;
    		else
    			v[i]=1;
    		last[a[i]]=i;
    	}
    	root->Build_Tree(1,n);
    	for(i=1;i<=n;i++)
    		if(v[i])
    			root->Update(1,n,i,next[i]?next[i]-1:n,w[a[i]]);
    	for(i=1;i<=n;i++)
    	{
    		ans=max(ans, root->Get_Ans(1,n,i,n) );
    		root->Update(1,n,i,next[i]?next[i]-1:n,-w[a[i]]);
    		if(next[i])
    			root->Update(1,n,next[i],next[next[i]]?next[next[i]]-1:n,w[a[next[i]]]);
    	}
    	cout<<ans<<endl;
    }
    


  • 相关阅读:
    iOS 定位坐标不准确的相关整理及解决方案汇总
    ASIHTTPRequest 类库在iOS 7.0中,会有一些报错警告,需要稍作修改
    2013年9月29日 iOS 周报
    适配iOS7之—UITableView和UISearchBar
    IOS开发~开机启动&无限后台运行&监听进程
    IOS开发~灵活使用 dismissViewControllerAnimated / dismissModalViewControllerAnimated
    IOS7开发~API变化
    IOS7开发~NSAttributedString
    IOS7开发~新UI学起(三)
    关于14道魔鬼js考题的整理
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4605178.html
Copyright © 2011-2022 走看看