zoukankan      html  css  js  c++  java
  • FJD1T3(LOJ 2773 学习轨迹)

    发现了\(FJOI\)原题
    没什么想法,想到自己考场上连\(n^2\)做法都不会就很感慨。
    考虑如果只选择一个序列的任务,那么肯定全部选择会更加优秀。
    那么考虑如果我们选择了两个序列的一部分。
    如果\(A\)中选择的部分的权值和小于\(A\)权值和的一半,且\(B\)也如此,那我们不如只选择一个序列来的优。
    我们考虑强制一个序列\(A\)选择超过一半,然后再反过来做一遍。
    那么考虑在\(A\)中第一个大于一半的位置\(p\),那么这个位置是一定要选上的,否则选择的序列全在左边,或全在右边,都不满足条件。
    那么考虑维护这个\(B\)中的序列右端,则每次都只有一个新出现\(ban\)点,考虑用线段树维护\([1...r-1,r]\)这些序列的答案。
    考虑用单调栈来维护,在每次新增 ban 掉的点时,不断将它能覆盖的点弹出,把原来的贡献删掉,在最后把现在的贡献一起加上.
    任然觉得自己考场上太蠢了。
    开始\(rush\)代码。

    LOJ 2773 学习轨迹
    //%std
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define y1 ysgh
    inline int read()
    {
    	int out = 0, fh = 1;
    	char jp = getchar();
    	while ((jp > '9' || jp < '0') && jp != '-') 
    		jp = getchar();
    	if (jp == '-') fh = -1, jp = getchar();
    	while (jp >= '0' && jp <= '9') 
    		out = out * 10 + jp - '0', jp = getchar();
    	return out * fh;
    }
    void print(int x)
    {
    	if (x >= 10) print(x / 10);
    	putchar('0' + x % 10);
    }
    void write(int x, char c)
    {
    	if (x < 0) putchar('-'), x = -x;
    	print(x);
    	putchar(c);
    }
    const int N = 5e5 + 10;
    int n, m, a[N], b[N], c[N << 1], p1, p2, p3, p4, swaped = 0;
    ll ans, suma[N], sumb[N];
    ll mx[N << 2], ext[N << 2];
    void pushup(int x)
    {
    	mx[x] = max(mx[x << 1], mx[x << 1 | 1]) + ext[x];
    }
    void BuildTree(int x, int l, int r)
    {
    	ext[x] = 0;
    	if (l == r)
    	{
    		mx[x] = suma[n] - sumb[l - 1];
    		return;
    	}
    	int mid = (l + r) >> 1;
    	BuildTree(x << 1, l, mid);
    	BuildTree(x << 1 | 1, mid + 1, r);
    	pushup(x);
    }
    void upd(int x, int l, int r, int L, int R, ll d)
    {
    	if (L <= l && r <= R)
    	{
    		mx[x] += d, ext[x] += d;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if (L <= mid)
    		upd(x << 1, l, mid, L, R, d);
    	if (R > mid)
    		upd(x << 1 | 1, mid + 1, r, L, R, d);
    	pushup(x);
    }
    int query(int x, int l, int r)
    {
    	if (l == r)
    		return l;
    	int mid = (l + r) >> 1;
    	if (mx[x] == mx[x << 1] + ext[x])
    		return query(x << 1, l, mid);
    	return query(x << 1 | 1, mid + 1, r);
    }
    void report(ll val, int a, int b, int c, int d)
    {
    	if (val > ans)
    	{
    		if (swaped)
    			swap(a, c), swap(b, d);
    		ans = val, p1 = a, p2 = b, p3 = c, p4 = d;
    	}
    }
    int tpl, tpr, sl[N], sr[N];
    void solve()
    {
    	int p = lower_bound(suma + 1, suma + n + 1, (suma[n] + 1) >> 1) - suma;
    	BuildTree(1, 1, m);
    	tpl = tpr = 0;
    	for (int i = 1; i <= m; ++i)
    	{
    		if (b[i])
    		{
    			if (b[i] <= p)
    			{
    				while (tpl && b[i] > b[sl[tpl]])
    				{
    					upd(1, 1, m, sl[tpl - 1] + 1, sl[tpl], suma[b[sl[tpl]]]);
    					--tpl;
    				}
    				upd(1, 1, m, sl[tpl] + 1, i, -suma[b[i]]);
    				sl[++tpl] = i;
    			}
    			else
    			{
    				while (tpr && b[i] < b[sr[tpr]])
    				{
    					upd(1, 1, m, sr[tpr - 1] + 1, sr[tpr], suma[n] - suma[b[sr[tpr]] - 1]);
    					--tpr;
    				}
    				upd(1, 1, m, sr[tpr] + 1, i, suma[b[i] - 1] - suma[n]);
    				sr[++tpr] = i;
    			}
    		}
    		int j = query(1, 1, m);
    		int pl = lower_bound(sl + 1, sl + tpl + 1, j) - sl;
    		int pr = lower_bound(sr + 1, sr + tpr + 1, j) - sr;
    		pl = pl <= tpl ? b[sl[pl]] + 1 : 1;
    		pr = pr <= tpr ? b[sr[pr]] - 1 : n;
    		report(sumb[i] + mx[1], pl, pr, j, i);
    	}
    }
    int main()
    {
    	n = read(), m = read();
    	for (int i = 1; i <= n; ++i) a[i] = read();
    	for (int i = 1; i <= n; ++i) suma[i] = suma[i - 1] + read();
    	for (int i = 1; i <= m; ++i) c[read()] = i;
    	for (int i = 1; i <= m; ++i) sumb[i] = sumb[i - 1] + read();
    	for (int i = 1; i <= n; ++i) a[i] = c[a[i]], b[a[i]] = i;
    	report(suma[n], 1, n, 0, 0), report(sumb[m], 0, 0, 1, m);
    	solve();
    	swap(n, m), swap(a, b), swap(suma, sumb), swaped = 1;
    	solve();
    	printf("%lld\n", ans);
    	printf("%d %d\n", p1, p2);
    	printf("%d %d\n", p3, p4);
    	return 0;
    }
    
  • 相关阅读:
    js原型杂谈
    arguments.callee.caller
    $resource
    sql的四种匹配模式
    AMD规范
    module.ngdoc
    angularjs杂谈
    浏览器前缀
    css21规范学习
    <meta>标签
  • 原文地址:https://www.cnblogs.com/dixiao/p/14661925.html
Copyright © 2011-2022 走看看