Problem C
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 113 Accepted Submission(s) : 14
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.
Output
Output just according to said.
Sample Input
5 1 2 3 4 5 3 Q R 1 3 Q
Sample Output
10 8
题意:
共n个数,m次操作,Q表示询问n个数有多少顺序数,R a,b表示区间[a,b]中的数转动一下(a+1~b每个数向前移动,a位置的数到b位置).
思路:
如果每询问一次就求一次顺序数很费时间,先求出最初的顺序数ans,每转动一次时如果a+1~b位置的数大于a位置的数,ans--,如果小于a,ans++,那么就用到了数状数组求逆序数
代码:
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<vector>
#define maxn 10005
#define M 3000010
#define ll long long
using namespace std;
int tree[maxn];
int num[M];
int lowbit(int x){
return x&-x;
}
void update(int i,int v) {
while(i<maxn) {
tree[i]+=v;
i+=lowbit(i);
}
}
ll getsum(int i) {
ll s=0;
while(i>0) {
s+=tree[i];
i-=lowbit(i);
}
return s;
}
int main() {
int n,m;
int i,j;
int x,y;
char str[10];
ios::sync_with_stdio(false);
while(cin>>n){
ll ans=0;
memset(tree,0,sizeof(tree));
for(i=0;i<n;i++){
cin>>num[i];
ans+=getsum(num[i]-1);//nixushu
update(num[i],1);
}
cin>>m;
while(m--){
cin>>str;
if(str[0]=='Q'){
cout<<ans<<endl;
}
else{
cin>>x>>y;
int s=num[x];
for(i=x;i<y;i++){
num[i]=num[i+1];
if(s<num[i]){
ans--;
}
if(s>num[i]){
ans++;
}
}
num[y]=s;
}
}
}
return 0;
}