zoukankan      html  css  js  c++  java
  • [题解] [JSOI2014] 奇怪的计算器

    题面

    题解

    我们发现经过若干次操作后这些数的相对大小都不会变

    排序之后, 就只有一段前缀改为 L , 或一段后缀改为 R 了

    考虑这样一个函数

    [displaystyle\f(a_1, a_2, a_3) = a_1 * c_i + a_2*a_i + a_3 ]

    其中 (c_i) 代表 (i) 这个位置现在的数, (a_i) 代表 (i) 这个位置原来的数

    那么每次操作都可以看做加这个函数

    • (k) , 乘上(f(1, 0, k))
    • (k) , 乘上 (f(1, 0, -k))
    • (k) , 乘上 (f(k, 0, 0))
    • (@k) , 乘上 (f(1, k, 0))

    线段树维护一下就好了

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    const int N = 100005;
    typedef long long ll; 
    using namespace std;
    
    int m, L, R, n, op[N], ans[N], num[N]; 
    char s[104]; 
    struct node
    {
        int v, id;
        bool operator < (const node &p) const
    	{
    	    return v < p.v; 
    	}
    } a[N];
    struct Tree { ll mn, mx, p1, p2, p3; } t[N << 2]; 
    
    template < typename T >
    inline T read()
    {
        T x = 0, w = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * w; 
    }
    
    void pushup(int p) { t[p].mn = t[p << 1].mn, t[p].mx = t[p << 1 | 1].mx; }
    
    void pushtag(int p, int l, int r, ll p1, ll p2, ll p3)
    {
        t[p].p1 *= p1, t[p].p2 = t[p].p2 * p1 + p2, t[p].p3 = t[p].p3 * p1 + p3;
        t[p].mn = t[p].mn * p1 + p2 * a[l].v + p3;
        t[p].mx = t[p].mx * p1 + p2 * a[r].v + p3; 
    }
    
    void pushdown(int p, int l, int r)
    {
        if(t[p].p1 != 1 || t[p].p2 || t[p].p3)
        {
    	int mid = (l + r) >> 1; 
    	pushtag(p << 1, l, mid, t[p].p1, t[p].p2, t[p].p3);
    	pushtag(p << 1 | 1, mid + 1, r, t[p].p1, t[p].p2, t[p].p3);
    	t[p].p1 = 1, t[p].p2 = 0, t[p].p3 = 0; 
        }
    }
    
    void build(int p, int l, int r)
    {
        t[p].p1 = 1; 
        if(l == r) return (void) (t[p].mn = t[p].mx = a[l].v); 
        int mid = (l + r) >> 1; 
        build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
        pushup(p); 
    }
    
    void modifymn(int p, int l, int r)
    {
        if(l == r) return pushtag(p, l, r, 0, 0, L);
        pushdown(p, l, r);
        int mid = (l + r) >> 1;
        if(t[p << 1 | 1].mn < L)
    	pushtag(p << 1, l, mid, 0, 0, L), modifymn(p << 1 | 1, mid + 1, r);
        else modifymn(p << 1, l, mid);
        pushup(p); 
    }
    
    void modifymx(int p, int l, int r)
    {
        if(l == r) return pushtag(p, l, r, 0, 0, R);
        pushdown(p, l, r);
        int mid = (l + r) >> 1;
        if(t[p << 1].mx > R)
    	pushtag(p << 1 | 1, mid + 1, r, 0, 0, R), modifymx(p << 1, l, mid);
        else modifymx(p << 1 | 1, mid + 1, r);
        pushup(p); 
    }
    
    void query(int p, int l, int r)
    {
        if(l == r) return (void) (ans[a[l].id] = t[p].mn);
        pushdown(p, l, r);
        int mid = (l + r) >> 1;
        query(p << 1, l, mid), query(p << 1 | 1, mid + 1, r);
        pushup(p); 
    }
    
    int main()
    {
        m = read <int> (), L = read <int> (), R = read <int> ();
        for(int i = 1; i <= m; i++)
        {
    	scanf("%s", s + 1), num[i] = read <int> (); 
    	if(s[1] == '+') op[i] = 1;
    	else if(s[1] == '-') op[i] = 1, num[i] = -num[i];
    	else if(s[1] == '*') op[i] = 2;
    	else op[i] = 3; 
        }
        n = read <int> ();
        for(int i = 1; i <= n; i++) a[i].v = read <int> (), a[i].id = i;
        sort(a + 1, a + n + 1), build(1, 1, n); 
        for(int i = 1; i <= m; i++)
        {
    	if(op[i] == 1) pushtag(1, 1, n, 1, 0, num[i]);
    	else if(op[i] == 2) pushtag(1, 1, n, num[i], 0, 0);
    	else if(op[i] == 3) pushtag(1, 1, n, 1, num[i], 0);
    	if(t[1].mn < L) modifymn(1, 1, n);
    	if(t[1].mx > R) modifymx(1, 1, n); 
        }
        query(1, 1, n);
        for(int i = 1; i <= n; i++) printf("%d
    ", ans[i]); 
        return 0; 
    }
    
  • 相关阅读:
    非静态成员的sizeof
    Android中java.lang.ClassNotFoundException: ***.**** in loader dalvik.system.PathClassLoader[/data/app
    手机 SIM卡的EF
    android 获取手机ip的三种方式
    获取图片倒影效果
    python基础
    Python学习_数据处理split方法
    Python学习_从文件读取数据和保存数据
    Python学习_列表推导和Lambda表达式
    python学习_数据处理编程实例(一)
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12296619.html
Copyright © 2011-2022 走看看