ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2019牛客暑期多校训练营(第七场) E (线段树, 点代表一个区间)

2019-08-09 14:43:32  阅读:249  来源: 互联网

标签:val int 第七场 多校 mid 牛客 区间 now lz


 

给你的区间 是 1e9 的,所以需要我们离散一下,然后每个点代表一个区间就可以了. 

思路:

首先我们考虑到 N 是4e5 的,所以说不同点的个数最多就是 2*N 的,

我们就可以用线段树来做 了.

方法一:

我们考虑离散一个区间,把 右区间的端点 +1,区间算是左闭右开的, 这样算一个区间的值就是 右端点的值减去左区间的值.

我们就可以用 左区间的值代表整个区间.

[1,7] [5,10]
我们换成左闭右开的区间 .
[1,8 )  [5,11).
然后离散化 .
1 5 8 11

每个点代表的区间就是 [ a[i], a[i+1] )


1 这个点代表区间 [1,5) .
2 这个点代表区间 [5,8) .
3 这个点代表区间 [8,11).
4 这个点代表 最右面的端点.
区间变成了.
[1,3)  [2,4)

a[3] - a[1] 就是第一个区间的值.
a[4] - a[2] 就是第二个区间的值.

当我们处理第一区间的时候,
只需要修改  [1,2] 这个区间就可以了,它代表原来的 [1,7] 这个区间,
处理第二个区间的时候,
只需要修改 [2,3] 这个区间就是了,代表原来的 [5,10] 这个区间.

最后查询的时候,我们要找到具体的点,然后由点去找具体的区间.
由点去找对应的区间就很好找.随便搞搞就行了. 

方法二:
我们可以不换成左闭右开的区间,
然后我们有 2*N 个点,这些点就代表一个点,然后每两个相邻的点之间我们在加一个点,代表两个点相邻的区间.

[1,7] [5,10]
我们离散化之后
1 5 7 10
每个点代表的区间就是.
[1,1] [2,4], [5,5] ,[6,6],[7,7],[8.9] ,[10,10]
要修改 [1,7] 这个区间,我们就需要修改 [1,5] 这个区间,
要修改 [5,10] 就要修改,[3,7] 这个区间.


方法一的代码:

#include<bits/stdc++.h>
#define ls now << 1
#define rs now << 1 | 1
using namespace std;
const int N  = 4e5 + 100;
const int M = N << 2;
long long x[N], y[N],z[M];

namespace SEG {
    long long val[M<<2], lz[M<<2];
    void pushdown(int now, int l, int r){
        if (lz[now] == 0) return;
        int mid = (l + r) >> 1;
        val[ls] += (z[mid] - z[l])*lz[now];
        val[rs] += (z[r] - z[mid])*lz[now];
        lz[ls] += lz[now]; lz[rs] += lz[now];
        lz[now] = 0;
    }
    void Modify(int now, int l, int r, int a, int b){
        if (a <= l && b >= r - 1){
            lz[now] += 1;
            val[now] += z[r] - z[l]; 
            return;
        }
        pushdown(now,l,r);
        int mid = (l + r) >> 1;
        if (a < mid) Modify(ls, l, mid, a, b);
        if (b >= mid) Modify(rs, mid,r,a,b);
        val[now] = val[ls] + val[rs];
    }
    int Query(int now, int l, int r, long long k){
        if (l + 1 == r){
            long long tmp = val[now] / (z[r] - z[l]);
            k = (k - 1) / tmp;
            return z[l] + k;
        }
        pushdown(now, l, r);
        int mid = (l + r) >> 1;
        if (k <= val[ls]) return Query(ls, l, mid, k);
        if (k > val[ls]) return Query(rs, mid, r, k - val[ls]);
        return 0;
    }

};
long long a1, a2, b1, b2, c1, c2, m1, m2;
int   n, m, tot,l[N],r[N],cnt;
int main() {
    scanf("%d",&n);
    scanf("%lld%lld%lld%lld%lld%lld", &x[1], &x[2], &a1, &b1, &c1, &m1);
    scanf("%lld%lld%lld%lld%lld%lld", &y[1], &y[2], &a2, &b2, &c2, &m2);
    for (int i = 3; i <= n; ++i) {
        x[i] = ((a1 * x[i - 1]) + (1ll*b1 * x[i - 2]) + c1) % m1;
        y[i] = ((a2 * y[i - 1]) + (1ll*b2 * y[i - 2]) + c2) % m2;
    }

    for (int i = 1; i <= n; ++i) {
        l[i] = min(x[i], y[i]) + 1;
        r[i] = max(x[i], y[i]) + 1 + 1;
        z[++tot] = l[i];
        z[++tot] = r[i];
    }
    sort(z+1, z + tot+1);
    tot = unique(z+1, z + tot + 1) - z - 1;
    for (int i = 1; i <= n; ++i) {
        l[i] = lower_bound(z+1,z+tot+1,l[i]) - z;
        r[i] = lower_bound(z+1,z+tot+1,r[i]) - z;
    }
    long long tmp = 0;
    for (int i = 1; i <= n; ++i){
        SEG::Modify(1,1,tot+1,l[i],r[i] - 1);
        tmp += z[r[i]] - z[l[i]];
        int ans =  SEG::Query(1,1,tot+1,(tmp + 1) / 2);
        printf("%d\n",ans);
    }
    return 0;
}
/*
5
3 1 4 1 5 9
2 7 1 8 2 9
5
1 2 3 4 5 4
2 3 4 5 6 4


*/

方法二的代码:

#include<bits/stdc++.h>
#define ls now << 1
#define rs now << 1 | 1
using namespace std;
const int N  = 4e5 + 100;
const int M = N << 2;
int x[M], y[M];

namespace SEG {
    long long val[M << 2];
    int lz[M << 2];
    void pushdown(int now, int l, int r) {
        if (lz[now] == 0) return;
        int mid = (l + r) >> 1;
        val[ls] += 1ll * (y[mid] - x[l] + 1) * lz[now];
        val[rs] += 1ll * (y[r] - x[mid + 1] + 1) * lz[now];
        lz[ls] += lz[now];
        lz[rs] += lz[now];
        lz[now] = 0;
    }
    void Modify(int now, int l, int r, int a, int b) {
        if (l > r) return;
        if (a <= l && b >= r) {
            lz[now] += 1;
            val[now] += y[r] - x[l] + 1;
            return;
        }
        pushdown(now, l, r);
        int mid = (l + r) >> 1;
        if (a <= mid) Modify(ls, l, mid, a, b);
        if (b > mid) Modify(rs, mid + 1, r, a, b);
        val[now] = val[ls] + val[rs];
    }
    int Query(int now, int l, int r, long long k) {
        if(l > r) return 0;
        if (l == r) {
            long long tmp = val[now] / (y[l] - x[l] + 1);
            k = (k - 1) / tmp;
            return x[l] + k;
        }
        pushdown(now, l, r);
        int mid = (l + r) >> 1;
        if (k <= val[ls]) return Query(ls, l, mid, k);
        if (k > val[ls]) return Query(rs, mid + 1, r, k - val[ls]);
        return 0;
    }

};
int a1, a2, b1, b2, c1, c2, m1, m2;
int  z[M], n, m, tot, l[N], r[N], cnt;
int main() {
    scanf("%d", &n);
    scanf("%d%d%d%d%d%d", &x[1], &x[2], &a1, &b1, &c1, &m1);
    scanf("%d%d%d%d%d%d", &y[1], &y[2], &a2, &b2, &c2, &m2);
    for (int i = 3; i <= n; ++i) {
        x[i] = ((1ll * a1 * x[i - 1]) % m1 + (1ll * b1 * x[i - 2]) % m1 + c1) % m1;
        y[i] = ((1ll * a2 * y[i - 1]) % m2 + (1ll * b2 * y[i - 2]) % m2 + c2) % m2;
    }

    for (int i = 1; i <= n; ++i) {
        l[i] = min(x[i], y[i]) + 1;
        r[i] = max(x[i], y[i]) + 1;
        z[tot++] = l[i];
        z[tot++] = r[i];
    }

    sort(z, z + tot);
    tot = unique(z, z + tot) - z;
    for (int i = 0; i < tot; ++i) {
        if (i) {
            if (z[i - 1] + 1 < z[i]) {
                x[++cnt] = z[i - 1] + 1;
                y[cnt] = z[i] - 1;
            }
        }
        x[++cnt] = z[i], y[cnt] = z[i];
    }
    for (int i = 1; i <= n; ++i) {
        l[i] = lower_bound(x + 1, x + cnt + 1, l[i]) - x;
        r[i] = lower_bound(y + 1, y + cnt + 1, r[i]) - y;
    }
    long long tmp = 0;
    for (int i = 1; i <= n; ++i) {
        SEG::Modify(1, 1, cnt, l[i], r[i]);
        tmp = tmp + (y[r[i]] - x[l[i]] + 1);
        int ans =  SEG::Query(1, 1, cnt, (tmp + 1) / 2);
        printf("%d\n", ans);
    }
    return 0;
}
/*
5
3 1 4 1 5 9
2 7 1 8 2 9
5
1 2 3 4 5 4
2 3 4 5 6 4


*/

 

 

标签:val,int,第七场,多校,mid,牛客,区间,now,lz
来源: https://blog.csdn.net/kidsummer/article/details/98956037

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有