hdu-2688 Rotate---樹狀數組+模擬
阿新 • • 發佈:2018-04-27
\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---樹狀數組+模擬