[APIO2016]
2016的题貌似是韩国棒子出的,好丧啊.... 看了题解还想了好久......
-------------------------------------------------
A.Boat
有n个数,每个数字可取[li,ri]内的任意整数si,但是要求对于任意i<j,都有si<sj,求方案数 n<=500,l,r<=10^9
题解:首先离散,然后不同区间的方案数很好转移,我们考虑相同区间的方案数,发现是一个差分了多次的数列,如果区间长度是l,选m个这样的区间,那么方案数是11111...差分m次后的第l项。然后我们可以发现这个其实是一个组合数,等于C(m,m+l)。我们用f[i][j]表示第i个选第j个区间的方案数,然后我们把f数组前缀和之后推出公式,
f[i][j]=∑C(i-i'-1,i-i'+l-1) * f[i'-1][j-1]
复杂度n^3
#include<iostream>
#include<cstdio>
#include<algorithm>
#define mod 1000000007
#define MAXN 1000
#define int long long
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} int tot=-,n,L[*MAXN+];
int l2[MAXN*+],l[MAXN+],r[MAXN+];
int f[MAXN+][MAXN*+];
int inv[MAXN+],p[MAXN+]; main()
{
p[]=inv[]=p[]=inv[]=;
for(int i=;i<=MAXN;i++)
{
p[i]=1LL*p[i-]*i%mod;
inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
}
//for(int i=2;i<=MAXN;i++) inv[i]=1LL*inv[i]*inv[i-1]%mod;
n=read();
for(int i=;i<=n;i++)
{
l[i]=l2[i*-]=read();
r[i]=l2[i<<]=read();l2[i<<]+=;
}
sort(l2+,l2+n*+);
for(int j=;j<=n*;j++)if(l2[j]!=l2[j-])
l2[++tot]=l2[j]; tot++;
for(int i=;i<tot;i++) L[i]=l2[i]-l2[i-];
for(int i=;i<=n;i++)
{
l[i]=upper_bound(l2,l2+tot,l[i])-l2;
r[i]=upper_bound(l2,l2+tot,r[i])-l2;
// cout<<l[i]<<" "<<r[i]<<endl;
}
for(int i=;i<tot;i++) f[][i]=;
for(int i=;i<=n;i++)
{
f[i][]=;
for(int j=l[i];j<=r[i];j++)
{
f[i][j]=(long long)L[j]*f[i-][j-]%mod;//cout<<f[i][j]<<endl;
int now=;long long c=L[j]-;
for(int k=i-;k;--k)
if(l[k]<=j&&j<=r[k])
{
now++;
c=c*(long long)(L[j]+now-)%mod*inv[now]%mod;
if(!c)break;
f[i][j]=(f[i][j]+(long long)f[k-][j-]*c)%mod;
}
}
for(int j=;j<tot;j++)
f[i][j]=((long long)f[i][j]+f[i-][j]+f[i][j-]-f[i-][j-]+mod)%mod;
// for(int j=1;j<tot;j++)
// cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
}
cout<<(long long)(f[n][tot-]-+mod)%mod;
return ;
}
B.给定一棵n个非叶节点,m个叶节点的树,有边权,定义修改边权的费用为前后边权的差的绝对值,你要让所有叶节点到根节点的距离相同,但又不能把边权改成负数,求最小费用。
n,m<=300000
题解:我们用f[i][j]表示第i个点,子树中的叶节点到它的距离都是j的最小费用,那么f[i][0]=∑Wjk (jk都在子树i中)。
很显然,f函数是一个下凸的函数,并且存在一些拐点,拐点前后斜率变化是1,但是拐点可以重在某一个点上。只有一个叶节点时,拐点有两个,且都为于0,凸壳形状像一个绝对值函数。
所以我们只要知道所有拐点,就可以知道这个函数啦。
我们考虑向一个子树添加边时候的影响,由于w可以无限增大,在一定大小后只修改这一条边一定最优,斜率肯定都是1,所以对于斜率大于1的部分我们都可以舍去,即弹掉所有原来斜率大等0的拐点。
这样一次合并我们实际上只把它向右平移了一下。需要删除和合并操作,所以写一个可并堆就好啦。
复杂度(n+m)log(n+m)
#include<iostream>
#include<cstdio>
#define MN 600000
#define ll long long
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} int n,m,fa[MN+],in[MN+];
ll w[MN+],ans=; struct Heap{
Heap *l,*r;
ll p;int d;
Heap(ll _p):p(_p),l(),r(),d(){};
inline friend int dis(Heap*x){return x?x->d:;}
friend Heap* Merge(Heap*x,Heap*y)
{
if(!x) return y;if(!y) return x;
if(x->p<y->p) swap(x,y);
x->r=Merge(x->r,y);
if(dis(x->r)>dis(x->l)) swap(x->l,x->r);
x->d=dis(x->r)+; return x;
}
}*s[MN+],*a,*b; int main()
{
n=read();m=read();n+=m;
for(int i=;i<=n;i++)
{++in[fa[i]=read()];ans+=(w[i]=read());}
for(int i=n;i>;i--)
{
if(!s[i]) s[i]=Merge(new Heap(),new Heap());
for(int j=;j<in[i];j++)
s[i]=Merge(s[i]->l,s[i]->r);
a=new Heap(s[i]->p+w[i]);s[i]=Merge(s[i]->l,s[i]->r);
b=new Heap(s[i]->p+w[i]);s[i]=Merge(s[i]->l,s[i]->r);
s[fa[i]]=Merge(s[fa[i]],Merge(s[i],Merge(a,b)));
}
int top=;
while(s[])w[++top]=s[]->p,s[]=Merge(s[]->l,s[]->r);w[top+]=;
for(int i=top;m;m--,i--) ans-=(w[i]-w[i+])*m;
printf("%lld\n",ans);
return ;
}
C.Gap
给定一个长度为n的严格递增数列,你每次可以询问一个数字区间的最大值,最小值,求最大差分。n<=100000
题解:对于subtask1,询问次数不超过(n+1)/2,我们枚举左右节点查,然后缩短这个区间就好啦。
对于subtask2,询问的区间含有k个数时费用是k+1,要让费用不超过3n。我们先求最大值x和最小值y,显然答案不会低于(y-x)/(n-1),所以我们把数字分块,每块内不存在答案,都询问一次就行了。
#include "gap.h"
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
#define INF 1000000000000000000LL
ll s[];
ll ans=;
int cnt=; ll solve(int x)
{
ll l,r;
MinMax(,INF,s+,s+x);cnt=;int i=,j=x-;
for(l=s[]+,r=s[x]-;i<=j;l=s[i++]+,r=s[j--]-)
{
MinMax(l,r,s+i,s+j);
}
for(int i=;i<=x;i++)
ans=max(ans,s[i]-s[i-]);
return ans;
} ll findGap(int T, int N)
{
if(T==) return solve(N);
if(N==) return ;
MinMax(,INF,s+,s+);cnt=;
ll p=(s[]-s[]-)/(N-)+;
for(ll i=s[]+;i<=s[]-;i+=p)
{
MinMax(i,min(i+p-,s[]-),s+cnt+,s+cnt+);
if(s[cnt+]>)cnt+=;
}
sort(s+,s+cnt+);
for(int i=;i<=cnt;i++)
ans=max(ans,s[i]-s[i-]);
return ans;
}
[APIO2016]的更多相关文章
- BZOJ 4584 luogu P3643: [Apio2016]赛艇
4584: [Apio2016]赛艇 Time Limit: 70 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在首尔 ...
- [洛谷P3643] [APIO2016]划艇
洛谷题目链接:[APIO2016]划艇 题目描述 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 \(N\) 个划艇学校,编号依次为 \(1\) 到 \(N\).每个学校都拥有若干艘 ...
- 【APIO2016】Fireworks[DP 可并堆维护凸包优化]
4585: [Apio2016]烟火表演 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 100 Solved: 66[Submit][Status] ...
- 【BZOJ4584】[Apio2016]赛艇 DP
[BZOJ4584][Apio2016]赛艇 Description 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着个划艇学校,编号依次为到.每个学校都拥有若干艘划艇.同一所学校的所 ...
- UOJ #205/BZOJ 4585 【APIO2016】Fireworks 可并堆+凸包优化Dp
4585: [Apio2016]烟火表演 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 115 Solved: 79[Submit][Status] ...
- Loj #2568. 「APIO2016」烟花表演
Loj #2568. 「APIO2016」烟花表演 题目描述 烟花表演是最引人注目的节日活动之一.在表演中,所有的烟花必须同时爆炸.为了确保安全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连 ...
- 「APIO2016」烟花表演
「APIO2016」烟花表演 解题思路 又是一道 solpe trick 题,观察出图像变化后不找一些性质还是挺难做的. 首先令 \(dp[u][i]\) 为节点 \(u\) 极其子树所有叶子到 \( ...
- 写在APIO2016之前
时间过得真快.仿佛前天的我还在为联赛的MLE悲伤,昨天的我还在为省选看错题而崩溃,今天就到了APIO的前夜了.虽然明天不是正赛,但我的学弟们都是明天离开.也就是说,我只能为在遥远帝都的他们默默地祈祷了 ...
- P3643 [APIO2016]划艇
P3643 [APIO2016]划艇 题意 一个合法序列可表示为一个长度为 \(n\) 的序列,其中第 \(i\) 个数可以为 0 或 \([l_i,r_i]\) 中一个整数,且满足所有不为零的数组成 ...
- CTSC2016&&APIO2016滚粗记&&酱油记&&游记<del>(持续更新)</del>
挖一波坑 #include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs. ...
随机推荐
- 自己动手写CPU(基于FPGA与Verilog)
大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
- PCB名詞解釋:通孔、盲孔、埋孔(转载)
文章转载自:https://www.researchmfg.com/2011/07/pth-blind-hole-buried-hole/ PCB名詞解釋:通孔.盲孔.埋孔 Posted by 工作熊 ...
- salesforce零基础学习(八十七)Apex 中Picklist类型通过Control 字段值获取Dependent List 值
注:本篇解决方案内容实现转自:http://mysalesforceescapade.blogspot.com/2015/03/getting-dependent-picklist-values-fr ...
- 新概念英语(1-3)Sorry, sir
Does the man get his umbrella back? A:My coat and my umbrella please. B:Here is my ticket. A:Thank y ...
- 【52ABP实战教程】00-- ASP.NET CORE系列介绍
为什么是.net core? 记得在半年前.NET CORE刚刚出了1.0,当时有朋友推荐我使用的时候,个人觉得还不成熟. 现在.NET Core已经到了2.0,.NET Standard 2.0 添 ...
- express实践(一)
涉及以下这些内容: 主体. cookie.session 数据 模板引擎 服务器基本结构: const express=require('express'); const static=require ...
- linux centos-7.2-64bit 安装配置启动nginx
1.安装依赖包yum -y install openssl openssl-develyum install pcre*yum install openssl*yum install zlib yum ...
- 基于 MySQL 的数据库实践(准备工作)
背景 本学期在北京大学选修了<数据库概论>的实验班课程,由于 SQL 语法并不是特别理论的内容,因此课上暂时也没有特别展开.出于探索数据库领域的兴趣,使用国内普遍使用的数据库软件 MySQ ...
- [Kaggle] dogs-vs-cats之模型训练
上一步建立好模型之后,现在就可以训练模型了. 主要代码如下: import sys #将当期路径加入系统path中 sys.path.append("E:\\CODE\\Anaconda\\ ...
- 字典的update方法
>>> dict = {"name":"zara", "age": 7} >>> dict2 = {&q ...