LuckiestShawn @ 2023-03-16 19:42:37
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct AB{
int l,r,lazy;
int value,sum,max,min;
bool vist;
bool leave;
}listTree[80000];
int n,value[20000],q,k,l,r,i,treeLength,link[4],linktot;
int max(int a,int b)
{
return a > b ? a : b;
}
void buildTree(int link,int l,int r)
{
if(l>r) return ;
listTree[link].l = l;
listTree[link].r = r;
if(l==r)
{
treeLength = max(treeLength,link);
listTree[link].vist = false;
listTree[link].leave = true;
listTree[link].value = listTree[link].max = listTree[link].min = listTree[link].sum = value[l];
return ;
}
buildTree(link*2,l,(l+r)/2);
buildTree((link*2)+1,(l+r)/2+1,r);
return ;
}
void printTree()
{
int tot=0;
while(++tot<=treeLength&&listTree[tot].l)
printf("[%d,%d] sum:%d vist:%d\n",listTree[tot].l,listTree[tot].r,listTree[tot].sum,listTree[tot].vist);
return ;
}
int _treeSum(int link)
{
if(link == 0)
return 0;
if(listTree[link].leave)
return listTree[link].value;
if(!listTree[link].sum)
listTree[link].sum = _treeSum(link*2)+_treeSum(link*2+1);
return listTree[link].sum;
}
int treeSum(int tot)
{
int sum = 0;
// printf("link[%d] - ",tot);
while(tot-->=0)
{
// link[tot] ? printf("%d ",link[tot]) : 0;
sum += link[tot] ? _treeSum(link[tot]) : 0;
listTree[link[tot]].vist = false;
}
// printf("\n");
return sum;
}
// 左 false 右 true
int findlink(int comperl,int comperr,bool mainLR,int link)
{
if(comperl>n||comperr>n||comperl<1||comperr<1)
return 0;
// printf("%d %d\n",comperl,comperr);
if(listTree[link].vist)
return 0;
if(comperl>comperr)
return 0;
if(mainLR)
{
if(comperr==listTree[link].r)
{
if(comperl<=listTree[link].l)
{
listTree[link].vist = true;
return link;
}
else
return findlink(comperl,comperr,true,link*2+1);
}
if(comperr<=(listTree[link].l+listTree[link].r)/2)
return findlink(comperl,comperr,true,link*2);
else
return findlink(comperl,comperr,true,link*2+1);
}
else
{
if(comperl==listTree[link].l)
{
if(comperr>=listTree[link].r)
{
listTree[link].vist = true;
return link;
}
else
return findlink(comperl,comperr,false,link*2);
}
if(comperl<=(listTree[link].l+listTree[link].r)/2)
return findlink(comperl,comperr,false,link*2);
else
return findlink(comperl,comperr,false,link*2+1);
}
return 0;
}
void searchLink(int l,int r)
{
if(l>r)
return ;
// printf("l:%d r:%d\n",l,r);
int ans;
ans = findlink(l,r,false,1);
if(ans > 0)
{
link[linktot] = ans;
linktot++;
// printf("%d %d " ,link[linktot],linktot);
}
ans = findlink(l,r,true,1);
if(ans > 0)
{
link[linktot] = ans;
linktot++;
// printf("%d %d\n",link[linktot],linktot);
}
searchLink(l+1,r-1);
return ;
}
int _swap(int a,int b)
{
return a>b;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%d",&value[i]);
buildTree(1,1,n);
while(q--)
{
// printTree();
scanf("%d%d%d",&k,&l,&r);
if(k==1)
{
scanf("%d",&k);
for(i=l;i<=r;i++)
value[i] += k;
buildTree(1,1,n);
}
else
{
if(l>n||r>n||l<1||r<1)
continue;
linktot = 0;
searchLink(l,r);
sort(link,link+linktot,_swap);
// printf("%d %d %d %d\n",link[0],link[1],link[2],link[3]);
// for(i=0;i<=linktot;i++)
// printf("%d ",link[i]);
// printf("\n");
printf("%d",treeSum(unique(link,link+linktot)-link));
printf("\n");
}
}
return 0;
}
/*
16 8
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 16
*/
by The_Wandering_Earth @ 2023-03-16 20:09:37
@itshawn 的确,你写的这是全家桶吧,建议还是代码越简单越好,越规范越好(建议重写一遍)
by LuckiestShawn @ 2023-03-16 20:27:53
这是我好久以前第一次学线段树的代码,当时把问题想得过于复杂了导致这代码惨不忍睹......