1. 程式人生 > >hdu-2688 Rotate---樹狀數組+模擬

hdu-2688 Rotate---樹狀數組+模擬

\n 大小 ans 什麽 nlogn 如果 efi log for

題目鏈接:

http://acm.hdu.edu.cn/showproblem.php?pid=2688

題目大意:

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

解題思路:

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

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 #define N 10001
 7 #define ll long long
 8 #define Lowbit(x) ((x)&(-x))
 9 
10 ll C[N];
11 ll num[N*300];
12 int T;
13 
14 
15 void add(ll C[],ll pos,ll num) {
16     while(pos <= N) {//
x最大是N 17 C[pos] += num; 18 pos += Lowbit(pos); 19 } 20 } 21 22 ll Sum(ll C[],ll end) { 23 ll sum = 0; 24 while(end > 0) { 25 sum += C[end]; 26 end -= Lowbit(end); 27 } 28 return sum; 29 } 30 31 int main() { 32 int n, s, t, i, j, T, k; 33 ll ans, tmp;
34 while(~scanf("%d",&T)) { 35 memset(C,0,sizeof(C)); 36 ans = 0; 37 for(i = 0; i < T; i ++) { 38 scanf("%I64d",&num[i]); 39 add(C,num[i],1); 40 ans += Sum(C,num[i] - 1); 41 } 42 scanf("%d",&n); 43 char c[10]; 44 while(n--) { 45 scanf("%s",c); 46 switch(c[0]) { 47 case Q: 48 printf("%I64d\n",ans); 49 break; 50 case R: 51 scanf("%d%d",&s,&t); 52 int v = num[s]; 53 for(i = s; i < t; i++){ 54 num[i] = num[i + 1]; 55 if(v > num[i])ans++; 56 else if(v < num[i])ans--; 57 } 58 num[t] = v; 59 break; 60 } 61 } 62 63 } 64 return 0; 65 }

hdu-2688 Rotate---樹狀數組+模擬