GTY's gay friends
题意:给n个数和m次查询;(1<n,m<1000,000);之后输入n个数值(1 <= ai <= n);问下面m次查询[L,R]中是否存在1~R-L+1的序列;
Sample Input
8 5
2 1 3 4 5 2 3 1
1 3
1 1
2 2
4 8
1 5
3 2
1 1 1
1 1
1 2
Sample Output
YES
NO
YES
YES
YES
YES
NO
分析:问区间是否存在1~R-L+1的排列;注意里面没有一个数相同,并且还都在[1,R-L+1]的区间内;可以等价 每个数前面出现的最大标号一定要小于L(保证了不重复);其次输入的区间和要与结果的和相等;这样就确定了是在这个区间;
利用线段树维护区间pre[](每个点前面出现的最大标号)的最大值;着重理解里面的rt与区间的关系即可;
ps:这道题有更好的算法,使用线段树基本上都 2000+,我的代码2574MS 25448K AC状态很不满意啊!!
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define inf 0x3f3f3f3f #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1|1 typedef __int64 ll; template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+'0'); } const int MAXN = 1e6+10; int id[MAXN],mx[MAXN<<2],pre[MAXN]; ll sum[MAXN]; void pushup(int rt) { mx[rt] = max(mx[rt<<1],mx[rt<<1|1]); } void build(int l,int r,int rt) { if(l == r){ mx[rt] = pre[l]; return ; } int m = l + r >> 1; build(lson); build(rson); pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L <= l && r <= R){ return mx[rt]; } int m = l + r >> 1,ret = 0; if(L <= m) ret = max(ret,query(L,R,lson)); if(R > m) ret = max(ret,query(L,R,rson)); return ret; } int main() { int n,m; while(scanf("%d%d",&n,&m) == 2){ int x; fill(id,id+n+1,0); rep1(i,1,n){ sum[i] = 0; read1(x); sum[i] += sum[i-1] + x; pre[i] = id[x]; id[x] = i; } build(1,n,1); int a,b; rep0(i,0,m){ read2(a,b); int len = b-a+1; ll sm = (len+1)*len/2; if(sm != sum[b] - sum[a-1]) puts("NO"); else{ int ret = query(a,b,1,n,1); //out(ret); puts(ret < a?"YES":"NO"); } } } return 0; }