首页 > 其他分享 >[ARC176E] Max Vector 题解

[ARC176E] Max Vector 题解

时间:2024-07-22 15:44:41浏览次数:10  
标签:ch idx int 题解 void le Vector Max define

题目链接

点击打开链接

题目解法

这个题的一个转化很关键:
把一次操作 \(j\) 等价看作 必须满足 \((\forall_{1\le i\le n}X_i\ge a_{j,i})|(\forall_{1\le i\le n}Y_i\ge a_{j,i})=1\)
正确性是显然的

另外的一个关键思路是网络流
有了上面的转化,我们考虑切糕模型(其实接下来都好想了)
对于 \(X\) 序列,我们从 \(1\) 到 \(V\) 连链
对于 \(Y\) 序列,我们从 \(V\) 到 \(1\) 连链
最初序列的限制是好满足的
考虑一次操作如何连边:我们建虚点,然后 \(Y\) 序列的表示 \(<a_{j,i}\) 的向虚点连边,虚点向 \(X\) 序列的表示 \(<a_{j,i}\) 的虚点连边

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int inf=1e9;
namespace Dinic{
    const int NN=12000,MM=100000;
    int S,T;
    int e[MM],f[MM],ne[MM],h[NN],idx;
    int d[NN],cur[NN];
    queue<int> Q;
    void clr(){ ms(h,-1);idx=0;}
    void add(int x,int y,int z){ e[idx]=y,f[idx]=z,ne[idx]=h[x],h[x]=idx++;}
    void add_edge(int x,int y,int z){ add(x,y,z),add(y,x,0);}
    bool bfs(){
        while(!Q.empty()) Q.pop();
        ms(d,-1);
        d[S]=0,cur[S]=h[S],Q.push(S);
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            if(u==T) return 1;
            for(int i=h[u];~i;i=ne[i]){
                int v=e[i];
                if(f[i]&&d[v]==-1) d[v]=d[u]+1,cur[v]=h[v],Q.push(v);
            }
        }
        return 0;
    }
    int find(int u,int lmt){
        if(u==T) return lmt;
        int res=0;
        for(int i=cur[u];~i&&res<lmt;i=ne[i]){
            cur[u]=i;
            int v=e[i];
            if(d[u]+1==d[v]&&f[i]){
                int t=find(v,min(f[i],lmt-res));
                if(!t) d[v]=-1;
                res+=t,f[i]-=t,f[i^1]+=t;
            }
        }
        return res;
    }
    int dinic(){
        int res=0,add;
        while(bfs()) while(add=find(S,inf)) res+=add;
        return res;
    }
}
const int N=15,M=510;
int n,m,x[N],y[N],a[M][N];
int ind(int x,int y){ return (x-1)*501+y;}
int main(){
    read(n),read(m);
    F(i,1,n) read(x[i]);
    F(i,1,n) read(y[i]);
    F(i,1,m) F(j,1,n) read(a[i][j]);
    Dinic::S=n*2*501+m+5,Dinic::T=Dinic::S+1;
    Dinic::clr();
    F(i,1,n){
        Dinic::add_edge(Dinic::S,ind(i,1),inf);
        F(j,1,500) Dinic::add_edge(ind(i,j),ind(i,j+1),j);
        F(j,1,500) Dinic::add_edge(ind(i,j+1),ind(i,j),inf);
        Dinic::add_edge(ind(i,501),Dinic::T,inf);
    }
    F(i,n+1,2*n){
        Dinic::add_edge(Dinic::S,ind(i,501),inf);
        F(j,1,500) Dinic::add_edge(ind(i,j+1),ind(i,j),j);
        F(j,1,500) Dinic::add_edge(ind(i,j),ind(i,j+1),inf);
        Dinic::add_edge(ind(i,1),Dinic::T,inf);
    }
    F(i,1,n) Dinic::add_edge(Dinic::S,ind(i,x[i]),inf);
    F(i,1,n) Dinic::add_edge(ind(i+n,y[i]),Dinic::T,inf);
    F(i,1,m){
        int nw=n*2*501+i;
        F(j,1,n){
            Dinic::add_edge(ind(j+n,a[i][j]),nw,inf);
            Dinic::add_edge(nw,ind(j,a[i][j]),inf);
        }
    }
    printf("%d\n",Dinic::dinic());
    return 0;
}

标签:ch,idx,int,题解,void,le,Vector,Max,define
From: https://www.cnblogs.com/Farmer-djx/p/18316121

相关文章

  • 题解 B3694 数列离散化
    link简而言之,离散化就是把一个数列转化为由小到大的排名来缩小范围。离散化需要这个题不用数字本身。举个例子:-200244879914993235793离散化后就是:15243\(-2002\)最小,所以它对应\(1\)\(448799\)最大,所以它对应\(5\)实现考虑如何实现。首先由于离散化前后......
  • 【Web】ImaginaryCTF 2024 部分题解
    目录journalcrystalsP2CreadmeTheAmazingRacejournal简单的assert命令拼接payload:?file=test','..')===true||system("echo`tac/flag-cARdaInFg6dD10uWQQgm.txt`")||strpos('testcrystalsdocker-compose.yml里让服务报错读到泄露的hos......
  • 题解:牛客周赛 Round 52 A
    A两数之和时间限制:C/C++1秒,其他语言2秒空间限制:C/C++262144K,其他语言524288KSpecialJudge,64bitIOFormat:%lld题目描述对于给定的正整数\(z\),你需要寻找两个不同的正整数\(x\)和\(y\),使得\(x+y=z\)成立。如果不存在这样的\(x\)和\(y\),你只需要输出NO。......
  • ABC363 DEF 题解
    ABC363DEF题解前情提要:赛时过了ABCE。D-PalindromicNumber题目链接其实赛时已经看出了一些性质,但没想完做法,赛后看题解才发现这么简单/fn首先,为了方便,我们不把\(0\)视作回文数(因此需要特判一下\(n=1\)的情况)。下面要证明:\(d\)位回文数有\(10^{\left\lfloor\f......
  • 题解 P1115 最大子段和
    link容易想到朴素做法:for(intl=1;i<=n;++i){for(intr=1;j<=n;++j){intv=s[r]-s[l-1];ans=max(ans,v);}}但是显然\(\mathrm{\color{#052242}TLE}\)再回头看代码:想要v最大,只需要\(\large{S_{l-1}}\)最小即可......
  • Python学习计划——2.3常用内置函数(len, max, min, sum, etc.)
    Python提供了许多内置函数,用于简化对数据结构的操作。以下是一些常用的内置函数及其详细说明。1.len()len()函数用于返回对象(如列表、元组、字符串、字典等)的长度(元素个数)。示例:#列表fruits=["apple","banana","cherry"]print(len(fruits))#输出:3#元组c......
  • 题解:P7482 不条理狂诗曲
    题解:P7482不条理狂诗曲本题解借鉴blossom_j大佬思路,但这位大佬的题解似乎没放正确代码。题意对于每一个\(a\)的子区间\(a_{l\dotsr}\),求选择若干个不连续的数的和的最大值,对答案取模\(10^{9}+7\)。思路主要算法:分治。计算跨过中点\(mid\)的区间的\(f\)之和。首......
  • P3128 [USACO15DEC] Max Flow P
    链接https://www.luogu.com.cn/problem/P3128题目分析LCA+树上差分。思路就是先定义1为根节点,然后进行dfs1的预处理,配置好LCA的环境。然后条件思路就是端点++,lca--,lca的父亲(fa[lca][0])--。最后再做树上前缀和。就是从根节点开始跑dfs,每个节点的值等于所有子树的值的和。进......
  • P3041 [USACO12JAN] Video Game G 题解 AC自动机
    本题是一道AC自动机上的dp。首先不难想到状态定义f(i,j)表示仅考虑前i 个位置,第i 个字符是j 的分数,但无法转移,所以考虑将j这一维转化为表示AC自动机上的点。再定义val(i)表示以i 结尾的所有技能种数,则转移方程为f(i,j)=max(f(i,j),f(i-1,father(j)+val(j......
  • Loj P10064 黑暗城堡 题解 最短路径树记数
    这道题是一道最短路径树问题。首先,什么是最短路径树呢?定义一个图的最短路径树表示一个图上的生成树,且根节点到图上任一点的距离等于原图上两者之间的距离。而不难发现,题目其实是在求图上最短路径树记数。首先,建出最短路径树。枚举每条边,判断边两个端点到根的距离之差是否为......