C: Sigma Problem
- 二分查詢
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
int n = rd.nextInt();
long[] a = new long[n];
for (int i = 0; i < n; i++) {
a[i] = rd.nextInt();
}
Arrays.sort(a);
long[] sum = new long[n];
sum[0] = a[0];
for (int i = 1; i < n; i++) {
sum[i] = sum[i - 1] + a[i];
}
long ans = 0;
for (int i = 1; i < n; i++) {
// 第一個大於等於
int insertPoint = lowerBound(a,0, i, 1000_000_00 - a[i]);
// 1 , 1000_000_00 - 1
// from 0 .. insertPoint -1 之間的數就可以直接算出來
long before = 0;
if (insertPoint > 0) {
before += (sum[insertPoint - 1] + a[i] * insertPoint);
}
long after = 0;
if (insertPoint < i) {
after += (sum[i - 1] - (insertPoint == 0 ? 0 : sum[insertPoint - 1]) - (1000_000_00L - a[i]) * (i - insertPoint));
}
ans += (before + after);
}
System.out.println(ans);
}
/**
* [from, to) 找到第一個>=target的數的index, 未找到是返回to
*
* @param a
* @param from
* @param to
* @param target
* @return
*/
public static int lowerBound(long[] a, int from, int to, long target) {
int low = from;
int high = to;
while(low < high) {
int mid = (low + high) / 2;
if ( a[mid] >= target) {
high = mid;
}
else {
low = mid + 1;
}
}
return low;
}
static class rd {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokenizer = new StringTokenizer("");
// nextLine()讀取字串
static String nextLine() throws IOException {
return reader.readLine();
}
// next()讀取字串
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) tokenizer = new StringTokenizer(reader.readLine());
return tokenizer.nextToken();
}
// 讀取一個int型數值
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
// 讀取一個double型數值
static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
// 讀取一個long型數值
static long nextLong() throws IOException {
return Long.parseLong(next());
}
// 讀取一個BigInteger
static BigInteger nextBigInteger() throws IOException {
BigInteger d = new BigInteger(rd.nextLine());
return d;
}
}
}
D Another Sigma Problem
- 字首和
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
int n = rd.nextInt();
int[] a = new int[n];
long[] sum = new long[n];
for (int i = 0; i < n; i++) {
a[i] = rd.nextInt();
if (i == 0) {
sum[i] = a[0];
} else {
sum[i] = sum[i - 1] + a[i];
sum[i] %= 998244353;
}
}
//
long ans = 0;
for (int i = 1; i < n; i++) {
ans += f(a, i, sum) % 998244353;
ans %= 998244353;
}
System.out.println(ans);
}
public static long f(int[] a, int i, long[] sum) {
long base = 1;
long num = a[i];
while (num != 0) {
num = num / 10;
base = base * 10 % 998244353;
base %= 998244353;
}
return sum[i - 1] % 998244353 * base % 998244353 + (long)i % 998244353 * (long)a[i] % 998244353 ;
}
}
class rd {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokenizer = new StringTokenizer("");
// nextLine()讀取字串
static String nextLine() throws IOException {
return reader.readLine();
}
// next()讀取字串
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) tokenizer = new StringTokenizer(reader.readLine());
return tokenizer.nextToken();
}
// 讀取一個int型數值
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
// 讀取一個double型數值
static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
// 讀取一個long型數值
static long nextLong() throws IOException {
return Long.parseLong(next());
}
// 讀取一個BigInteger
static BigInteger nextBigInteger() throws IOException {
BigInteger d = new BigInteger(rd.nextLine());
return d;
}
}
E - Yet Another Sigma Problem
- trie樹
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.*;
public class Main {
static int n;
static class TrieNode {
TrieNode[] children = new TrieNode[26];
int cnt = 0;
int depth = 0;
char ch;
public long getValue() {
return (long)cnt * (cnt - 1) / 2;
}
public TrieNode(char ch) {
this.ch = ch;
for (int i = 0; i < 26; i++) {
children[i] = null;
}
this.cnt = 0;
this.depth = 0;
}
public TrieNode getChild(char ch) {
return children[ch - 'a'];
}
public TrieNode(int parentDepth, char ch) {
this.depth = parentDepth + 1;
this.ch = ch;
this.cnt = 1;
for (int i = 0; i < 26; i++) {
children[i] = null;
}
}
public void addChild(TrieNode child) {
this.children[child.ch - 'a'] = child;
}
}
static TrieNode dummy = new TrieNode('a');
public static void build(String str) {
TrieNode curr = dummy;
for (int i = 0; i < str.length(); i++) {
int parentDepth = curr.depth;
char ch1 = str.charAt(i);
TrieNode child = curr.getChild(ch1);
if (child != null) {
child.cnt++;
} else {
child = new TrieNode(parentDepth, ch1);
curr.addChild(child);
}
curr = child;
}
}
public static long travel() {
ArrayDeque<TrieNode> arrayDeque = new ArrayDeque<>();
arrayDeque.add(dummy);
long ans = 0;
while (!arrayDeque.isEmpty()) {
TrieNode node = arrayDeque.poll();
long val1 = node.getValue();
long val2 = 0;
for (int i = 0; i < 26; i++) {
if (node.children[i] != null) {
val2 += node.children[i].getValue();
arrayDeque.add(node.children[i]);
}
}
ans += (val1 - val2) * node.depth;
}
return ans;
}
public static void main(String[] args) throws IOException {
n = rd.nextInt();
String[] str = rd.nextLine().split(" ");
for (int i = 0; i < n; i++) {
build(str[i]);
}
long ans = travel();
System.out.println(ans);
}
static class rd {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokenizer = new StringTokenizer("");
// nextLine()讀取字串
static String nextLine() throws IOException {
return reader.readLine();
}
// next()讀取字串
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) tokenizer = new StringTokenizer(reader.readLine());
return tokenizer.nextToken();
}
// 讀取一個int型數值
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
// 讀取一個double型數值
static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
// 讀取一個long型數值
static long nextLong() throws IOException {
return Long.parseLong(next());
}
// 讀取一個BigInteger
static BigInteger nextBigInteger() throws IOException {
BigInteger d = new BigInteger(rd.nextLine());
return d;
}
}
}