JSOI2010~2011
2021-04-21 10:27
标签:sign line sim har query define 交换 优化 top
题面:bzoj 题面:bzoj 题面:Luogu 题面:Luogu 题面:Luogu 题面:bzoj
top
top
top
A 旅行
题解:神奇的\(dp\)
先按长度把边排序
指定必须走前\(l\)条边,枚举\(l\)
设\(dis[i][j][k]\)表示当前到了\(i\)节点,已走过了\(j\)条前\(l\)条边,用了\(k\)次交换次数
codeB 找零钱的洁癖
题解:更为神奇
首先直接bfs,到一定程度break
其次乱贪心
据\(\text{M}\)\(\color{red}{\text{_sea}}\)说正解是整数规划?
不会,告辞
codeH 柠檬
题解:斜率优化
首先有一个显然的性质就是:一段两端必定相同并且是这一段选定的大小(否则可以证明结果必定小于这种)
设\(dp[i]\)表示前\(i\)个的答案,\(s[i]\)表示\(i\)是\(1\sim n\)内相同大小的第几个
\[dp[i]=max_{0
于是有
只与\(i\)有关的:\(a[i]*s[i]^2+2*a[i]*s[i]+a[i]\)
只与\(j\)有关的:\(dp[j-1]+a[i]*s[j]^2-2*a[i]*s[j](a[i]==a[j])\)
既和\(i\)有关又和\(j\)有关的:\(-2a[i]s[i]s[j]\)
于是套斜率优化板子,维护上凸壳,栈顶最优决策
注意要先把自己丢进去再决策
由于空间问题用\(vector\)模拟栈
codeI 分特产
题解:容斥
设至少\(x\)个人什么都没有
也就是把\(a[i]\)个特产分给\(n-x\)个人
于是在\(n-x-1\)个空格里随意插\(a[i]\)块隔板
根据乘法原理,对每一种特产考虑最后再乘起来
方案数就是\(\prod_{i=1}^{m}{C_{n-x-1+a[i]}^{a[i]}}\)
反演一下(相比之下我更喜欢这个而不是容斥)
答案就是恰好0人什么都没有
\[ans=\sum_{i=0}^{n-1}{(-1)^iC_{n}^{i}\prod_{j=1}^{m}{C_{n-i-1+a[j]}^{a[j]}}}\]
codeJ 棒棒糖
是重题
建一颗主席树,如果\([1,mid]\)内没有这么多个数字就显然没有,再看\([mid+1,r]\)
codeK 任务调度
题解:可并堆
修改操作就把这个点抠出来(合并它的左右儿子),再塞回去
据说可以用pb_ds水过去(然而我搞了一下午没搞出来)
codecode A
#include
B code
#include
H code
#include
I code
n; ++i)
{
f[0] = 1;
for (int j = 1; j
#include
top
J code
#include
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
inline void read(int& x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 500005
int ls[maxn*32],rs[maxn*32],val[maxn*32],rt[maxn],tot;
int n,m,w;
void build(int& rt,int l,int r)
{
rt=++tot;
if(l==r) return;
int mid=(l+r)>>1;
build(ls[rt],l,mid);
build(rs[rt],mid+1,r);
}
void update(int& rt,int las,int l,int r,int pos)
{
rt=++tot;
ls[rt]=ls[las],rs[rt]=rs[las],val[rt]=val[las]+1;
if(l==r) return;
int mid=(l+r)>>1;
if(pos>1;
if(((val[ls[to]]-val[ls[fr]])len) r=mid,fr=ls[fr],to=ls[to];
else if(((val[rs[to]]-val[rs[fr]])len) l=mid+1,fr=rs[fr],to=rs[to];
else return 0;
}
}
int main()
{
read(n),read(m);
build(rt[0],1,n);
for(int i=1;i
top
K code
#include
using namespace std;
inline void read(int& x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 300005
int dis[maxn],rt[maxn],val[maxn],fa[maxn],son[maxn][2];
int merge(int x,int y)
{
if(!x||!y) return x|y;
if(val[x]>val[y]) swap(x,y);
son[x][1]=merge(son[x][1],y);
if(dis[son[x][0]]
top
JSOI2010~2011
标签:sign line sim har query define 交换 优化 top
原文地址:https://www.cnblogs.com/123789456ye/p/12250181.html