ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P4514 上帝造题的七分钟

2019-07-22 17:01:30  阅读:182  来源: 互联网

标签:ch 洛谷 int pos 2048 七分钟 read 造题 include


P4514 上帝造题的七分钟

题目背景

裸体就意味着身体。

题目描述

“第一分钟,X说,要有矩阵,于是便有了一个里面写满了000的n×mn×mn×m矩阵。
第二分钟,L说,要能修改,于是便有了将左上角为(a,b)(a,b)(a,b),右下角为(c,d)(c,d)(c,d)的一个矩形区域内的全部数字加上一个值的操作。
第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作。
第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围。
第五分钟,和雪说,要有耐心,于是便有了时间限制。
第六分钟,吃钢琴男说,要省点事,于是便有了保证运算过程中及最终结果均不超过32位有符号整数类型的表示范围的限制。
第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。”
——《上帝造裸题的七分钟》
所以这个神圣的任务就交给你了。
输入输出格式
输入格式:

输入数据的第一行为X n m,代表矩阵大小为n×mn×mn×m。
从输入数据的第二行开始到文件尾的每一行会出现以下两种操作:

L a b c d delta —— 代表将(a,b),(c,d)(a,b),(c,d)(a,b),(c,d)为顶点的矩形区域内的所有数字加上delta。
k a b c d —— 代表求(a,b),(c,d)(a,b),(c,d)(a,b),(c,d)为顶点的矩形区域内所有数字的和。

请注意,kkk为小写。

输出格式:

针对每个k操作,在单独的一行输出答案。

输入输出样例

输入样例#1: 复制

X 4 4
L 1 1 3 3 2
L 2 2 4 4 1
k 2 2 3 3

输出样例#1: 复制

12

说明

对于10%的数据,1≤n≤16,1≤m≤161 ≤ n ≤ 16, 1 ≤ m ≤ 161≤n≤16,1≤m≤16, 操作不超过200个.
对于60%的数据,1≤n≤512,1≤m≤5121 ≤ n ≤ 512, 1 ≤ m ≤ 5121≤n≤512,1≤m≤512.
对于100%的数据,1≤n≤2048,1≤m≤2048,−500≤delta≤5001 ≤ n ≤ 2048, 1 ≤ m ≤ 2048, -500 ≤ delta ≤ 5001≤n≤2048,1≤m≤2048,−500≤delta≤500,操作不超过200000个,保证运算过程中及最终结果均不超过32位带符号整数类型的表示范围。
by XLk

题解

树上差分。子树权值和即为根节点权值。
修改u到v的路径上的点,权值增加x,则u,v加x,lca(u,v)和fa[lca(u,v)]减x

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <iostream>
void swap(int &a, int &b){int tmp = a;a = b, b = tmp;}
int max(int a, int b){return a > b ? a : b;}
int min(int a, int b){return a < b ? a : b;}
void read(int &x)
{
    x = 0;char ch = getchar(), c = ch;
    while(ch < '0' || ch > '9') c = ch, ch = getchar();
    while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    if(c == '-') x = -x;
}

const int INF = 0x3f3f3f3f;
const int MAXN = 50000 + 10;

struct Edge
{
    int u, v, nxt;
    Edge(int _u, int _v, int _nxt){u = _u, v = _v, nxt = _nxt;}
    Edge(){}
}edge[MAXN << 1];
int head[MAXN], cnt;

void insert(int a, int b)
{
    edge[++ cnt] = Edge(a, b, head[a]), head[a] = cnt;
    edge[++ cnt] = Edge(b, a, head[b]), head[b] = cnt;
}

int val[MAXN], n, k;

int p[20][MAXN], deep[MAXN], M;

void dfs(int x, int pre)
{
    for(int pos = head[x];pos;pos = edge[pos].nxt)
    {
        int v = edge[pos].v;
        if(v == pre) continue;
        deep[v] = deep[x] + 1;
        p[0][v] = x;
        dfs(v, x);
    }
}

void yuchuli()
{
    dfs(1, -1);
    for(M = 0;(1 << M) <= n;++ M); -- M;
    for(int i = 1;i <= M;++ i)
        for(int j = 1;j <= n;++ j)
            p[i][j] = p[i - 1][p[i - 1][j]];
}

int LCA(int u, int v)
{
    if(deep[u] < deep[v]) swap(u, v);
    for(int i = M;i >= 0;-- i)
        if(deep[u] - deep[v] >= (1 << i))
            u = p[i][u];
    if(u == v) return u;
    for(int i = M;i >= 0;-- i)
        if(p[i][u] != p[i][v])
            u = p[i][u], v = p[i][v];
    return p[0][u];
}

int ma, sum[MAXN];

void find(int x, int pre)
{
    sum[x] = val[x];
    for(int pos = head[x];pos;pos = edge[pos].nxt)
    {
        int v = edge[pos].v;
        if(v == pre) continue;
        find(v, x);
        sum[x] += sum[v];
    }
}

int main()
{
    read(n), read(k);
    for(int i = 1;i < n;++ i)
    {
        int tmp1, tmp2;
        read(tmp1), read(tmp2);
        insert(tmp1, tmp2);
    }
    yuchuli();
    for(int i = 1;i <= k;++ i)
    {
        int tmp1, tmp2, lca;
        read(tmp1), read(tmp2), lca = LCA(tmp1, tmp2);
        val[tmp1] += 1, val[tmp2] += 1, val[lca] -= 1, val[p[0][lca]] -= 1;
    }
    find(1, -1);
    for(int i = 1;i <= n;++ i) ma = max(ma, sum[i]);
    printf("%d", ma);
    return 0;
} 

标签:ch,洛谷,int,pos,2048,七分钟,read,造题,include
来源: https://www.cnblogs.com/huibixiaoxing/p/11226871.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有