zoukankan      html  css  js  c++  java
  • 【LG3582】[POI2015]KIN

    【LG3582】[POI2015]KIN

    题面

    洛谷

    题解

    这题维护区间的信息有点像最大子段和,我们往最大子段和上面靠。

    对于一个颜色,我们有一个直观的想法就是将它一次出现的权值设为正,二次出现就设为负。

    但是当区间中出现次数多于两次怎么办呢?我们可以考虑从左往右扫这个序列,这个数出现在最靠右的位置时设权值为正,第二靠右出现时设权值为负,否则全部设为0,这样子的话,我们用最大子段和维护就行了。就算你只访问到一个负的权值也没关系,因为你在前面已经把这种情况的答案算进去了。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    using namespace std; 
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (!isdigit(ch) && ch != '-') ch = getchar(); 
        if (ch == '-') w = -1, ch = getchar(); 
        while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
        return w * data; 
    } 
    const int MAX_N = 1e6 + 5; 
    #define lson (o << 1) 
    #define rson (o << 1 | 1) 
    struct Node { long long ls, rs, ms, ss; } t[MAX_N << 2]; 
    void pushup(int o) { 
    	t[o].ms = t[lson].ms + t[rson].ms; 
    	t[o].ls = max(t[lson].ms + t[rson].ls, t[lson].ls); 
    	t[o].rs = max(t[rson].ms + t[lson].rs, t[rson].rs); 
    	t[o].ss = max(max(t[lson].ss, t[rson].ss), t[lson].rs + t[rson].ls); 
    } 
    void modify(int o, int l, int r, int pos, int v) { 
    	if (l == r) return (void)(t[o] = (Node){v, v, v, v}); 
    	int mid = (l + r) >> 1; 
    	if (pos <= mid) modify(lson, l, mid, pos, v); 
    	else modify(rson, mid + 1, r, pos, v); 
    	pushup(o); 
    } 
    int N, M, a[MAX_N], w[MAX_N]; 
    int pre[MAX_N], lst[MAX_N]; 
    int main () {
    #ifndef ONLINE_JUDGE 
        freopen("cpp.in", "r", stdin);
    #endif 
    	N = gi(), M = gi(); 
    	for (int i = 1; i <= N; i++) a[i] = gi(); 
    	for (int i = 1; i <= M; i++) w[i] = gi(); 
    	long long ans = 0; 
    	for (int i = 1; i <= N; i++) { 
    		pre[i] = lst[a[i]], lst[a[i]] = i; 
    		if (pre[i]) modify(1, 1, N, pre[i], -w[a[i]]); 
    		if (pre[pre[i]]) modify(1, 1, N, pre[pre[i]], 0); 
    		modify(1, 1, N, i, w[a[i]]); 
    		ans = max(ans, t[1].ss); 
    	} 
    	printf("%lld
    ", ans); 
        return 0; 
    } 
    
  • 相关阅读:
    我爱java系列之---【微服务间的认证—Feign拦截器】
    我爱java系列之---【设置权限的三种解决方案】
    581. Shortest Unsorted Continuous Subarray
    129. Sum Root to Leaf Numbers
    513. Find Bottom Left Tree Value
    515. Find Largest Value in Each Tree Row
    155. Min Stack max stack Maxpop O(1) 操作
    painting house
    Minimum Adjustment Cost
    k Sum
  • 原文地址:https://www.cnblogs.com/heyujun/p/11711486.html
Copyright © 2011-2022 走看看