Day1

事实上D1的题目还是比较简单的= =然而D1T2爆炸了就十分尴尬……错失一波键盘

看题

T1

传送门

Description

现在你手里有一个计算器,上面显示了一个数\(S\),这个计算器十分的牛逼,他只有两个按钮,分别可以把屏幕上显示的数加上\(1\)或者减去\(1\)。并且,如果计算器屏幕上的数变成了负数,那么计算器就会损坏。现在你想要在\(K\)次操作之内吧屏幕上的数字变成\(T\),而且不让计算器损坏,求一共有多少种方案。

两种方案不同当且仅当按钮被按下的序列不同

Input

一行三个整数\(S,T,K\)

Output

一行一个正整数,表示答案

Sample Input

0 1 3

Sample Output

3

Hint

\(For~All:\)

\(0~\leq~S,T,K~\leq~100000\)

\(For~30~percents:\)

\(S,T,K~\leq~10\)

\(For~60~percents:\)

\(S,T,K~\leq~1000\)

Solution

前30分枚举加和减

60分做法:DP。

设\(f_{i,j}\)为,第\(i\)次操作将计算器变成\(j\)的方案数。转移显然,枚举第\(i\)次加一还是减一。

\[f_{i,j}=f_{i-1,j-1}+f_{i-1}{j+1}$$。当$j=0$时不能从$j-1$转移。答案显然就是$\sum_{i=0}^{k}~f_{k,T}$,边界为$f_{0,S}=1$

满分做法:数学推导。

由于$S$到$T$的方案数严格等价于$T$到$S$的方案数,故不妨设$S~\leq~T$

考虑题目事实上等价于在一个平面直角坐标系中,有一个点$(S,0)$,求这个点到$(T,k)$的方案数。其中$0~\leq~k~\leq~K$

每次移动只能从$(x,y)$移动到$(x+1,y+1)$或$(x-1)(y+1)$。其中不允许越过$x=0$这条线。考虑这么做的方案数,等价于将坐标轴旋转$45°$,以原先的$(S,0)$为原点,不允许越过$y=x+S$这条直线,到达$(T-S,k)$的方案数。先考虑不存在不许越过直线的限制,那么方案数即为$C_{T-S+k}^{k}$。考虑不合法的方案。发现将不合法的方案在直线下方的部分关于直线对称后与他关于直线的对称点到目标的方案一一对应。于是显然另一个方案数可以求出。做差即为答案。

### Code

~~我懒得写了所以就把std放上来了~~

~~这std写的真丑~~

```cpp
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = (int)2e5, mod = (int)1e9 + 7;
typedef long long ll;

int S, T, K;
int fac[N + 10], ifac[N + 10];

int pow(int x, int y) {
ll t = x, r = 1;
for ( ; y; y >>= 1, t = t * t % mod)
if (y & 1) r = r * t % mod;
return r;
}

void preprocessing() {
fac[0] = 1;
for (int i = 1; i <= N; ++i) fac[i] = (ll)fac[i - 1] * (ll)i % mod;
ifac[N] = pow(fac[N], mod - 2);
for (int i = N - 1; i >= 0; --i) ifac[i] = (ll)ifac[i + 1] * (ll)(i + 1) % mod;
}

int c(int n, int r) {
return (ll)fac[n] * (ll)ifac[r] % mod * (ll)ifac[n - r] % mod;
}

int main() {

preprocessing();
scanf("%d %d %d", &S, &T, &K);
if (S > T) swap(S, T);

int ans = 0;
for (int i = 0; i <= K; ++i) {
if ((i + T - S) & 1) continue;
int x = (i - T + S) >> 1, y = (i + T - S) >> 1;
if (x < 0) continue;
(ans += c(x + y, x)) %= mod;
if (x > S) (ans += (mod - c(x + y, x - S - 1))) %= mod;
}

printf("%d\n", ans);
return 0;
}
```

## T2

[传送门](https://www.luogu.org/problemnew/show/T50010)

### Description

有一个工厂一共有$n$个排成一排的机器,其中第$i$台机器的效率是$e_i$。

机器有开或关两种状态,显然当所有机器都开着时工作效率可以达到最大。但是由于工厂的供电系统出现了故障,不能够同时开启任意连续$k$台机器,否则工厂就会爆炸。

求工厂在不发生爆炸的前提下能达到的最大效率

### input

第一行两个整数$n$和$k$

接下来$n$行,每行一个整数代表$e_i$

### Output

一行一个数代表答案

### Sample Input

```
5 2
1
2
3
4
5
```

### Sample Output

```
12
```

### Hint

$For~All:$

$1~\leq~n,k~\leq~10^5~,~1~\leq~e_i~\leq~10^9$

$For~30~percents:$

$1~\leq~n~\leq~100$

### Solution

DP。

考虑设$f_i$为前$i$个的答案,其中一定不选第$i$个。显然可以通过枚举哪一个不选进行转移。$f_i=$$\max\{f_j+e_{j+1}+e_{j+2}+...+e_{i}\}$,其中满足$i-k~<~j~<~i$。$e_i$显然可以前缀和处理。另外发现因为$k$恒定,所以转移的左端点时单调不降的。于是可以单调队列把整个复杂度降低到$O(n)$。事实上使用线段树维护区间最大值也是可以的。

## Code

```cpp
#include<cstdio>
#define rg register
#define ci const int
#define cl const long long int

namespace IO {
char buf[110];
}

typedef long long int ll;

template <typename T>
inline void qr(T &x) {
char ch=getchar(),lst=' ';
while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst == '-') x=-x;
}

template <typename T>
inline void write(T x,const char aft,const bool pt) {
if(x < 0) {putchar('-');x=-x;}
rg int top=0;
do {
IO::buf[++top]=x%10+'0';x/=10;
} while(x);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}

template <typename T>
inline T mmax(const T a,const T b) {return a > b ? a : b;}
template <typename T>
inline T mmin(const T a,const T b) {return a < b ? a : b;}
template <typename T>
inline T mabs(const T x) {return x < 0 ? -x : x;}

template <typename T>
inline void mswap(T &a,T &b) {
T temp=a;a=b;b=temp;
}

const int maxn = 100010;

int n,k,front,end;
ll frog[maxn],que[maxn],sum[maxn];

int main() {
qr(n);qr(k);
for(rg int i=1;i<=n;++i) {qr(sum[i]);sum[i]+=sum[i-1];}
front=end=1;
for(rg int i=1;i<=n;++i) {
if(i-que[front] > k) ++front;
while((front <= end) && ((frog[que[end]]-sum[que[end]]) <= (frog[i]-sum[i]))) --end;
que[++end]=i;
frog[i+1]=frog[que[front]]-sum[que[front]]+sum[i];
}
write(frog[n+1],'\n',true);
return 0;
}
```

## T3

[传送门](https://www.luogu.org/problemnew/show/T50011)

### Description

![qwq](https://cdn.luogu.org/upload/pic/35123.png )

### Input

![qwq](https://cdn.luogu.org/upload/pic/35124.png)

### Output

对于每组询问输出一行代表答案

### Sample Input

```
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
```

### Sample Output

```
1
0
2
```

### Solution

这不是没穿衣服的带权并查集嘛

### Code

```cpp
// i forgot to reset the seed of the rand
// maybe i will get zero pts
// upd: i ain't get WA for this task
// i feel very happy
#include<cstdio>
#define rg register
#define ci const int
#define cl const long long int

namespace IO {
char buf[110];
}

template <typename T>
inline void qr(T &x) {
char ch=getchar(),lst=' ';
while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst == '-') x=-x;
}

template <typename T>
inline void write(T x,const char aft,const bool pt) {
if(x < 0) {putchar('-');x=-x;}
rg int top=0;
do {
IO::buf[++top]=x%10+'0';x/=10;
} while(x);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}

template <typename T>
inline T mmax(const T a,const T b) {return a > b ? a : b;}
template <typename T>
inline T mmin(const T a,const T b) {return a < b ? a : b;}
template <typename T>
inline T mabs(const T x) {return x < 0 ? -x : x;}

template <typename T>
inline void mswap(T &a,T &b) {
T temp=a;a=b;b=temp;
}

const int maxn = 30010;

int up[maxn],down[maxn],dist[maxn];

int findup(ci);
int finddown(ci);

int main() {
freopen("cubes.in","r",stdin);
freopen("cubes.out","w",stdout);
rg int m=0;qr(m);
for(rg int i=1;i<=maxn;++i) up[i]=i,down[i]=i,dist[i]=0;
rg int a,b;rg char ch;
while(m--) {
ch=getchar();
while((ch != 'M') && (ch != 'C')) ch=getchar();
if(ch == 'M') {
a=b=0;qr(a);qr(b);
a=finddown(a);b=findup(b);
down[a]=b;up[b]=a;dist[a]=1;
}
else {
a=0;qr(a);
finddown(a);
write(dist[a],'\n',true);
}
}
return 0;
}

int findup(ci x) { return up[x] != x ? up[x]=findup(up[x]) : x; }

int finddown(ci x) {
if(down[x] == x) return x;
int tk=finddown(down[x]);
dist[x]+=dist[down[x]];
return down[x]=tk;
}
```

## Summary

这套题大概是6天里面最简单的一套了……起码有260保底……然而竟然挂在了最拿手的DP上……

在写DP的时候发现有一部分转移无法优化时,可以考虑这一块转移是否是必须的,如果不是,可以直接删除该转移

一定记得srand!\]

【套题】qbxt国庆刷题班D1的更多相关文章

  1. 【套题】qbxt国庆刷题班D2

    D2 今天的题感觉还是好妙的 T1 传送门 Description 现在有一张\(n\)个节点\(m\)条边的无向连通图\(G=(V,E)\),满足这张图中不存在长度大于等于3的环且图中没有重边和自环 ...

  2. JS、JAVA刷题和C刷题的一个很重要的区别

    就是最近在做树方面的题时,发现JS和JAVA刷题和C刷题的一个很重要的区别就是传入null的区别 当遍历的时候,C传参数时可以传进去null的指针,因为递归进去,出来时,指针还是指着那个地方 但是JS ...

  3. 再也不用c刷题了!!——c++刷题必备

    致读者: 博主是一名数据科学与大数据专业大二的学生,真正的一个互联网萌新,写博客一方面是为了记录自己的学习历程,一方面是希望能够帮助到很多和自己一样处于困惑的读者.由于水平有限,博客中难免会有一些错误 ...

  4. 2017北京国庆刷题Day5 afternoon

    期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)… ...

  5. 2017北京国庆刷题Day1 afternoon

    期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms   Memory Limit:128MB 题目 ...

  6. 2017北京国庆刷题Day7 morning

    期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...

  7. 2017北京国庆刷题Day3 morning

    期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...

  8. 2017北京国庆刷题Day2 afternoon

    期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一 ...

  9. 2017北京国庆刷题Day2 morning

    期望得分:100+100+40=240 实际得分:100+40+0=140 T1 一道图论神题(god) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK ...

随机推荐

  1. Linux命令应用大词典-第38章 网络命令

    38.1 traceroute:显示跟踪到网络主机的路由数据包 38.2 mli-tool:查看.操纵网络接口状态 38.3 ifconfig:显示和配置网络接口 38.4 ifdown:关闭网络接口 ...

  2. 关于java获取网页内容

    最近项目需求,做一些新闻站点的爬取工作.1.简单的jsoup爬取,静态页面形式: String url="a.atimo.cn";//静态页面链接地址Document doc = ...

  3. 【outPut_Class 输出类】使用说明

    对象:outPut 说明:定义输出结果类的相关操作.此对象的核心是[JSON]类,所以它继承了[JSON]类的所有方法 重要: 输出结果样式为XML时,自带根节点"root".输出 ...

  4. 165. Merge Two Sorted Lists【LintCode by java】

    Description Merge two sorted (ascending) linked lists and return it as a new sorted list. The new so ...

  5. 【转】: 《江湖X》开发笔谈 - 热更新框架

    前言 大家好,我们这期继续借着我们工作室正在运营的在线游戏<江湖X>来谈一下热更新机制以及我们的理解和解决方案.这里先简单的介绍一下热更新的概念,熟悉这部分的朋友可以跳过,直接看我们的方案 ...

  6. 【转】cocos2d工具汇总

    位图字体工具Bitmap Font Tools BMFont (Windows)FonteditorGlyph DesignerHieroLabelAtlasCreator 粒子编辑工具Particl ...

  7. [HNOI2017]大佬

    参考题解 \(\text{Solution}\) 我们发现5个行为中2操作与其它操作无关,所以我们采用贪心,尽量让多的时间去攻击大佬. 设 \(f[i][j]\) 表示前 \(i\) 天剩 \(j\) ...

  8. 为什么安装beego和框架的失败 以及常用命令

    1.安装了几个版本,版本之间相互影响. 把没用的删掉 2.网上找的教程存在问题. 都是相互抄袭.最权威的还是官网. which go rm -rf test/ echo path 获取路径 vim ~ ...

  9. Dictionary tabPage使用

    public override bool AccptChange() { //if (oldvalue == null || oldvalue.Count <= 0) //{ // return ...

  10. oracle数据库分页原理

    Oracle数据库的rownum 在Oracle数据库中,分页方式没有MySql这样简单,它需要依靠rownum来实现.Rownum表示一条记录的行号,值得注意的是它在获取每一行后才赋予.因此,想指定 ...