feat: 实现线段树功能并优化.gitignore

添加线段树实现,支持区间加、乘和查询操作
移除.gitignore中/test.*前的斜杠以正确忽略测试文件
This commit is contained in:
Zengtudor 2025-10-17 23:37:34 +08:00
parent e867cd207f
commit 65fe11a140
2 changed files with 152 additions and 13 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
/build
/.cache
/test.*
test.*
*.in
*.ans

View File

@ -1,16 +1,155 @@
#include <stdio.h>
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct node
{
int date = 0;
int lan = 0;
int left = 0;
int right = 0;
int lanc = 0;
};
int n, q, m;
vector<int> a;
vector<node> tree;
void build(vector<node> &tree, vector<int> &a, int rt, int left, int right)
{
if(left == right)
{
tree[rt].left = left;
tree[rt].right = right;
tree[rt].date = a[left] % 38;
tree[rt].lan = 0;
tree[rt].lanc = 1;
return;
}
int mid = left + (right - left) / 2;
build(tree, a, rt * 2, left, mid);
build(tree, a, rt * 2 + 1, mid + 1, right);
tree[rt].left = left;
tree[rt].right = right;
tree[rt].lan = 0;
tree[rt].lanc = 1;
tree[rt].date = (tree[rt * 2].date + tree[rt * 2 + 1].date) % 38;
}
void lazycl(vector<node> &tree, int rt)
{
if(tree[rt].lan > 0 or tree[rt].lanc != 1)
{
int laz = tree[rt].lan / (tree[rt].right - tree[rt].left + 1);
tree[rt * 2].date += (laz * ((tree[rt * 2].right - tree[rt * 2].left) + 1)) % 38;
tree[rt * 2].lan += laz * ((tree[rt * 2].right - tree[rt * 2].left) + 1);
tree[rt * 2].date = (tree[rt * 2].date * tree[rt].lanc) % 38;
tree[rt * 2].lanc *= tree[rt].lanc;
tree[rt * 2 + 1].date += (laz * ((tree[rt * 2 + 1].right - tree[rt * 2 + 1].left) + 1)) % 38;
tree[rt * 2 + 1].lan += laz * ((tree[rt * 2 + 1].right - tree[rt * 2 + 1].left) + 1);
tree[rt * 2 + 1].date = (tree[rt * 2 + 1].date * tree[rt].lanc) % 38;
tree[rt * 2 + 1].lanc *= tree[rt].lanc;
tree[rt].lan = 0;
tree[rt].lanc = 1;
}
}
void qjadd(vector<node> &tree, int rt, int add, int cl, int cr, int left, int right)
{
lazycl(tree,rt);
if(cl > right or cr < left)
{
return;
}
if(cl <= left and cr >= right)
{
tree[rt].date += (add * (tree[rt].right - tree[rt].left + 1)) % 38;
tree[rt].lan += add * (tree[rt].right - tree[rt].left + 1);
return;
}
int mid = left + (right - left) / 2;
qjadd(tree, rt * 2, add, cl, cr, tree[rt].left, mid);
qjadd(tree, rt * 2 + 1, add, cl, cr, mid + 1, tree[rt].right);
tree[rt].date = (tree[rt * 2].date + tree[rt * 2 + 1].date) % 38;
}
void qjmul(vector<node> &tree, int rt, int mul, int cl, int cr, int left, int right)
{
if(cl > right or cr < left)
{
return;
}
if(cl <= left and cr >= right)
{
tree[rt].date *= (mul * tree[rt].lanc) % 38;
tree[rt].lanc = mul * tree[rt].lanc;
//cout << tree[rt].date << " [" << tree[rt].left << "," << tree[rt].right << "]" << tree[rt].lan << " " << tree[rt].lanc << endl;
return;
}lazycl(tree,rt);
int mid = left + (right - left) / 2;
qjmul(tree, rt * 2, mul, cl, cr, tree[rt].left, mid);
qjmul(tree, rt * 2 + 1, mul, cl, cr, mid + 1, tree[rt].right);
tree[rt].date = (tree[rt * 2].date + tree[rt * 2 + 1].date) % 38;
//cout << tree[rt].date << " [" << tree[rt].left << "," << tree[rt].right << "]" << tree[rt].lan << " " << tree[rt].lanc << endl;
using uint64 = unsigned long long;
void (*ptr)(void) = (void(*)(void))0xDEADBEEF;
}
void qjcx(vector<node> &tree, int rt, int cl, int cr, int left, int right, int &sum)
{
lazycl(tree, rt);
if(cl > right or cr < left)
{
return;
}
if(cl <= left and cr >= right)
{
sum += tree[rt].date % 38;
//cout << tree[rt].date << " [" << tree[rt].left << "," << tree[rt].right << "]" << tree[rt].lan << " " << tree[rt].lanc << endl;
return;
}
int mid = left + (right - left) / 2;
qjcx(tree, rt * 2, cl, cr, tree[rt].left, mid, sum);
qjcx(tree, rt * 2 + 1, cl, cr, mid + 1, tree[rt].right, sum);
int main(){
uint64 nptr =(uint64)(printf);
printf("func ptr= %lx\n",printf);
ptr=(void(*)(void))nptr;
ptr();
ptr();
ptr();
ptr();
ptr();
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> q >> m;
a.resize(n + 1);
tree.resize((n + 1) * 4);
for(int i = 1;i <= n; i++)
{
cin >> a[i];
}
build(tree, a, 1, 1, n);
// for(int i = 1;i <= n * 4; i++)
// {
// cout << tree[i].date << " [" << tree[i].left << "," << tree[i].right << "]" << tree[i].lan << " " << tree[i].lanc << endl;
// }
for(int i = 1;i <= q;i ++)
{
int c, x, y;
cin >> c >> x >> y;
if(c == 1)
{
int k;
cin >> k;
qjmul(tree, 1, k % 38, x, y, 1, n);
}
else if(c == 2)
{
int k;
cin >> k;
qjadd(tree, 1, k % 38, x, y, 1, n);
}
else
{
int sum = 0;
qjcx(tree, 1, x, y, 1, n, sum);
cout << sum % 38 << endl;
}
}
}