zoukankan      html  css  js  c++  java
  • UVaLive6443(线段树)

    要点

    • 题意……题意往往是个大坎Orz:输入操作 p 则在区间([x_1,x_2])插入一个三次函数, t 则先查询区间([x_1,x_2])的函数值的和,然后按题目要求得到新的(x_1)(x_2)并插入一个三次函数。都是整形。
    • 解决方法:三次函数只有四个部分,栽4棵代表不同次幂函数的线段树即可,这样每次只维护某一特定次幂的函数是很容易做到的。
    • 感觉这题很简单了对吧,然而每个月都要来那么一次红红的一板WA ……我调了很久才过的(菜鸡才会掉的)坑:
    • 预处理的sum不应在询问答案时再使用,因为题目意思是没有函数的点函数值算0。所以要在线段树的sum的维护的过程中就使用这个数组。
    • 一些手(智)生(障)的错误:把标准同步关了却还用printf、减法取模不加mod直接%mod、线段树更新写错了(这可还行……)。
    • 休息并出门(调出bug的神奇做法)之后回来一眼看出(x[i])是int范围的,要 x[i] = (x[i] % mod + mod) % mod;,原来写的 x[i] = (x[i] + mod) % mod

    压着时限过的

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    const int X = 1e6 + 5, mod = 1e9 + 7;
    const ll INF = 1e18;
    
    int Test, N, l, r;
    ll x[4];
    ll sum[4][X];
    char s[2];
    
    struct SegmentTree {
        #define ls(p) p << 1
        #define rs(p) p << 1 | 1
        struct Node {
            int l, r;
            int sum, tag;
        }t[X << 2];
    
        void Deal(int s, int p, int id) {
            t[s].sum = ((ll)t[s].sum + (ll)t[p].tag * (sum[id][t[s].r] - sum[id][t[s].l - 1] + mod) % mod) % mod;
            t[s].tag = ((ll)t[s].tag + (ll)t[p].tag) % mod;
        }
    
        void Push_down(int p, int id) {
            if (t[p].tag) {
                Deal(ls(p), p, id), Deal(rs(p), p, id);
                t[p].tag = 0;
            }
        }
    
        void Build(int l, int r, int p) {
            t[p].l = l, t[p].r = r, t[p].tag = t[p].sum = 0;
            if (l == r) return;
            int mid = (l + r) >> 1;
            Build(l, mid, ls(p));
            Build(mid + 1, r, rs(p));
        }
        
        void Update(int l, int r, int p, ll k, int id) {
            if (l <= t[p].l && t[p].r <= r) {
                t[p].sum = ((ll)t[p].sum + k * (sum[id][t[p].r] - sum[id][t[p].l - 1] + mod) % mod) % mod;
                t[p].tag = ((ll)t[p].tag + k) % mod;
                return;
            }
            Push_down(p, id);
            int mid = (t[p].l + t[p].r) >> 1;
            if (l <= mid)   Update(l, r, ls(p), k, id);
            if (mid < r)    Update(l, r, rs(p), k, id);
            t[p].sum = ((ll)t[ls(p)].sum + t[rs(p)].sum) % mod;
        }
    
        ll Query(int l, int r, int p, int id) {
            if (l <= t[p].l && t[p].r <= r) return t[p].sum;
            Push_down(p, id);
            int mid = (t[p].l + t[p].r) >> 1;
            if (l > mid)    return Query(l, r, rs(p), id);
            if (r <= mid)   return Query(l, r, ls(p), id);
            return ((ll)Query(l, r, ls(p), id) + Query(l, r, rs(p), id)) % mod;
        }
    }T[4];
    
    void Pre(int k) {
        for (int i = 0; i <= X - 5; i++) {
            ll t = 1LL;
            for (int j = 1; j <= k; j++)
                t = t * i % mod;
            sum[k][i + 1] = (t + sum[k][i]) % mod;
        }
    }
    
    int main() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    
        for (int i = 0; i < 4; i++)
            Pre(i);
        cin >> Test;
        for (int kase = 1; kase <= Test; kase++) {
            cout << "Case #" << kase << ":
    ";
    
            for (int i = 0; i < 4; i++)
                T[i].Build(1, X - 4, 1);
            for (cin >> N; N; N--) {
                cin >> s >> l >> r;
                l++, r++;
                for (int i = 3; ~i; --i)
                    cin >> x[i], x[i] = (x[i] % mod + mod) % mod;
    
                if (s[0] == 'p') {
                    for (int i = 3; ~i; --i)
                        T[i].Update(l, r, 1, x[i], i);
                } else {
                    ll ans = 0LL;
                    for (int i = 3; ~i; --i) {
                        ans = (ans + T[i].Query(l, r, 1, i)) % mod;
                    }
                    cout << ans << '
    ';
    
                    l--, r--;
                    l = ans * l % 1000000;
                    r = ans * r % 1000000;
                    if (l > r)  swap(l, r);
                    l++, r++;
                    for (int i = 3; ~i; --i)
                        T[i].Update(l, r, 1, x[i], i);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Dynamics CRM开发参考资料
    Sql Server存储过程和游标的配合操作
    C#字符处理的性能问题
    Windows安装完ADFS后卸载ADFS清除ADFS数据库
    C#修改AD账号及密码
    Dynamics CRM安装教程九(续):自建证书的CRM项目客户端设置CRM访问
    Kubernetes实践之深入掌握Pod——Pod健康检查和服务可用性检查
    Kuberbetes实践——镜像拉取策略、command args参数、Pod生命周期和重启策略
    Kubernetes实践之深入掌握Pod——在容器内获取Pod信息
    Kubernetes实践之深入掌握Pod——ConfigMap
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10815349.html
Copyright © 2011-2022 走看看