jzoj6801-NOIP2020.9.19模拟patrick【树状数组】
生活随笔
收集整理的這篇文章主要介紹了
jzoj6801-NOIP2020.9.19模拟patrick【树状数组】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
nnn個連續的數,第iii個為hih_ihi?。有操作
解題思路
考慮計算連通塊尾的數量,我們可以發現一個位置作為聯通塊尾部當且僅當hi≥Hh_i\geq Hhi?≥H且hi+1<Hh_{i+1}<Hhi+1?<H。
也就是如果hi+1>hih_{i+1}>h_ihi+1?>hi?,那hih_ihi?能作為尾部的情況當且僅當H∈[hi+1+1,hi]H\in[h_{i+1}+1,h_i]H∈[hi+1?+1,hi?]。用樹狀數組維護每個位置的貢獻區間即可。
時間復雜度O((n+q)log?n)O(\ (n+q)\ \log n)O(?(n+q)?logn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) using namespace std; const int N=2e6+10,S=2e6+1; int n,m,t[N],a[N]; void Change(int x,int w){x++;while(x<S){t[x]+=w;x+=lowbit(x);}return; } int Ask(int x){int ans=0;x++;while(x){ans+=t[x];x-=lowbit(x);}return ans; } int main() {freopen("patrick.in","r",stdin);freopen("patrick.out","w",stdout);scanf("%d%d",&n,&m);a[n+1]=0;for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=0;i<=n;i++)if(a[i]>a[i+1]){Change(a[i+1],1);Change(a[i],-1);}int last=0;for(int i=1;i<=m;i++){char op[5];int x,y;scanf("%s",op);if(op[0]=='Q'){scanf("%d",&x);x^=last;x--;printf("%d\n",last=Ask(x));}else{scanf("%d%d",&x,&y);x^=last;y^=last; if(a[x-1]>a[x])Change(a[x],-1),Change(a[x-1],1);if(a[x]>a[x+1])Change(a[x],1),Change(a[x+1],-1);a[x]=y;if(a[x-1]>a[x])Change(a[x],1),Change(a[x-1],-1);if(a[x]>a[x+1])Change(a[x],-1),Change(a[x+1],1);}} }總結
以上是生活随笔為你收集整理的jzoj6801-NOIP2020.9.19模拟patrick【树状数组】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你知道该如何选购户外电源吗如何购买电脑电
- 下一篇: 如何防止睡着如何防止电脑睡眠