ACM-ICPC 2018 徐州赛区网络预赛 H - Ryuji doesn't want to study

版权声明:转载请说明,欢迎交流! https://blog.csdn.net/qq_39599067/article/details/82560026

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

Catalog

Problem:Portal传送门

 原题目描述在最下面。
 求 a [ l ] l e n + a [ l + 1 ] ( l e n 1 ) + . . . + a [ r 1 ] 2 + a [ r ] , l e n = r l + 1 .

Solution:

用到类似前缀和,求子串的hash值的思想。
可将上式转化为 ( i = l r a [ i ] ( n i + 1 ) ) ( n r ) i = l r a [ i ]
这个式子不就是两个前缀和吗?
将数组逆序,维护一个逆序后 a [ i ] i a [ i ] 的前缀和即可,树状数组解决。

AC_Code:

#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int mod = 1e9+7;
const int MXN = 1e6 + 7;
int n, m;
LL bit[MXN], ar[MXN], hh[MXN];
int lowbit(int x){return (x&(-x));}
void add(int x,LL c){for(;x <= n;x += lowbit(x)) bit[x]+=c;}
LL query(int x){LL ans = 0;for(;x;x -= lowbit(x))ans+=bit[x];return ans;}
void add1(int x,LL c){for(;x <= n;x += lowbit(x)) hh[x]+=c;}
LL query1(int x){LL ans = 0;for(;x;x -= lowbit(x))ans+=hh[x];return ans;}
int main(){
    while(~scanf("%d%d", &n, &m)){
        memset(bit,0,sizeof(bit));
        memset(hh,0,sizeof(hh));
        for(int i = 1; i <= n; ++i){
            scanf("%lld", &ar[i]);
        }
        reverse(ar+1, ar + 1 + n);
        for(int i = 1; i <= n; ++i){
            add(i, ar[i]);
            add1(i, ar[i]*i);
        }
        int op, x, y, l, r;
        for(int t = 0; t < m; ++t){
            scanf("%d%d%d", &op, &x, &y);
            if(op == 1){
                l = n + 1 - y; r = n + 1 - x;
                LL ans = query1(r) - query1(l-1);
                //printf("*%d %d %d %d %lld\n", l, r, x, y, ans);
                ans -= (query(r) - query(l-1))*(l-1);
                printf("%lld\n", ans);
            }else{
                x = n + 1 - x;
                add(x, y - ar[x]);
                add1(x, x*(y - ar[x]));
                ar[x] = y;
            }
        }
    }
    return 0;
}


Problem Description:

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/82560026