zoukankan      html  css  js  c++  java
  • 2020.3.1考试 T2 数据结构 分块+李超线段树

    将序列分块后面对每一个序列维护一个李超线段树

    操作一:整块的用李超线段树求,残余的暴力搞。

    操作二:因为 (v) 是正数,所以直接加入一条新的线段就能覆盖掉原来的线段。

    操作三:整块的用 (tag) 标记维护,残块的直接覆盖掉。

    注意题面中说操作一和操作三不会超过 (10^5),复杂度有保证。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    using namespace std;
    int n, m, siz, opt, l, r, x, y;
    LL ans;
    const int N = 200010;
    int id[N], lp[1010], rp[1010];
    LL k[N], b[N], tag[N];
    inline int read()
    {
    	int res = 0; char ch = getchar(); bool XX = false;
    	for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
    	for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
    	return XX ? -res : res;
    }
    struct Tree
    {
    #define lson (rt<<1)
    #define rson ((rt<<1)|1)
    	struct xian {LL k, b;} li[4200];
    	inline LL val(int x, LL k, LL b) {return k * x + b;}
    	void change(int rt, int l, int r, int k, int b)
    	{
    		if (l == r)
    		{
    			if (val(l, k, b) >= val(l, li[rt].k, li[rt].b))li[rt].k = k, li[rt].b = b;
    			return;
    		}
    		int mid = (l + r) >> 1;
    		if (val(mid , k , b) <= val(mid , li[rt].k , li[rt].b))
    		{
    			if (val(l , k , b) < val(l , li[rt].k , li[rt].b)) change(rson , mid + 1 , r , k , b);
    			else change(lson , l , mid , k , b);
    		}
    		else
    		{
    			if (val(l , k , b) < val(l , li[rt].k , li[rt].b)) change(lson , l , mid , li[rt].k , li[rt].b);
    			else change(rson , mid + 1 , r , li[rt].k , li[rt].b);
    			li[rt].k = k; li[rt].b = b;
    		}
    	}
    	LL ask(int rt, int l, int r, int pos)
    	{
    		if (l == r)return val(pos, li[rt].k, li[rt].b);
    		int mid = (l + r) >> 1;
    		return max(val(pos, li[rt].k, li[rt].b), pos <= mid ? ask(lson, l, mid, pos) : ask(rson, mid + 1, r, pos));
    	}
    } S[510];
    LL solve(int l, int r, int x)
    {
    	LL ans = 0;
    	for (int i = l; i <= r; ++i)ans = max(ans, k[i] * x + b[i] + tag[id[i]]);
    	return ans;
    }
    void build(int x)
    {
    	for (int i = lp[x]; i <= rp[x]; ++i)S[x].change(1, 1, 1000, k[i], b[i]);
    }
    signed main()
    {
    	cin >> n >> m; siz = sqrt(n);
    	for (int i = 1; i <= n; ++i)k[i] = read();
    	for (int i = 1; i <= n; ++i)b[i] = read();
    	for (int i = 1; i <= n; ++i)
    	{
    		id[i] = (i - 1) / siz + 1;
    		if (!lp[id[i]])lp[id[i]] = i;
    		rp[id[i]] = i;
    	}
    	for (int i = 1; i <= id[n]; ++i)build(i);
    	while (m--)
    	{
    		opt = read();
    		if (opt == 1)
    		{
    			l = read(); r = read(); x = read();
    			if (id[l] == id[r])printf("%lld
    ", solve(l, r, x));
    			else
    			{
    				ans = max(solve(l, rp[id[l]], x), solve(lp[id[r]], r, x));
    				for (int i = id[l] + 1; i <= id[r] - 1; ++i)
    					ans = max(ans, S[i].ask(1, 1, 1000, x) + tag[i]);
    				printf("%lld
    ", ans);
    			}
    		}
    		else if (opt == 2)
    		{
    			x = read(); y = read(); k[x] += y;
    			S[id[x]].change(1, 1, 1000, k[x], b[x]);
    		}
    		else if (opt == 3)
    		{
    			l = read(); r = read(); x = read();
    			if (id[l] == id[r])
    			{
    				for (int i = l; i <= r; ++i)b[i] += x;
    				build(id[l]);
    			}
    			else
    			{
    				for (int i = l; i <= rp[id[l]]; ++i)b[i] += x, S[id[l]].change(1, 1, 1000, k[i], b[i]);
    				for (int i = id[l] + 1; i <= id[r] - 1; ++i)tag[i] += x;
    				for (int i = lp[id[r]]; i <= r; ++i)b[i] += x, S[id[r]].change(1, 1, 1000, k[i], b[i]);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    下拉菜单的option的value属性值问题
    GDAL1.9.1 IN VS2008 C#中的编译及使用
    多表连接 去重
    【示例代码】HTML+JS 画图板源码分享
    Winet API 支持HTTPP/SOCKS代理
    入门Html
    关于CDC在非控件类中的使用
    The document "ViewController.xib" could not be opened. Could not read archive.
    华为的一道题
    [置顶] WEBSOKET服务器搭建
  • 原文地址:https://www.cnblogs.com/wljss/p/12662514.html
Copyright © 2011-2022 走看看