重金属代码,不想调了,仅供参观

P3372 【模板】线段树 1

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

这是我好久以前第一次学线段树的代码,当时把问题想得过于复杂了导致这代码惨不忍睹......


|