hdu_2688_Rotate(樹狀數組)

題目連接:hdu_2688_Rotate

題意:給你n數,(n<=3e6),有兩個操作,Q爲 當前有多少對數,滿足嚴格遞增,R l,r爲旋轉l,r這個區間的數

題解:求嚴格遞增的順序對我們可以反向用樹狀數組求逆序對,300W的數據還是有點夠嗆,不過這裏求出來也就nlogn,然後對於旋轉操作,因爲區間大小不超過1000,我們只需統計該區間的第一個數和後面的數的關係,如果第一個數比後面的數大,就ans++,如果小於就ans--,等於就不管,因爲是嚴格遞增,然後就是這裏我加入讀入優化,感覺還是沒什麼卵用,反而比不加快,可能我寫的優化不行吧。這題卡常數卡的有點緊,要注意常數優化,還有就是HDOJ的穩定性不是很好,同一個代碼有時能過,有時不能過

#include<cstdio>
#include<cstring>
#define F(i,a,b) for(int i=a;i<=b;++i)
typedef long long LL;
int sum[10010],a[3000010];char op[2];

inline void add(int x,int c){while(x<=10000)sum[x]+=c,x+=x&-x;}
inline int ask(int x){int ans=0;while(x>0)ans+=sum[x],x-=x&-x;return ans;}

int main(){
    int n,m;
    while(~scanf("%d",&n)){
        memset(sum,0,sizeof(sum));
        LL ans=0;
        F(i,0,n-1)scanf("%d",&a[i]),ans+=ask(a[i]-1),add(a[i],1);
        scanf("%d",&m);
        F(i,1,m){
            scanf("%s",op);
            if(op[0]=='Q')printf("%I64d\n",ans);
            else{
                int l,r;
                scanf("%d%d",&l,&r);
                int now=a[l];
                F(i,l+1,r){
                    if(a[i]>now)ans--;
                    else if(a[i]<now)ans++;
                    a[i-1]=a[i];
                }
                a[r]=now;
            }
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章