[AGC029F] Construction of a tree

[AGC030C] Coloring Torus

[AGC030D] Inversion Sum

[AGC030E] Less than 3

[AGC030F] Permutation and Minimum

把所有数(包括已经确定的)从大往小考虑。那么每一个 \(b\) 是什么就是看它对应的那一对什么时候被填完。

如果一对都已经有数了,没有意义,扔掉。

令 \(f_{i,j,k}\) 表示考虑了 \(i\) 到 \(2n\) 的数,填了一个数的对中,有 \(j\) 对是人为填了一个数,有 \(k\) 对是天然填了一个数。后两维是有区别的,因为后面那种是每对固定了位置,前面的没有。

注意到由于前面那种可以每对之间任排,所以就暂不考虑前面那种之间的顺序,答案为 \(f_{1,0,0}\times c!\)。

边界 \(f_{2n+1,0,0}=1\)。

如果是一个人为填进去的数,看看是新开一对,还是与另一个人为填的配,还是与天然填的配。\(f_{i,j,k}=f_{i+1,j-1,k}+f_{i+1,j+1,k}+(k+1)f_{i+1,j,k+1}\)。

如果是一个天然填进去的数,同样,注意不能和另一个天然填的配。\(f_{i,j,k}=f_{i+1,j,k-1}+f_{i+1,j+1,k}\)。

时间复杂度 \(O(n^3)\)。

#include

using namespace std;

typedef long long ll;

typedef pair PII;

const int maxn=333,mod=1000000007;

#define MP make_pair

#define PB push_back

#define lson o<<1,l,mid

#define rson o<<1|1,mid+1,r

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)

#define ROF(i,a,b) for(int i=(a);i>=(b);i--)

#define MEM(x,v) memset(x,v,sizeof(x))

inline ll read(){

char ch=getchar();ll x=0,f=0;

while(ch'9') f|=ch=='-',ch=getchar();

while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();

return f?-x:x;

}

int n,f[maxn*2][maxn][maxn],cnt1,cnt2,ans;

bool vis[maxn*2],ind[maxn*2];

int main(){

n=read();

FOR(i,1,n){

int x=read(),y=read();

if(~x && ~y) vis[x]=vis[y]=true;

else if(~x) ind[x]=true,cnt2++;

else if(~y) ind[y]=true,cnt2++;

else cnt1++;

}

f[2*n+1][0][0]=1;

ROF(i,2*n,1) FOR(j,0,cnt1+cnt2) FOR(k,0,cnt2){

if(vis[i]) f[i][j][k]=f[i+1][j][k];

else if(ind[i]){

if(k) f[i][j][k]=(f[i][j][k]+f[i+1][j][k-1])%mod;

if(j!=cnt1+cnt2) f[i][j][k]=(f[i][j][k]+f[i+1][j+1][k])%mod;

}

else{

if(j) f[i][j][k]=(f[i][j][k]+f[i+1][j-1][k])%mod;

if(j!=cnt1+cnt2) f[i][j][k]=(f[i][j][k]+f[i+1][j+1][k])%mod;

if(k!=cnt2) f[i][j][k]=(f[i][j][k]+1ll*(k+1)*f[i+1][j][k+1])%mod;

}

}

ans=f[1][0][0];

FOR(i,1,cnt1) ans=1ll*ans*i%mod;

printf("%d\n",ans);

}

[AGC031D] A Sequence of Permutations

[AGC031E] Snuke the Phantom Thief

[AGC031F] Walk on Graph

[AGC032C] Three Circuits

[AGC032D] Rotation Sort

[AGC032E] Modulo Pairing

[AGC032F] One Third

[AGC033D] Complexity

[AGC033E] Go around a Circle

[AGC033F] Adding Edges

[AGC034D] Manhattan Max Matching

[AGC034E] Complete Compress

[AGC034F] RNG and XOR

[AGC035C] Skolem XOR Tree

[AGC035D] Add and Remove

留下的卡肯定是第一张和最后一张。

最后答案可以表示成 \(\sum a_ik_i\) 的形式。下称 \(k_i\) 为贡献系数。

考虑把整个过程倒过来,一开始只有第一张和最后一张卡(但是权值不是输入给出的那个),然后每次中间长出一张卡(权值也不是输入给出的),两边的权值减掉中间那个卡的权值。

\(f_{l,r,x,y}\) 表示第 \(l\) 张卡和第 \(r\) 张卡相邻,\(k_l=x,k_r=y\),这时的最小值。

答案即为 \(f_{1,n,1,1}\)。

边界,\(l+1=r\) 时,\(f_{l,r,x,y}=xa_l+ya_r\)。

转移,枚举中间长出的是第 \(i\) 张卡。那么 \(k_i=x+y\)。

方程 \(f_{l,r,x,y}=\min\limits_{l+1\le i\le r-1}(f_{l,i,x,x+y}+f_{i,r,x+y,y}-a_i(x+y))\)。

虽然看起来状态数很多,但是如果我们固定看第三、四维,实际上只有 \(2^n\) 种,要么往左就肯定是 \((x,x+y)\),要么往右就肯定是 \((x+y,y)\)。

此时有时间复杂度 \(O(2^nn^3)\) 带比较小的常数。据说可以继续分析到 \(O(2^nn)\)。

由于我比较菜,弄了一堆组合式子算出来个 \(O(3^nn)\),就不拿出来丢人现眼了。

#include

using namespace std;

typedef long long ll;

typedef pair PII;

typedef pair st;

const int maxn=100010;

#define MP make_pair

#define PB push_back

#define lson o<<1,l,mid

#define rson o<<1|1,mid+1,r

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)

#define ROF(i,a,b) for(int i=(a);i>=(b);i--)

#define MEM(x,v) memset(x,v,sizeof(x))

inline ll read(){

char ch=getchar();ll x=0,f=0;

while(ch'9') f|=ch=='-',ch=getchar();

while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();

return f?-x:x;

}

int n,a[maxn];

vector dp[20][20];

ll DP(int l,int r,int x,int y,int t){

if(l+1==r) return 1ll*a[l]*x+1ll*a[r]*y;

ll &d=dp[l][r][t];

if(d) return d;

ll s=1e18;

FOR(i,l+1,r-1) s=min(s,DP(l,i,x,x+y,t<<1)+DP(i,r,x+y,y,t<<1|1)-1ll*a[i]*(x+y));

return d=s;

}

int main(){

n=read();

FOR(i,1,n) a[i]=read();

FOR(i,1,n) FOR(j,i+1,n) dp[i][j].resize(1<

printf("%lld\n",DP(1,n,1,1,1));

}

[AGC035E] Develop

[AGC035F] Two Histograms

[AGC036D] Negative Cycle

[AGC036E] ABC String

[AGC036F] Square Constraints

[AGC037D] Sorting a Grid

为了方便,给每个数染上它最后应该在的那个行的编号的颜色,共 \(n\) 种颜色。

在第三次重排前,一定有每一行已经有了它该有的那些数。

在第二次重排前,一定有每一列都有每一种颜色恰好一个。

所以第一次重排,就是要让每一列都有每种颜色恰好一个。

确定了第一次重排的方案,第二次重排就很简单了,列内按颜色排序即可。

考虑从左往右一列一列地填第一次重排完后的矩阵。在填一列的时候,就是要让每一行能和每一种颜色一一配对。

那么如果一行中有一种颜色,就把它和这种颜色连边。出现多次就连多条边。

网络流求出这个二分图的完美匹配,就能知道这一列怎么填了。把这些匹配边删掉然后填下一列。

关于每次都能找到完美匹配的正确性证明:

Hall 定理:一个两部点数相同的二分图有完美匹配,当且仅当对于左点集的任意一个子集,出边连向的右边点的并集大小大于等于该点集大小。

必要性显然,下证充分性。

考虑它的最大匹配,若存在一个点 \(u\) 没有匹配上,由前提一定有至少一个与它相连的点。

如果这些点中有没被匹配的,那么它们是可以匹配的,与最大匹配矛盾。

否则,设这连向的点有 \(x\) 个,把这 \(x\) 个点对应的匹配点也拎出来。

考虑这些点和 \(u\) 共 \(x+1\) 个点,由前提一定至少有 \(x+1\) 个与它们相连的点。

由于和 \(u\) 相连的点都已经在相连点集中了(只有 \(x\) 个),所以剩下的那些点一定是与除了 \(u\) 的其它 \(x\) 个点相邻。

如果那些点有没被匹配的,那么存在增广路,矛盾。否则继续连,继续……

最后会全部左点都在里面,就只能矛盾了。

用它来证这题就很简单了:在填第 \(i\) 列的时候,左边右边每个点度数都是 \(m-i+1\),所以对于左边大小为 \(s\) 的点集,与它相连的右边点集度数和至少是 \(s(m-i+1)\),大小也肯定至少是 \(s\)。

时间复杂度 \(O(nm^2\sqrt{n})\)。

#include

using namespace std;

typedef long long ll;

typedef pair PII;

const int maxn=222,maxm=22222;

#define MP make_pair

#define PB push_back

#define lson o<<1,l,mid

#define rson o<<1|1,mid+1,r

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)

#define ROF(i,a,b) for(int i=(a);i>=(b);i--)

#define MEM(x,v) memset(x,v,sizeof(x))

inline ll read(){

char ch=getchar();ll x=0,f=0;

while(ch'9') f|=ch=='-',ch=getchar();

while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();

return f?-x:x;

}

int n,m,a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],tmp[maxn];

int s,t,q[maxn],h,r,dis[maxn],el,head[maxn],cur[maxn],to[maxm],nxt[maxm],w[maxm];

bool use[maxm];

inline void add(int u,int v,int w_){

to[++el]=v;nxt[el]=head[u];head[u]=el;w[el]=w_;

to[++el]=u;nxt[el]=head[v];head[v]=el;w[el]=0;

}

bool bfs(){

MEM(dis,-1);

q[h=r=1]=s;

dis[s]=0;

while(h<=r){

int u=q[h++];

for(int i=head[u];i;i=nxt[i]) if(w[i]){

int v=to[i];

if(dis[v]==-1) dis[v]=dis[u]+1,q[++r]=v;

}

}

return ~dis[t];

}

int dfs(int u,int minres){

if(u==t || !minres) return minres;

int f,rtf=0;

for(int &i=cur[u];i;i=nxt[i]){

int v=to[i];

if(dis[v]==dis[u]+1 && (f=dfs(v,min(minres,w[i])))){

minres-=f;rtf+=f;

w[i]-=f;w[i^1]+=f;

if(!minres) break;

}

}

return rtf;

}

int main(){

n=read();m=read();

FOR(i,1,n) FOR(j,1,m) a[i][j]=read();

s=2*n+1;t=2*n+2;

FOR(i,1,m){

FOR(i,1,2*n+2) head[i]=0;

FOR(i,1,el) to[i]=nxt[i]=w[i]=0;

el=1;

FOR(i,1,n) add(s,i,1),add(i+n,t,1);

FOR(i,1,n) FOR(j,1,m) if(!use[a[i][j]]) add(i,(a[i][j]+m-1)/m+n,1);

int f=0;

while(bfs()){

FOR(i,1,2*n+2) cur[i]=head[i];

f+=dfs(s,1e9);

}

assert(f==n);

FOR(j,1,n) for(int e=head[j];e;e=nxt[e]) if(!w[e]){

int tp=to[e]-n;

FOR(k,1,m) if((a[j][k]+m-1)/m==tp && !use[a[j][k]]){

use[b[j][i]=a[j][k]]=true;break;

}

}

}

FOR(i,1,n){

FOR(j,1,m) printf("%d ",b[i][j]);

puts("");

}

FOR(j,1,m){

FOR(i,1,n) tmp[i]=b[i][j];

sort(tmp+1,tmp+n+1);

FOR(i,1,n) c[i][j]=tmp[i];

}

FOR(i,1,n){

FOR(j,1,m) printf("%d ",c[i][j]);

puts("");

}

}

[AGC037E] Reversing and Concatenating

[AGC037F] Counting of Subarrays

[AGC038E] Gachapon

[AGC038F] Two Permutations

[AGC039D] Incenters

[AGC039E] Pairing Points

以下令 \(n\) 为真正的总点数。

枚举 \(1\) 和哪个点配,设为 \(i\)。

现在是要:在 \([2,i)\) 中选一些点 \(p_1q_2>\dots>q_x\),\(p_i\) 和 \(q_i\) 连线,对于剩下那些没被选到的点,之间连,的合法方案数。

令这个为 \(f_{l,i,r}\),要求即为所有 \(f_{2,i,n}\) 的和。边界 \(l=i=r\) 方案数是 \(1\)。

枚举 \(p_1\) 和 \(q_1\),设为 \(j\) 和 \(k\)。

注意到 \((j,i)\) 中连出去的边中,只可能是 \([l,j)\) 和 \((i,k)\)。且应该存在一个 \(p\) 使得 \(p\) 和之前的都连向 \([l,j)\),\(p+1\) 和之后的都连向 \((i,k)\)。

另一边同理,设分界点为 \(q\)。

注意到 \([l,j)\) 和 \((j,p]\) 连出的线不可能离开这一段,所以这里的方案数是 \(f_{l,j,p}\)。

另一边同理,\(f_{q,k,r}\)。

对于下面的 \([p+1,i)\) 和 \((i,q-1]\) 也是一样,\(f_{p+1,i,q-1}\)。

所以转移方程是 \(f_{l,i,r}+=\sum f_{p+1,i,q-1}f_{l,j,p}f_{q,k,r}[a_{j,k}=1]\)。

转移顺序是按 \(r-l+1\) 从小到大枚举。

时间复杂度 \(O(n^7)\),虽然 \(n\le 40\),由于常数极其优秀已经可以通过。

(看转移条件大概就能看出来了:\(l\le j\le p

但是这个是可以继续优化的。

仍然按 \(r-l+1\) 从小到大枚举。然后里面先枚举 \(p,q\)。

注意到如果枚举了 \(i\),那么 \(f_{l,i,r}+=f_{p+1,i,q-1}\sum f_{l,j,p}f_{q,k,r}[a_{j,k}=1]\),后面和 \(i\) 无关。

设这个为 \(s\)。考虑如何快速计算 \(s\)。

令 \(sum_{l,k,p}=\sum f_{l,j,p}[a_{j,k}=1]\)。那么 \(s=\sum sum_{l,k,p}f_{q,k,r}\)。

在适当的时候更新 \(sum\) 即可。

时间复杂度 \(O(n^5)\),常数依然小的可怕。经过测试如果改成取模,能跑 \(n\le 100\)(这里的 \(n\) 是新的 \(n\))。

#include

using namespace std;

typedef long long ll;

typedef pair PII;

const int maxn=44;

#define MP make_pair

#define lson o<<1,l,mid

#define rson o<<1|1,mid+1,r

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)

#define ROF(i,a,b) for(int i=(a);i>=(b);i--)

#define MEM(x,v) memset(x,v,sizeof(x))

inline int read(){

int x=0,f=0;char ch=getchar();

while(ch'9') f|=ch=='-',ch=getchar();

while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();

return f?-x:x;

}

int n,a[maxn][maxn];

char s[maxn];

ll f[maxn][maxn][maxn],fs[maxn][maxn][maxn],ans;

int main(){

n=read()*2;

FOR(i,1,n){

scanf("%s",s+1);

FOR(j,1,n) a[i][j]=s[j]-'0';

}

if(n==2) return printf("%d\n",a[1][2]),0;

FOR(i,2,n){

f[i][i][i]=1;

FOR(j,2,n) if(a[i][j]) fs[i][j][i]+=f[i][i][i];

}

FOR(len,3,n-1) if(len%2==1) FOR(l,2,n-len+1){

int r=l+len-1;

FOR(i,l,r) FOR(j,2,n) if(a[i][j]) fs[l][j][r]-=f[l][i][r];

FOR(p,l,r) FOR(q,p+1,r){

ll s=0;

FOR(k,q,r) s+=fs[l][k][p]*f[q][k][r];

FOR(i,p+1,q-1) f[l][i][r]+=s*f[p+1][i][q-1];

}

FOR(i,l,r) FOR(j,2,n) if(a[i][j]) fs[l][j][r]+=f[l][i][r];

}

FOR(i,2,n) if(a[1][i]) ans+=f[2][i][n];

printf("%lld\n",ans);

}

[AGC039F] Min Product Sum

[ARC089D] ColoringBalls

[ARC091D] Strange Nim

[ARC092D] Two Faced Edges

[ARC093C] Bichrome Spanning Tree

[ARC093D] Dark Horse

[ARC095D] Permutation Tree

[ARC096C] Everything on It

[ARC096D] Sweet Alchemy

[ARC097D] Monochrome Cat

[ARC098D] Donation

[ARC099D] Eating Symbols Hard

[ARC100D] Colorful Sequences

[ARC101C] Ribbons on Tree

[ARC101D] Robots and Exits

[ARC102D] Revenge of BBuBBBlesort!

[ARC103B] Robot Arms

[ARC103D] Distance Sums

ioi2020集训队作业_IOI2020 集训队作业 Part 3相关推荐

  1. 北师大计算机网络原理和应用作业,北师大网络作业计算机组成原理 作业一(可编辑)...

    <计算机组成原理>作业(一) 学完1-2章后可以完成作业(一).作业总分100分,将作为平时成绩记入课程总成绩. 一.解释下列英文缩写的中文含义(包括英文全称.中文名.功能三部分):(每题 ...

  2. python编程书籍1020python编程书籍_代写INFT 1020作业、Database作业代做、Java课程作业代写、c++,Python编程作业代做...

    代写INFT 1020作业.Database作业代做.Java课程作业代写.c++,Python编程作业代做 日期:2020-04-25 10:27 INFT 1020 Database Fundam ...

  3. 作业调度算法--短作业优先 操作系统_处理器管理_编程题

    操作系统_处理器管理_编程题 作业调度算法–短作业优先 输入N个作业,输入每个的作业名字,到达的时间,服务的时间,根据短作业优先算法,计算出每个作业的完成的时间,周转的时间,带权周转的时间(其中保留2 ...

  4. 对于牛老师作业陈老师作业补充(老陈、小石头的典型用户、用例图、场景)...

    对于牛老师作业陈老师作业补充(老陈,小石头的典型用户.用例图.场景) 一  :  典型用户 (1)名字:小石头 性别:男 年龄:    8岁 职业:学生 收入:无 知识层次能力:小学二年级 生活/工作 ...

  5. 集美大学1414班软件工程个人作业2——个人作业2:APP案例分析

    一.作业链接 个人作业2:APP案例分析 二.博文要求 通过分析你选中的产品,结合阅读<构建之法>,写一篇随笔,包含下述三个环节的所有要求.  第一部分 调研, 评测 下载软件并使用起来, ...

  6. flash作业_一起作业,你很智障!

    电子作业现在貌似很流行,在很多学校都有,具体的利弊就不再赘述,可以点击前面的超链接跳转到某度百科自己看.今天只是忍不住怕盘点下国内知名电子作业平台--一起作业网的一些智障设计...本来想写到这里去的: ...

  7. 现代软件工程 作业 3 团队作业

    这是现代软件工程课的作业列表, 老师可以根据情况选用, 建议要保证每周都有作业. 团队作业 Team Homework: 适合团队完成的作业 这些作业都要团队的成员互相配合才能完成,  团队可以选出一 ...

  8. Java编程作业体会_Java作业的几点总结感想

    本次博客主要是总结近几次作业,交流一下自己的感受. 本次作业主要是对近几次Java课程的巩固作业,第一次作业主要是一些基础的题目,包括选择循环等一些基本语句,其目的在于掌握java一些基本知识,感受出 ...

  9. HTML期末作业-旅游网页作业Html+css+Bootstarp

    HTML期末作业-旅游网页作业Html+css+JavaScript+Bootstarp,共有8个页面 部分网页截图 网页源码 <!DOCTYPE html> <html lang= ...

  10. python作业案例_作业解析-python bayesian案例

    目录 1. 作业题目 ------------------------. 2. 作业目的------------------------. 3. 运行效果----------------------- ...

最新文章

  1. HDU1880(map)
  2. 企业网站设计方案需先明确网站主题
  3. stm32f103c8t6芯片IAP升级填坑记
  4. Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
  5. 项目启动:java程序包不存在_ideaError:(3, 24) java: 程序包不存在的问题
  6. 哈工大未来计算机院士,中国双一流大学拥有院士校友数排名,这是真实力!哈工大依然很强...
  7. MySQL入门 (一) : 资料库概论与MySQL的安装
  8. Integer你真的了解吗,快来瞅瞅吧
  9. vijos1214——伤心的AsukaNoKaze
  10. Java编写的“滑稽”表情屏保程序
  11. FLOW 3D二次开发
  12. newton's three laws of motion(牛顿三大运动定律)
  13. 任正非——《一江春水向东流》
  14. iOS TouchID和FaceID登录验证 简单使用
  15. 《基于微信小程序的美食推荐系统》硕士论文
  16. ubuntu16.04录制4K屏软件使用备注
  17. 验证哥德巴赫猜想:任一充分大的偶数,可以用两个素数之和表示。
  18. 做了7年开源数据库开发,我学到了什么?
  19. 数据论《西游记》关系网:猪八戒最主动喜欢别人
  20. 3.2 使用直线段工具标注尺寸信息 [Illustrator CC教程]

热门文章

  1. PMOS管的简单应用
  2. Docker和Jenkins构建项目总结
  3. docker笔记(转自:陈沙克日志)
  4. Struck Structured Output Tracking with Kernels阅读笔记
  5. 【Struck】论文阅读笔记
  6. Touch Bar 和歌词的组合就很养眼不是吗?如何在 Touch Bar 上显示歌词?
  7. 什么是编程?为什么要编程?
  8. 杨韬的Markdown自定义CSS样式
  9. cygwin apt-cyg
  10. 系统hosts文件进行域名解析