zoukankan      html  css  js  c++  java
  • AHOI2014/JSOI2014 奇怪的计算器

    题目传送门

    好久没写博客了,咕咕咕


    一开始自己想了想,搞了一颗线段树,结果(4)个标记,写到自闭
    打开题解,仿佛打开了新世界的大门,让我知道了自己代码的丑陋


    将所有的要进行操作的数从小到大排序,建一颗线段树,对它们进行统一修改

    用线段树维护区间最大值和最小值,且支持区间加减、区间乘、区间加原数的(x)倍和区间覆盖
    一开始我用了(4)个标记维护,然后自闭了,发现题解构建了一个函数,大大节省了编程的复杂度
    对线段树的一个元素(x),设计这样一个更新函数:(f(k1,k2, k3) = x imes k1 + y imes k2 + k3),其中(y)是最初输入进来的数
    然后区间加:(f(1, 0, add)),区间乘:(f(mul,0, 0)),区间加原数:(f(1, addx, 0)),区间覆盖:(f(0,0,x))
    这样就好写多了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    #define mid ((l + r) >> 1)
    #define ls p << 1
    #define rs p << 1 | 1
    using namespace std;
    LL read() {
        LL k = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
            k = k * 10 + c - 48, c = getchar();
        return k * f;
    }
    struct zzz {
        char flag; LL x;
    }opt[100010];
    struct hhh {
        int l, r; LL max, min, k1, k2, k3;
    }tree[100010 << 2];
    struct jjj {
        int pos; LL x;
    }a[100010];
    void up(int p) {
        tree[p].max = tree[rs].max;
        tree[p].min = tree[ls].min;
    }
    void build(int l, int r, int p) {
        tree[p].l = l, tree[p].r = r, tree[p].k1 = 1;
        if(l == r) {
            tree[p].max = tree[p].min = a[l].x; return ;
        }
        build(l, mid, ls); build(mid+1, r, rs);
        up(p);
    }
    void pushnow(int p, LL k1, LL k2, LL k3) {
    	tree[p].k1 *= k1, tree[p].k2 = tree[p].k2 * k1 + k2, tree[p].k3 = tree[p].k3 * k1 + k3;
    	tree[p].max = tree[p].max * k1 + a[tree[p].r].x * k2 + k3;
    	tree[p].min = tree[p].min * k1 + a[tree[p].l].x * k2 + k3;
    }
    void down(int p) {
    	hhh &x = tree[p];
    	pushnow(ls, x.k1, x.k2, x.k3),
    	pushnow(rs, x.k1, x.k2, x.k3);
    	x.k1 = 1, x.k2 = x.k3 = 0;
    }
    void update_low(int p, int k) {
    	if(tree[p].l == tree[p].r) {
    		pushnow(p, 0, 0, k); return ;
    	}
    	down(p);
    	if(tree[ls].max > k) pushnow(rs, 0, 0, k), update_low(ls, k);
    	else update_low(rs, k);
    	up(p);
    }
    void update_up(int p, int k) {
    	if(tree[p].l == tree[p].r) {
    		pushnow(p, 0, 0, k); return ;
    	}
    	down(p);
    	if(tree[rs].min < k) pushnow(ls, 0, 0, k), update_up(rs, k);
    	else update_up(ls, k);
    	up(p);
    }
    LL ans[100010];
    void query(int p) {
    	//cout << tree[p].l << ' ' << tree[p].r << endl;
        if(tree[p].l == tree[p].r) {
        	//cout << tree[p].l << endl;
    		ans[a[tree[p].l].pos] = tree[p].min;
    		return ;
    	}
        down(p);
        query(ls), query(rs);
    }
    bool cmp(jjj x, jjj y) {
        return x.x < y.x;
    }
    int main() {
        int m = read(), l = read(), r = read();
        for(int i = 1; i <= m; ++i) {
            char c = getchar();
            while(c != '+' && c != '-' && c != '*' && c != '@') c = getchar();
            opt[i].flag = c, opt[i].x = read();
        }
        int n = read();
        for(int i = 1; i <= n; ++i) a[i].pos = i, a[i].x = read();
        sort(a+1, a+n+1, cmp);
        build(1, n, 1);
        for(int i = 1; i <= m; ++i) {
            if(opt[i].flag == '+')
                pushnow(1, 1, 0, opt[i].x);
            else if(opt[i].flag == '-')
                pushnow(1, 1, 0, -opt[i].x);
            else if(opt[i].flag == '*')
                pushnow(1, opt[i].x, 0, 0);
            else if(opt[i].flag == '@')
                pushnow(1, 1, opt[i].x, 0);
            if(tree[1].max > r) update_low(1, r);
            if(tree[1].min < l) update_up(1, l);
        }
        query(1);
        for(int i = 1; i <= n; ++i) cout << ans[i] << endl;
        return 0;
    }
    
  • 相关阅读:
    JSP中page和pageContext的区别
    exe4j生成的exe文件没有把jre文件也打进exe文件中
    exe4j将jar文件和jre文件打包成exe
    exe4j打包jar文件为exe文件出现的问题:The JAVA_HOME environment variable does not point to a working 32-bit JDK or JRE.
    JS作用域
    js 函数
    js数组
    js表达式和语句
    js操作符
    js注释和数据类型转换
  • 原文地址:https://www.cnblogs.com/morslin/p/11855647.html
Copyright © 2011-2022 走看看