Codeforces Round #498 (Div. 3)

被虐惨了,实验室里数十位大佬中的一位闲来无事切题(二,然后出了5t,当然我要是状态正常也能出5,主要是又热又有蚊子什么的...

题都挺水的。包括F题。

A:

  略

B:

  找k个最大的数存一下下标然后找段长度就行

  public static void main(String[] args) {
        int n = nextInt();
        int k = nextInt();
        PriorityQueue<Integer> q = new PriorityQueue<>();
        int a[] = new int[n];
        for(int i=0;i<n;i++){
            a[i] = nextInt();
            q.add(a[i]);
        }
        while (q.size()>k){
            q.poll();
        }
        boolean b[] = new boolean[n];
        int sum = 0;
        int last = 0;
        for(int i=n-1;i>=0;i--){
            if (q.contains(a[i])){
                last=i>last?i:last;
                sum+=a[i];
                b[i] = true;
                q.remove(a[i]);
            }
        }
        out.println(sum);
        int temp = -1;
        for(int i=0;i<last;i++){
            if (b[i]){
                out.print(i-temp+" ");
                temp = i;
            }
        }
        out.print(n-1-temp);
        out.flush();
    }
main 方法

C:

  从两个端点向中间遍历

 public static void main(String[] args) {
        int n = nextInt();
        long d[] = new long[n];
        for(int i=0;i<n;i++){
            d[i] = nextInt();
        }
        long sum1 = 0;
        long sum3 = 0;
        int i=0,j=n-1;
        long ans = 0;
        while (j>i){
            if (sum3==sum1){
                ans = sum1>ans?sum1:ans;
                sum3+=d[j];
                sum1+=d[i];
                i++;j--;
                if (sum3==sum1)
                    ans = sum1>ans?sum1:ans;
            }else if (sum3<sum1){
                sum3+=d[j];
                j--;
            }else if (sum3>sum1){
                sum1+=d[i];
                i++;
            }
        }
        if (j==i){
            if (sum3<sum1){
                sum3+=d[j];
            }else if (sum3>sum1){
                sum1+=d[i];
            }
            if (sum3==sum1)
                ans = sum1>ans?sum1:ans;
        }
        out.print(ans);
        out.flush();
    }
View Code

D:

  大水题,四个位置上的元素判断一下情况就行,我直接分的类很莽就不放代码了。

E:

  求出dfs序,顺手存个子树大小,结点下标就完了。

package R498;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

public class Main4 {
    static BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer tok;
    static boolean hasNext()
    {
        while(tok==null||!tok.hasMoreTokens())
            try{
                tok=new StringTokenizer(in.readLine());
            }
            catch(Exception e){
                return false;
            }
        return true;
    }
    static String next()
    {
        hasNext();
        return tok.nextToken();
    }
    static long nextLong()
    {
        return Long.parseLong(next());
    }
    static int nextInt()
    {
        return Integer.parseInt(next());
    }
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));

    static int N = 200005;
    static Vector<Integer> g[] = new Vector[N];
    static int size[] = new int[N];//存子树大小
    static boolean b[] = new boolean[N];//染色
    static int ans[] = new int[N];//dfs序
    static int index[] = new int[N];//下标
    static int pos = 0;


    public static void main(String[] args) {
        int n = nextInt();
        int q = nextInt();
        for(int i=1;i<=n;i++){
            g[i] = new Vector<>();
        }
        int u;
        for(int i=2;i<=n;i++){
            u = nextInt();
            g[u].add(i);
        }
        dfs(1);
        int t,k;
        while (q--!=0){
            t = nextInt();
            k = nextInt();
            if (k>size[t]){
                out.println(-1);
            }else {
                out.println(ans[index[t]+k-1]);
            }
        }
        out.flush();
    }
    public static void dfs(int v){
        b[v]=true;
        size[v]++;
        ans[pos++] = v;
        index[v] = pos-1;
        for(int i=0;i<g[v].size();i++){
            int u = g[v].get(i);
            if(!b[u]){
                dfs(u);
                size[v]+=size[u];
            }
        }
    }
}
View Code

F:很显然上来就想到了从两个点往中间搜搜一半,但是我写炸了,就找了份代码看了看,对于 “一半”,这个地方  要用 (n/2+m/2)而不是 (n+m)/2  ,ex:1 1 10 10.

还是很好懂的 ,哦还需要知道这么一个事, a^b=c 的话 那么 b^c=a; 原谅我是二进制小白,有几个相关公式可以直接百度

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.*;

public class Main6 {
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer tok;
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    static boolean hasNext() {
        while (tok == null || !tok.hasMoreTokens())
            try {
                tok = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                return false;
            }
        return true;
    }

    static String next() {
        hasNext();
        return tok.nextToken();
    }

    static long nextLong() {
        return Long.parseLong(next());
    }

    static int nextInt() {
        return Integer.parseInt(next());
    }

    static int n;
    static int m;
    static long k;
    static long ans = 0;
    static long a[][];
    static Map<Long,Long> map[][];
    public static void main(String[] args) {
        n = nextInt();
        m = nextInt();
        k = nextLong();
        a = new long[n][m];
        map = new Map[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                a[i][j] = nextLong();
                map[i][j] = new HashMap<>();
            }
        }
        dfsbe(0,0,0);
        dfsend(n-1,m-1,0);

        out.print(ans);
        out.flush();
    }
    public static void dfsbe(int i,int j,long temp){
        if (i>=n||j>=m)
            return;
        temp ^= a[i][j];
        if (i+j==n/2+m/2){
            if (map[i][j].get(temp)==null){
                map[i][j].put(temp,1l);
            }else {
                map[i][j].put(temp,map[i][j].get(temp)+1);
            }
            return;
        }
        dfsbe(i+1,j,temp);
        dfsbe(i,j+1,temp);
    }
    public static void dfsend(int i,int j,long temp){
        if (i<0||j<0)
            return;
        if (i+j==n/2+m/2){
            long num = temp^k;
            if (map[i][j].get(num)!=null){
                ans+=map[i][j].get(num);
            }
            return;
        }
        temp^=a[i][j];
        dfsend(i-1,j,temp);
        dfsend(i,j-1,temp);
    }
}
/**
 * 1^1=0
 * 0^0=0
 * 1^0=1
 * 0^1=1
 * a ^ b = b ^ a
 * a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
 * d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
 * a ^ b ^ a = b.
 */
View Code

  

原文地址:https://www.cnblogs.com/MXang/p/9322785.html