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 MBSubmit: 715 Solved: 269
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 2 0
2 1 2
1 1
1 3
2 1 2
1 1
1 3
Sample Output
0
3
3
HINT
M,N<=3*10^5,Ai<=10^9