为什么理论复杂度正确但是跑得这么慢
查看原帖
为什么理论复杂度正确但是跑得这么慢
912241
dream_on_screen楼主2023/11/4 14:42

我写的是二维线段树,理论时间复杂度是 O(nlog2n)O(nlog^2n) ,看起来好像可行,但是不知道为什么就tle 63分了

愿意看的话代码在这里

#include <iostream>
using namespace std;
const int p=2048*2048*8+5;
template <class type>
class segment_tree
{
    //在运行时确定具体范围
    template <class node_type>
    struct node
    {
        node_type sum;
        node_type lazy;
    };
    node<type> t[p];
    int n,m;
    type build(int id,int lx,int ly,int rx,int ry,type *a[])
    {
        if(lx==rx&&ly==ry)
            return t[id].sum=a[lx][ly];
        int midx=(lx+rx)/2,midy=(ly+ry)/2;
        return t[id].sum=build(id*4-2,lx,ly,midx,midy,a)+build(id*4-1,lx,midy+1,midx,ry,a)+build(id*4,midx+1,ly,rx,midy,a)+build(id*4+1,midx+1,midy+1,rx,ry,a);
    }
    inline void pushdown(int id,int lx,int ly,int rx,int ry)
    {
        if(lx!=rx||ly!=ry)
        {
            t[id*4-2].lazy+=t[id].lazy;
            t[id*4-1].lazy+=t[id].lazy;
            t[id*4  ].lazy+=t[id].lazy;
            t[id*4+1].lazy+=t[id].lazy;
        }
        t[id].sum+=t[id].lazy*(rx-lx+1)*(ry-ly+1);
        t[id].lazy=0;
    }
    inline bool in(int lx,int ly,int rx,int ry,int x,int y)
    {
        return lx<=x&&ly<=y&&x<=rx&&y<=ry;
    }
    inline int max(int x,int y)
    {
        return x>y?x:y;
    }
    inline int min(int x,int y)
    {
        return x<y?x:y;
    }
    void change(int id,int lx,int ly,int rx,int ry,int ux,int uy,int vx,int vy,type delta)
    {
        if(lx==ux&&ly==uy&&rx==vx&&ry==vy)
        {
            t[id].lazy+=delta;
            return;
        }
        t[id].sum+=(rx-lx+1)*(ry-ly+1)*delta;
        int mx=(ux+vx)/2,my=(uy+vy)/2;
        bool f1=in(ux,uy,mx,my,lx,ly),
             f2=in(ux,my+1,mx,vy,lx,ry),
             f3=in(mx+1,uy,vx,my,rx,ly),
             f4=in(mx+1,my+1,vx,vy,rx,ry);
        if(f1)
            change(id*4-2,lx,ly,min(rx,mx),min(ry,my),ux,uy,mx,my,delta);
        if(f2)
            change(id*4-1,lx,max(ly,my+1),min(rx,mx),ry,ux,my+1,mx,vy,delta);
        if(f3)
            change(id*4+0,max(lx,mx+1),ly,rx,min(ry,my),mx+1,uy,vx,my,delta);
        if(f4)
            change(id*4+1,max(lx,mx+1),max(ly,my+1),rx,ry,mx+1,my+1,vx,vy,delta);
    }
    type request(int id,int lx,int ly,int rx,int ry,int ux,int uy,int vx,int vy)
    {
        pushdown(id,ux,uy,vx,vy);
        if(lx==ux&&ly==uy&&rx==vx&&ry==vy)
            return t[id].sum;
        int mx=(ux+vx)/2,my=(uy+vy)/2;
        bool f1=in(ux,uy,mx,my,lx,ly),
             f2=in(ux,my+1,mx,vy,lx,ry),
             f3=in(mx+1,uy,vx,my,rx,ly),
             f4=in(mx+1,my+1,vx,vy,rx,ry);
        type ans=0;
        if(f1)
            ans+=request(id*4-2,lx,ly,min(rx,mx),min(ry,my),ux,uy,mx,my);
        if(f2)
            ans+=request(id*4-1,lx,max(ly,my+1),min(rx,mx),ry,ux,my+1,mx,vy);
        if(f3)
            ans+=request(id*4+0,max(lx,mx+1),ly,rx,min(ry,my),mx+1,uy,vx,my);
        if(f4)
            ans+=request(id*4+1,max(lx,mx+1),max(ly,my+1),rx,ry,mx+1,my+1,vx,vy);
        return ans;
    }
    public:
        void build(int x,int y)
        {
            n=x,m=y;
        }
        void build(int sizex,int sizey,type *a[])
        {
            n=sizex,m=sizey;
            build(1,1,1,n,m,a);
        }
        void change(int lx,int ly,int rx,int ry,type delta)
        {
            change(1,lx,ly,rx,ry,1,1,n,m,delta);
        }
        type request(int lx,int ly,int rx,int ry)
        {
            return request(1,lx,ly,rx,ry,1,1,n,m);
        }
};
segment_tree<int> t;
/*
class duipai
{
    int a[1005][1005];
    public:
    void change(int lx,int ly,int rx,int ry,int delta)
    {
        for(int x=lx;x<=rx;x++)
            for(int y=ly;y<=ry;y++)
                a[x][y]+=delta;
    }
    int request(int lx,int ly,int rx,int ry)
    {
        int ans=0;
        for(int i=lx;i<=rx;i++)
            for(int j=ly;j<=ry;j++)
                ans+=a[i][j];
        return ans;
    }
};
duipai g;
*/
int main()
{
    char op='X';
    int n,m;
    cin>>op>>n>>m;
    t.build(n,m);
    while(cin>>op)
    {
        if(op=='L')
        {
            int lx,ly,rx,ry,delta;
            cin>>lx>>ly>>rx>>ry>>delta;
            t.change(lx,ly,rx,ry,delta);
        }
        else if(op=='k')
        {
            int lx,ly,rx,ry;
            cin>>lx>>ly>>rx>>ry;
            cout<<t.request(lx,ly,rx,ry)<<"\n";
        }
    }
    return 0;
}
2023/11/4 14:42
加载中...