牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ
G 智乃酱的平方数列(线段树,等差数列,多项式)
题目描述
想必你一定会用线段树维护等差数列吧?让我们来看看它的升级版。
请你维护一个长度为5×10 ^5的数组,一开始数组中每个元素都为0,要求支持以下两个操作:
1、区间[l,r]加自然数的平方数组,即al+=1,al+1+=4,al+2+=9,al+3+=16...ar+=(r−l+1)∗(r−l+1)
2、区间[l,r]查询区间和mod 10^9 + 7
输入描述:
第一行输入n,m,(1≤n,m≤5*10 ^5)
接下来m行,对于每行,先读入一个整数q。
当q的值为1时,还需读入两个整l,r,(1≤l≤r≤n)表示需要对区间[l,r]进行操作,让第一个元素加1,第二个元素加4,第三个元素加9...以此类推。
当q的值为2时,还需读入两个整数l,r(1≤l≤r≤n)表示查询l到r的元素和
输出描述:
对于每一个q=2,输出一行一个非负整数,表示l到r的区间和mod 110^9+7。
示例1
输入
复制
4 4
2 1 4
1 1 4
1 3 4
2 1 4
输出
复制
0
35
示例2
输入
复制
10 6
1 1 6
1 8 9
1 3 6
2 1 10
1 1 10
2 1 10
输出
复制
126
511
解析:
等差数列可以写成 [x-(l-1)]^2,其中 x 表示当前的位置,等价于 x^2-2*x*(l-1)+(l-1)^2,通过线段树维护其系数即可
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <sstream>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <stdio.h>
#include <tuple>
using namespace std;
/*
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
*/
typedef long long LL;
#define int long long
#define ld long double
//#define INT __int128
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9+7;
const ld eps = 1e-12;
const int N = 5e5 + 10, M = N + 10;
int n, m;
struct TREE {
int l, r;
int la1, la2, la3;
int sum;
int base1, base2;
}tr[N << 2];
#define ls u<<1
#define rs u<<1|1
void cal(int u, int la1, int la2, int la3) {
la3 %= mod;
int len = tr[u].r - tr[u].l + 1;
tr[u].sum = (tr[u].sum + len * la3 % mod) % mod;
tr[u].sum = (tr[u]

最低0.47元/天 解锁文章
510

被折叠的 条评论
为什么被折叠?



