博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2018黑龙江省赛 A Sequence Game 主席树+st表 / 主席树+线段树 / st表+莫队+离散化...
阅读量:5112 次
发布时间:2019-06-13

本文共 6596 字,大约阅读时间需要 21 分钟。

7218: A Sequence Game

时间限制: 1 Sec  内存限制: 128 MB

提交: 128  解决: 32
[] [] [] [命题人:]

题目描述

One day, WNJXYK found a very hard problem on an Online Judge. This problem is so hard that he had been thinking about the solutions for a couple of days. And then he had a surprise that he misunderstood that problem and easily figured out a solution using segment tree. Now he still wonders that solution for the misread problem.

There is a sequence with N positive integers A1,A2,…,An and M queries. Each query will give you an interval [L,R] and require an answer with YES / NO indicates that whether the numbers in this interval are continuous in its integer range. 
Let us assume that the maximal number in an interval is mx and the minimal   number is mi. The numbers in this interval are continuous in its integer range means that each number from mi to mx appears at least once in this interval.

 

输入

The input starts with one line contains exactly one positive integer T which is the number of test cases. And then there are T cases follow.

The first line contains two positive integers n,m which has been explained above.
The second line contains n positive integers A1,A2,…,An.
Then there will be m lines followed. Each line contains to positive numbers Li,Ri indicating that the i th query’s interval is [Li,Ri].

 

输出

For each test case, output m line.

Each of following m lines contains a single string “YES”/ “NO” which is the answer you have got.

 

样例输入

23 33 1 2 2 31 31 25 31 2 2 4 5 1 51 33 3

 

样例输出

YESYESNONOYESYES

 

提示

T=5

1≤n≤100000
1≤Ai≤10^9
1≤m≤100000
The input file is very large, so you are recommend to use scanf() and printf() for IO.

 

来源/分类

 

这道题,比赛时写到头秃

一开始用主席树+st表,结果开大了MLE,开小了RE,几番试探没结果

然后换算法,另一个队友用莫队+st表写,我用主席树+线段树写,然后在比赛结束之前

我一直wa,找不到bug,她先wa再TLE,不知道怎么优化

然后,令人欣zhi喜xi的地方来了,比赛结束不久,她加了离散化就A了,我有个最小值初值赋错了,然后也A了

自闭

题意:给一个长度为n的序列,m次询问,每次求 [ l , r ] 内是否是连续的一串数,最大值到最小值之间的数最少出现一次

思路:解决的公式为 最大值 - 最小值 + 1 是否等于 不同数的个数 

           判断区间内不同数的个数,想到了主席树还有莫队,然后最大最小用st表,后来又想到再建一个线段树维护最大最小

我的代码:

#include 
#include
#include
#include
#include
typedef long long ll;using namespace std;const int MAXN = 1e5 + 7;const int M = MAXN * 100;const int inf=1e9+100;int n, q, tot;int a[MAXN];int T[MAXN], lson[M], rson[M], c[M];int maxx[MAXN << 2], minn[MAXN << 2];void pushup(int rt){ maxx[rt] = max(maxx[rt << 1], maxx[rt << 1 | 1]); minn[rt] = min(minn[rt << 1], minn[rt << 1 | 1]);}void build1(int l, int r, int rt){ if (l == r) { maxx[rt] = a[l]; minn[rt] = a[l]; return; } int mid = (l + r) >> 1; build1(l, mid, rt << 1); build1(mid + 1, r, rt << 1 | 1); pushup(rt);}int querymaxn(int L, int R, int l, int r, int rt){ if (L <= l && R >= r) return maxx[rt]; int mid = (l + r) >> 1; int ret = 0; if (L <= mid) ret = max(ret, querymaxn(L, R, l, mid, rt << 1)); if (R > mid) ret = max(ret, querymaxn(L, R, mid + 1, r, rt << 1 | 1)); return ret;}int queryminn(int L, int R, int l, int r, int rt){ if (L <= l && R >= r) return minn[rt]; int mid = (l + r) >> 1; int ret = 0x3f3f3f3f; if (L <= mid) ret = min(ret, queryminn(L, R, l, mid, rt << 1)); if (R > mid) ret = min(ret, queryminn(L, R, mid + 1, r, rt << 1 | 1)); return ret;}int build(int l, int r) { int root = tot++; c[root] = 0; if (l != r) { int mid = (l + r) >> 1; lson[root] = build(l, mid); rson[root] = build(mid + 1, r); } return root;}int update(int root, int pos, int val) { int newroot = tot++, tmp = newroot; c[newroot] = c[root] + val; int l = 1, r = n; while (l < r) { int mid = (l + r) >> 1; if (pos <= mid) { lson[newroot] = tot++; rson[newroot] = rson[root]; newroot = lson[newroot]; root = lson[root]; r = mid; } else { rson[newroot] = tot++; lson[newroot] = lson[root]; newroot = rson[newroot]; root = rson[root]; l = mid + 1; } c[newroot] = c[root] + val; } return tmp;}int query(int root, int pos) { int ret = 0; int l = 1, r = n; while (pos < r) { int mid = (l + r) >> 1; if (pos <= mid) { r = mid; root = lson[root]; } else { ret += c[lson[root]]; root = rson[root]; l = mid + 1; } } return ret + c[root];}int main() { int t; scanf("%d", &t); while (t--) { memset(maxx, 0, sizeof(maxx)); memset(T, 0, sizeof(T)); memset(lson, 0, sizeof(lson)); memset(rson, 0, sizeof(rson)); memset(c, 0, sizeof(c)); for(int i=0; i<(MAXN<<2); i++){ minn[i]=0x3f3f3f3f; } scanf("%d%d", &n, &q); tot = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } build1(1, n, 1); T[n + 1] = build(1, n); map
mp; for (int i = n; i >= 1; i--) { if (mp.find(a[i]) == mp.end()) { T[i] = update(T[i + 1], i, 1); } else { int tmp = update(T[i + 1], mp[a[i]], -1); T[i] = update(tmp, i, 1); } mp[a[i]] = i; } while (q--) { int l, r; scanf("%d%d", &l, &r); //cout << querymaxn(l, r, 1, n, 1) << endl; //cout << queryminn(l, r, 1, n, 1) << endl; if (querymaxn(l, r, 1, n, 1) - queryminn(l, r, 1, n, 1) + 1 == query(T[l], r)) puts("YES"); else puts("NO"); } } return 0;}

队友莫队的代码:

#include 
const int N=1e5+10;using namespace std;typedef long long ll; int n,m,block;int lg2[N];int a[N],b[N],dmax[N][35],dmin[N][35];int cur=0,cnt[N];struct node{ int l,r,id;}q[N];bool ans[N]; bool cmp(node x,node y){ return x.l/block==y.l/block?x.r
inline void read(T &x){ x=0; char c=getchar(); T f=1; while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ x=x*10+c-'0';c=getchar();} x*=f;}inline void log2(){ lg2[0]=-1; for(int i=1;i
>1]+1;}void get_st(){ for(int j=1;(1<
<=n;j++){ for(int i=1;i-1+(1<
<=n;i++){ dmax[i][j]=max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]); dmin[i][j]=min(dmin[i][j-1],dmin[i+(1<<(j-1))][j-1]); } }}inline int rmq(int l,int r,bool f){ int k=lg2[r+1-l]; if(f) return max(dmax[l][k],dmax[r+1-(1<
q[i].l) add(a[--l]); while(r
q[i].r) del(a[r--]); int maxx=rmq(l,r,1); int minx=rmq(l,r,0); if(maxx+1-minx==cur) ans[q[i].id]=1; else ans[q[i].id]=0; } for(int i=1;i<=m;i++){ if(ans[i]) puts("YES"); else puts("NO"); } } return 0;}

 

转载于:https://www.cnblogs.com/renxiaomiao/p/9642649.html

你可能感兴趣的文章
burp suite 的intruder 四种攻击方式
查看>>
机器学习----人脸对齐的算法-ASM.AAM..CLM.SDM
查看>>
自定义文本选中样式
查看>>
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
查看>>
MySQL 数据库 的安装和基本管理
查看>>
MyEclipse中JavaMail冲突问题
查看>>
四边形面积探索
查看>>
曾有一个人,爱我如生命(2)
查看>>
POJ3264
查看>>
日常记录
查看>>
抽象工厂模式(abstract factory)
查看>>
QueueAPI记录
查看>>
Luogu P1538 迎春舞会之数字舞蹈 | 模拟
查看>>
uva 562
查看>>
Python程序使用pyinstaller打包
查看>>
数组举例
查看>>
【代码笔记】Web-HTML-布局
查看>>
MySql和Oracle数据库区别
查看>>
Nginx配置详解
查看>>
向学,相遇。
查看>>