首页 > 其他分享 >HDU2024 R4

HDU2024 R4

时间:2024-07-31 22:40:09浏览次数:15  
标签:R4 node HDU2024 suf int ++ bcnt ans

T4

先把四组分成两组,左边两组叫 \(L\),右边两组叫 \(R\)。直接爆搜每个数属于 \(L\) 还是 \(R\),过程中顺带 \(01\) 背包出两组分别能取到哪些子集异或和。接下来不妨设 \(w_{f(A)} \ge w_{f(B)}\),\(w_{f(C)} \ge w_{f(D)}\)。若 \(w_{f(A)} \ge w_{f(C)}\),则答案为 \(w_{f(A)} - w_{f(D)}\),否则答案为 \(w_{f(C)} - w_{f(B)}\)。按 \(w\) 升序枚举 \(f(A)\) 和 \(f(C)\),则 \(f(B)\) 和 \(f(D)\) 只需要异或一下。枚举的时候把 \(f(A)\) 和 \(f(C)\) 一起枚举,顺便记录 \(f(B)\) 和 \(f(D)\) 的前缀最大值。

代码
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, S;
int a[20];
int w[2005];
int p[2005];
bool f[2][20][2005];
int ans = 0;
void dfs(int x, int sl, int sr) {
    if (x == n + 1) {
        for (int j = 0, ml = -1, mr = -1; j <= S; j++) {
            int i = p[j];
            if (f[0][x][i] && w[i] >= w[sl ^ i]) {
                ml = max(ml, w[sl ^ i]);
                if (mr != -1) 
                    ans = min(ans, w[i] - min(w[sl ^ i], mr));
            }
            if (f[1][x][i] && w[i] >= w[sr ^ i]) {
                mr = max(mr, w[sr ^ i]);
                if (ml != -1) 
                    ans = min(ans, w[i] - min(w[sr ^ i], ml));
            }
        }
        return;
    }
    for (int i = 0; i <= S; i++) {
        f[0][x + 1][i] = (f[0][x][i] | f[0][x][i ^ a[x]]);
        f[1][x + 1][i] = f[1][x][i];
    }
    dfs(x + 1, sl ^ a[x], sr);
    for (int i = 0; i <= S; i++) {
        f[0][x + 1][i] = f[0][x][i];
        f[1][x + 1][i] = f[1][x][i] | f[1][x][i ^ a[x]];
    }
    dfs(x + 1, sl, sr ^ a[x]);
}
int main() {
    int tc;
    cin >> tc;
    while (tc--) {
        ans = 2147483647;
        cin >> n >> m;
        S = (1 << m) - 1;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 0; i <= S; i++) cin >> w[i], p[i] = i;
        sort(p, p + S + 1, [](int a, int b) { return w[a] < w[b]; });
        for (int i = 0; i <= S; i++) f[0][2][i] = f[1][2][i] = 0;
        f[0][2][a[1]] = f[0][2][0] = f[1][2][0] = 1;
        dfs(2, a[1], 0);
        cout << ans << "\n";
    }
    return 0;
}

T12

按照平面直角坐标系第一象限建系。

先预处理出 \(pre[i]\) 表示从起点到达 \((i, p_i)\) 的最大收益,\(suf[i]\) 表示从终点到 \((i, p_i)\) 的最大收益。然后考虑对于一个询问,肯定是从起点到达其左上或右下的一个点,然后从这个点到终点。考虑左上,则右下同理。若区域内存在至少一个点,则这个区域的答案就是 \(\max\limits_{(i, p_i) 在区域内} \{ pre[i] + suf[i] \}\)。如果区域内不存在一个点,那就可以强制令路径经过这区域内的某个点。所以我们考虑对每个询问在左上右下各建一个虚点(建在整个地图的左上和右下应该也行),然后令这些虚点的权值为 \(0\),正常求它们的 \(pre\) 和 \(suf\),然后查询就可以变成二维数点。然后整个题就只需要一堆二维数点即可。

代码
#include <iostream>
#include <algorithm>
#include <math.h>
#define int long long
#define lowbit(x) ((x) & (-(x)))
using namespace std;
bool bg;
int n, m;
struct node {
    int x, y, v;
} a[1200005], b[2000005];
int pre[1200005];
int suf[1200005];
struct PBIT {
    int bit[900005];
    void add(int x, int y) { for (; x <= n + 10; x += lowbit(x)) bit[x] = max(bit[x], y); }
    int query(int x) {
        int ret = 0;
        for (; x; x -= lowbit(x)) ret = max(ret, bit[x]);
        return ret;
    }
    void clear() { for (int i = 0; i <= n + 10; i++) bit[i] = 0; }
} pbit;
struct SBIT {
    int bit[900005];
    void add(int x, int y) { for (; x; x -= lowbit(x)) bit[x] = max(bit[x], y); }
    int query(int x) {
        // cerr << x << "qq\n";
        int ret = 0;
        for (; x <= n + 10; x += lowbit(x)) ret = max(ret, bit[x]);
        return ret;
    }
    void clear() { for (int i = 0; i <= n + 10; i++) bit[i] = 0; }
} sbit;
int ans[400005];
bool ed;
signed main() {
    // cout << (&ed - &bg) / 1024.0 / 1024.0 << "\n";
    // freopen("data.in", "r", stdin);
    // freopen("data.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int tc;
    cin >> tc;
    while (tc--) {
        cin >> n >> m;
        for (int i = 1; i <= m; i++) ans[i] = 0;
        for (int i = 1; i <= n; i++) {
            a[i].x = i;
            cin >> a[i].y >> a[i].v;
            ++a[i].x, ++a[i].y;
        }
        int bcnt = 0;
        for (int i = 1; i <= m; i++) {
            int x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            swap(y1, y2);
            ++bcnt;
            b[bcnt].x = x1, b[bcnt].y = y1;
            ++b[bcnt].x, ++b[bcnt].y;
            a[++n] = (node) { b[bcnt].x - 1, b[bcnt].y + 1, 0 };
            --b[bcnt].x, ++b[bcnt].y;
            b[bcnt].v = i;

            ++bcnt;
            b[bcnt].x = x2, b[bcnt].y = y2;
            ++b[bcnt].x, ++b[bcnt].y;
            a[++n] = (node) { b[bcnt].x + 1, b[bcnt].y - 1, 0 };
            ++b[bcnt].x, --b[bcnt].y;
            b[bcnt].v = -i;
        }
        sort(a + 1, a + n + 1, [](node a, node b) { return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); });
        for (int i = 1; i <= n; i++) {
            pre[i] = pbit.query(a[i].y) + a[i].v;
            pbit.add(a[i].y, pre[i]);
        }
        for (int i = n; i; i--) {
            suf[i] = sbit.query(a[i].y) + a[i].v;
            sbit.add(a[i].y, suf[i]);
            suf[i] -= a[i].v;
        }
        pbit.clear(), sbit.clear();
        for (int i = 1; i <= n; i++) b[++bcnt] = a[i], b[bcnt].v = n + i;
        sort(b + 1, b + bcnt + 1, [](node a, node b) { return a.x == b.x ? (a.v > b.v) : (a.x < b.x); });
        for (int i = 1; i <= bcnt; i++) {
            if (b[i].v > n) 
                sbit.add(b[i].y, pre[b[i].v - n] + suf[b[i].v - n]);
            else if (b[i].v > 0)
                ans[b[i].v] = max(ans[b[i].v], sbit.query(b[i].y));
        }
        sort(b + 1, b + bcnt + 1, [](node a, node b) { return a.x == b.x ? (a.v > b.v) : (a.x > b.x); });
        for (int i = 1; i <= bcnt; i++) {
            if (b[i].v > n) 
                pbit.add(b[i].y, pre[b[i].v - n] + suf[b[i].v - n]);
            else if (b[i].v < 0)
                ans[-b[i].v] = max(ans[-b[i].v], pbit.query(b[i].y));
        }
        for (int i = 1; i <= m; i++) cout << ans[i] << "\n";
        pbit.clear(), sbit.clear();
    }
    return 0;
}

标签:R4,node,HDU2024,suf,int,++,bcnt,ans
From: https://www.cnblogs.com/forgotmyhandle/p/18335648

相关文章

  • HDU2024 R2 T9 题解
    考虑维护一下每个点的速度。把区间加拆成后缀加和后缀减,然后考虑后缀加。减就同理。考虑在一段后缀的目标速度增加之后,哪些时刻的加速度会变化。这里加速度必然只会变大\(1\),因此在这个时刻之后的速度都会增加\(1\),又由于目标速度也增加了\(1\),所以这个位置之后的加速度都不再......
  • 【Vulnhub系列】Vulnhub_Dr4g0n_b4ll 靶场渗透(原创)
    【Vulnhub系列靶场】Vulnhub_Dr4g0n_b4ll靶场渗透原文转载已经过授权原文链接:Lusen的小窝-学无止尽,不进则退(lusensec.github.io)一、环境搭建选择打开.ovf文件配置名称和路径打开后调整网络连接模式为【NAT】即可二、信息收集1、主机发现nmap.exe-sn192.1......
  • Java解压rar5兼容rar4
    RAR文件格式由WinRAR开发,广泛用于文件压缩和归档。随着技术的发展,RAR5作为更新的版本,引入了多项改进以提高压缩效率和数据安全性。压缩效率:RAR5通过增大字典大小至32MB,相较于RAR4的4MB,能够更有效地找到数据中的重复模式,从而提高压缩率,特别是在处理大型文件时。安全......
  • SAP中MIR4使用的BAPI是什么,如何使用?
    在SAP系统中,MIR4是一个用于采购发票校验的事务代码,它允许用户处理与采购订单相关的发票。关于MIR4使用的BAPI(BusinessApplicationProgrammingInterface,业务应用程序编程接口),并没有一个特定的、直接对应MIR4的BAPI名称,因为BAPI通常是针对SAP系统中特定的业务对象或功能而......
  • MBR40150FCT-ASEMI无人机专用MBR40150FCT
    编辑:llMBR40150FCT-ASEMI无人机专用MBR40150FCT型号:MBR40150FCT品牌:ASEMI封装:TO-220F批号:最新最大平均正向电流(IF):40A最大循环峰值反向电压(VRRM):150V最大正向电压(VF):0.60V~0..95V工作温度:-65°C~150°C反向恢复时间:35ns芯片个数:2芯片尺寸:74mil引脚数量:3正向浪涌电流(IFM......
  • 题解:P8144 [JRKSJ R4] BBWWBB
    思路分析题意可得,白方必定不会胜利,只能尽量让游戏无限进行下去。那么我们只考虑黑方能否胜利。若想让戏能无限进行下去,必须满足以下条件。白方先手。若黑方先手必然可以吃掉一个白方,白方仅有一个棋子,必输。白方第一轮可以吃掉一颗黑方。因为只有\(3,4\)是白方,所以......
  • 降水临近预报_Weather4cast_RainAI阅读分享
    降水临近预报_Weather4cast_RainAI阅读分享本文是论文阅读分享,后续会进行对应的代码分享,欢迎交流讨论。背景知识RainAI-Weather4Cast2023ResultsWeather4cast-Super-ResolutionRainMoviePredictionunderSpatio-TemporalShifts2023年Weather4cast竞赛的......
  • StyleWriter4英语论文润色神器安装使用教程
    StyleWriter4是一款强大的英文写作助手软件,论文润色非常优秀,专注于提升用户书面表达的清晰度、简洁性和专业性。它通过深度分析技术检测文本风格、语法、冗余及复杂性等问题,提供实时修改建议,帮助用户改进文档可读性,遵循最佳写作实践,并确保内容符合特定的文体要求,适用于学术论文、......
  • 在IdentityServer4生成的JWT中添加一个自定义的Claim,用于ABP框架中要用到的token信息
    用过IdentityServer4或者熟悉ASP.NETCore认证的都应该知道有Claim,如何理解ids4中的Claim?这里可以理解为声明,我们每个用户都有多个Claim,每个Claim声明了用户的某个信息比如:Role=Admin,UserID=1000等等,这里Role,UserID每个都是用户的Claim,都是表示用户信息的单元 ,我们不妨把它称为......
  • blender4.1添加骨骼复制位置和复制旋转约束代码(Armature-Biped_Root)
    添加旋转旋转约束importbpy#定义骨架中骨骼的映射关系bone_mapping={"mixamorig:Hips":"Pelvis","mixamorig:LeftUpLeg":"Left_Thigh","mixamorig:LeftLeg":"Left_Calf","mixamorig:LeftFoot&q......