• bzoj3747: [POI2015]Kinoman


    题目链接

    bzoj3747: [POI2015]Kinoman

    题解

    维护pre[i],为i节点前一个与它相同的点的位置
    固定右端点,向左计算,得到区间内的价值最大字段,怎么计算呢,钦定这个点一定只看一遍,那么区间pre[i] + 1到i的总价值直接加上i的价值
    那么我们就只需要在pre[i]到pre[pre[i]]这段区间减掉这个值了, 因为在 per[pre[i]]之前的已经被减掉了
    那么,线段树区间修改+维护最大值

    代码

    /*
    维护pre[i],为i节点前一个与它相同的点的位置 
    固定右端点,向左计算,得到价值最大区间,怎么计算呢,钦定这个点一定只看一遍,那么区间pre[i] + 1到i的总价值直接加上i的价值
    那么我们就只需要在pre[i]到pre[pre[i]]这段区间减掉这个值了, 因为在 per[pre[i]]之前的已经被减掉了
    那么,线段树区间修改+维护最大值 
    */ 
    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
    #define LL long long 
    inline int read() { 
    	int x = 0,f = 1;
    	char c = getchar(); 
    	while(c < '0' || c > '9') c = getchar(); 
    	while(c <= '9' && c >= '0')x = x * 10 + c- '0',c = getchar(); return x; 
    } 
    int n,m; 
    const int maxn = 1000007; 
    int a[maxn],val[maxn],last[maxn],pre[maxn]; 
    LL tree[maxn << 2] ,tag[maxn << 2]; 
    void update(int x) { 
    	tree[x] = std::max(tree[x << 1],tree[x << 1 | 1]); 
    } 
    void pushdown(int x) { 
    	if(!tag[x])return; 
    	tag[x << 1] += tag[x];tag[x << 1 | 1] += tag[x]; 
    	tree[x << 1] += tag[x]; 
    	tree[x << 1 | 1] += tag[x]; 
    	tag[x] = 0; 
    } 
    void add(int x,int l,int r,int tl,int tr,int w) {
    	if(l >= tl && r <= tr) {  
    		tag[x] += w; tree[x] += w; return ; 
    	} 
    	int mid = l + r >> 1; 
    	pushdown(x); 
    	if(tl <= mid) add(x << 1,l,mid,tl,tr,w); 
    	if(tr > mid) add(x << 1 | 1,mid + 1,r,tl,tr,w); 
    	update(x);  
    } 
    int main() { 
    	n = read(),m = read(); 
    	for(int i = 1;i <= n;++ i) a[i] = read(); 
    	for(int i = 1;i <= m;++ i) val[i] = read(); 
    	for(int i = 1;i <= n;++ i) { 
    		pre[i] = last[a[i]],
    		last[a[i]] = i; 
    	} 
    	LL ans = 0; 
    	for(int i = 1;i <= n;++ i) { 
    		add(1,1,n,pre[i] + 1,i,val[a[i]]); 
    		if(pre[i]) add(1,1,n,pre[pre[i]] + 1,pre[i],-val[a[i]]); 
    		ans = std::max(ans,tree[1]); 
    	} 
    	printf("%lld
    ",ans); 
    	return 0; 
    } 
     
    
  • 相关阅读:
    使用Pandas DataFrames在Python中绘制条形图
    在Pandas DataFrames中选择行和列使用iloc,loc和ix
    如何使用[] 、. loc,iloc,.at和.iat
    Pandas 分类数据
    按索引和值对Pandas DataFrame进行排序
    可能需要的建议
    时间线
    第四章-赶路
    第三章-担忧
    lipo命令拆分、合并iOS静态库
  • 原文地址:https://www.cnblogs.com/sssy/p/9265372.html
Copyright © 2020-2023  润新知