zoukankan      html  css  js  c++  java
  • 国家集训队 矩阵乘法

    题目描述

    题解:

    考虑到答案具有单调性,我们将其放入二维树状数组/二维线段树即可。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 505
    #define Q 60050
    #define ll long long
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,ans[Q],mx,lp[N*N],rp[N*N],to[N*N];
    struct node
    {
        int x,y,k;
    }p[N*N];
    struct sqr
    {
        int x_,y_,_x,_y,k,id;
        void read()
        {
            x_ = rd(),y_ = rd(),_x = rd(),_y = rd(),k = rd();
        }
    }q[Q],tmpl[Q],tmpr[Q];
    bool cmp(node a,node b)
    {
        return a.k<b.k;
    }
    struct BIT
    {
        ll f[N][N];
        void up(int x,int y,ll d)
        {
            if(!x||!y)return ;
            for(int i=x;i<N;i+=(i&-i))
                for(int j=y;j<N;j+=(j&-j))
                    f[i][j]+=d;
        }
        ll down(int x,int y)
        {
            if(!x||!y)return 0;
            ll ret = 0;
            for(int i=x;i;i-=(i&-i))
                for(int j=y;j;j-=(j&-j))
                    ret+=f[i][j];
            return ret;
        }
    }tr;
    void update(int k,int d)
    {
        for(int i=lp[k];i<=rp[k];i++)
            tr.up(p[i].x,p[i].y,d);
    }
    ll ask(int x_,int y_,int _x,int _y)
    {
        return tr.down(_x,_y)+tr.down(x_-1,y_-1)-tr.down(_x,y_-1)-tr.down(x_-1,_y);
    }
    int tim;
    void divi(int l,int r,int beg,int ens)
    {
        if(beg>ens)return ;
        if(l==r)
        {
            for(int i=beg;i<=ens;i++)
                ans[q[i].id] = to[l];
            return ;
        }
        int mid = (l+r)>>1;
        while(tim<mid)tim++,update(tim,1);
        while(tim>mid)update(tim,-1),tim--;
        int lt = 0,rt = 0;
        for(int i=beg;i<=ens;i++)
        {
            ll sum = ask(q[i].x_,q[i].y_,q[i]._x,q[i]._y);
            if(sum>=q[i].k)tmpl[++lt] = q[i];
            else tmpr[++rt] = q[i];
        }
        for(int i=beg;i<=beg+lt-1;i++)q[i]=tmpl[i-beg+1];
        for(int i=beg+lt;i<=ens;i++)q[i]=tmpr[i-beg-lt+1];
        divi(l,mid,beg,beg+lt-1);
        divi(mid+1,r,beg+lt,ens);
    }
    int main()
    {
        n = rd(),m = rd();
        for(int i=1;i<=n*n;i++)
        {
            p[i].x = (i-1)/n+1;
            p[i].y = (i-1)%n+1;
            p[i].k = rd();
        }
        sort(p+1,p+1+n*n,cmp);
        for(int las=-1,i=1;i<=n*n;i++)
        {
            if(p[i].k!=las)
            {
                rp[mx] = i-1;
                las = p[i].k;
                mx++;
                lp[mx] = i;
                to[mx] = las;
            }
            p[i].k = mx;
        }
        rp[mx] = n*n;
        for(int i=1;i<=m;i++)
            q[i].read(),q[i].id=i;
        divi(1,mx+1,1,m);
        for(int i=1;i<=m;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    P1966 火柴排队
    其实,我可以假装这篇随笔的名字很长,很长
    通用技术课的准备
    浅谈高压线除冰技术
    浅谈发电厂的环保问题
    本地MD搬运
    高考作文专题
    奇奇怪怪的错误收集 (鸽)
    2019CSP-S2专题
    模拟赛 ——“与” 小象涂色 行动!行动!
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10201409.html
Copyright © 2011-2022 走看看