Important matches Gym - 101840I —— 二维莫队

In the qualification rounds of the World Cup, there were two disjoint sets of teams S1 = [1, · · · , N] and
S2 = [1, · · · , M]. Given a matrix X that decides the importance of the match between team i ∈ S1
against team j ∈ S2 by the value Xi,j . S1 represents the rows of the matrix X, and S2 represents the
columns of the matrix X. We would like to answer Q queries, where each decides the importance of all
the matches played by all the teams from the subgroup [A, · · · , C] from S1 against all teams from the
subgroup [B, · · · , D] from S2, such that 1 ≤ A ≤ C ≤ N, 1 ≤ B ≤ D ≤ M. The importance of a set
of matches between two subgroups is determined by the median importance of all the matches between
the teams from the first subgroup against all the teams from the second group, namely the median of the
submatrix XA···C,B···D.
Input
The first line of the input contains a single integer 1 ≤ T ≤ 100 the number of test cases. Each test case
begins with a line containing 3 spaces separated integers N, M, Q. The importance matrix X is given by
the next N lines each containing M space separated integers. The remaining Q lines, each contains 4
space separated integers A, B, C, D of the query; where 1 ≤ N, M ≤ 200, 1 ≤ Q ≤ 10000, and for the
given importance matrix X, 1 ≤ Xi,j ≤ 2000 for all i, j.
Output
For each test case output a line displaying the case number, followed by Q lines each containing a single
integer, the importance of the matches of the corresponding query.
Example
important.in standard output
1
3 4 2
1 2 3 1
2 1 1 4
7 8 9 3
1 1 1 1
1 2 3 4
Case 1:
1
3
Note
• The median of a set of numbers is the middle element in the sorted list of the given set. If the set
has two middle elements, then we choose the second one. For example the median of {2, 1, 3} is 2
and the median of {4, 2, 3, 1} is 3.
• The second query asks for the median of the submatrix that is excluding the first column. This
submatrix contains the elements {2, 3, 1, 1, 1, 4, 8, 9, 3}, which has the sorted form {1, 1, 1, 2, 3,
3, 4, 8, 9}, therefore the median is 3.

题意:

给你一个矩阵,然后q个询问,每次询问给你l1,l2,r1,r2,分别是这个矩阵的上界下界,左界右界,问你这个矩阵的中值是什么,就是大小最中间的那个数,若是1234就是3.

题解:

我也不知道是不是莫队,但感觉像。由于他有4个变量,这时候就需要用xia JB排序法,简称乱排。然后右界往右移的时候就加上上界到下界在右界上的所有数,以此类推,然后就过了咦嘿嘿嘿

#include<bits/stdc++.h>
using namespace std;
int len;
struct node
{
    int up,down,l,r,id;
    bool operator< (const node& a)const
    {
        if(up/len==a.up/len)
        {
            if(l/len==a.l/len)
            {
                if(down/len==a.down/len)
                    return r<a.r;
                return down<a.down;
            }
            return l<a.l;
        }
        return up<a.up;
    }
}p[10005];
vector<int>vec;
int Map[205][205];
int ans[10050];
void addr(int up,int down,int r)
{
    for(int i=up;i<=down;i++)
        vec.push_back(Map[i][r]);
}
void adddown(int l,int r,int down)
{
    for(int i=l;i<=r;i++)
        vec.push_back(Map[down][i]);
}
void delr(int up,int down,int r)
{
    for(int i=up;i<=down;i++)
        vec.erase(lower_bound(vec.begin(),vec.end(),Map[i][r]));
}
void deldown(int l,int r,int down)
{
    for(int i=l;i<=r;i++)
        vec.erase(lower_bound(vec.begin(),vec.end(),Map[down][i]));
}
int main()
{
    freopen("important.in","r",stdin);
    int t;
    scanf("%d",&t);
    int cas=0;
    while(t--)
    {
        vec.clear();
        int n,m,q;
        len=min(sqrt(n),sqrt(m));
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&Map[i][j]);
        for(int i=1;i<=q;i++)
            scanf("%d%d%d%d",&p[i].up,&p[i].l,&p[i].down,&p[i].r),p[i].id=i;
        sort(p+1,p+1+q);
        int up=1,l=1,down=1,r=1;
        vec.push_back(Map[1][1]);
        for(int i=1;i<=q;i++)
        {
            while(r<p[i].r)
                r++,addr(up,down,r);
            while(down<p[i].down)
                down++,adddown(l,r,down);
            while(l>p[i].l)
                l--,addr(up,down,l);
            while(up>p[i].up)
                up--,adddown(l,r,up);
            sort(vec.begin(),vec.end());
            while(r>p[i].r)
                delr(up,down,r),r--;
            while(down>p[i].down)
                deldown(l,r,down),down--;
            while(l<p[i].l)
                delr(up,down,l),l++;
            while(up<p[i].up)
                deldown(l,r,up),up++;
            //cout<<"siz+1/2: "<<vec[(vec.size()+1)/2]<<endl;
            ans[p[i].id]=vec[vec.size()/2];
        }
        //for(int i=0;i<vec.size();i++)
            //printf("%d ",vec[i]);
        printf("Case %d:\n",++cas);
        for(int i=1;i<=q;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值