• 徐州网络赛H-Ryuji doesn't want to study【线段树】


    Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i].

    Unfortunately, the longer he learns, the fewer he gets.

    That means, if he reads books from ll to rr, he will get a[l] imes L + a[l+1] imes (L-1) + cdots + a[r-1] imes 2 + a[r]a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r](LL is the length of [ ll, rr ] that equals to r - l + 1r−l+1).

    Now Ryuji has qq questions, you should answer him:

    11. If the question type is 11, you should answer how much knowledge he will get after he reads books [ ll, rr ].

    22. If the question type is 22, Ryuji will change the ith book's knowledge to a new value.

    Input

    First line contains two integers nn and qq (nn, q le 100000q≤100000).

    The next line contains n integers represent a[i]( a[i] le 1e9)a[i](a[i]≤1e9) .

    Then in next qq line each line contains three integers aa, bb, cc, if a = 1a=1, it means question type is 11, and bb, cc represents [ ll , rr ]. if a = 2a=2 , it means question type is 22 , and bb, cc means Ryuji changes the bth book' knowledge to cc

    Output

    For each question, output one line with one integer represent the answer.

    样例输入复制

    5 3
    1 2 3 4 5
    1 1 3
    2 5 0
    1 4 5

    样例输出复制

    10
    8

    题目来源

    ACM-ICPC 2018 徐州赛区网络预赛

    题意:两种操作 一种是更新某节点

    一种是查询l-r的一个值 这个值的计算公式是:

    思路:

    看上去就应该是一个线段树 区间查询单点更新

    但是对于查询的处理没有那么简单

    可以采用前缀和的思想 因为这个公式中的系数是递减的

    那么我们在线段树中维护两个值 一个是本身的值 一个是(n-i+1)倍的值

    那么我们查询的时候只需要查到倍数之和 减去 本身之和的(n-r)倍就可以了

    WA了一会 因为没用long long

    还是要注意啊这些细节 虽然单个没有超int 但是相加就会超的

    
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<stack>
    #include<queue>
    #include<map>
    #include<vector>
    #include<set>
    //#include<bits/stdc++.h>
    #define inf 0x7f7f7f7f7f7f7f7f
    using namespace std;
    typedef long long LL;
    
    const int maxn = 1e5 + 10;
    LL tree[maxn << 2], treetime[maxn << 2], a[maxn];
    int n, q;
    
    void pushup(int rt)
    {
    	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
    	treetime[rt] = treetime[rt << 1] + treetime[rt << 1 | 1];
    }
    
    void build(int rt, int l, int r)
    {
    	if (l == r) {
    		tree[rt] = a[l];
    		treetime[rt] = a[l] * (n - l + 1);
    		return;
    	}
    	int m = (l + r) / 2;
    	build(rt << 1, l, m);
    	build(rt << 1 | 1, m + 1, r);
    	pushup(rt);
    }
    
    void update(int x, LL val, int l, int r, int rt)
    {
    	if (l == r) {
    		tree[rt] = val;
    		treetime[rt] = val * (n - l + 1);
    		return;
    	}
    	int m = (l + r) / 2;
    	if (x <= m) {
    		update(x, val, l, m, rt << 1);
    	}
    	else {
    		update(x, val, m + 1, r, rt << 1 | 1);
    	}
    	pushup(rt);
    }
    
    LL query(int L, int R, int l, int r, int rt)
    {
    	if (L <= l && R >= r) {
    		return tree[rt];
    	}
    	int m = (l + r) / 2;
    	LL ans = 0;
    	if (L <= m) {
    		ans += query(L, R, l, m, rt << 1);
    	}
    	if (R > m) {
    		ans += query(L, R, m + 1, r, rt << 1 | 1);
    	}
    	pushup(rt);
    	return ans;
    }
    
    LL querytime(int L, int R, int l, int r, int rt)
    {
    	if (L <= l && R >= r) {
    		return treetime[rt];
    	}
    	int m = (l + r) / 2;
    	LL ans = 0;
    	if (L <= m) {
    		ans += querytime(L, R, l, m, rt << 1);
    	}
    	if (R > m) {
    		ans += querytime(L, R, m + 1, r, rt << 1 | 1);
    	}
    	return ans;
    }
    
    void init()
    {
        memset(tree, 0, sizeof(tree));
        memset(treetime, 0, sizeof(treetime));
    }
    
    int main()
    {
    	while (scanf("%d%d", &n, &q) != EOF) {
    	    if(n == 0){
                while(q--){
                    int op, l, r;
                    scanf("%d%d%d", &op, &l, &r);
                    printf("0
    ");
                }
                continue;
    	    }
            init();
    		for (int i = 1; i <= n; i++) {
    			scanf("%lld", &a[i]);
    		}
    		build(1, 1, n);
    
    		for (int i = 0; i < q; i++) {
    			int op, l, r;
    			scanf("%d%d%d", &op, &l, &r);
    			if (op == 1) {
    				LL ans = querytime(l, r, 1, n, 1) - (n - r) * query(l, r, 1, n, 1);
    				printf("%lld
    ", ans);
    			}
    			else {
    				update(l, r, 1, n, 1);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    xml转换为json格式时,如何将指定节点转换成数组 Json.NET
    快速删除C#代码中的空白行
    C#编程中的Image/Bitmap与base64的转换及 Base-64 字符数组或字符串的长度无效问题 解决
    Flash设置(各种版本浏览器包括低版本IE)
    使用vcastr22.swf做flash版网页视频播放器
    使用VLC Activex插件做网页版视频播放器
    web项目 在visual studio 输出窗口显示调试信息
    geos 3.6.3库windows版本 已编译完成的32位版本和64位版本
    vs2017 打开附带的localdb v13
    visual studio code 里调试运行 Python代码
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643366.html
Copyright © 2020-2023  润新知