2024 杭电多校 第四场

news2024/9/17 9:17:27

 

分组

给定 n 个正整数 a1,a2,…,an (1≤ai<2m) 以及 0 到 2m−1 的权重 w0,w1,…,w2m−1;你需要把这 n 个正整数分成四组 A,B,C,D,令 f(A),f(B),f(C),f(D) 分别表示每组中所有数字的异或和,你的分组方案需要最小化 wf(A),wf(B),wf(C),wf(D) 的极差,即:

max(wf(A),wf(B),wf(C),wf(D))−min(wf(A),wf(B),wf(C),wf(D))

每组都可以为空,此时 f(⋅)=0。

(4≤n≤18, 1≤m≤10)。

dp+暴搜。注意到n和m的数据范围比较小,去枚举每个数字选或者不选的复杂度O(2^n),枚举所有异或和的情况O(2^m),O(2^(n+m))加点优化,似乎正好能卡过。

我们先不去考虑异或值有权重的情况,只考虑异或值极差最小的情况(假如我们能解决异或值极差最小的情况,无非是将原来的异或值套一层映射看成新的异或值)

           

我们先分为两个区间,其中a1假定一定为左区间,O(2^(n-1))枚举他们的分组情况,同时能得到左右区间异或和xor1,xor2。

我们假定左区间分出wa,wb,满足wa>wb,右区间分出wc,wd,满足wc>wd。此时我们只要知道wa就能确定wb,知道wc就能确定wd。

此时区间的极差有两种情况:

1)wa>=wc,wa取得最大值,最小值在wb和wd中产生,需要去维护此时wd可能取得的最大值。

2)wc>=wa,wc取得最大值,最小值在wb和wd中产生,需要去维护此时wb可能取得的最大值。

如何去维护wd和wb呢?

以1)为例,wa>=wc>=wd,wd是在[0,wc]里最大的那个,我们在枚举wc时可以立马确定wd取值,于是我们从小到大枚举wc,就可以知道在当前wc范围内wd的最大取值。但是我们没有必要另开一个数组去存wd在何种范围下的最大值,直接左右区间同时从小到大去枚举wa和wc即可。

最后将异或映射到权值,注意从权值小的异或开始枚举。

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
int n, m;
int a[20];
struct node {
    ll w;
    int x;
} b[2020];

bool cmp(node aa, node bb) {
    return aa.w < bb.w;
}

ll ans;
int sum;
int fl[20][2020], fr[20][2020];
ll val[2020];


void dfs(int pos, int xor1, int xor2) {

    if (pos == n) {

        ll ml = -1, mr = -1;
        for (int i = 0; i < (1 << m); i++) {

            int x = b[i].x;
            if (fl[n][x] == 1 && val[x] >= val[xor1 ^ x]) {
                ml = max(ml, val[xor1 ^ x]);
                if (mr != -1) ans = min(ans, val[x] - min(val[xor1 ^ x], mr));
            }

            if (fr[n][x] == 1 && val[x] >= val[xor2 ^ x]) {
                mr = max(mr, val[xor2 ^ x]);
                if (ml != -1) ans = min(ans, val[x] - min(val[xor2 ^ x], ml));
            }
        }

        return;
    }

    int v = a[pos + 1];
    for (int i = 0; i < (1 << m); i++) {
        fl[pos + 1][i] = fl[pos][i] | fl[pos][i ^ v];
        fr[pos + 1][i] = fr[pos][i];
    }
    dfs(pos + 1, xor1 ^ a[pos + 1], xor2);

    for (int i = 0; i < (1 << m); i++) {
        fl[pos + 1][i] = fl[pos][i];

        fr[pos + 1][i] = fr[pos][i] | fr[pos][i ^ v];
    }

    dfs(pos + 1, xor1, xor2 ^ v);

}

void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)cin >> a[i];
    for (int i = 0, x; i < (1 << m); i++) {
        cin >> x;
        val[i] = x;
        b[i].w = x;
        b[i].x = i;
    }
    sort(b, b + (1 << m), cmp);

    ans = 1e14;
    for (int i = 0; i < (1 << m); i++)fl[1][i] = fr[1][i] = 0;
    fl[1][0] = fr[1][0] = 1;//
    fl[1][a[1]] = 1;
    dfs(1, a[1], 0);

    cout << ans << '\n';

}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int _ = 1;
    cin >> _;
    while (_--) solve();
    return 0;
}

寻找宝藏

你得到了一张藏宝图,这上面标记了埋藏在地底下的 n 个海盗藏宝箱,编号依次为 1 到 n,第 i 个宝箱的坐标是 (i,pi),打开它你将得到 vi 枚金币。

你现在位于 (0,0),每次你可以选择从 (x,y) 移动到 (x+1,y) 或者 (x,y+1),当你位于某个宝箱正上方时,你将可以挖出它并拿走里面的所有金币。

不幸的是,有一个危险的陷阱区域没有被标记出来!通过多方调研,你得知这是一个边平行坐标轴的矩形区域,它是 m 种可能的位置分布之一。请对于每种可能的情况分别计算按照最优路线你能拿走多少金币。

假设陷阱区域的位置分布是第 i 种可能,假设它是以 (x1,y1) 和 (x2,y2) 为对顶点的矩形,那么 (x,y) 是陷阱当且仅当 x1≤x≤x2 且 y1≤y≤y2。你的路线不能途径任何陷阱点。当然,你只需要考虑当前的第 i 个矩形,不需要考虑其它 m−1 个矩形。

扫描线+树状数组

f i 表示 (0 , 0) ( i, p i ) 的最大收益,则 f i = v i + max j<i,p j <p i { f j } ,可以通过扫描线 +
树状数组在 O ( n log n ) 时间内求出。同理可以求出 g i 表示 ( i, p i ) ( n + 1 , n + 1) 的最大收益,
再令 h i 表示经过 ( i, p i ) 的最大收益,有 h i = f i + g i v i
直接经过左下区域或者右上区域的,比较它们的hx即可。

不经过左下或者右上区域任何一个点的,去枚举他们经过L1区域的最后一个点和经过R1区域的第一个点的情况。(这里就画了不经过右上区域的情况)

如果对于每一个禁区都去扫这六个区域肯定要超时,考虑从区域角度去从小往大扫,将每一个询问的禁区边界作为上界,用树状数组即可得到在该边界内区域贡献的最大值。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int long long
const int N = 1e6 + 10;

int a[N], w[N];
int f[N], g[N], h[N];
int n, m;
int d1[N];
int ans[N];

int lowbit(int x) {

    return x & (-x);
}

void add(int x, int w) {

    while (x <= n) {
        d1[x] = max(d1[x], w);
        x += lowbit(x);
    }
}

int query(int x) {
    int ans = 0;
    while (x) {
        ans = max(d1[x], ans);
        x -= lowbit(x);
    }
    return ans;
}

vector<int> xu[N], xd[N];
int yu[N], yd[N];

int fa[N], fb[N], ga[N], gb[N];

void solve() {
    cin >> n >> m;
    for (int i = 1, x, v; i <= n; i++) {
        cin >> x >> v;
        a[i] = x, w[i] = v;
        xu[i].clear();
        xd[i].clear();
    }

    for (int i = 1; i <= m; i++) {

        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;

        xu[x1].push_back(i);
        xd[x2].push_back(i);

        yu[i] = y2;
        yd[i] = y1;
    }

    for (int i = 1; i <= n; i++) d1[i] = 0;
    for (int i = 1; i <= n; i++) {
        for (auto idx: xu[i]) {
            fa[idx] = query(yu[idx]);
        }
        f[i] = query(a[i]) + w[i];
        add(a[i], f[i]);
        for (auto idx: xd[i]) {
            fb[idx] = query(yd[idx] - 1);
        }
    }

    for (int i = 1; i <= n; i++) d1[i] = 0;
    for (int i = n; i >= 1; i--) {
        for (auto idx: xd[i]) {
            fb[idx] += query(n - yd[idx] + 1);
        }
        g[i] = query(n - a[i] + 1) + w[i];
        add(n - a[i] + 1, g[i]);
        h[i] = f[i] + g[i] - w[i];
        for (auto idx: xu[i]) {
            fa[idx] += query(n - yu[idx]);
        }
    }
    for (int i = 1; i <= m; i++) {
        ans[i] = max(fa[i], fb[i]);
    }


    for (int i = 1; i <= n; i++) d1[i] = 0;
    for (int i = 1; i <= n; i++) {
        for (auto idx: xu[i]) {
            ans[idx] = max(ans[idx], query(n - yu[idx]));
        }
        add(n - a[i] + 1, h[i]);
    }

    for (int i = 1; i <= n; i++) d1[i] = 0;
    for (int i = n; i >= 1; i--) {
        for (auto idx: xd[i]) {
            ans[idx] = max(ans[idx], query(yd[idx] - 1));
        }
        add(a[i], h[i]);
    }
    
    for (int i = 1; i <= m; i++) {
        cout << ans[i] << '\n';
    }


}

signed main() {

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--)solve();


    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧社区的秘密武器:数据可视化的力量

在现代城市的发展中&#xff0c;智慧社区已成为提升居民生活品质和管理效率的重要方式。而数据可视化作为信息技术的关键工具&#xff0c;正是实现智慧社区目标的强大助推器。通过将复杂的数据转化为直观的图表和可视化图像&#xff0c;数据可视化不仅能够帮助社区管理者快速理…

前端工具专有名词记录

目录 前言 正文 1.包管理器 2.构建工具和开发环境&#xff08;项目管理器&#xff09; 3.自动化测试工具 4.JavaScript 框架和模版 5.代码质量工具 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Security and so…

全新小体积RK3562核心板,解锁神秘技能!

RK3562小体积金手指系列核心板基于瑞芯微四核Cortex-A53Cortex-M0处理器设计&#xff0c;工作主频高达2GHz&#xff0c;最高搭载4GB高速LPDDR4、32GB eMMC。该核心板拥有204 Pin脚&#xff0c;尺寸仅为67.6mm *45mm&#xff0c;支持千兆网、USB3.0、串口、PCIE、HDMI等丰富外设…

vite tsx项目的element plus集成 - 按需引入踩坑

前面我们进行了开源组件的自研&#xff0c;很多组件可直接用现成的开源组件库&#xff0c;并不需要自己重复造轮子&#xff0c;为此我们讲如何在当前vite vitepress tsx技术整合的项目中实现element plus组件的按需引入&#xff0c;同时解决遇到的一些坑。 安装Element Plus…

《史上最简单的SpringAI+Llama3.x教程》-03-ETL pipeline解决RAG文件处理问题

在企业内部构建基于大型语言模型&#xff08;LLM&#xff09;的应用程序时&#xff0c;数据的提取、转换和加载&#xff08;ETL&#xff09;过程至关重要。Spring AI 提供了一个集成的框架&#xff0c;可以简化这一过程&#xff0c;特别是在使用 LLM 进行检索增强生成&#xff…

Postman 接口测试工具简易使用指南

一、Postman是什么? 我通过kimi问了这样一个问题&#xff0c;它给我的回答是这样的: 它的回答也算比较中规中矩&#xff0c;简单的说postman实际上就是一款接口测试工具&#xff0c;同时它还可以编写对应的测试脚本以及自动生成对应的API文档&#xff0c;结合我的习惯来说&am…

Springboot处理跨域请求

文章目录 概要同源策略跨域问题复现解决跨域方法1方法2方法3 jwt拦截器验证token防止请求存在缓存 概要 跨域请求&#xff08;Cross-Origin Requests&#xff09;指的是在一个网页中加载的资源来自与当前网页不同的域、协议或端口。浏览器出于安全考虑&#xff0c;默认会限制这…

Mybatis超级方便操作数据方式(注解+封装mapper接口)!!!

Mybatis作为一个流行的持久层框架&#xff0c;其优化了Java程序与数据库的交互过程。它的核心在于使用Mapper接口与XML映射文件或注解绑定来实现对数据库的操作。这种方式不仅简化了数据库操作&#xff0c;还提升了开发效率&#xff0c;使得开发者可以从繁琐的JDBC代码中解放出…

索引排序以及explain

标题 explain函数typekeyextrarows 索引排序 前言&#xff0c;如无特殊提醒&#xff0c;默认建立如下索引。 explain函数 type type列反映了访问类型。表示mysql如何找到数据。访问类型有很多种&#xff0c;从全表扫描到索引扫描、范围扫描、唯一索引查询、常数引用等。这里列…

Oracle <left> join on where 先过滤还是先join

一、left join onon条件是在生成临时表时使用的条件&#xff0c;它不管on中的条件是否为真&#xff0c;都会返回左边表中的记录。 二、left join on and&#xff08;1&#xff09;如果and语句是对左表进行过滤的&#xff0c;那么不管真假都不起任何作用。&#xff08;2&#x…

视频剪辑免费素材哪里能找到?

在创作视频时&#xff0c;素材的选择至关重要。为了让您的项目更具吸引力和专业性&#xff0c;我整理了8个剪辑必备素材网站&#xff0c;它们提供了丰富多样的资源&#xff0c;从高清视频到优质音乐&#xff0c;应有尽有。让我们一起探索这些资源丰富、质量上乘的平台&#xff…

倍思开放式耳机佩戴舒服吗?南卡、倍思、QCY三款热门产品测评!

​放式蓝牙耳机已然成为年轻族群的新风尚&#xff0c;就连不少中老年朋友也偏爱在公园漫步时佩戴它们。这些耳机在娱乐、学习、健身、办公等多元化场景中展现出强大的实用性。作为一名数码博主和耳机狂热粉&#xff0c;我最近一直收到不少小伙伴的私信&#xff0c;想让我测评一…

reaConverter(图片格式转换工具) Pro v7.819 中文授权版

reaConverter是一款图片文件格式转换工具&#xff0c;它支持480多种不同的文件格式。使用reaConverter可以轻松的转换一批图片文件&#xff0c;也可以对其进行编辑和优化。 软件功能&#xff1a; 1. 图片文件格式转换&#xff1a;支持将JPEG、PNG、GIF、TIFF、BMP等格式的图片…

java多线程, 该如何处理异常?

目录 如何处理线程运行时异常 UncaughtExceptionHandler 没有注入 未捕捉异常处理器, 线程是如何处理异常的? 看的时候, 希望自己能在idea中跟着ctrl 鼠标左键, 点一遍. . . 如何处理线程运行时异常 先来了解一下java的异常: 在Java中&#xff0c;异常&#xff08;Excep…

fastjson-流程分析

参考视频&#xff1a;fasfjson反序列化漏洞1-流程分析 分析版本 fastjson1.2.24 JDK 8u65 分析过程 新建Person类 public class Person {private String name;private int age;public Person() {System.out.println("constructor_0");}public Person(String na…

API调度

API调度 什么是API什么是HTTP请求如何使用影刀API流程创建密钥获取token启动应用 如何通过代码调用影刀API下载requests库准备工作搭建框架获取token&#xff08;鉴权&#xff09;转换请求为json调用函数按照键名进行提取 获取应用查询状态结束流程 什么是API 什么是HTTP请求 如…

[极客大挑战 2019]Http1

打开题目 鼠标右键查看源码看看有外部链接 点击氛围&#xff0c;弹出新页面 修改请求头 得到flag 说只读&#xff0c;然后改

Java 反射(reflex)

反射理解 反射解析 Java 的反射机制是指在运行状态中。对于任意一个类&#xff0c;都能知道这个类的属性和方法&#xff1b; 对于任意一个对象&#xff0c;都能够调用它的任意一个方法&#xff1b; 这种动态获取信息以及动态调用对象方法的功能称为 java 的反射机制。 正射…

Python .whl 独立安装和全部依赖安装命令

以安装 Flask 为例&#xff1a; 1. 独立安装 pip install whl_files/Flask-1.1.2-py2.py3-none-any.whl 2. 安装 Flask 全部依赖包和自己 cd /path/to/flask/1.0 pip install --no-index --find-links/path/to/downloaded/files Flask1.1.2 cd /path/to/flask/2.0 pip install …

55533

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年6月20日 最后&#xff1a; 十分感谢你可以耐着性子把它读完和我可以坚持写到这里&#xff0c;送几句话&#xff0c;对你&#xff0c;也对我&#xff1a; 1.一个冷知识&#xff1a; …