送分题(songfen)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK喜欢干一些有挑战的事,比如说求区间最大子段和。它知道这个题目有O(n)的做法。于是它想加强一下。

也就是说,LYK一开始有n个数,第i个数字是ai,它找来了一个新的数字P,并想将这n个数字中恰好一个数字替换成P。要求替换后的最大子段和尽可能大。

LYK知道这个题目仍然很简单,于是就扔给大家来送分啦~

注:最大子段和是指在n个数中选择一段区间[L,R](L<=R)使得这段区间对应的数字之和最大。

输入格式(songfen.in)

第一行两个数n,P。

接下来一行n个数ai。

输出格式(songfen.out)

一个数表示答案。

输入样例

5 3

-1 1 -10 1 -1

输出样例

5

样例解释

将第三个数变成3后最大子段和为[2,4]。

数据范围

对于30%的数据n<=100。

对于另外30%的数据ai,P>=0。

对于100%的数据n<=1000,-1000<=ai,P<=1000。

Note:提前AK的同学可以想一想O(n)的做法。

枚举改哪个,再做O(n)的最大子段和。总复杂度:O(n²)

O(n)做法用栈,不会。。。。。。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,p,ans,tmp,out=-1e8;
int dp[],a[];
int main()
{
freopen("songfen.in","r",stdin);
freopen("songfen.out","w",stdout);
scanf("%d%d",&n,&p);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
int x;
for(int k=;k<=n;k++)
{
tmp=a[k]; a[k]=p;
for(int i=;i<=n;i++)
{
x=a[i];
if(dp[i-]+x>=x) dp[i]=dp[i-]+x;
else dp[i]=x;
if(dp[i]>ans) ans=dp[i];
}
out=max(out,ans);
a[k]=tmp;
memset(dp,,sizeof(dp));
ans=-1e8;
}
printf("%d",out);
}

错误的O(n):

dp[i][0]到了第i个,第i个没有改

dp[i][1]到了第i个,第i个改了

dp[i][]=max(dp[i-][]+x,dp[i-][]+x);
dp[i][]=max(dp[i][],x);
dp[i][]=max(dp[i-][]+p,p);
ans=max(ans,dp[i][]);
ans=max(ans,dp[i][]);

错因:不能保证之修改一次

第i个改了,第i+1个的不改由第i个的改和不改转移,第i+2个的改由第i+1个的不改转移,这就改了两次

树状数组(lowbit)

Time Limit:1000ms   Memory Limit:128MB

题目描述

这天,LYK在学习树状数组。

当它遇到一个叫lowbit的函数时有点懵逼。lowbit(x)的意思是将x分解成二进制,它的值就是 ,其中k是最小的满足(x & )>0的数。(&是二进制中的and运算)

LYK甚至知道lowbit(x)=(x&-x)。但这并没什么用处。

现在LYK有了n个数字,为了使自己更好的理解lowbit是什么意思。它想对所有n^2个二元组求lowbit。具体的,对于一个二元组(ai,aj),它的值为lowbit(ai xor aj) (xor表示异或的意思),那么总共有n^2对二元组,LYK想知道所有二元组的值加起来是多少。

这个答案可能很大,你只需输出这个值对1000000007取模后的结果就可以了。

输入格式(lowbit.in)
    第一行一个数n,表示有n个这样的数字。

第二行n个数ai。

输出格式(lowbit.out)

一个数表示答案。

输入样例

5

1 2 3 4 5

输出样例

32

数据范围

对于30%的数据n<=1000。

对于另外10%的数据ai<=1。

对于再另外10%的数据ai<=3。

对于再再另外20%的数据ai<1024。

对于100%的数据1<=n<=100000,0<=ai<2^30。

分治

二进制最后一位是0的放左边,最后一位是1的放右边,对答案的贡献为两者个数的乘积* 2^0

对于左边的和右边的,分别做:

二进制倒数第二位是0的放左边,倒数第二位是1的放右边,对答案的贡献为两者个数的乘积* 2^1

。。。。。。

边界条件1: 没有数了

边界条件2:二进制位数>30 (非常重要,他保证了最多分治30层,高效解决应重复出现的数)

#include<cstdio>
#define mod 1000000007
#define N 100001 using namespace std;
int n;
int a[N],b[N];
long long ans;
void divide(int l,int r, int k)
{
if(l>=r || k>) return;
int L=l,R=r;
for(int i=l;i<=r;i++)
if(a[i] & (<<k)) b[L++]=a[i];
else b[R--]=a[i];
ans=(ans+1ll*(L-l)*(r-R)*(<<k))%mod;
for(int i=l;i<=r;i++) a[i]=b[i];
if(l!=L) divide(l,L-,k+);
if(r!=R) divide(R+,r,k+);
}
int main()
{
freopen("lowbit.in","r",stdin);
freopen("lowbit.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
divide(,n,);
printf("%I64d",(ans<<)%mod);
}

防AK好题(fangak)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK觉得,这场比赛到目前为止,题目都还太简单了。

于是,它有意在最后一题为难一下大家。它定义了一个非常复杂的运算。具体的,一开始它有n个数ai。令c表示最大的相邻两个数的差。也就是说c=max{| |}(i∈[2,n])。这个值显然是一个常数。

但是问题来了,LYK为了刁难你们,它想改变其中k个数,也就是说将其中至多k个数变成任意的数,并且LYK要求这么做完后c的值尽可能小。

输入格式(fangak.in)

第一行两个数n,k。

接下来一行n个数表示ai。

输出格式(fangak.out)

一个数表示最小的k的值。

输入样例

6 3

1 2 3 7 8 9

输出样例

1

数据范围

对于20%的数据n<=8。1<=ai<=8。

对于另外20%的数据k=1。

对于再另外20%的数据ai一开始是单调递增的。

对于再再另外20%的数据n<=100。

对于100%的数据1<=k<=n<=1000,-10^9<=ai<=10^9。

二分+DP

dp[i] 表示 到第i个数, 在满足条件(任意两个相邻的数,差<=mid)的情况下,并且i没有被改变,最少改变多少数字。

状态转移: dp[i]=dp[k]+(i-k-1)    k=0~i-1  表示 k+1~i-1 都被改变了

转移条件:mid*(k-i)>=abs(a[k]-a[i])  k~i这段区间能满足条件

只管修改了多少个数,至于改成了什么,不关心

最大的差最小,就是让数均匀分布,那么二分最大的差,条件就是差*个数>= | 区间右边-左边 |

也就是假设区间左右端点都不改变,而区间内部都改变

区间内部都改变是最差的情况,他会随着区间左端点的移动而变小

个人感觉:这是一道区间DP

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1001
using namespace std;
int n,k,maxn=-2e9,minn=2e9;
int a[N],dp[N+];
bool check(int mid)
{
dp[]=;
for(int i=;i<=n;i++)
{
dp[i]=n+;
for(int j=i-;j>=;j--)
if(!j || mid*(i-j)>=abs(a[i]-a[j])) dp[i]=min(dp[i],dp[j]+i-j-);
}
for(int i=;i<=n;i++)
if(dp[i]+n-i<=k) return true;
return false;
}
int main()
{
freopen("fangak.in","r",stdin);
freopen("fangak.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&a[i]),maxn=max(maxn,a[i]),minn=min(minn,a[i]);
int l=,r=maxn-minn,mid,ans;
while(l<=r)
{
mid=l+r>>;
if(check(mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d",ans);
}

2017 济南综合班 Day 1的更多相关文章

  1. 2017 济南综合班 Day 7

     a 两个指针L.R R开始指向恰好[R,n]有不超过k个逆序对的地方 随着L的右移,R指针只会右移 逆序对有2部分 1.L左侧与其他位置形成的逆序对 2.R右侧与其他位置形成的逆序对 用树状数组分别 ...

  2. 2017 济南综合班 Day 6

    循环移动 (cyclic.cpp/c/pas) (1s/256M) 问题描述 给出一个字符串S与N个操作.每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K ...

  3. 2017 济南综合班 Day 5

    毕业考试 (exam.cpp/c/pas) (1s/256M) 问题描述 快毕业了,Barry希望能通过期末的N门考试来顺利毕业.如果他的N门考试平均分能够达到V分,则他能够成功毕业.现在已知每门的分 ...

  4. 2017 济南综合班 Day 4

    T1 外星人 二维前缀和 #include<cstdio> #define N 1001 using namespace std; bool v[N][N]; int sum[N][N]; ...

  5. 2017 济南综合班 Day 3

    T1  黑化 题意: 求一个字符串是否可能包含另一个字符串 字符串中的?可以匹配任意字母 可能输出 God bless You! 一定不可能 输出 Game Over! 计算fail数组时,fail数 ...

  6. 2017 济南综合班 Day 2

    木棍(stick) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有很多木棍,具体的,总共有n根,且每根木棍都有一个长度.为了方便起见,我们可以用一个正 ...

  7. 2017 济南精英班 Day1

    不管怎么掰都是n*m-1 #include<cstdio> using namespace std; int main() { freopen("bpmp.in",&q ...

  8. JavaScript脚本语言基础(四)

    导读: JavaScript和DOM DOM文档对象常用方法和属性 DOW文档对象运用 JSON数据交换格式 正则表达式 1.JavaScript和DOM [返回] 文档对象模型(Document O ...

  9. JeeSite(2):导入数据,进入系统

    本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/50954485 未经博主同意不得转载. 博主地址是:http://blog.csd ...

随机推荐

  1. es6从零学习(五):Module的语法

    es6从零学习(五):Module的语法 ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量 一:es6模块化和 CommonJS 和 AMD 模块 (运行 ...

  2. 嵌入式码农的10年Bug调试经验,值得一看

    下面这些都是我经历过的会导致难点bug的问题: 1.事件顺序.在处理事件时,提出下列问题会很有成效:事件可以以不同的顺序到达吗?如果我们没有接收到此事件会怎么样?如果此事件接连发生两次会怎么样?哪怕通 ...

  3. 找bug——加分作业

    bug1:while循环中的*des++ =*src++; 不能这么写吧... bug2:maxSize没有定义 暂时看到这么多

  4. 从零讲JAVA ,给你一条 清晰地学习道路!该学什么就学什么!!

    1.计算机基础: 1.1数据机构基础: 主要学习:1.向量,链表,栈,队列和堆,词典.熟悉2.树,二叉搜索树.熟悉3.图,有向图,无向图,基本概念4.二叉搜索A,B,C类熟练,9大排序熟悉.5.树的前 ...

  5. eg_1

    1. 编写一个程序,输出一个字符串中的大写英文字母个数,小写英文字母个数以及非英文字母个数. 第一种方法: public class Test { public static void main(St ...

  6. SQL SERVER技术内幕之4 子查询

    最外层查询的结果集会返回给调用者,称为外部查询.内部查询的结果是供外部查询使用的,也称为子查询.子查询可以分成独立子查询和相关子查询两类.独立子查询不依赖于它所属的外部查询,而相关子查询则须依赖它所属 ...

  7. cmake & make

    大家都知道,写程序大体步骤为: 1.用编辑器编写源代码,如.c文件. 2.用编译器编译代码生成目标文件,如.o. 3.用链接器连接目标代码生成可执行文件,如.exe. 但如果源文件太多,一个一个编译时 ...

  8. wpf 验证方法

    效果图,当放鼠标到文本框上会显示出错的提示.

  9. Python基础教程系列目录,最全的Python入门系列教程!

    Python是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. 在现在的工作及开发当中,Python的使用越来越广泛,为了方便大家的学习,Linux大学 特推出了 <Python基 ...

  10. java map的键是唯一的 所有 用set类型存放