改了三天,提交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 ( " %c", &opt ); if ( opt == 'Q' ) { int l, r; scanf ( "%d%d", &l, &r ); node *ans = query ( root, 1, n, l, r ); printf ( "%lld ", ( 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 ", ( 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; }