萌新求助,整体二分全 TLE 了,代码有注释

P1527 [国家集训队] 矩阵乘法

Drind @ 2024-05-04 16:20:56

RT,我也不知道为什么,总之挂了。

#include<bits/stdc++.h>
using namespace std;
const int N=5e2+10;
const int M=6e4+10;
const int inf=1e9;
inline int _abs(int x){if(x>0) return x;return -x;}

struct BIT{//二维树状树组
    int tree[N][N];
    int lowbit(int x){
        return x&(-x);
    }

    void modify(int x,int y,int val){
        while(x<N){
            int ty=y;
            while(ty<N){
                tree[x][ty]+=val;
                ty+=lowbit(ty);
            }
            x+=lowbit(x);
        }
    }

    int q(int x,int y){
        int ans=0;
        while(x){
            int ty=y;
            while(ty){
                ans+=tree[x][ty];
                ty-=lowbit(ty);
            }
            x-=lowbit(x);
        }
        return ans;
    }

    int query(int x,int y,int _x,int _y){//(x,y) left-up  (_x,_y) right-down
        return q(_x,_y)-q(_x,y-1)-q(x-1,_y)+q(x-1,y-1);
    }
}bit;

struct queries{
    int l,r,_l,_r,id,opt,k;
}t[M+N*N]; int F[M],cnt1,cnt2,cnt;
queries q1[M+N*N],q2[M+N*N];

void solve(int l,int r,int L,int R){
    if(l>r) return;//没东西了 就return
    //cout<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
    //for(int i=l;i<=r;i++){
    //  cout<<t[i].l<<" "<<t[i].r<<" "<<t[i]._l<<" "<<t[i]._r<<" "<<t[i].id<<" "<<t[i].opt<<" "<<t[i].k<<"\n";
    //}
    if(L==R){//如果到一个区间上,就是答案
        for(int i=l;i<=r;i++){
            if(t[i].opt==1) F[t[i].id]=L;
        }
        return;
    }

    int mid=(L+R)>>1; cnt1=cnt2=0;
    for(int i=l;i<=r;i++){
        if(t[i].opt==0){//如果是数字,就加上去
            if(t[i].k<=mid){
                bit.modify(t[i].l,t[i].r,1);
                q1[++cnt1]=t[i];
            }else{
                q2[++cnt2]=t[i];
            }
        }else{//如果是查询,就二分
            int tmp=bit.query(t[i].l,t[i].r,t[i]._l,t[i]._r);
            //cout<<t[i].id<<" "<<tmp<<"\n";
            if(tmp>=t[i].k){
                q1[++cnt1]=t[i];
            }else{
                t[i].k-=tmp;
                q2[++cnt2]=t[i];
            }
        }
    }

    for(int i=1;i<=cnt1;i++){//树状数组回退
        if(q1[i].opt==0) bit.modify(q1[i].l,q1[i].r,-1);
    }
    //合并左右边
    for(int i=1;i<=cnt1;i++) t[l+i-1]=q1[i];
    for(int i=1;i<=cnt2;i++) t[l+cnt1+i-1]=q2[i];
    solve(l,l+cnt1-1,L,mid);//递归
    solve(l+cnt1,r,mid+1,R);
}

int a[N][N];
int qwq[N*N],res;

void fake_main(){
    int n,q; cin>>n>>q;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j]; qwq[++res]=a[i][j];
            //t[++cnt]={i,j,0,0,0,0,a[i][j]};
        }
    }
    sort(qwq+1,qwq+res+1);//离散化
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            a[i][j]=lower_bound(qwq+1,qwq+res+1,a[i][j])-qwq;
            t[++cnt]={i,j,0,0,0,0,a[i][j]};
        }
    }

    for(int i=1;i<=q;i++){
        int l,r,_l,_r,k; cin>>l>>r>>_l>>_r>>k;
        t[++cnt]={l,r,_l,_r,i,1,k};
    }//存入查询

    solve(1,cnt,1,n*n);//二分

    for(int i=1;i<=q;i++){
        cout<<qwq[F[i]]<<"\n";
    }
}

signed main(){
    ios::sync_with_stdio(false);
    int t; t=1;
    while(t--) fake_main();
}

by d0j1a_1701 @ 2024-05-04 16:21:45

@夜明 @AutumnMoon


by d0j1a_1701 @ 2024-05-04 16:21:58

@d0j1a_1701


by TernaryTree @ 2024-05-04 16:22:05

@d0j1a_1701 wyy,jbl


by d0j1a_1701 @ 2024-05-04 16:22:24

@TernaryTree wyy,jbl


by _determination_ @ 2024-05-04 16:44:39

@lao_wang


by xiao7_Mr_10_ @ 2024-05-04 16:46:53

@lao_wang 这个敬业的人会帮助你的


by YD0923 @ 2024-05-04 16:50:02

《萌新求助》《真·萌新》


by lao_wang @ 2024-05-04 16:57:27

@Joker_Fish wdf???


by lao_wang @ 2024-05-04 16:59:36

@Drind 我只知道你的整体二分应该没写错,你看看你的树状数组


by lao_wang @ 2024-05-04 17:00:41

@Drind 大哥你整体二分还离散化????


| 下一页