• hdu 5654 xiaoxin and his watermelon candy 树状数组维护区间唯一元组


    题目链接

    题意:序列长度为n(1<= n <= 200,000)的序列,有Q(<=200,000)次区间查询,问区间[l,r]中有多少个不同的连续递增的三元组

    思路:连续三元组->递推O(n)将第一次出现该三元组的下标记录到树状数组中,并且用一个Next[]来表示递推关系,即同一个三元组下一次出现的位置是Next[x];这很关键,在之后按照左边界处理时(有点像莫队算法),一直递推在l+1左侧重复出现的三元组,为了把该三元组推到出现在[l,r]或者[r+1,..]中,这样不重不漏。

    使用map维护出现的id即可,题目很经典~~

    #include<bits/stdc++.h>
    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 MSi(a) memset(a,0x3f,sizeof(a))
    #define inf 0x3f3f3f3f
    #define lson l, m, rt << 1
    #define rson m+1, r, rt << 1|1
    typedef pair<int,int> PII;
    #define A first
    #define B second
    #define MK make_pair
    typedef __int64 ll;
    typedef unsigned int uint;
    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');
    }
    int T,kase = 1,i,j,k,n,m,l,r;
    #define N 200200
    map<pair<PII,int>,int> mp;
    int a[N],B[N],Next[N],x[N],y[N],o[N],ans[N];
    bool cmp(int a,int b){return x[a] < x[b];}
    #define lowbit(x) (x&(-x))
    void update(int p,int d)
    {
        while(p <= n) B[p] += d,p += lowbit(p);
    }
    int query(int x)
    {
        int ans = 0;
        while(x) ans += B[x],x -= lowbit(x);
        return ans;
    }
    int main()
    {
        //freopen("data.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        read1(T);
        while(T--){
            mp.clear();
            read1(n);
            rep1(i,1,n) B[i] = Next[i] = 0;
            rep1(i,1,n) read1(a[i]);
            rep1(i,3,n){
                if(a[i] >= a[i-1] && a[i-1] >= a[i-2]){
                    int x = mp[MK(MK(a[i],a[i-1]),a[i-2])];
                    if(x == 0) update(i,1);
                    else Next[x] = i;//递推
                    mp[MK(MK(a[i],a[i-1]),a[i-2])] = i;
                }
            }
            read1(m);
            rep0(i,0,m) read2(x[i],y[i]),o[i] = i;
            sort(o,o+m,cmp);
            int p = 1;
            rep0(i,0,m){
                int l = x[o[i]],r = y[o[i]];
                while(p <= l+1){
                    if(Next[p]) update(Next[p],1);//递推到下一个~~
                    p++;
                }
                if(r > l + 1) ans[o[i]] = query(r) - query(l+1);
                else ans[o[i]] = 0;
            }
            rep0(i,0,m){
                printf("%d
    ",ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    layui弹出层:使用icon图标小结
    layui弹出层:使用icon图标小结
    存储过程分页
    .net 更改GridView标题文字
    PHP文件结尾符的问题
    JAVA中使用JSON进行数据传递
    Ubuntu LAMP环境安装
    PHP中使用class_exists判断类是否存在
    NS_ERROR_XPC_BAD_CONVERT_JS: Could not convert JavaScript argument
    Android开发教程 葵花宝典第六层 控件之 Dialog ListView GridView
  • 原文地址:https://www.cnblogs.com/hxer/p/5343445.html
Copyright © 2020-2023  润新知