首页 > 其他分享 >2023冲刺国赛模拟 28.1

2023冲刺国赛模拟 28.1

时间:2023-07-01 21:14:26浏览次数:46  
标签:val int 2023 flow long edge 国赛 2kC 28.1

T3 函数

首先存在结论 \(f(a+2C)=f(a)+2C\) 。

简单证明,设 \(b=2f(a)-a+1\) ,那么 \(f(b)=f(a)+C\) ,设 \(d=2f(b)-b+1\) ,那么 \(f(d)=f(a)+2C\) ,同时:

\[\begin{aligned} d&=2f(b)-b+1\\ &=2f(a)+2C-2f(a)+a-1+1\\ &=a+2C \end{aligned} \]

根据结论可以知道,我们可以将函数 \(f(x)\) 按照 \(x\operatorname{mod} 2C\) 分组,每组可以表示为 \(a+2kC\) 的形式。

设 \(b=2f(a)-a+1\) ,那么 \(a+b=2f(a)+1\) ,考虑将 \(a, b\) 的范围限制在 \([0,2C)\) 中,设 \(a=a'+2kC, b=b'+2tC\) ,那么有 \(a'+b'+2kC+2tC=2f(a'+2kC)+1=f(a')+4kC+1\) ,那么 \(a'+b'=f(a')+2kC-2tC+1\) ,由于 \(b\) 由 \(f(a)\) 决定,因此 \(t\) 的取值任意,简化一下有: \(a'+b'=f(a')-2nC+1\) 。

容易发现 \(a', b'\) 奇偶性不同,不妨设 \(a'=2X, b'=2Y+1\) ,那么有:

\[\begin{aligned} a'+b'&=2f(a')+1-2nC\\ 2X+2Y+1&=2f(a')+1-2nC\\ 2f(a')&=2X+2Y+2nC\\ f(a')&=X+Y+nC \end{aligned} \]

\[\begin{aligned} f(b')&=f(a'+2kC)+C-2tC\\ f(b')&=f(a')+C-2nC\\ f(b')&=X+Y-(n-1)C \end{aligned} \]

对于 \(a'\) ,如果确定了 \(f(a')\) ,那么就唯一确定其对应的 \(b'\) 以及 \(f(b')\) ,不难发现这构成了两两配对的关系,因此考虑一对配对的 \(a', b'\) 所造成的贡献。

考虑一组点 \((x_i, y_i)\) ,如果 \(x_i\) 属于 \(a'\) 组内,设 \(x_i=2kC+a'\) ,那么:

\[\begin{aligned} |f(x_i)-y_i|&=|f(a'+2kC)-y_i|\\ &=|f(a')+2kC-y_i|\\ &=|X+Y+nC+2kC-y_i| \end{aligned} \]

设 \(W_i=X+Y+2kC-y_i\) ,那么 \(|f(x_i)-y_i|=|W_i+nC|\) 。

如果 \(x_i\) 属于 \(b'\) 组内,设 \(x_i=2kC+b'\) ,那么:

\[\begin{aligned} |f(x_i)-y_i|&=|f(b'+2kC)-y_i|\\ &=|f(b')+2kC-y_i|\\ &=|X+Y-(n-1)C+2kC-y_i|\\ &=|y_i-X-Y-2kC-C+nC| \end{aligned} \]

设 \(W_i=y_i-X-Y-2kC-C\) ,那么 \(|f(x_i)-y_i|=|W_i+nC|\) 。

直接二分图最大权匹配即可。

code
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
#include <queue>
#include <cassert>
using namespace std;

const int max1 = 600;
const int inf = 0x3f3f3f3f;
int n, C;
vector < pair <int, int> > bin[max1 + 5];

struct Graph_Net
{
    struct Node
    {
        int next, v, flow;
        long long cost;
    }edge[max1 * max1 + 5];
    int head[max1 + 5], total;
    int s, t;

    int maxflow;
    long long mincost;

    long long dis[max1 + 5], h[max1 + 5];
    int flow[max1 + 5], pre_point[max1 + 5], pre_edge[max1 + 5];
    bool vis[max1 + 5];

    struct Point
    {
        int x; long long d;

        Point () {}
        Point ( int __x, long long __d )
            { x = __x, d = __d; }
        
        bool operator < ( const Point &A ) const
            { return d > A.d; }
    };

    priority_queue <Point> que;

    void Clear ()
    {
        memset(head, 0, sizeof(int) * (C + C + 2));
        total = 1;
        return;
    }

    void Add ( int u, int v, int f, long long c )
    {
        edge[++total].v = v;
        edge[total].flow = f;
        edge[total].cost = c;
        edge[total].next = head[u];
        head[u] = total;
        return;
    }

    void Add_Edge ( int u, int v, int f, long long c )
    {
        return Add(u, v, f, c), Add(v, u, 0, -c);
    }

    bool Dijikstra ()
    {
        while ( !que.empty() )
            que.pop();
        
        memset(dis, 0x3f, sizeof(long long) * (C + C + 2));
        memset(vis, 0, sizeof(bool) * (C + C + 2));
        dis[s] = 0; flow[s] = inf; pre_point[s] = pre_edge[s] = -1;
        que.push(Point(s, 0));

        while ( !que.empty() )
        {
            int x = que.top().x; que.pop();
            if ( vis[x] )
                continue;
            
            vis[x] = true;
            for ( int i = head[x]; i; i = edge[i].next )
            {
                int v = edge[i].v, f = edge[i].flow;
                long long c = edge[i].cost + h[x] - h[v];

                if ( f && dis[v] > dis[x] + c )
                {
                    assert(c >= 0);
                    dis[v] = dis[x] + c;
                    flow[v] = min(flow[x], f);
                    pre_point[v] = x;
                    pre_edge[v] = i;
                    que.push(Point(v, dis[v]));
                }
            }
        }
        return vis[t];
    }

    void Update ()
    {
        for ( int i = 0; i < C + C + 2; i ++ )
            h[i] += dis[i];
        maxflow += flow[t];
        mincost += h[t] * flow[t];

        int x = t;
        while ( x != s )
        {
            edge[pre_edge[x]].flow -= flow[t];
            edge[pre_edge[x] ^ 1].flow += flow[t];
            x = pre_point[x];
        }
        return;
    }

    void EK ()
    {
        memset(h, 0, sizeof(long long) * (C + C + 2));

        maxflow = mincost = 0;

        while ( Dijikstra() )
            Update();
        return;
    }
}Graph;

long long Calc ( const vector <int> &val, int p )
{
    long long sum = 0;
    for ( auto v : val )
        sum += abs(p - v);
    return sum;
}

long long Connect ( int u, int v, int X, int Y )
{
    vector <int> val; val.clear();
    for ( auto x : bin[u] )
        val.push_back(-x.second + X + Y + x.first * C * 2);
    for ( auto x : bin[v] )
        val.push_back(x.second - X - Y - x.first * C * 2 - C);
    
    if ( val.empty() )
        return 0LL;

    sort(val.begin(), val.end());

    int mid = val.size() >> 1;
    mid = val[mid] / C;

    return min({ Calc(val, (mid - 1) * C), Calc(val, mid * C), Calc(val, (mid + 1) * C) });
}

int main ()
{
    freopen("function.in", "r", stdin);
    freopen("function.out", "w", stdout);

    scanf("%d%d", &n, &C);
    for ( int i = 1, x, y; i <= n; i ++ )
    {
        scanf("%d%d", &x, &y);
        bin[x % (C + C)].push_back(make_pair(x / (C + C), y));
    }

    Graph.Clear();
    for ( int i = 0; i < C; i ++ )
        for ( int j = 0; j < C; j ++ )
            Graph.Add_Edge(i + i, j + j + 1, 1, Connect(i + i, j + j + 1, i, j));
    
    Graph.s = C + C;
    Graph.t = C + C + 1;

    for ( int i = 0; i < C; i ++ )
        Graph.Add_Edge(Graph.s, i + i, 1, 0);
    for ( int i = 0; i < C; i ++ )
        Graph.Add_Edge(i + i + 1, Graph.t, 1, 0);
    
    Graph.EK();

    printf("%lld\n", Graph.mincost);

    return 0;
}

标签:val,int,2023,flow,long,edge,国赛,2kC,28.1
From: https://www.cnblogs.com/KafuuChinocpp/p/17519910.html

相关文章

  • 2023-07-01:redis过期策略都有哪些?LRU 算法知道吗?
    2023-07-01:redis过期策略都有哪些?LRU算法知道吗?答案2023-07-01:缓存淘汰算法(过期策略)当Redis的内存超出物理内存限制时,内存中的数据就会频繁地与磁盘进行交换,这个过程叫做交换(swap)。由于交换的高开销,Redis的性能会急剧下降。对于访问频率较高的Redis实例来说,这样低效的存取效率......
  • 2023-07-01:redis过期策略都有哪些?LRU 算法知道吗?
    2023-07-01:redis过期策略都有哪些?LRU算法知道吗?答案2023-07-01:缓存淘汰算法(过期策略)当Redis的内存超出物理内存限制时,内存中的数据就会频繁地与磁盘进行交换,这个过程叫做交换(swap)。由于交换的高开销,Redis的性能会急剧下降。对于访问频率较高的Redis实例来说,这样低效的存取效率几乎......
  • 周报2023/7/1
    周一:1.饭店打工2.下班卸载jdk20改装jdk17;安装eclipse;周二:在b站上找的黑马程序员的java课程开始学习;下午写pta;周三:在b站上继续学习java。下午写pta;周四:在b站上继续学习java。下午写pta;周五:在b站上继续学习java。下午写pta;周六:早上7点到下午5点去练车,又热又累,比打工......
  • HO引擎近况20230701
    6月份忘了来写博客了,原因主要就是我离职了,好多事所以这个彻底忘了离职的原因是公司说现金流断了,没钱了,整个项目组都砍了,别的项目组据说也快了于是这个月就在找工作中,各种原因,真的不好找我感觉可以自己需要再去充充电了,而且需要开拓一下自己以前想做没做的方面,为以后多......
  • 2023年光伏行业发展面临哪些困难和挑战?拆卸组件回收
    (昆山鹏欣硅片硅料回收公司:摘要关键词:硅片回收,硅料回收,电池片回收,组件回收,逆变器回收,多晶硅回收,单晶硅回收,太阳能电池板回收)光伏行业发展取得突破的同时,也面临一些困难和挑战。补贴缺口持续扩大。国家能源局有关负责人介绍,截至2017年底,累计可再生能源发电补贴缺口总计达到1127亿元......
  • 2023年我国硅片总产能有多少?
    (昆山鹏欣硅片硅料回收公司:摘要关键词:硅片回收,硅料回收,电池片回收,组件回收,逆变器回收,多晶硅回收,单晶硅回收,太阳能电池板回收)2018年底,国内硅片总产能174GW,其中单晶硅片约81GW,超过多晶硅片。而今年仅隆基、中环、晶科三家扩产规模就高达80GW!直接让单晶硅片的产能至少翻一番! ......
  • 2023年光伏将回到快速发展轨道
    (昆山鹏欣硅片硅料回收公司:摘要关键词:硅片回收,硅料回收,电池片回收,组件回收,逆变器回收,多晶硅回收,单晶硅回收,太阳能电池板回收)近日,记者从苏州光伏产业协会得到一份苏州光伏产业2012年调研报告,这份材料显示,在过去的一年中,苏州市光伏企业在欧美双反中遭遇巨大冲击,多数企业业绩均出现严......
  • 【题解】#119. 最大整数 题解(2023-07-01更新)
    #119.最大整数题解题目传送门更新日志2023-05-2617:20文章完成2023-05-3015:22文章审核通过2023-07-0116:04修改了代码题目知识点字符串+贪心题意说明设有n个正整数($n<20$),将它们连接成一排,组成一个最大的多位整数。(题目简介明了,一看就是出题人懒得写题目背景)......
  • (2023.7.1)DPAA手册熟悉
    //路径https://www.nxp.com.cn/design/documentation:DOCUMENTATION#/collection=documents&start=0&max=12&language=cn&query=type%3E%3E%E5%BA%94%E7%94%A8%E7%AC%94%E8%AE%B0&sorting=ModifiedDate.desc&keyword=dpaaAN13329:  ......
  • 2023暑假软件工程打卡第一周
    一、学习使用cmd命令窗口1、打开cmd①、按下win+R键,在计算机中会出现运行窗口。 ②、输入cmd,点击回车,进入cmd命令窗口。 2、输入cmd命令①、常见的cmd命令Ⅰ、盘符加冒号。  因为默认为再C盘路径下操作,如果我们输入盘符+冒号后进行回车,我们就可以转换为在此盘符下操......