Codeforces Round #340 (Div. 2) E. XOR and Favorite Number(分块 (java))

来源:互联网 发布:同花顺龙虎榜数据 编辑:程序博客网 时间:2024/06/06 02:56

题意:

n个长度的序列, m个询问,一个询问[L, R], 求[L, R]又多少个子区间的xor和为k

 nm and k (1 ≤ n, m ≤ 100 0000 ≤ k ≤ 1 000 000)

思路:

对于原序列的前缀和序列,即询问[L, R] 中有多少对(l, r) Al ^ Ar = k

所以分块容易解决


代码:

import java.util.*;  import java.math.*;  import java.io.*;public class Main {        public static void main(String[] args) {          InputStream inputStream = System.in;          OutputStream outputStream = System.out;          Scanner in = new Scanner(inputStream);          PrintWriter out = new PrintWriter(outputStream);          TaskE solver = new TaskE();          solver.solve(1, in, out);          out.close();      }          static class MyComprator implements Comparator {    public int compare(Object arg0, Object arg1) {    node a = (node)arg0;    node b = (node)arg1;    if(a.id != b.id) return a.id - b.id;    return a.Y - b.Y;    }    }        static node []op;    static int []cnt = new int[3000000];    static int []a;    static int block = (int) Math.sqrt(100000);    static long []res;    static class TaskE {          public void solve(int testNumber, Scanner in, PrintWriter out) {          int n = in.nextInt();        int m = in.nextInt();        int K = in.nextInt();        a = new int[n + 1];        op = new node[m];        res = new long[m];        for(int i = 0; i < m; i ++) op[i] = new node(0, 0, 0);        for(int i = 1; i <= n; i ++) a[i] = in.nextInt();        for(int i = 0; i < m; i ++) {        op[i].X = in.nextInt();        op[i].X --;        op[i].Y = in.nextInt();        op[i].getID();        op[i].ID = i;        }        Arrays.sort(op, new MyComprator());        int curl = 0, curr = 0;        int L = 0, R = -1;        long ans = 0;        for(int i = 0; i < m; i ++) {        while(L < op[i].X) {        curl ^= a[L];        cnt[curl] --;        ans -= cnt[curl ^ K];        L ++;        }        while(L > op[i].X) {        L --;        ans += cnt[curl ^ K];        cnt[curl] ++;        curl ^= a[L];        }        while(R > op[i].Y) {        cnt[curr] --;        ans -= cnt[curr ^ K];        curr ^= a[R];        R --;        }        while(R < op[i].Y) {        R ++;        curr ^= a[R];                 ans += cnt[curr ^ K];        cnt[curr] ++;        }        res[op[i].ID] = ans;        }                for(int i = 0; i < m; i ++) out.println(res[i]);        }      }      static class node {    int X, Y;    int id, ID;    node(int X, int Y, int Z) {    this.X = X;    this.Y = Y;    this.id = Z;    }    public void getID() {    this.id = X / block;    }    }    static class pii implements Comparable<pii> {          int X, Y;          pii(int X, int Y) {              this.X = X;              this.Y = Y;          }          public int compareTo(pii a) {              if(this.X - a.X != 0) return this.X - a.X;              else return this.Y - a.Y;          }      }      static class Scanner {            BufferedReader br;            StringTokenizer st;                            public Scanner(InputStream in) {              br = new BufferedReader(new InputStreamReader(in));              eat("");          }                     private 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());            }                        public long nextLong() {                return Long.parseLong(next());            }                            public double nextDouble() {                return Double.parseDouble(next());            }                        public BigInteger nextBigInteger() {                return new BigInteger(next());            }                    }    }   


0 0