HDU5172GTY's gay friends——区间查询(区间内的数互不相同)

http://acm.split.hdu.edu.cn/showproblem.php?pid=5172

官方题解

一个区间是排列只需要区间和为len(len+1)2(len为区间长度),且互不相同,对于第一个问题我们用前缀和解决,对于第二个问题,预处理每个数的上次出现位置,记它为pre,互不相同即区间中pre的最大值小于左端点,使用线段树或Sparse Table即可在O(n)/O(nlogn)的预处理后 O(logn)/O(1)回答每个询问.不过我们还有更简单的hash做法,对于[1..n]中的每一个数随机一个64位无符号整型作为它的hash值,一个集合的hash值为元素的异或和,预处理[1..n]的排列的hash和原序列的前缀hash异或和,就可以做到线性预处理,O(1)回答询问.

前缀和+线段树

1419MS 25360K 1368 B

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=1100000;
using namespace std;
int n,m;
ll c[maxn];
int head[maxn],pre[maxn];
void addnode(int p,int x){
    pre[p]=head[x];
    head[x]=p;
}

int mx[maxn<<2];
void push_up(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);
    push_up(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;
    int vmax=-1;
    if(L<=m) vmax=max(vmax,query(L,R,lson));
    if(m<R) vmax=max(vmax,query(L,R,rson));
    return vmax;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        c[0]=0;
        memset(head,-1,sizeof(head));
        for(int i=1;i<=n;++i){
            scanf("%I64d",&c[i]);
            addnode(i,c[i]);
            c[i]+=c[i-1];
        }
        build(1,n,1);
        int l,r;
        while(m--){
            scanf("%d%d",&l,&r);
            ll ans=c[r]-c[l-1];
            ll len=r-l+1;
            if(ans==len*(len+1)/2&&query(l,r,1,n,1)<l) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

HDU5172GTY's gay friends——区间查询(区间内的数互不相同)

时间: 2024-07-28 16:43:21

HDU5172GTY's gay friends——区间查询(区间内的数互不相同)的相关文章

hdu3709(求区间内平衡数的个数)数位dp

题意:题中平衡数的定义: 以一个位置作为平衡轴,然后左右其他数字本身大小作为重量,到平衡轴的距离作为全职,实现左右平衡(即杠杆原理平衡).然后为区间[x,y]内平衡数的个数. (0 ≤ x ≤ y ≤ 1018) 解法:数位dp.如果一个数的平衡数,那么它的平衡轴位置是确定的.原来一直尝试数位dp在dfs时候列举平衡轴的位置,后来才意识到可以提前枚举平衡轴位置,然后再dfs,这样比较好写.dp[mid][pre][wei];表示对称轴是mid,计算第pre个位置以后需要力矩大小wei的数的个数.

Codeforces Round #271 (Div. 2) F.Ant colony(线段树 + 统计区间内某数的个数)

F. Ant colony Mole is hungry again. He found one ant colony, consisting of n ants, ordered in a row. Each ant i (1 ≤ i ≤ n) has a strength si. In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He c

SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)

DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the

SPOJ DQUERY 区间内不同数的个数 主席树

#include <iostream> #include <map> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 30010,MAXLOG = 20; struct ChairTree { int l,r; int ans; }ct[MAXN*MAXLOG]; int ctRoot[MAXN]; in

【大杀器】利用划分树秒杀区间内第k大的数

最近看了一道题,大概就是给出一个序列,不断询问其子区间内第k大的数,下面是个截图 绕了一圈没找到中文版题目,if(你是大佬) then 去看截图:else{我来解释:给出一个整数n,和一个整数m,分别表示序列元素个数和询问次数,然后输入n个数和m个询问,每个询问包含3个数,分别是区间起止点(l和r)和k,求出区间内第k大的数并输出:}这是一道很简单的模板题,怎么解决呢?小编最初想到的是打暴力,正所谓暴力出奇迹,说不定可以成功,反正不会优化,先试试吧,直接把规定区间[l,r]排一次序了,然后在查找

HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5101    Accepted Submission(s): 2339 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping abilit

HDU-5172-GTY&#39;s gay friends-线段树单点更新

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5172 题意:给出n个数,m个询问,问你[l,r]区间内是否为1到r-l+1的全排列. 大小很容易我们通过记录前缀和很容易求出来,但是关键是去重. 考虑线段树做法,我们记录每个点的靠左最近的相同元素的位置,然后求 整个区间的最大值(即最大的前驱)如果小于l,即满足条件,输出YES. 好吧,其实这个题目我是搜的RMQ算法出来的,因为我想练一下RMQ算法,所以我就看了一下别人的博客,自己也写了一下,结果死

hdu5172---GTY&#39;s gay friends

Problem Description GTY has n gay friends. To manage them conveniently, every morning he ordered all his gay friends to stand in a line. Every gay friend has a characteristic value ai , to express how manly or how girlish he is. You, as GTY's assista

HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s. And you have some query,each time you should calculate f(s[l...r]), s[l