题目
分析
树状数组求解逆序对,至于后面的反转区间,通过化解公式可知与(R-L+1)*(R-L)/2的奇偶有关
先求解总的逆序对,求法很多我用的数组数组,通过求出顺序对,然后和总序对相减求出总的逆序对。
反转区间,可以看出它不影响反转区间之外的逆序对,只会影响内部。
通过公式 总序对=逆序对+顺序对 可知 ,假设此区间左右区间端点为L,R,区间的逆序对为X,而总序对可知为(R-L+1)(R-L)/2)。
如果反转,逆序对变为(R-L+1)(R-L)/2)-X.与之前逆序对数相差(R-L+1)(R-L)/2)-2X。然后看本题只考虑反转之后总的逆序对数的奇偶性,可知相差的2*X对答案不影响,有影响的只有 (R-L+1)(R-L)/2。
PS:此题需要加下快读快输
代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class 兔子的逆序对 {
static int n;
static long ans,su;
static int nod[];
public static void main(String[] args) {
n=sc.nextInt();nod=new int[n+1];
ans=(long)n*(n-1)/2;su=0;
int x;
for (int i =1; i <=n; i++) {
x=sc.nextInt();
su+=query(x);update(x);//先查询这个数能产生的顺序对数量,然后放入数组中
}
ans-=su;ans%=2;//得到逆序对数,后面只考虑奇偶性了
int m=sc.nextInt();
int l,r;
for (int i =1; i <=m; i++) {
l=sc.nextInt();r=sc.nextInt();
ans+=(r-l+1)*(r-l)/2;
if((ans=ans%2)==0) {
out.println("like");
}else {
out.println("dislike");
}
}
out.flush();
}
//----------------树状数组模板----------------------
public static int lowbit(int x) {
return x&(-x);
}
public static void update(int x) {
for (int i =x; i <=n; i+=lowbit(i)) {
nod[i]+=1;
}
}
public static int query(int x){
int sum=0;
for (int i =x; i>0;i-=lowbit(i)) {
sum+=nod[i];
}
return sum;
}
//-----------------------------------------------------------
static class FastScanner{//用于快速读入大量数据
BufferedReader br;
StringTokenizer st;
public FastScanner(InputStream in) {
br = new BufferedReader(new InputStreamReader(in),16384);
eat("");
}
public void eat(String s) {
st = new StringTokenizer(s);
}
public String nextLine() {
try {
return br.readLine();
} catch (IOException e) {
return null;
}
}
public boolean hasNext() {
while(!st.hasMoreTokens()) {
String s = nextLine();
if(s==null) return false;
eat(s);
}
return true;
}
public String next() {
hasNext();
return st.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
static FastScanner sc = new FastScanner(System.in);//快读
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));//快速输出
}