hdu2688 Roate

Rotate
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5038 Accepted Submission(s): 877

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 Fi
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

Author
yifenfei

算了一下后面往后移的复杂度10的7次方,不会超,主要解决的是如何将每个点前面有几个比他小的数在log2n的复杂度下算出来,没想到啊,用哈希的思想,因为f【i】给的范围比较小,完全可以用树状数组做
这题交G++会超时,交c++才能a,比较考常数优化,if用if…else…写,减掉一些不不必要的判断
998ms过的,太险了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
int n;
const int N = 3000005;
int a[N];
int c[10005];
void add(int k)
{
    while(k <= 10000)
    {
        c[k]++;
        k += k&-k;
    }
}
LL read(int k)
{
    LL sum = 0;
    while(k)
    {
        sum += c[k];
        k -= k&-k;
    }
    return sum;
}

int main()
{
    while(~scanf("%d",&n))
    {
        LL ans = 0;
        memset(c,0,sizeof(c));
        for(int i = 0;i < n;++i)
        {
            scanf("%d",&a[i]);
            add(a[i]);
            ans += read(a[i] - 1);
        }
        int m;
        scanf("%d",&m);
        char s[2];
        for(int i = 0;i < m;++i)
        {
            scanf("%s",s);
            if(s[0] == 'Q'){
                printf("%lld\n",ans);
            }
            else{
                int x,y;
                scanf("%d %d",&x,&y);
                int temp = a[x];
                for(int i = x;i < y;++i)
                {
                    a[i] = a[i + 1];
                    //把这里用了if....else...才过的
                    if(a[i] > temp) ans--;
                    else{
                        if(a[i] < temp) ans++;
                    }
                }
                a[y] = temp;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/80486248
hdu