解题思路:
看坐标之和,奇数偶数不同字符即可。
解题思路:
题目应该是求连续的k长度最大值,遍历比较字符串,最后再取模。
javaimport java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String s = scanner.next(); int k = scanner.nextInt(); int p = scanner.nextInt(); String cur = s.substring(0, k); int n = s.length(); for (int i = k; i < n; i++) { String t = s.substring(i - k + 1, i + 1); if (t.compareTo(cur) > 0) { cur = t; } } // 高精度取模 long sum = 0; for (int i = 0; i < k; i++) { sum = (sum * 10 + (cur.charAt(i) - '0')) % p; } System.out.println(sum); } }
解题思路:
普通前缀积做不了,取模涉及除法就复杂起来了。线段树直接套就好了。静态线段树,并且只有区间查询。因为维护区间积只涉及乘法,可以取模。
3
1 2 3
1 2
2 3
解题思路:
只要一个数每位之和是三的倍数,这个数就是三的倍数。
以0为根结点,得到以每个节点i为根的子树的答案设为g[i][j],即模3为j的个数。再以0为根结点,f[0]=g[0],开始树形dp。具体地,root父节点遍历到一个子节点v,
k=(9+j-a[v]%3)%3,让k+a[v]模3是j。这样f[root][k]代表所有v到root开始的路径模3为j的个数。
m=(3+k-a[root]%3)%3,让m+a[root]模3是k。这样g[v][k]代表以v开始自己子树路径模3为k的个数。这被f[root][k]包含,需要减去。
f[v][j]=g[v][j]+f[root][k]-g[v][m];自己子树路径和模3为j,加上父节点除该子树外路线和模3为k的个数
采用先序遍历。
javapackage org.example; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; public class MyClass { int N=100005; int[][] g=new int[N][3]; int[][] f=new int[N][3]; int[] a=new int[N]; List<ArrayList<Integer>> arr= new ArrayList<ArrayList<Integer>>(); //获得以每个节点为根,其子树路径构成3倍数的个数 void getG(int last,int root){ int m=a[root]%3; g[root][m]=1; for(int i=0;i<arr.get(root).size();i++){ int v=arr.get(root).get(i); if(v==last){ continue; } getG(root,v); for(int j=0;j<3;j++){ g[root][j]+=g[v][(j-m+3)%3]; } } // System.out.println(Arrays.toString(g[root])); } //前序遍历每个节点,状态转移 void getF(int last,int root){ for(int i=0;i<arr.get(root).size();i++){ int v=arr.get(root).get(i); if(v==last){ continue; } for(int j=0;j<3;j++){ int k=(9+j-a[v]%3)%3; int m=(9+k-a[root]%3)%3; f[v][j]=g[v][j]+f[root][k]-g[v][m]; } // System.out.println(Arrays.toString(f[v])); getF(root,v); } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); MyClass myClass=new MyClass(); int n; n=scanner.nextInt(); for(int i=0;i<n;i++){ myClass.a[i]=scanner.nextInt(); myClass.arr.add(new ArrayList<>()); } for(int i=0;i<n-1;i++){ int u,v; u=scanner.nextInt(); v=scanner.nextInt(); myClass.arr.get(u-1).add(v-1); myClass.arr.get(v-1).add(u-1); } myClass.getG(-1,0); //初始化 System.arraycopy(myClass.g[0], 0, myClass.f[0], 0, 3); myClass.getF(-1,0); for(int i=0;i<n;i++){ System.out.println(myClass.f[i][0]); } } }