MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
题目地址:
http://acm.hdu.edu.cn/showproblem.php?pid=2688
题目描述:
Rotate
Time 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.
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](0<F[i]<=10000)
Third 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.
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](0<F[i]<=10000)
Third 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 : MiYu
Test : 1
Program : 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 ;
}
MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
http://www.cnblog.com/MiYu
Author By : MiYu
Test : 1
Program : 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 ;
}