HDU 4819 Mosaic D区段树

简介:

连接:http://acm.hdu.edu.cn/showproblem.php?pid=4819

意:给出一个800×800下面的矩阵。每次更新一个点的值为以这个点为中心的长度为Li的矩阵内的最大值和最小值的平均值。而且输出这个值。

思路:线段树模板题。二维线段树就是一个树套树的情况。



题的意义就在于给我带了一个二维线段树的模板,跑了2359ms。结构体的线段树不会被卡。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 1000
#define INF 0x7fffffff
#define eps 1e-16
#define MOD 1000000009
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int x_pos[maxn],y_pos[maxn];
int n;//y最大范围
struct y_line
{
    int left,right;
    int Max,Min;
    //int sum;
    int mid(){return (left+right)>>1;}
};
struct x_line
{
    int left,right;
    y_line yy[maxn*4];
    int mid(){return (left+right)>>1;}
    void build_ytree(int i,int l,int r)
    {
        yy[i].Max=-INF;
        yy[i].Min=INF;
        yy[i].left=l;
        yy[i].right=r;
        if(l==r)
        {
            y_pos[l]=i;
            return ;
        }
        build_ytree(i<<1,l,yy[i].mid());
        build_ytree(i<<1|1,yy[i].mid()+1,r);
    }
    int query_Min(int i,int y1,int y2)
    {
        if(yy[i].left==y1&&yy[i].right==y2)
            return yy[i].Min;
        if(yy[i].mid()>=y2)
            return query_Min(i<<1,y1,y2);
        if(yy[i].mid()<y1)
            return query_Min(i<<1|1,y1,y2);
        return min(query_Min(i<<1,y1,yy[i].mid()),query_Min(i<<1|1,yy[i].mid()+1,y2));
    }
    int query_Max(int i,int y1,int y2)
    {
        if(yy[i].left==y1&&yy[i].right==y2)
            return yy[i].Max;
        if(yy[i].mid()>=y2)
            return query_Max(i<<1,y1,y2);
        if(yy[i].mid()<y1)
            return query_Max(i<<1|1,y1,y2);
        return max(query_Max(i<<1,y1,yy[i].mid()),query_Max(i<<1|1,yy[i].mid()+1,y2));
    }
}xx[maxn*4];
void build_xtree(int i,int l,int r)
{
    xx[i].left=l;
    xx[i].right=r;
    xx[i].build_ytree(1,1,n);
    if(l==r)
    {
        x_pos[l]=i;
        return ;
    }
    build_xtree(i<<1,l,xx[i].mid());
    build_xtree(i<<1|1,xx[i].mid()+1,r);
}
void change(int x,int y,int num)
{
    int x_p=x_pos[x],y_p=y_pos[y];
    for(int i=x_p;i>0;i>>=1)
        for(int j=y_p;j>0;j>>=1)
            if(j==y_p&&i==x_p)
            {
                xx[i].yy[j].Max=xx[i].yy[j].Min=num;
            }
            else if(j==y_p)
            {
                xx[i].yy[j].Max=max(xx[i<<1].yy[j].Max,xx[i<<1|1].yy[j].Max);
                xx[i].yy[j].Min=min(xx[i<<1].yy[j].Min,xx[i<<1|1].yy[j].Min);
            }
            else
            {
                xx[i].yy[j].Max=max(xx[i].yy[j<<1].Max,xx[i].yy[j<<1|1].Max);
                xx[i].yy[j].Min=min(xx[i].yy[j<<1].Min,xx[i].yy[j<<1|1].Min);
            }
}
int query_Min(int i,int x1,int y1,int x2,int y2)
{
    if(xx[i].left==x1&&xx[i].right==x2)
        return xx[i].query_Min(1,y1,y2);
    if(xx[i].mid()>=x2)
        return query_Min(i<<1,x1,y1,x2,y2);
    if(xx[i].mid()<x1)
        return query_Min(i<<1|1,x1,y1,x2,y2);
    return min(query_Min(i<<1,x1,y1,xx[i].mid(),y2),query_Min(i<<1|1,xx[i].mid()+1,y1,x2,y2));
}
int query_Max(int i,int x1,int y1,int x2,int y2)
{
    if(xx[i].left==x1&&xx[i].right==x2)
        return xx[i].query_Max(1,y1,y2);
    if(xx[i].mid()>=x2)
        return query_Max(i<<1,x1,y1,x2,y2);
    if(xx[i].mid()<x1)
        return query_Max(i<<1|1,x1,y1,x2,y2);
    return max(query_Max(i<<1,x1,y1,xx[i].mid(),y2),query_Max(i<<1|1,xx[i].mid()+1,y1,x2,y2));
}
int main()
{
    int T,tot,c_x,c_y,r;
    scanf("%d",&T);
    for(int ii=1;ii<=T;ii++)
    {
        scanf("%d",&n);
        build_xtree(1,1,n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                int x;
                scanf("%d",&x);
                change(i,j,x);
            }
        scanf("%d",&tot);
        printf("Case #%d:\n",ii);
        for(int i=0;i<tot;i++)
        {
            scanf("%d%d%d",&c_x,&c_y,&r);
            int a,b,c,d;
            a=max(1,c_x-r/2);
            b=max(1,c_y-r/2);
            c=min(n,c_x+r/2);
            d=min(n,c_y+r/2);
            int t_min=query_Min(1,a,b,c,d);
            int t_max=query_Max(1,a,b,c,d);
            int t_need=(t_min+t_max)>>1;
            change(c_x,c_y,t_need);
            printf("%d\n",t_need);
        }
    }
    return 0;
}




版权声明:本文博客原创文章,博客,未经同意,不得转载。







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4720699.html,如需转载请自行联系原作者


相关文章
UVa10075 - Airlines(所有点对之间的最短距离)
UVa10075 - Airlines(所有点对之间的最短距离)
48 0
|
SQL Shell
HDU-4348 To the moon(主席树区间修改 永久化标记)
HDU-4348 To the moon(主席树区间修改 永久化标记)
154 0
HDU-4348 To the moon(主席树区间修改 永久化标记)
UPC-趾压板矩阵(强行找规律)
UPC-趾压板矩阵(强行找规律)
107 0
UPC-趾压板矩阵(强行找规律)
|
算法
[Nowcoder] Agamemnon‘s Odyssey | 树的直径
题意: 有一棵树,n − 1 n-1n−1条边中,两两之间都有一个边权,可以从任意一个点出发,最多经过每一条边k次,只有第一次经过的时候才会算上边权的贡献,问最大的贡献是多少? 其实这道题是非常简单的,是比较模板的题 首先我们考虑,当k ⩾ 2 k \geqslant 2k⩾2的情况,我们可以将整棵树遍历过一遍,所以说最大贡献便是所有的边权和 当k = = 1 k == 1k==1的情况下,其实就是树的直径,树的直径上,满足贡献最大
113 0
[Nowcoder] Agamemnon‘s Odyssey | 树的直径
|
人工智能 BI Go
[Atcoder ABC222] F - Expensive Expense | 妙用树的直径 | Dijkstra
Problem Statement The Kingdom of AtCoder is composed of N towns and N−1 roads. The towns are labeled as Town 1, Town 2, …, Town N. Similarly, the roads are labeled as Road 1, Road 2, …, Road N−1. Road i connects Towns Ai and Bi bidirectionally, and you have to pay the toll of Ci to go through it.
220 0
[Atcoder ABC222] F - Expensive Expense | 妙用树的直径 | Dijkstra
【word小技巧】插入三阶以上的矩阵
简介:【word小技巧】插入三阶以上的矩阵
【word小技巧】插入三阶以上的矩阵
|
人工智能 安全
UPC——校门内的树—>二分
题目描述 FZYZ 大门的左侧有一排 n 棵树木。它们按照距离的远近排列,第 1 棵树的高度为 a1 米,第 2 棵树木的高度为 a2 米,第 3 棵树木的高度为 a3 米,……,第 n 棵树木的高度为 an米。 为了给同学们以积极向上的感觉,一些同学自发地决定对树木进行修剪,使得树木呈现上升的趋势。具体地说,他们希望对树木进行修剪和整理,使得修剪之后的树木高度 b1,b2,b3,…,bn 米且满足 b1<b2<b3<…<bn。
136 0
|
C语言
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
103 0