import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
//ST表快速查找素组中某个区间内最大值
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static final int N = (int)5e5+7;
static int n,q,l,r;
static int[] a = new int[N];
static int[][] st = new int[N][22];//st[i][j]表示从index为i开始2^j个数 这个区间内最大值
public static void main(String[] args)throws IOException {
String[] nq = in.readLine().split(" ");
n = Integer.parseInt(nq[0]);
q = Integer.parseInt(nq[1]);
nq = in.readLine().split(" ");
for(int i=1;i<=n;i++) {
a[i] = Integer.parseInt(nq[i-1]);
st[i][0] = a[i];//初始化
}
for(int j=1;j<=20;j++) { //枚举区间长度
for(int i=1;i<=n;i++) { //枚举左端点
if(i+(1<<j)-1<=n) {//右端点合法 都从左边开始算
st[i][j] = Math.max(st[i][j-1],st[i+(1<<(j-1))][j-1]);//左端点
}
}
}
while(q-->0) {
nq = in.readLine().split(" ");
l = Integer.parseInt(nq[0]);
r = Integer.parseInt(nq[1]);
out.println(get_max(l,r));
}
out.flush();
}
public static int get_max(int l,int r) {
int k = (int)(Math.log(r-l+1)/Math.log(2));//压缩长度 从两边开始取最小值
return Math.max(st[l][k],st[r-(1<<k)+1][k]);// 左加右减
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
//马拉车算法找最长回文子串长度
public class Main{
static final int N = (int)1e6+9;//记住一定要开2倍
static char[] S = new char[N];
static char[] T = new char[N];
static int[] p = new int[N]; // 表示回文半径
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args)throws IOException{
String s = in.readLine();
int n = s.length();
for(int i=1;i<=n;i++)S[i] = s.charAt(i-1);
//用一个字符串也可以
//初始化
for(int i=2*n+1;i>=1;i--) {
int t = i;
T[t] = (t%2==1)?'#':S[t>>1];//奇数#
}
T[0] = '^';
T[2*n+2] = '$';
int C = 0,R = 0;//中心 右端点
for(int i=1;i<=2*n+1;i++) {
//如i<R 说明当前位置i在当前已知的回文子串范围内(合法) 此时R-i表示当前位置i到已知回文子串右边界R的距离
//如果R-i更小 说明当前位置i距离已知回文子串有边界更近 因此可以直接利用该距离为当前位置的回文半径
p[i] = (i<R)?Math.min(R-i,p[2*C-i]):1;//保证合法 右端点不超出R因为R右边不知道 且长度至少是1
while(T[i+p[i]] == T[i-p[i]])p[i]++;//在前面的基础上半径还可以更大
if(i+p[i]>R) {//下一个右端点已经顶到了
C = i;//更新中心
R = i + p[i];//更换右端点
}
}
int ans = 0;
for(int i=1;i<=2*n+1;i++) {
ans = Math.max(ans,p[i] - 1);
}
out.print(ans);
out.flush();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
//KMP求一个字符串在另一个字符串中出现了多少次
public class Main{
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static final int N = (int) 1e7+7;
static char[] S = new char[N];//S是模式串
static char[] T = new char[N];//T是文本串
static int[] nex = new int[N];//nex数组表示失配时指针应该移动到哪个位置
static int m,n;//m是模式串的长度 n是文本串的长度
static int ans = 0;
public static void main(String[] args)throws IOException{
String strS = in.readLine();//模式串
m = strS.length();
strS.getChars(0, m, S, 0);//将字符串转化成字符数组
String strT = in.readLine();//文本串
n = strT.length();
strT.getChars(0, n, T, 0);//将字符串转化成字符数组
getnex(m);//对模式串求nex数组
KMP(m,n);//模式串 文本串
out.println(ans);
out.flush();
}
public static void getnex(int m) {//对模式串求nex数组 模式串自查 也就是初始化
nex[0] = -1;//初始化为-1
for(int i=1,j=0;i<m;i++) {//注意这里是从1开始遍历模式串
while(j>0&&S[i]!=S[j])j = nex[j];//如果不匹配 那么就返回到原来的位置
if(S[i]==S[j])j++;//如果匹配那么继续移动
nex[i] = j;//更新
}
}
public static void KMP(int m,int n) {//针对文本串
for(int i=0,j=0;i<n;i++) {//修改为从0开始遍历文本串
while(j>0&&T[i]!=S[j])j = nex[j];//如果不匹配 那么就返回到原来的位置
if(T[i]==S[j])j++;//如果匹配那么继续移动
if(j==m) {//匹配到完整的模式串了
ans ++ ;
j = nex[j];
}
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Scanner;
//字符串hash
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static final int N = (int)1e6+5;
static final int P = 2;//质数
static long[] h1 = new long[N];
static long[] h2 = new long[N];
static long[] p = new long[N];
public static void main(String[] args)throws IOException {
Scanner scanner = new Scanner(System.in);
char[] b = new char[N];
char[] a = new char[N];
String strB = scanner.next();//模式串
String strA = scanner.next();//文本串
for (int i = 1; i <= strB.length(); i++)b[i] = strB.charAt(i - 1);
for (int i = 1; i <= strA.length(); i++)a[i] = strA.charAt(i - 1);
int aLen = strA.length();
int bLen = strB.length();
// 对文本串和模式串分别进行哈希处理
myHash(h1, aLen, a);//文本串
myHash(h2, bLen, b);//模式串
int res = 0;
//滑动窗口检查模式串在文本串中出现的次数
for(int i=1;i+bLen-1<=aLen;i++) {//枚举左端点 保证右端点合法
int j = i + bLen -1;//右端点
if(get(i,j)==h2[bLen]) res++;//h2[bLen]表示index<=bLen的字符
}
out.println(res);
out.flush();
}
//通过前缀和快速计算子串的哈希值
private static long get(int l, int r) {
return h1[r] - h1[l-1] * p[r-l+1];//是乘p[r-l+1] 长度
}
private static void myHash(long[] ha, int n, char[] str) {
p[0] = 1;//初始化
for(int i=1;i<=n;i++) {
p[i] = p[i-1] * P;
ha[i] = ha[i-1]*P + str[i] - 'A';// 字符串处理前缀和 加上str[i]表示这个位置的字母
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
//ST表:快速查找数组中某个区间内的最大值
public class Main{
static final int N = (int)1e6+9;
static int[][] nex = new int[N][26];//表示从结点i触发边为a的下个结点的地址
static int[] cnt = new int[N];//表示以结点i结尾的字符串的数量
static int idx = 2;//动态开点
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args)throws IOException{
String[] nm = in.readLine().split(" ");
int n = Integer.parseInt(nm[0]);
int m = Integer.parseInt(nm[1]);
String s ;
for(int i=1;i<=n;i++) {
s = in.readLine();
insert(s);//插入字典树中
}
for(int i=1;i<=m;i++) {
s = in.readLine();
out.println(check(s)?'Y':'N');
}
out.flush();
}
// 插入字符串到字典树中
public static void insert(String s) {
int x = 1;
for (int i = 0; i < s.length(); i++) {
int c = s.charAt(i) - 'a'; // 计算字符在字母表中的索引
if (nex[x][c] == 0) {
nex[x][c] = idx++; // 如果当前节点没有这个字符的子节点,创建一个新节点
}
x = nex[x][c]; // 移动到下一个节点
}
}
//检查字符串是否在字典树中
public static boolean check(String T) {
int x = 1;
for(int i=0;i<T.length();i++) {
int c = T.charAt(i) - 'a';//计算字符在字母表中的索引
x = nex[x][c];//移动到下一个结点
if(x==0)return false;//如果当前这个结点不存在了 那么就失败
}
return true;
}
}
/*多源最短路*/
import java.io.*;
import java.util.*;
public class FloydWarshall {
static final long INF = 0x3f3f3f3f3f3f3f3fL;
static int n,m,q;
static long[][] dis;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String[] nmq = in.readLine().split(" ");
n = Integer.parseInt(nmq[0]);//n个景点
m = Integer.parseInt(nmq[1]);//m条道路
q = Integer.parseInt(nmq[2]);//q个观景计划
dis = new long[n + 1][n + 1];//注意这个n要在里面初始化
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dis[i][j] = INF;//初始化
}
}
for (int i = 1; i <= n; i++)dis[i][i] = 0;//初始化
for (int i = 1; i <= m; i++) {
String[] abc = in.readLine().split(" ");
int a = Integer.parseInt(abc[0]);//地点1
int b = Integer.parseInt(abc[1]);//地点2
int c = Integer.parseInt(abc[2]);//距离
dis[a][b] = dis[b][a] = Math.min(dis[a][b], c);
}
for (int k = 1; k <= n; k++) {//经过地点k
for (int i = 1; i <= n; i++) {//从地点i
for (int j = 1; j <= n; j++) {//到地点j
dis[i][j] = Math.min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
for (int i = 0; i < q; i++) {
String[] st = in.readLine().split(" ");
int s = Integer.parseInt(st[0]);
int t = Integer.parseInt(st[1]);
if (dis[s][t] == INF) {
out.println("-1");
} else {
out.println(dis[s][t]);
}
}
out.flush();
}
}
/*多源最短路*/
import java.io.*;
import java.util.*;
public class FloydWarshall {
static final long INF = 0x3f3f3f3f3f3f3f3fL;
static int n,m,q;
static long[][] dis;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String[] nmq = in.readLine().split(" ");
n = Integer.parseInt(nmq[0]);//n个景点
m = Integer.parseInt(nmq[1]);//m条道路
q = Integer.parseInt(nmq[2]);//q个观景计划
dis = new long[n + 1][n + 1];//注意这个n要在里面初始化
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dis[i][j] = INF;//初始化
}
}
for (int i = 1; i <= n; i++)dis[i][i] = 0;//初始化
for (int i = 1; i <= m; i++) {
String[] abc = in.readLine().split(" ");
int a = Integer.parseInt(abc[0]);//地点1
int b = Integer.parseInt(abc[1]);//地点2
int c = Integer.parseInt(abc[2]);//距离
dis[a][b] = dis[b][a] = Math.min(dis[a][b], c);
}
for (int k = 1; k <= n; k++) {//经过地点k
for (int i = 1; i <= n; i++) {//从地点i
for (int j = 1; j <= n; j++) {//到地点j
dis[i][j] = Math.min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
for (int i = 0; i < q; i++) {
String[] st = in.readLine().split(" ");
int s = Integer.parseInt(st[0]);
int t = Integer.parseInt(st[1]);
if (dis[s][t] == INF) {
out.println("-1");
} else {
out.println(dis[s][t]);
}
}
out.flush();
}
}
import java.io.*;
import java.util.*;
public class Main {
static final long INF = Long.MAX_VALUE;//3个3f
static final int N = (int)3e5+7;
static long[] dis;//从起点到i的最短距离为dis[i]
static int[] e, w, ne, h;
static boolean[] st;
static int idx;
static int n, m, s;
static void add(int a, int b, int c) {
e[idx] = b;//终点end是b
w[idx] = c;//值weight是c
ne[idx] = h[a];//找完idx这条边就去next即h[a]这条边
h[a] = idx++;//h[a]表示 以顶点a为起点的边的idx
}
//dijkstra单源最短路
static void dijkstra() {
//初始化
for (int i = 0; i <= n; i++) {
dis[i] = INF;
st[i] = false;
}
PriorityQueue<long[]> heap = new PriorityQueue<>((o1, o2) -> Long.compare(o1[1], o2[1]));//升序
dis[s] = 0;//起点到起点的最短距离为0
heap.add(new long[]{s, 0});// 加入队列中 (终点,距离) 表示从起点到达终点s的最短距离
while (!heap.isEmpty()) {
long[] t = heap.poll();
int ver = (int)t[0];//终点
if (st[ver]) continue;
st[ver] = true;//我们已经遍历过ver所能到达的所有地点
for (int i = h[ver]; i != -1; i = ne[i]) {//对于ver所能到达的所有点
int j = e[i];//终点
if (dis[j] > t[1] + w[i]) {//已知的从起点到达终点的距离 > 从起点到达ver 再从ver到达j的距离
dis[j] = t[1] + w[i];// 则更新已知的
heap.add(new long[]{j, dis[j]});//并加入队列中
}
}
}
}
public static void main(String[] args) throws IOException {
//快读快写
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String[] nm = in.readLine().split(" ");
n = Integer.parseInt(nm[0]);//一共n个建筑
m = Integer.parseInt(nm[1]);//一共m条道路
s = 1;//s是起点
e = new int[N];
w = new int[N];
ne = new int[N];
h = new int[N];
dis = new long[N];
st = new boolean[N];
idx = 0;
//初始化
for (int i = 0; i < N; i++)h[i] = -1;
for (int i = 0; i < m; i++) {
String[] abc = in.readLine().split(" ");
int a = Integer.parseInt(abc[0]);//起点
int b = Integer.parseInt(abc[1]);//终点
int c = Integer.parseInt(abc[2]);//距离
add(a, b, c);//添加边
}
dijkstra();
for(int i=1;i<=n;i++) {
if(dis[i]==INF)out.print("-1 ");
else {out.print(dis[i]);out.print(" ");}
}
out.flush();
}
}
import java.io.*;
import java.util.*;
//最小生成树 连接整个地图
//建边 并查集 排序
//不能有环
public class Main {
static int[] fa;
static class Edge{
//地点1 地点2 长度
int f,t,dis;
public Edge(int f,int t,int dis) {
this.f = f;
this.t = t;
this.dis = dis;
}
}
//并查集
public static int find(int x) {
if(fa[x] != x)fa[x] = find(fa[x]);
return fa[x];
}
public static void main(String[] args) throws IOException {
//快读快写
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String[] nmk = in.readLine().split(" ");
int n = Integer.parseInt(nmk[0]);//n个节点
int m = Integer.parseInt(nmk[1]);//m条边
fa = new int[n+1];
for(int i=0;i<=n;i++)fa[i] = i;//初始化
List<Edge> edges = new ArrayList<>();
for(int i=0;i<m;i++) {
String[] ft = in.readLine().split(" ");
int f = Integer.parseInt(ft[0]);
int t = Integer.parseInt(ft[1]);
int dis = Integer.parseInt(ft[2]);
edges.add(new Edge(f, t, dis));
}
//按照dis<排序
edges.sort((e1,e2)->Integer.compare(e1.dis, e2.dis));
int ans = 0;
int numEdges = 0;
for(Edge edge : edges) {//先拿到的一定是最短距离 因为排序是<
int eu = find(edge.f);
int ev = find(edge.t);
if(eu!=ev) {//如果两个父节点不同 说明没有连接
fa[eu] = ev;
ans = Math.max(ans,edge.dis);
numEdges ++ ;
if(numEdges == n-1) {
break;
}
}
}
out.println(numEdges == n-1?ans:-1);
out.flush();
}
}
唯一分解定理:一个数可以由若干个质数的若干次方相乘得到
也可以通过若干个2的次方相加得到
//本题考查约数个数定理和约数和定理
//约数个数定理:
//对于大于1的正整数x,可将其表示为x=pow(p1,k1)*pow(p2,k2)*...*pow(pn,kn)
//可以理解为x一定可以且唯一可以表示成若干个质数的若干幂次之积
//若要求x的约数的个数,则对于如上的p1,p2,...,pn,其幂次可以取[0,k1],[0,k2,],...,[0,kn]
//即对于每个质因子pi,有ki+1种取法
//故对于x,其约数个数为(k1+1)*(k2+1)*...*(kn+1)
//约数和定理:
//因数p1可以贡献的约数为1或p1^1或p1^2...或p1^k1,p2,pn同理
//若x=72,仅对于p1可以形成约数1,2,4,8,仅对于p2可以形成约数1,3,9,
//这些数字组合相乘可形成所有的约数
//若要计算所有的约数之和
//则等同于计算(1+p1^1+p1^2+...+p1^k1)*...*(1+pn^1+pn^2+...+pn^kn)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static int n, ans = 1; // 初始化ans为1,因为后续是乘法操作
static int mod = 998244353;
static HashMap<Integer, Integer> factor = new HashMap<Integer, Integer>();
public static void main(String[] args) throws IOException {
n = Integer.parseInt(in.readLine());
cal_factor(n); // 填充 factor HashMap
long ans = 1; // 使用 long 类型存储最终结果
for (int k : factor.keySet()) {
int base = k; // 当前质因数
int power = factor.get(k); // 次数
long sum = 1; // 使用 long 类型存储当前质因数的幂次和
for (int i = 1; i <= power; i++) {
sum = (sum + qmi(base, i)) % mod;
}
ans = (ans * sum) % mod;
}
out.println(ans);
out.flush();
}
// 寻找n!的所有质因数与其出现的次数
public static void cal_factor(int x) {
for (int i = 2; i <= x; i++) { // 从2遍历到x
int m = i;
for (int j = 2; j * j <= m; j++) { // 从2遍历到sqrt(m)
while (m % j == 0) { // 如果j是m的质因数
factor.put(j, factor.getOrDefault(j, 0) + 1); // 更新质因数的次数
m /= j;
}
}
if (m > 1) // 如果m大于1,说明m本身是质数
factor.put(m, factor.getOrDefault(m, 0) + 1);
}
}
// 快速幂函数,计算 a^b 对 mod 取模的结果
public static int qmi(int a, int b) {
int res = 1;
while (b > 0) {
if ((b & 1) == 1) {
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res;
}
}
import java.io.*;
import java.time.LocalDate;
import java.util.*;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static int n;
static HashMap<Integer, ArrayList<Integer>> map;
static HashMap<Integer,Integer> cnt;
public static void main(String[] args) throws IOException {
n = Integer.parseInt(in.readLine());
map = new HashMap<Integer, ArrayList<Integer>>();
cnt = new HashMap<Integer,Integer>();
for(int i=0;i<n;i++) {
String[] ab = in.readLine().split(" ");
int a = Integer.parseInt(ab[0]);
int b = Integer.parseInt(ab[1]);
map.computeIfAbsent(a, k -> new ArrayList<>()).add(b);//注意!!
cnt.compute(a,(k,v)->(v==null?1:v+1));
}
for(int k:cnt.keySet())Collections.sort(map.get(k));
int res = n/10;
int ans = 0;
for(Integer key:map.keySet()) {
int times = cnt.get(key) - res;//多了多少
if(times>0) {
for(int i=0;i<times;i++) {
ans += map.get(key).get(i);
}
}
}
out.println(ans);
out.flush();
}
}
-
//欧拉函数Eluar(n)表示小于n且与n互质的正整数的个数,另有Eular(1)=1
-
//由唯一分解定理,n=p1^k1*p2^k2*...*pm^km
-
//则可推出Eular(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pm)
-
化简为Eular(n)=n*(p1-1)/p1*(p2-1)/p2*...*(pm-1)/pm,
-
//a^(p-1) = 1(mod p) p是质数
-