【openjudge】 CDQZ challenge 4

改了三天,提交17次,一定要纪念一下!

 

1004:Challenge 4

总时间限制: 
10000ms
 
单个测试点时间限制: 
1000ms
 
内存限制: 
262144kB
描述

给一个长为N的数列,有M次操作,每次操作时以下三种之一:

(1)修改数列中的一个数

(2)求数列中某连续一段所有数的两两乘积的和 mod 1000000007

(3)求数列中某连续一段所有相邻两数乘积的和 mod 1000000007

输入
第一行两个正整数N和M。
第二行N的整数表示这个数列。
接下来M行,每行开头是一个字符,若该字符为'M',则表示一个修改操作,接下来两个整数x和y,表示把x位置的值修改为y;若该字符为'Q',则表示一个询问操作,接下来两个整数x和y,表示对[x,y]区间做2号询问;若该字符为'A',则表示一个询问操作,接下来两个整数x和y,表示对[x,y]区间做3号询问。
输出
对每一个询问操作单独输出一行,表示答案。
样例输入
5 5
1 2 3 4 5
Q 1 5
A 1 5
M 2 7
Q 1 5
A 1 5
样例输出
85
40
150
60
提示
1<=N<=10^5,1<=M<=10^5,输入保证合法,且所有整数可用带符号32位整型存储。

更新操作其实是很简单的,稍微推一下就可以出来,可是细节很多!还有毒瘤数据有负数!所以所有的mod操作都要模加模!!

还有就是指针池的大小问题...因为过程中一直在开新节点...改了三天的大毒瘤

 

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;

const int mod = 1000000007;
const int N = 100005;

ll a[N];
int n, m;

struct node {
    node *ls, *rs;
    ll sum, num1, num2, lf, rg;
} pool[N*32], *tail = pool, *zero, *root;///////////指针池大小

void update ( node *nd, node *ld, node *rd ) {
    nd -> sum = ( ld -> sum + rd -> sum + mod ) % mod;
    nd -> num1 = (  ld -> sum * rd -> sum  % mod + ld -> num1 + rd -> num1 + mod ) % mod;
    nd -> num2 = ( ld -> num2 + rd -> num2 + ld -> rg * rd -> lf % mod + mod ) % mod;
    nd -> lf = ld -> lf % mod; nd -> rg = rd -> rg % mod;
}

node *build ( int l, int r ) {
    node *nd = ++ tail;
    if ( l == r ) {
        ll pp = ( a[l] % mod + mod ) % mod;
        nd -> lf = nd -> rg = pp;
        nd -> sum = pp; nd -> num1 = nd -> num2 = 0;
        return nd;
    }
    int mid = ( l + r ) >> 1;
    nd -> ls = build ( l, mid );
    nd -> rs = build ( mid + 1, r );
    update ( nd, nd -> ls, nd -> rs );
    return nd;
}

node *query ( node *nd, int l, int r, int L, int R ) {
    if ( l >= L && r <= R )
        return nd;
    int mid = ( l + r ) >> 1;
    node *nd1 = ++ tail, *nd2 = ++ tail;
    if ( mid >= L )
        nd1 = query ( nd -> ls, l, mid, L, R );
    if ( mid < R )
        nd2 = query ( nd -> rs, mid + 1, r, L, R );
    node *st = ++ tail;
    update ( st, nd1, nd2 );
    return st;
}

void modify ( node *nd, int l, int r, int pos, ll d ) {
    if ( l == r ) {
        nd -> lf = nd -> rg = d;
        nd -> sum = d;
        return ;
    }
    int mid = ( l + r ) >> 1;
    if ( pos <= mid ) modify ( nd -> ls, l, mid, pos, d );
    else modify ( nd -> rs, mid + 1, r, pos, d );
    update ( nd, nd -> ls, nd -> rs );
}

int main ( ) {
    scanf ( "%d%d", &n, &m );
    for ( int i = 1; i <= n; i ++ )
        scanf ( "%lld", &a[i] );
    root = build ( 1, n );
    for ( int i = 1; i <= m; i ++ ) {
        char opt;
        scanf ( "\n%c", &opt );
        if ( opt == 'Q' ) {
            int l, r;
            scanf ( "%d%d", &l, &r );
            node *ans = query ( root, 1, n, l, r );
            printf ( "%lld\n", ( ans -> num1 + mod ) % mod );
        } else if ( opt == 'A' ) {
            int l, r;
            scanf ( "%d%d", &l, &r );
            node *ans = query ( root, 1, n, l, r );
            printf ( "%lld\n", ( ans -> num2 + mod ) % mod );
        } else {
            int pos; ll r;
            scanf ( "%d%lld", &pos, &r );
            r = ( r + mod ) % mod;////
            modify ( root, 1, n, pos, r );
        }
    }
    return 0;
}

 

posted @ 2018-08-13 15:39  Wans_ovo  阅读(189)  评论(0编辑  收藏  举报