zoukankan      html  css  js  c++  java
  • bzoj3956: Count(主席树+单调栈)

    bzoj3956: Count(主席树+单调栈)

    bzoj3956: Count

    思路

    对友好点对建边的话,可以看出最多只有2n条边,先用单调栈使所有左端点记录右端点,然后对左端点前缀建权值主席树,查询的时候只要判断T[r] - T[l-1] 这颗主席树中有多少点在[l,r]这段区间就行了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    #define dd(x) cout<<#x<<"="<<x<<" "
    #define rep(i,a,b) for(int i=(a);i<(b);i++)
    #define de(x) cout<<#x<<"="<<x<<"
    "
    #define mes(p) memset(p,0,sizeof(p))
    #define fi first
    #define se second
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define sz(x) (int)x.size()
    #define pb push_back
    #define ls (rt<<1)
    #define rs (ls|1)
    #define all(x) x.begin(),x.end()
    const int maxn=300005;
    typedef long long ll;
    typedef vector <int > vi;
    typedef pair <int, int> pi;
    int n, m, ty, a[maxn], T[maxn], cnt;
    struct node{
        int sum, l,r;
        node() {sum=l=r=0;}
    }t[maxn<<6]; 
    vector <int > v[maxn];
    void update(int pre,int &now,int l,int r,int pos){
        now = ++cnt ;
        t[now].sum= t[pre].sum+1;
        if(l==r) return ;
        t[now].l= t[pre].l;
        t[now].r= t[pre].r;
        int mid =l+ r >> 1;
        if(pos <= mid ) update(t[pre].l,t[now].l,l,mid,pos);
        else update(t[pre].r,t[now].r,mid+1,r,pos);
    }
    int qr(int x,int y,int l,int r,int xx,int yy){
        if(l>=xx &&  r<=yy){
            return t[y].sum-t[x].sum;
        }
        int mid = l+r>>1, s=0;
        if(xx<=mid) s+=qr(t[x].l,t[y].l,l,mid,xx,yy);
        if(mid<yy) s+= qr(t[x].r,t[y].r,mid+1,r,xx,yy);
        return s;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&ty);
        rep(i,1,n+1) scanf("%d",&a[i]);
        stack< int > s;
        rep(i,1,n+1){
            while(sz(s) &&a[s.top()] <= a[i]) {
                v[s.top()].pb(i);
                s.pop();
            }
            s.push(i);
        }
        while(sz(s)) s.pop();
        for(int i=n;i>0;i--){
            while(sz(s)&& a[s.top()] <= a[i]){
                v[i].pb(s.top());
                s.pop();
            }
            s.push(i);
        }
        rep(i,1,n+1){
            T[i] = T[i-1];
            sort(all(v[i]));
            rep(j,0,sz(v[i]))
            if(!j || v[i][j]!=v[i][j-1])
                update(T[i],T[i],1,n,v[i][j]);
        }
        int last =0 ;
        while(m--){
            int x, y;
            scanf("%d%d",&x,&y);
            if(ty) x=(x+last-1)%n + 1 , y =(y+last-1)%n+1;
            int l = min(x,y);
            y=x+y-l;
            x=l;
            last = qr(T[x-1],T[y],1,n,x,y);
            printf("%d
    ",last);
        }
        return 0;
    }
    
  • 相关阅读:
    Spring事务(三)事务增强器
    Spring事务(二)事务自定义标签
    Spring事务(一)JDBC方式下的事务使用示例
    Spring整合MyBatis(五)MapperScannerConfigurer
    Spring整合MyBatis(四)MapperFactoryBean 的创建
    BOS物流管理系统-第五天
    BOS物流管理系统-第一天
    SSM
    【剑指offer】翻转单词顺序,C++实现
    【特征选择】嵌入式特征选择法
  • 原文地址:https://www.cnblogs.com/seast90/p/10836115.html
Copyright © 2011-2022 走看看