E. Modular Sequence:
题目描述:
思路解析:
这里第一个一定要需要填充x,然后后面每一位填充 ai-1 + y 或者 ai-1 % y,那么其实相当于除了第一位固定,后面每一位都可以表现为 a + ki * y;其中 a = x % y。这是显然的。那么ki有一个性质,ki 要么等于 ki-1 + 1 要么为 0.
那么问题就转化成 ki的和 等于 (s - x - (n-1) * a) / y;
那么我们只需要找到满足这样至少需要满足这样的和至少需要多少位,如果少于n-1位即可。(这个需要多少位,可以通过预处理得到)如果我们让第二位接在第一位,那这样预处理是没意义的,他只能针对这一种情况,所以我们让第二位k2为0,但是这样可能导致无法满足,那在这种情况下,我们让第二位接在第一位上,然后让k3为0,如果不行,继续往后延。
这样如果存在满足条件我们一定能得到。
代码实现:
import java.util.*;
import java.io.*;
public class Main {
static int[] a;
static int[] dp;
static int[] from;
public static void main(String[] args) throws IOException {
a = new int[633];
a[1] = 0;
for (int i = 2; i < 633; i++) {
a[i] = a[i-1] + i-1;
}
dp = new int[200005];
Arrays.fill(dp, Integer.MAX_VALUE / 10);
dp[0] = 0;
from = new int[200005];
for (int i = 1; i <= 200000; i++) {
for (int j = 2; j <= 632; j++) {
if (i - a[j] < 0) break;
if (dp[i] > dp[i-a[j]] + j){
dp[i] = dp[i-a[j]] + j;
from[i] = i-a[j];
}
}
}
int t = f.nextInt();
while (t > 0) {
solve();
t--;
}
w.flush();
w.close();
}
public static void solve() throws IOException{
int n = f.nextInt();
int x = f.nextInt(); int y = f.nextInt(); int ned = f.nextInt();
int a = x % y;
if ((ned - x - (n - 1) * a) % y != 0 || (ned - x - (n-1) * a) < 0) {
w.println("NO");
return;
}
if (n == 1 ){
if (ned == x) {
w.println("YES");
w.println(ned);
}else {
w.println("NO");
}
return;
}
int[] res = new int[n+1];
res[1] = x;
ned -= x;
x+=y;
for(int s = 2; s <= n; s++){
if (ned < 0) break;
int c = (ned - (n-s+1) * a) / y;
if (c < 0) break;
int d = c ;
if (dp[c] <= n-s+1){
w.println("YES");
for (int i = 1; i < s; i++) {
w.print(res[i] + " ");
}
while (c != 0){
int r = dp[c];
int l = dp[from[c]];
c = from[c];
for (int i = l+1; i <= r; i++) {
w.print((i - l - 1) * y + a + " ");
}
}
for (int i = dp[d] + 1; i <= n-s+1; i++) {
w.print(a + " ");
}
w.println();
return;
}
res[s] = x;
ned -= x;
x+=y;
if (s == n && ned == 0){
w.println("YES");
for (int i = 1; i <= n; i++) {
w.print(res[i] + " ");
}
w.println();
return;
}
}
w.println("NO");
}
static PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out));
static Input f = new Input(System.in);
static class Input {
public BufferedReader reader;
public StringTokenizer tokenizer;
public Input(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() throws IOException{
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
public int nextInt() throws IOException {
return Integer.parseInt(next());
}
public long nextLong() throws IOException {
return Long.parseLong(next());
}
public Double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}
}