[20200729NOIP提高組模擬T2]學數數——坎坷
阿新 • • 發佈:2020-07-29
古今序列者,長皆矣.今有一序列,其長亦若此,名之曰.世人皆知其連續子序列之數為矣.現有一士,欲取之最大值於各連續子序列也.今用此值,構建新序列.序列,操作之本源也.於是生操作幾許.予君一數,試問新序列中大於/小於/等於k之數有幾何?
solution:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<map> #define R register #define next kdjadskfj #define debug puts("mlg") using namespace std; typedef long long ll; typedef long double ld; typedef unsignedlong long ull; inline ll read(); inline void write(ll x); inline void writeln(ll x); inline void writesp(ll x); ll n,Q; ll a[610000],b[620000]; ll q; ll dat[6100000]; ll type[610000],que[610000]; ll Dat[6100000],used[620000]; ll Count[620000][2]; inline void Update(ll p,ll l,ll r,ll k){ if(l==r){Dat[p]=used[k];return;} ll mid=l+r>>1; if(k<=mid) Update(p<<1,l,mid,k); else Update(p<<1|1,mid+1,r,k); Dat[p]=max(Dat[p<<1],Dat[p<<1|1]); } inline ll Query(ll p,ll l,ll r,ll u,ll v){ if(!Dat[p]||(u<=l&&r<=v)) return Dat[p]; ll mid=l+r>>1,Ans=0; if(u<=mid) Ans=max(Ans,Query(p<<1,l,mid,u,v)); if(v>mid) Ans=max(Ans,Query(p<<1|1,mid+1,r,u,v)); return Ans; } inline void update(ll p,ll l,ll r,ll k,ll val){ if(l==r){dat[p]+=val;return;} ll mid=l+r>>1; if(k<=mid) update(p<<1,l,mid,k,val); else update(p<<1|1,mid+1,r,k,val); dat[p]=dat[p<<1]+dat[p<<1|1]; } inline ll query(ll p,ll l,ll r,ll u,ll v){ if(!dat[p]||(u<=l&&r<=v)) return dat[p]; ll mid=l+r>>1,Ans=0; if(u<=mid) Ans+=query(p<<1,l,mid,u,v); if(v>mid) Ans+=query(p<<1|1,mid+1,r,u,v); return Ans; } inline void solve2(){ for(R ll i=1;i<=n;i++){ Count[i][0]=i-Query(1,1,q,a[i],q)-1; used[a[i]]=i; Update(1,1,q,a[i]); } memset(used,0,sizeof used); memset(Dat,0,sizeof Dat); for(R ll i=n;i>=1;i--){ Count[i][1]=(n-i+1)-Query(1,1,q,a[i]+1,q)-1; used[a[i]]=n-i+1; Update(1,1,q,a[i]); } for(R ll i=1;i<=n;i++){ update(1,1,q,a[i],(Count[i][0]+1)*(Count[i][1]+1)); } } inline void solve1(){ for(R ll i=1;i<=n;i++){ ll maxn=0; for(R ll j=i;j<=n;j++){ maxn=max(maxn,a[j]); update(1,1,q,maxn,1); } } } inline void work(){ for(R ll i=1;i<=Q;i++){ if(type[i]==1){ if(que[i]==q) writeln(0); else writeln(query(1,1,q,que[i]+1,q)); continue; } if(type[i]==2){ writeln(query(1,1,q,que[i],que[i])); continue; } if(type[i]==3){ if(que[i]==1) writeln(0); else writeln(query(1,1,q,1,que[i]-1)); continue; } } } int main(){ freopen("jxthree.in","r",stdin); freopen("jxthree.out","w",stdout); n=read();Q=read(); for(R ll i=1;i<=n;i++) a[i]=b[i]=read(); for(R ll i=1;i<=Q;i++){ char wn=getchar(); while(wn!='>'&&wn!='<'&&wn!='=') wn=getchar(); type[i]=((wn=='>')?1:((wn=='=')?2:3)); b[n+i]=que[i]=read(); } sort(b+1,b+n+Q+1); q=unique(b+1,b+Q+n+1)-b-1; for(R ll i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+q+1,a[i])-b; } for(R ll i=1;i<=Q;i++){ que[i]=lower_bound(b+1,b+q+1,que[i])-b; } solve2(); work(); } inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;} inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');} inline void writesp(ll x){write(x);putchar(' ');} inline void writeln(ll x){write(x);putchar('\n');}