• 暑期集训20190730 取模(mod)


    【题目描述】 给定一个长度为n的非负整数序列a,你需要支持以下操作: 1:给定l,r,输出a[l]+a[l+1]+…+a[r]。 2:给定l,r,x,将a[l],a[l+1],…,a[r]对x取模。 3:给定k,y,将a[k]修改为y。

    【输入数据】 第一行两个整数n,m。 第二行n个整数a[1]~a[n]。 接下来m行每行3或4个整数表示操作。

    【输出数据】 对于每个操作1,输出一行一个整数表示答案。

    【样例输入】 5 5 1 2 3 4 5 2 3 5 4 3 3 5 1 2 5 2 1 3 3 1 1 3

    【样例输出】 8 5

    【数据范围】 对于40%的数据,n,m<=1000。 对于100%的数据,n,m<=100000,1<=l<=r<=n,1<=k<=n,1<=x<=10^9, 0<=a[i],y<=10^9。

    用线段树处理,用线段树维护区间最大值以及区间和。

    进行取模操作时,如果x> 区间最大值那么退出,否则两边都递归下去。

    (其实第一次做也不太明白,套模板加瞎蒙数据结果还真ac了)

    这里先码一下,再复习一下线段树之后编辑详细思路。

    #include <bits/stdc++.h>
    #define N 1000010
    #define fuck return
    using namespace std;
    typedef long long ll;
    int n, m;
    int arr[N], l[N], r[N], maxn[N];
    ll sum[N];
    
    void upd(int num) {
        sum[num] = sum[num*2] + sum[num*2|1];
        maxn[num] = max(maxn[num*2], maxn[num*2|1]);
        fuck;
    }
    void build(int num, int pos, int y) {
        l[num] = pos, r[num]=y;
        if(pos == y) {
            maxn[num] = arr[pos];
            sum[num] = arr[pos];
            fuck;
        }
        build(num*2, pos, (pos+y)/2);
        build(num*2|1, (pos+y)/2+1 ,y);
        upd(num);
    }
    void mod(int num, int pos, int y, int val) {
        if(pos>r[num] || y<l[num] || maxn[num]<val) fuck;
        if(l[num] == r[num]) {
            sum[num] %= val;
            maxn[num] = sum[num];
            fuck;
        }
        mod(num*2, pos, y, val);
        mod(num*2|1, pos, y, val);
        upd(num);
    }
    void act(int num, int pos, int y) {
        if(l[num] == r[num]) {
            maxn[num] = y;
            sum[num] = y;
            fuck;
        }
        if(pos <= (l[num] + r[num]) / 2) act(num*2, pos, y);
        else act(num*2|1, pos, y);
        upd(num);
    }
    ll output(int num, int pos, int y) {
        if(pos>r[num] || y<l[num]) fuck 0;
        if(pos<=l[num] && y>=r[num]) fuck sum[num];
        fuck output(num*2, pos, y) + output(num*2|1, pos, y);
    }
    
    int main() {
        freopen("mod.in", "r", stdin);
        freopen("mod.out", "w", stdout);
        scanf("%d%d", &n, &m);
        for(int i=1; i<=n; i++) {
            scanf("%d", &arr[i]);
        }
        build(1, 1, n);
        int pos, y, val, opt;
        while(m--) {
            scanf("%d", &opt);
            switch(opt) {
                case 1:
                    scanf("%d%d", &pos, &y);
                    printf("%lld
    ", output(1, pos, y));
                    break;
                case 2:
                    scanf("%d%d%d", &pos, &y, &val);
                    mod(1, pos, y, val);
                    break;
                case 3:
                    scanf("%d%d", &pos, &y);
                    act(1, pos, y);
                    break;
            }
        }
        fuck 0;
    }
    //being fucked by this code (2) hr (16) min
  • 相关阅读:
    快速架设OpenStack云基础平台
    源码编译安装Nginx全程视频演示
    参加2012 Openstack亚太技术大会
    FFmpeg的安装与使用
    Linux下图解minicom安装
    [转]ARM/Thumb2PortingHowto
    [原]逆向iOS SDK -- _UIImageAtPath 的实现(SDK 6.1)
    [原]逆向iOS SDK -- +[UIImage imageNamed:] 的实现
    在 Emacs 中如何退出 Slime Mode
    [转] iOS ABI Function Call Guide
  • 原文地址:https://www.cnblogs.com/miserweyte/p/11270721.html
Copyright © 2020-2023  润新知