此文章可以使用目录功能哟↑(点击上方[+])

被自己蠢哭,去年还能进一下复赛,今年复赛都没戏了...

链接→2016"百度之星" - 初赛(Astar Round2B)

 Problem 1001 区间的价值

Accept: 0    Submit: 0
Time Limit: 10000/5000 mSec(Java/Others)    Memory Limit : 65536 KB

 Problem Description

 Input

 Output

 Sample Input

5
1 6 2 4 4

 Sample Output

36
16
12
12
6

 Problem Idea

解题思路:首先,我们可以用RMQ(理论上来说线段树也是可以的,查询O(logn),n次正好为O(nlogn),而ST算法预处理O(nlogn),查询O(1))预处理O(nlogn)出区间最大值,然后枚举区间的最小值点
为了枚举最小值点,我们需要知道每一个点作为最小值点左右可以延伸的最大范围l[i],r[i],求这两个数组可以用dp来做
预处理完之后,枚举最小值点,更新长度为r[i]-l[i]+1的区间的答案
枚举完之后,我们得到了一组值,但这并不是最后的答案
这是因为我们发现假如有一个最优区间,我们一定可以正好处理到或者处理到比这个区间的区间,也就是说我们求的区间最大的值具有向下的包含性
举例来说,假如当前处理的区间为l[i],r[i],得到了答案ans,那么任何长度小于等于r[l]-l[I]+1的区间的答案都至少为ans
所以我们再用线性的时间递推求出答案即可

题目链接→HDU 5696 区间的价值

 Source Code

[cpp] view plaincopy print?
  1. /*Sherlock and Watson and Adler*/
  2. #pragma comment(linker, "/STACK:1024000000,1024000000")
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #include<queue>
  7. #include<stack>
  8. #include<math.h>
  9. #include<vector>
  10. #include<map>
  11. #include<set>
  12. #include<cmath>
  13. #include<complex>
  14. #include<string>
  15. #include<algorithm>
  16. #include<iostream>
  17. #define exp 1e-10
  18. using namespace std;
  19. const int N = 100005;
  20. const int M = 40;
  21. const int inf = 100000000;
  22. const int mod = 2009;
  23. int s[N],n,maxnum[N][20],l[N],r[N];
  24. __int64 ans[N];
  25. void RMQ()          //预处理  O(nlogn)
  26. {
  27. int i,j;
  28. int m=(int)(log(n*1.0)/log(2.0));
  29. for(i=1;i<=n;i++)
  30. maxnum[i][0]=s[i];
  31. for(j=1;j<=m;j++)
  32. for(i=1;i+(1<<j)-1<=n;i++)
  33. maxnum[i][j]=max(maxnum[i][j-1],maxnum[i+(1<<(j-1))][j-1]);
  34. }
  35. int Ask_MAX (int a,int b)   //O(1)
  36. {
  37. int k=int(log(b-a+1.0)/log(2.0));
  38. return max(maxnum[a][k],maxnum[b-(1<<k)+1][k]);
  39. }
  40. int main()
  41. {
  42. int i,k;
  43. while(~scanf("%d",&n))
  44. {
  45. memset(ans,0,sizeof(ans));
  46. for(i=1;i<=n;i++)
  47. {
  48. scanf("%d",&s[i]);
  49. l[i]=r[i]=i;
  50. }
  51. RMQ();
  52. for(i=2;i<=n;i++)
  53. {
  54. k=i-1;
  55. while(s[i]<=s[k])
  56. k=l[k]-1;
  57. l[i]=k+1;
  58. }
  59. for(i=n-1;i>0;i--)
  60. {
  61. k=i+1;
  62. while(s[i]<=s[k])
  63. k=r[k]+1;
  64. r[i]=k-1;
  65. }
  66. for(i=1;i<=n;i++)
  67. ans[r[i]-l[i]+1]=max(ans[r[i]-l[i]+1],(__int64)Ask_MAX(l[i],r[i])*s[i]);
  68. for(i=n-1;i>0;i--)
  69. ans[i]=max(ans[i+1],ans[i]);
  70. for(i=1;i<=n;i++)
  71. printf("%I64d\n",ans[i]);
  72. }
  73. return 0;
  74. }

 Problem 1003 瞬间移动

Accept: 0    Submit: 0
Time Limit: 4000/2000 mSec(Java/Others)    Memory Limit : 65536 KB

 Problem Description

有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m列的格子有几种方案,答案对1000000007取模。

 Input

多组测试数据。

两个整数n,m(2≤n,m≤100000)

 Output

一个整数表示答案

 Sample Input

4 5

 Sample Output

10

 Problem Idea

解题思路:除去起点(1,1)和终点(n,m)已经固定,中间能经过的是一个(n-2)*(m-2)的矩阵

然后我们可以在这个矩阵里取0个(就是直接从起点跳到终点)、1个、2个……min(n,m)-2个间接点

而对于取i个间接点,其实就是确定这i个间接点行数与列数有多少种取法

于是,我们得到了组合数公式(假设n<m,此题n,m和m,n结果是一样的,过我们可以交换n,m实现n<m)

组合数的求解我们可以交给Lucas定理,但是这个公式,我们还需要化简,不然计算100000项的组合数还是会超时

为了让式子看起来更简洁,对于输入的n与m,我们预处理-2,即n-=2,m-=2,这样上述式子就变成了

化简

剩下的就是套Lucas模板了,嫌时间长的还可以进行阶乘预处理

题目链接→HDU 5698 瞬间移动

 Source Code

[cpp] view plaincopy print?
  1. /*Sherlock and Watson and Adler*/
  2. #pragma comment(linker, "/STACK:1024000000,1024000000")
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #include<queue>
  7. #include<stack>
  8. #include<math.h>
  9. #include<vector>
  10. #include<map>
  11. #include<set>
  12. #include<cmath>
  13. #include<complex>
  14. #include<string>
  15. #include<algorithm>
  16. #include<iostream>
  17. #define exp 1e-10
  18. using namespace std;
  19. const int N = 100005;
  20. const int M = 100;
  21. const int inf = 1600000000;
  22. const int p = 1000000007;
  23. typedef long long LL;
  24. LL quick_mod(LL a, LL b)
  25. {
  26. LL ans = 1;
  27. a %= p;
  28. while(b)
  29. {
  30. if(b & 1)
  31. {
  32. ans = ans * a % p;
  33. b--;
  34. }
  35. b >>= 1;
  36. a = a * a % p;
  37. }
  38. return ans;
  39. }
  40. LL C(LL n, LL m)
  41. {
  42. if(m > n) return 0;
  43. LL ans = 1;
  44. for(int i=1; i<=m; i++)
  45. {
  46. LL a = (n + i - m) % p;
  47. LL b = i % p;
  48. ans = ans * (a * quick_mod(b, p-2) % p) % p;
  49. }
  50. return ans;
  51. }
  52. LL Lucas(LL n, LL m)
  53. {
  54. if(m == 0) return 1;
  55. return C(n % p, m % p) * Lucas(n / p, m / p) % p;
  56. }
  57. int main()
  58. {
  59. __int64 n,m;
  60. int i;
  61. while(~scanf("%I64d%I64d",&n,&m))
  62. {
  63. n-=2,m-=2;
  64. if(n>m)
  65. swap(n,m);
  66. printf("%I64d\n",Lucas(m+n,n));
  67. }
  68. return 0;
  69. }
[cpp] view plaincopy print?
  1. /*Sherlock and Watson and Adler*/
  2. #pragma comment(linker, "/STACK:1024000000,1024000000")
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #include<queue>
  7. #include<stack>
  8. #include<math.h>
  9. #include<vector>
  10. #include<map>
  11. #include<set>
  12. #include<cmath>
  13. #include<complex>
  14. #include<string>
  15. #include<algorithm>
  16. #include<iostream>
  17. #define exp 1e-10
  18. using namespace std;
  19. const int N = 200005;
  20. const int M = 40;
  21. const int inf = 100000000;
  22. const int mod = 1000000007;
  23. __int64 fac[N];
  24. void init()//阶乘预处理
  25. {
  26. fac[0]=1;
  27. for(int i=1;i<=N;i++)
  28. fac[i]=i*fac[i-1]%mod;
  29. }
  30. __int64 pow_mod(__int64 a,__int64 b)
  31. {
  32. __int64 s=1;
  33. a=a%mod;
  34. while(b)
  35. {
  36. if(b&1)
  37. s=s*a%mod;
  38. a=a*a%mod;
  39. b>>=1;
  40. }
  41. return s;
  42. }
  43. __int64 C(int n,int m)
  44. {
  45. if(n==0||m==0)
  46. return 1;
  47. return  fac[n]*pow_mod(fac[m]*fac[n-m]%mod,mod-2)%mod;
  48. }
  49. int main()
  50. {
  51. int n,m;
  52. init();
  53. while(~scanf("%d%d",&n,&m))
  54. {
  55. n-=2;m-=2;
  56. printf("%I64d\n",C(m+n,min(n,m))%mod);
  57. }
  58. return 0;
  59. }

 Problem 1005 区间交

Accept: 0    Submit: 0
Time Limit: 8000/4000 mSec(Java/Others)    Memory Limit : 65536 KB

 Problem Description

 Input

 Output

一行表示答案

 Sample Input

5 2 3
1 2 3 4 6
4 5
2 5
1 4

 Sample Output

10

 Problem Idea

解题思路:此题的做法有很多种,不过有种利用STL来解的做法,我觉得挺巧妙的

首先利用vector将区间分组,将所有具有公共左端点的区间划分成一组,比如[3,7],[3,11],[3,4]等,这些都是一组的

接下来就是利用multiset来进行模拟了(顺带提一句,这里不能用set,而用multiset,是因为set无法存储重复相同的数)

对于当前所在位置i,将所有以i作为左端点的区间右端点值插入multiset(multiset内的数默认从小到大排列)中

若multiset的大小超过了k,那我就删除multiset内最小的值直到小于等于k(之所以删除最小的值,是因为在左端点固定的情况下,右端点越小,会使得区间交的位置数越少)

当且仅当multiset大小恰好等于k,且multiset中当前最小的右端点值≥i时,我们找到了一种符合题目要求的区间取法,于是我们更新答案

当然,在开始的时候,我们需要预处理前n项和sum[n]

题目链接→HDU 5700 区间交

 Source Code

[cpp] view plaincopy print?
  1. /*Sherlock and Watson and Adler*/
  2. #pragma comment(linker, "/STACK:1024000000,1024000000")
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #include<queue>
  7. #include<stack>
  8. #include<math.h>
  9. #include<vector>
  10. #include<map>
  11. #include<set>
  12. #include<cmath>
  13. #include<complex>
  14. #include<string>
  15. #include<algorithm>
  16. #include<iostream>
  17. #define exp 1e-10
  18. #define bitnum(a) __builtin_popcount(a)
  19. using namespace std;
  20. const int N = 100005;
  21. const int M = 10;
  22. const int inf = 1600000000;
  23. const int mod = 2009;
  24. __int64 sum[N],ans;
  25. multiset<int> s;
  26. vector<int> v[N];
  27. int main()
  28. {
  29. int n,k,m,i,j,l,r;
  30. while(~scanf("%d%d%d",&n,&k,&m))
  31. {
  32. s.clear();ans=0;
  33. for(i=1;i<=n;i++)
  34. {
  35. scanf("%I64d",&sum[i]);
  36. sum[i]+=sum[i-1];
  37. v[i].clear();
  38. }
  39. for(i=0;i<m;i++)
  40. {
  41. scanf("%d%d",&l,&r);
  42. v[l].push_back(r);
  43. }
  44. for(i=1;i<=n;i++)
  45. {
  46. for(j=0;j<v[i].size();j++)
  47. s.insert(v[i][j]);
  48. while(s.size()>k)
  49. s.erase(s.begin());
  50. if(s.size()==k&&*s.begin()>=i)
  51. ans=max(ans,sum[*s.begin()]-sum[i-1]);
  52. }
  53. printf("%I64d\n",ans);
  54. }
  55. return 0;
  56. }

 Problem 1006 中位数计数

Accept: 0    Submit: 0
Time Limit: 12000/6000 mSec(Java/Others)    Memory Limit : 65536 KB

 Problem Description

中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。

现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数。

 Input

多组测试数据

第一行一个数n(n≤8000)

第二行n个数,0≤每个数≤

 Output

N个数,依次表示第i个数在多少包含其的区间中是中位数。

 Sample Input

5
1 2 3 4 5

 Sample Output

1 2 3 2 1

 Problem Idea

解题思路:很显然,此题O(n^2logn)的暴力做法必然会TLE,所以我们要想办法做到O(n^2)的复杂度

首先对于第i个数,我们从i-1个数开始递减,分别与第i个数进行比较,假设比第i个数大的数的个数即为l,比第i个数小的数的个数即为r,dp[l-r=k]则为[比第i个数的数的个数]比[比第i个数的数的个数]多k个的区间个数,那要保证第i个数是区间内的中位数,我只需要在第i个数的右边找有多少个[比第i个数的数的个数]比[比第i个数的数的个数]多k个的区间,这样两个区间连接起来,正好[比第i个数的数的个数]与[比第i个数的数的个数]一样多,这样,第i个数就是此区间内的中位数

另外,因为数组下标必须为非负整数,故把数组的中心点移至8000,即dp[8000+k],这样就保证了下标一定是符合要求的

题目链接→HDU 5701 中位数计数

 Source Code

[cpp] view plaincopy print?
  1. /*Sherlock and Watson and Adler*/
  2. #pragma comment(linker, "/STACK:1024000000,1024000000")
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #include<queue>
  7. #include<stack>
  8. #include<math.h>
  9. #include<vector>
  10. #include<map>
  11. #include<set>
  12. #include<cmath>
  13. #include<complex>
  14. #include<string>
  15. #include<algorithm>
  16. #include<iostream>
  17. #define exp 1e-10
  18. using namespace std;
  19. const int N = 8005;
  20. const int M = 8000;
  21. const int inf = 100000000;
  22. const int mod = 1000000007;
  23. int s[N],dp[2*N];
  24. int main()
  25. {
  26. int n,i,j,k,ans;
  27. while(~scanf("%d",&n))
  28. {
  29. for(i=0;i<n;i++)
  30. scanf("%d",&s[i]);
  31. for(i=0;i<n;i++)
  32. {
  33. memset(dp,0,sizeof(dp));
  34. dp[M]=1;
  35. for(k=0,j=i-1;j>=0;j--)
  36. {
  37. if(s[j]>s[i])
  38. k++;
  39. else
  40. k--;
  41. dp[M+k]++;
  42. }
  43. for(ans=dp[M],k=0,j=i+1;j<n;j++)
  44. {
  45. if(s[j]>s[i])
  46. k++;
  47. else
  48. k--;
  49. ans+=dp[M-k];
  50. }
  51. printf("%d%c",ans,i!=n-1?' ':'\n');
  52. }
  53. }
  54. return 0;
  55. }

菜鸟成长记

2016百度之星 - 初赛(Astar Round2B)解题报告相关推荐

  1. 2014百度之星初赛第一轮解题报告:information

    Information 时间限制: 1s 内存限制: 65536K 问题描述 军情紧急,我们需要立刻开发出一个程序去处理前线侦察兵发回的情报,并做出相应的分析.现在由你负责其中的一个子模块,你需要根据 ...

  2. 2016百度之星 - 初赛(Astar Round2A)解题报告

    此文章可以使用目录功能哟↑(点击上方[+]) 有点智商捉急,第一题卡了好久,看来不服老,不服笨是不行的了...以下是本人目前的题解,有什么疑问欢迎提出 链接→2016"百度之星" ...

  3. 2016百度之星 - 初赛(Astar Round2B)1001 1003~1006

    1001 区间的价值 Problem Description 我们定义"区间的价值"为一段区间的最大值*最小值.一个区间左端点在LL,右端点在RR,那么该区间的长度为(R-L+1) ...

  4. 2016百度之星 初赛(Astar Round2B) 1001 区间的价值

    题意:我们定义"区间的价值"为一段区间的最大值*最小值. 一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1). 现在聪明的杰西想要知道,对于长度为k的区间,最大价值的 ...

  5. 2016百度之星 - 初赛(Astar Round2A)Gym Class(拓扑排序)

    Gym Class  Accepts: 849  Submissions: 4247  Time Limit: 6000/1000 MS (Java/Others)  Memory Limit: 65 ...

  6. [2016百度之星 - 初赛(Astar Round2A)]Snacks

    Pro QwQ Sol 其实就是求以x为根的子树到0点的距离最大值.用dfs序把每一个结点对应的子树区间和到0点的距离求出来,挂到线段树上,修改的时候直接在线段树上修改整个区间即可. (不太详细,待更 ...

  7. 【百度之星2020】Mosquito 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6749 (占个坑,有空再更新题解) Dinic: #include<cstdio> #inc ...

  8. 2016百度之星总结帖

    2016百度之星总结帖 测试赛 选的2015资格赛的部分题目,第二题字符串处理,第三题map计数 1001 大搬家 f f (x) = x 两次置换后回到原位 dp a->b && ...

  9. 2016百度之星复赛 1003 拍照 优先队列

    2016"百度之星" - 复赛(Astar Round3) Ended  2016-05-29 14:00:00 - 2016-05-29 17:00:00 Current Tim ...

最新文章

  1. 论坛报名 | 与联合国、世卫组织等专家共话人工智能伦理与可持续发展
  2. python为mysql设置id自增长_postgresql如何设置id自增长
  3. 飞秋爱好者(WZ132)
  4. Spring : Spring 切入点(Pointcut)
  5. 计算机网络概念,组成,功能和分类
  6. XCL-Charts圈图
  7. python语言翻译成汇编语言_计原 || 1计算机语言发展与计算机层次结构
  8. jdk1.8下载安装教程
  9. 动圈耳机振膜_不起眼却影响音质,揭秘耳机振膜的真相
  10. 为什么说HHKB是程序员最好的键盘?
  11. 【错误记录】Google Play 上架报错 ( 对于在 APK 中使用该权限的应用,您必须设置隐私权政策 | 生成并托管 隐私政策 )
  12. Linux用户登录和注销
  13. Android SELinux开发入门指南之如何增加Native Binder Service权限
  14. sql(Mysql)查询出时间数据在显示时加上时区
  15. java编程的一个猜数字有趣小游戏
  16. 我想转行程序员,上个编程培训班,能找到工作吗?我可以自学吗?
  17. Android Launcher分析和修改1——Launcher默认界面配置(default_workspace)
  18. 学习笔记——频率调制光谱(FMS)技术
  19. 2023ACP世界大赛教育者论坛:让职业教育直面AI机遇与挑战
  20. excel添加删除线

热门文章

  1. Linux文件实时同步--inotify + rsync + pyinotify
  2. vue中使用mockjs
  3. Android Wear开发 - 数据通讯 - 第二节 : 数据的发送与接收
  4. Android 开发第四弹:围住神经猫(简单Demo)
  5. Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的行数并保存日志文件...
  6. 如何让ssh登录时不提示是否要添加HostKey
  7. Sublime Text 新建文件的模版插件: SublimeTmpl
  8. 关于UseSubmitBehavior和OnClientClick同时使用,导致无法触发后台事件的问题
  9. 视频分享:编码与代码评审-质量与现实的最激烈冲突点(完整版)
  10. Docker 容器技术 — Swarm 集群