蓝桥杯111

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();
    }
}
  1. //欧拉函数Eluar(n)表示小于n且与n互质的正整数的个数,另有Eular(1)=1

  2. //由唯一分解定理,n=p1^k1*p2^k2*...*pm^km

  3. //则可推出Eular(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pm)

  4. 化简为Eular(n)=n*(p1-1)/p1*(p2-1)/p2*...*(pm-1)/pm,

  1. //a^(p-1) = 1(mod p) p是质数

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值