博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LibreOJ NOI Round #2 Day 1
阅读量:4954 次
发布时间:2019-06-12

本文共 3279 字,大约阅读时间需要 10 分钟。

T1:

别被定义弄晕了

反着做,A->1/A+B

取倒数没法做,所以变成a/b,维护2*2的矩阵

区间?不用线段树,不用倍增

存在逆矩阵,直接前缀积

注意左乘右乘方向

 

 

 

 

T2

模拟费用流

 

经典老鼠和洞的问题

序列:从左往右扫,

到了老鼠i,wi加入堆,

到了洞j,找权值最大的未匹配老鼠或者已经匹配的洞k,如果valk+vj>0,更新ans,pop,然后把-vj加入堆

外向树:可并堆进行上述操作

 

而本题带修

(52)60pts做法:

相当于模拟动态加边费用流,

建图方式就是树上直接建,S到miner,gold到T

加入一个miner,会和匹配的miner、未匹配的gold产生匹配

疯狂DFS走有流量的边到这些点,选择最大的

加入gold,和未匹配的miner、匹配的gold产生匹配

这里DFS,如果反向边有流量才走,因为实际在反向增广

如果有匹配并且贡献>0,暴力把整个路径流量改变

匹配和未匹配的miner和gold用2个堆维护

 

由于可能加入的费用过大,会造成正环

一般机械费用流要消正环

但是其实无所谓,正环只会产生在miner-S-miner之间,以及gold-T-gold之间

和我们的人工方法一致

#include
#define reg register int#define il inline#define fi first#define se second#define mk(a,b) make_pair(a,b)#define numb (ch^'0')#define pb push_back#define solid const auto &#define enter cout<
using namespace std;typedef long long ll;template
il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}template
il void output(T x){
if(x/10)output(x/10);putchar(x%10+'0');}template
il void ot(T x){
if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}template
il void prt(T a[],int st,int nd){ for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}namespace Modulo{const int mod=998244353;il int ad(int x,int y){ return x+y>=mod?x+y-mod:x+y;}il int sub(int x,int y){ return ad(x,mod-y);}il int mul(int x,int y){ return (ll)x*y%mod;}il void inc(int &x,int y){x=ad(x,y);}il void inc2(int &x,int y){x=mul(x,y);}il int qm(int x,int y=mod-2){ int ret=1;while(y){ if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}template
il int ad(const int a,const int b,const Args &...args) { return ad(ad(a,b),args...);}template
il int mul(const int a,const int b,const Args &...args) { return mul(mul(a,b),args...);}}//using namespace Modulo;namespace Miracle{const int N=100000+5;const int inf=0x3f3f3f3f;int n,m;ll ans;priority_queue
q[N][2];//0: matched miner ; no match gold//1: matched gold ; no match minerstruct node{ int nxt,to; int w,c;}e[2*N];int du[N];int hd[N],cnt=1;void add(int x,int y,int w,int c){ e[++cnt].nxt=hd[x]; e[cnt].to=y;e[cnt].w=w;e[cnt].c=c; hd[x]=cnt; e[++cnt].nxt=hd[y]; e[cnt].to=x;e[cnt].w=0;e[cnt].c=-c; hd[y]=cnt;}int pre[N]; ll mx;int id;void dfs(int x,int fa,ll d,int tp){ if(!q[x][tp].empty()){ if(q[x][tp].top()+d>mx){ mx=q[x][tp].top()+d; id=x; } } for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==fa) continue; if(tp==0){ if(e[i].w) pre[y]=i,dfs(y,x,d+e[i].c,tp); }else{ if(e[i^1].w) pre[y]=i,dfs(y,x,d+e[i^1].c,tp); } }}void wrk(int x,int v,int tp){ mx=1ll*-0x3f3f3f3f3f3f3f3f,id=0; dfs(x,0,0,tp); if(mx+v>0){ ans+=mx+v; ll val=q[id][tp].top(); q[id][tp].pop(); q[id][tp^1].push(-val); q[x][tp].push(-v); if(tp==0){ while(id!=x){ e[pre[id]].w--; e[pre[id]^1].w++; id=e[pre[id]^1].to; } }else{ while(id!=x){ e[pre[id]].w++; e[pre[id]^1].w--; id=e[pre[id]^1].to; } } }else{ q[x][tp^1].push(v); }}int main(){ rd(n);rd(m); int x,y,z; for(reg i=1;i
View Code

 

100pts:

miner往上跳到最高点,子树最大值就是答案

gold就是到根的链的所有轻儿子连通块内的最大值

树剖维护一下,找连通块,线段树pushup时候考虑中间边有没有,就好了

在写了在写了

 

T3:

好题

https://loj.ac/article/1779

没有大于号限制是好算的.

容斥的话,枚举i最后连续的不满足的大于号

分治NTT

dp0=1.题解打错了

转载于:https://www.cnblogs.com/Miracevin/p/11148295.html

你可能感兴趣的文章
wordpress自动截取文章摘要代码
查看>>
[置顶] 一名优秀的程序设计师是如何管理知识的?
查看>>
关于使用“状态模式”做工作流概要。
查看>>
谈谈:程序集加载和反射
查看>>
mysql主从复制(超简单)
查看>>
scanf和gets
查看>>
highcharts 图表实例
查看>>
定时器使用
查看>>
LeetCode Median of Two Sorted Arrays
查看>>
【知识强化】第二章 线性表 2.2 线性表的顺序表示
查看>>
19.30内置登录处理
查看>>
00_前情回顾
查看>>
fortran90简明教程
查看>>
flex知识点归纳
查看>>
hdu 5442 Favorite Donut 最大表示法+KMP
查看>>
ubuntu下如何查看用户登录及系统授权相关信息
查看>>
丶制作一个数字猜猜看小游戏
查看>>
秋季学期学习总结
查看>>
SpringBoot 优化内嵌的Tomcat
查看>>
Dagger2 入门解析
查看>>