Codeforces 846 D(线段树)

题目链接: D. Monitor

题意

求K*K格子的最大值。初始值都为inf.

思路

简单的线段树求区间最大值。

#include <bits/stdc++.h>
using namespace std;
int tree[3200][3200];
const int inf = 0x3f3f3f3f;
void update_y(int xnode,int ynode,int xbegin,int xend,int ybegin,int yend,int ypos,int k)
{
    if(ypos > yend || ypos < ybegin)
        return;
    if(ybegin == yend)
    {
        if(xbegin == xend)
        {
            tree[xnode][ynode] = k;
        }
        else
            tree[xnode][ynode] = max(tree[xnode << 1][ynode] ,tree[xnode << 1|1][ynode]);
        return;
    }
    int mid = (ybegin + yend) >> 1;
    update_y(xnode ,ynode << 1,xbegin,xend,ybegin,mid,ypos,k);
    update_y(xnode,ynode << 1|1,xbegin,xend,mid + 1,yend,ypos,k);
    tree[xnode][ynode] = max(tree[xnode][ynode << 1],tree[xnode][ynode << 1|1]);
}
void update_x(int xnode,int ynode,int xbegin,int xend,int ybegin,int yend,int xpos,int ypos,int k)
{
    if(xpos > xend || xpos < xbegin)
        return;
    if(xpos == xbegin && xpos == xend)
    {
        update_y(xnode,ynode,xbegin,xend,ybegin,yend,ypos,k);
        return;
    }
    int mid = (xbegin + xend) >> 1;
    update_x(xnode << 1,ynode,xbegin,mid,ybegin,yend,xpos,ypos,k);
    update_x(xnode << 1|1,ynode,mid + 1,xend,ybegin,yend,xpos,ypos,k);
    update_y(xnode,ynode,xbegin,xend,ybegin,yend,ypos,k);
}
int query_y(int xnode,int ynode,int ybegin,int yend,int y1,int y2)
{
    if(y1 > yend || y2 < ybegin)
    {
        return -1;
    }
    if(y1 <= ybegin && y2 >= yend)
    {
        return tree[xnode][ynode];
    }
    int mid = (ybegin + yend) >> 1;
    int maxer = -1;
    maxer = max(maxer, query_y(xnode,ynode << 1,ybegin,mid,y1,y2));
    maxer = max(maxer, query_y(xnode,ynode << 1|1,mid+1,yend,y1,y2));
    return maxer;
}
int query_x(int xnode,int ynode,int xbegin,int xend,int ybegin,int yend,int x1,int y1,int x2,int y2)
{
    if(x1 > xend || x2 < xbegin)
    {
        return -1;
    }
    if(xbegin >= x1 && xend <= x2)
    {
        return query_y(xnode,ynode,ybegin,yend,y1,y2);
    }
    int mid = (xbegin + xend) >> 1;
    int maxer = -1;
    maxer = max(maxer, query_x(xnode << 1,ynode,xbegin,mid,ybegin,yend,x1,y1,x2,y2));
    maxer = max(maxer, query_x(xnode << 1|1,ynode,mid + 1,xend,ybegin,yend,x1,y1,x2,y2));
    return maxer;
}
int main()
{
    int n,m,k,q,maxer,xpos,ypos,val;
    cin >> n >> m >> k >> q;
    maxer = inf ;
    memset(tree,inf,sizeof(tree));
    for(int i = 1; i <= q; i++)
    {
        cin >> xpos >> ypos >> val;
        update_x(1,1,1,n,1,m,xpos,ypos,val);
    }
    for(int i = 1; i + k - 1 <= n ;i++ )
        for(int j = 1; j + k - 1 <= m ;j++)
    {
         maxer = min(maxer, query_x(1, 1, 1, n, 1, m, i, j, i + k -1,j + k -1));
    }
    if(maxer != inf)
        cout << maxer << endl;
    else
        cout << "-1" << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值