BZOJ3956: Count

题解:  影魔的弱化版 需要处理等于的情况以及左边第一个最大值和右边第一个最大值与这个位置相邻的情况

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=3e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,m,type,cnt;
int a[MAXN],L[MAXN],R[MAXN],st[MAXN],tot,rt[MAXN];
typedef struct node{
    int l,r,sum;
}node;
node d[MAXN*42];
void update(int &x,int y,int l,int r,int t){
    x=++cnt;d[x]=d[y];d[x].sum++;
    //cout<<l<<" "<<r<<" "<<t<<endl;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(t<=mid)update(d[x].l,d[y].l,l,mid,t);
    else update(d[x].r,d[y].r,mid+1,r,t);
    //cout<<l<<"==="<<r<<" "<<d[x].sum<<endl;
}
int ans;
void querty(int x,int y,int l,int r,int ql,int qr){
    //cout<<l<<" "<<r<<" "<<d[y].sum<<" "<<d[x].sum<<endl;
    if(ql<=l&&r<=qr){ans+=d[y].sum-d[x].sum;return ;}
    int mid=(l+r)>>1;
    if(ql<=mid)querty(d[x].l,d[y].l,l,mid,ql,qr);
    if(qr>mid) querty(d[x].r,d[y].r,mid+1,r,ql,qr);
}
int main(){
    n=read();m=read();type=read();
    inc(i,1,n)a[i]=read();
    inc(i,1,n){
        while(tot&&a[st[tot]]<a[i])tot--;
        if(!tot)L[i]=n+1;else L[i]=st[tot];
        st[++tot]=i;
    }
    tot=0;reverse(a+1,a+n+1);
    inc(i,1,n){
        while(tot&&a[st[tot]]<a[i])tot--;
        if(!tot)R[n+1-i]=0;else R[n+1-i]=n-st[tot]+1;
        st[++tot]=i;
    }
    reverse(a+1,a+n+1);
    inc(i,1,n){
        //cout<<i<<"====="<<endl;
        rt[i]=++cnt;d[rt[i]]=d[rt[i-1]];
        if(R[i]>i+1){update(rt[i],rt[i],1,n,R[i]);}
        if(L[i]<i-1){
            if(a[L[i]]>a[i])update(rt[i],rt[i],1,n,L[i]);
        }
        //cout<<endl;
    }
    //inc(i,1,n)cout<<L[i]<<" "<<R[i]<<endl;
    int l,r,x,y,res=0;
    while(m--){
        l=read();r=read();
        if(type)x=(l+res-1)%n+1,y=(r+res-1)%n+1,l=min(x,y),r=max(x,y);
        ans=0;querty(rt[l-1],rt[r],1,n,l,r);
        //cout<<ans<<endl;
        res=ans+r-l;
        printf("%d\n",res);
    }
}

3956: Count

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 715  Solved: 269
[Submit][Status][Discuss]

Description

 

 

Input

 

 

Output

 

 

Sample Input

3 2 0
2 1 2
1 1
1 3

Sample Output

0
3

HINT

 

M,N<=3*10^5,Ai<=10^9

 

posted @ 2018-10-05 12:49  wang9897  阅读(244)  评论(0编辑  收藏  举报