HDOJ 2688 HDU 2688 Rotate ACM 2688 IN HDU

6695 ワード

MiYuオリジナル、転帖は明記してください:転載は______________白い家 から
タイトルアドレス:
http://acm.hdu.edu.cn/showproblem.php?pid=2688
タイトルの説明:
RotateTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 250    Accepted Submission(s): 68
Problem Description
Recently yifenfei face such a problem that give you millions of positive integers,tell how many pairs i and j that satisfy F[i] smaller than F[j] strictly when i is smaller than j strictly. i and j is the serial number in the interger sequence. Of course, the problem is not over, the initial interger sequence will change all the time. Changing format is like this [S E] (abs(E-S)<=1000) that mean between the S and E of the sequece will Rotate one times.
For example initial sequence is 1 2 3 4 5.
If changing format is [1 3], than the sequence will be 1 3 4 2 5 because the first sequence is base from 0.
 
Input
The input contains multiple test cases.
Each case first given a integer n standing the length of integer sequence (2<=n<=3000000) 
Second a line with n integers standing F[i](0Third a line with one integer m (m < 10000)
Than m lines quiry, first give the type of quiry. A character C, if C is ‘R’ than give the changing format, if C equal to ‘Q’, just put the numbers of satisfy pairs.
 
Output
Output just according to said.
 
Sample Input

        
          
5 1 2 3 4 5 3 Q R 1 3 Q

 
Sample Output

        
          
10 8

 
暴力であれば、一度も更新しないで計算し直すと、時間的な費用が非常に大きくなります.データを解析すると、回転するとき、最初の数を除いて、他の数の対数の数値がこの数に関係していることがわかるので、まず全体の対数sumを算出し、回転するときの各数と最初の数の大きさを比較してsumを更新すればよい.コードは次のとおりです.


コード#コード#
/*
MiYuオリジナル、転帖は明記してください:転載は_______白い家
http://www.cnblog.com/MiYu
Author By : MiYuTest      : 1Program   : 2688
*/
#include 
<
iostream
>
#include 
<
algorithm
>
using
 
namespace
 std;
const
 
int
 MAX 
=
 
10000
;
int
 nCount 
=
 
0
, N, M, x , y;
int
 com[MAX 
+
 
1
], num[
300
 
*
 MAX 
+
 
1
]; 
long
 
long
 sum 
=
 
0

char
 ask[
5
];inline 
int
 low ( 
int
 x ) {       
return
 x 
&
 ( 
-
x );}
void
 modify ( 
int
 x, 
int
 val ){     
//
変更
     
while
 ( x 
<=
 MAX ){            com[x] 
+=
 val; x 
+=
 low ( x );     }     }
int
 quy ( 
int
 x ){                  
//
検索
    
int
 sum 
=
 
0
;    
while
 ( x 
>
 
0
 ){           sum 
+=
 com[x]; x 
^=
 low ( x );    }    
return
 sum ;}inline 
bool
 scan_d(
int
 
&
num)      
//
入力
{        
char
 
in
;
bool
 IsN
=
false
;        
in
=
getchar();        
if
(
in
==
EOF) 
return
 
false
;        
while
(
in
!=
'
-
'
&&
(
in
<
'
0
'
||
in
>
'
9
'
)) 
in
=
getchar();        
if
(
in
==
'
-
'
){ IsN
=
true
;num
=
0
;}        
else
 num
=
in
-
'
0
'
;        
while
(
in
=
getchar(),
in
>=
'
0
'
&&
in
<=
'
9
'
){                num
*=
10
,num
+=
in
-
'
0
'
;        }        
if
(IsN) num
=-
num;        
return
 
true
;}
int
 main (){    
while
 ( scan_d ( N ) ){           memset ( com, 
0

sizeof
 ( com ) ); sum 
=
 
0
;           
for
 ( 
int
 i 
=
 
0
; i 
<
 N; 
++
 i ){                scan_d ( num[i] ); modify ( num[i], 
1
 );                 sum 
+=
 quy ( num[i] 
-
 
1
 );           }           scan_d ( M );           
while
 ( M 
--
 ){                  scanf ( 
"
%s
"
,ask );  
int
 temp;                   
switch
 ( ask[
0
] ){                          
case
 
'
Q
'
 : cout 
<<
 sum 
<<
 endl; 
break
;                          
case
 
'
R
'
 : scan_d ( x ), scan_d ( y ); temp 
=
 num[x];                                     
while
 ( x 
<
 y ) { num[x] 
=
 num[x
+
1
];                                              num[x] 
>
 temp 
?
 sum 
--
 : num[x] 
==
 temp 
?
: sum
++
 ; x 
++
;                                      }                                      num[y] 
=
 temp; 
break
;                                               }           }    }    
return
 
0
;}