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

    很套路的维护最大和子段

    #include <cmath>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <complex>
    #include <ctime>
    #include <vector>
    #define mp(x, y) make_pair(x, y)
    using namespace std;
    const int N = 1e6 + 5;
    int n, m, L;
    long long ans, res;
    int a[N], b[N];
    int pre[N], rec[N];
    bool vis[N];
    
    struct Seg{
        long long w[N << 2], ls[N << 2], rs[N << 2], sum[N << 2];
        void update(int rt){
    		sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    	    w[rt] = rs[rt << 1] + ls[rt << 1 | 1];
    	    ls[rt] = max(ls[rt << 1], sum[rt << 1] + ls[rt << 1 | 1]);
    	    rs[rt] = max(rs[rt << 1 | 1], sum[rt << 1 | 1] + rs[rt << 1]);
    	//	printf("%d %lld %lld %lld
    ", rt, w[rt], ls[rt], rs[rt]);	
    	}
    	void mdf(int rt, int l, int r, int x, int d){
    		if(l == r){sum[rt] = d, ls[rt] = rs[rt] = w[rt] = max(0, d); return;} 
    	    int mid = l + ((r - l) >> 1);
    	    if(x <= mid) mdf(rt << 1, l, mid, x, d);
    		else mdf(rt << 1 | 1, mid + 1, r, x, d);
    		update(rt);
    	}	
    }seg;
    
    int main(){
        scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; ++i)
    		scanf("%d", &a[i]), pre[i] = rec[a[i]], rec[a[i]] = i;
    	for(int i = 1; i <= m; ++i) scanf("%d", &b[i]);
    	for(int i = 1; i <= n; ++i){
    		seg.mdf(1, 1, n, i, b[a[i]]);
    		if(pre[i]) seg.mdf(1, 1, n, pre[i], -b[a[i]]);
    		if(pre[pre[i]]) seg.mdf(1, 1, n, pre[pre[i]], 0);
    	    ans = max(ans, seg.w[1]);
    	}
    	printf("%lld
    ", ans);
    	return 0;	
    }
    
  • 相关阅读:
    yii2权限控制rbac之rule详细讲解
    yii2权限控制rbac之详细操作步骤
    安装 Autoconf, Automake & Libtool
    Linux查看物理CPU个数、核数、逻辑CPU个数
    Nginx端口占用问题
    Druid加密
    Ubuntu16.04安装Zabbix3.2(快速安装教程)
    飞冰ICE
    BeiDou开源项目
    Arthas开源项目
  • 原文地址:https://www.cnblogs.com/hjmmm/p/10689044.html
Copyright © 2011-2022 走看看