GFOJ problem64 新年组队 解题报告
来源:互联网 发布:筑业软件 编辑:程序博客网 时间:2024/04/30 14:16
题目:http://www.gdfzoj.com/oj/problem/64
描述:给一个长度为n的数组a[i],和m个区间<l,r>,求<l,r>内最小子区间<i,j>使a[i] == a[j](n,m<5*10^5)
一开始想到 离散化+RMQ,但后来发现RMQ不能像维护区间最值一样用max/min维护该问题
正解是主席树或分块,时限5s,但分块写好的话1s也能过(746ms水过),其他题解写在注释里了
关于块的大小的推理可能不是很严谨,具体还要看不同题目的数据范围.
下面放代码
#include <cstdio>#include <map>#define k(x) ((x-1) / K+1)//x属于分块中的第k(x)块using namespace std;const int N = 500010,K = 150,M = N / K + 10;//K为块的大小 当K=1000时耗时1620ms,K=150时耗时746ms(相信玄学)//M为块数int a[N],f[M][M],nxt[N],pre[N],n,m,i,j,l,r,ans; //f为分块数组 f[i][j]表示第i块到第j块的最小方案//想不到只用next数组的方法,于是nxt[i]表示 a[i]=a[nxt[i]] 且 nxt[i] > i 的最小值//pre[i]表示 a[pre[i]]=a[i] 且 pre[i] < i 的最大值map <int,int> q;//偷懒用 map 离散化inline int min(int a,int b) {if (!a) return b;if (!b) return a;return (a < b) ? a : b;} //求a,b的最小值,特判a==0 b==0int main() {scanf("%d%d",&n,&m);for (i=1;i<=n;i++) {scanf("%d",a+i);j = q[a[i]];if (j) {nxt[j] = i; pre[i] = j;f[k(j)][k(i)] = min(f[k(j)][k(i)],i-j);} q[a[i]] = i;} //一个简单的用 map 实现的离散化 复杂度约 O(n log n)for (i=1;i<n/K+1;i++) for (j=1;i+j<n/K+1;j++) {f[i][i+j] = min(f[i][i+j-1],f[i][i+j]);f[i][i+j] = min(f[i][i+j],f[i+1][i+j]);} //i为区间长度,j为起始位置,一个预处理//f[i][i+j] = min(f[i][i+j],f[i+1][i+j],f[i][i+j+i])//复杂度 O(n²/k²)while (m--) {scanf("%d%d",&l,&r);l ^= ans; r ^= ans;ans = f[k(l)+1][k(r)-1];//块内最小答案 O(1)for (i=l;i<k(l) * K && i<=r;i++)if (nxt[i] <= r && nxt[i]) ans = min(ans,nxt[i] - i);l = i - 1;for (i=r;i>(k(r)-1) * K && i>=l;i--)if (pre[i] >= l) ans = min(ans,i - pre[i]);//暴力枚举块外答案(pre和nxt的作用) 复杂度 O(2k)if (!ans) ans = -1;printf("%d\n",ans);}//综上,时间复杂度约 O(n log n + n²/k² + 2mk)//代入n=m=500000,k≈540。但n,m<500000,因此k取约150-400是有一定道理的。}
0 0
- GFOJ problem64 新年组队 解题报告
- GFOJ problem468 出去玩 解题报告
- GFOJ problem 470: [HbFS-]Red is good 解题报告
- CUGBACM_Summer_Tranning 组队赛解题报告
- GDFZOJ Problem64新年团队 题解
- P1072新年趣事之债务解题报告
- oj_64 新年组队
- 作业1:新年组队
- 组队赛3解题报告:精度与二进制枚举
- 第三周组队训练赛-长沙现场赛解题报告
- nefu《2015综合训练9组队赛》解题报告
- nefu2015综合训练9组队赛解题报告
- SDUT - 2017年寒假集训 阶段测试赛3(组队) -- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- pyhthon 利用爬虫结合阿里大于短信接口实现短信发送天气预报
- FormData实现上传多图片,学习使用FormData
- 蒟蒻的第一篇博客
- Linux进程间通信——信号量
- 安卓NDK开发
- GFOJ problem64 新年组队 解题报告
- Java并发的四种风味:Thread、Executor、ForkJoin和Actor
- 《灵魂的事-节选》(史铁生)
- 五,ES6为数值做的一些扩展
- 二进制不同位数
- Programming Assignment 2: Deques and Randomized Queues
- 编程之法—实现单词翻转
- EasyIPCamera实现Windows PC桌面、安卓Android桌面同屏直播,助力无纸化会议系统
- Struts2 ---拦截器的理解