QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#554730#7748. Karshilov's Matching Problem II000226WA 1ms7656kbC++172.9kb2024-09-09 15:08:512024-09-09 15:08:52

Judging History

你现在查看的是最新测评结果

  • [2024-09-09 15:08:52]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:7656kb
  • [2024-09-09 15:08:51]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define lep(i, l, r) for(int i = (l); i <= (r); i ++)
#define rep(i, l, r) for(int i = (l); i >= (r); i --)
#define debug(...) fprintf(stderr, __VA_ARGS__)

using i64 = long long;

const int N = 1.5 * 1e5 + 5;
const int M = N << 1;

int n, m;
char s[N], t[N];
int w[N], p[N];
char S[M];
int z[M], border[N];
i64 sum[N], Tsum[N], sum_2[N];

#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)

int mx[N << 2];
void upd (int x) {
	mx[x] = max (mx[ls(x)], mx[rs(x)]);
}
void build (int x, int l, int r, int *val) {
	if (l == r) {
		mx[x] = val[l];
		return;
	}
	int mid = (l + r) >> 1;
	build (ls(x), l, mid, val);
	build (rs(x), mid + 1, r, val);
	upd (x);
}
int bq(int x, int l, int r, int v) {
	if (mx[x] < v) return 0;
	if (l == r) return l;
	int mid = (l + r) >> 1;
	if (mx[ls(x)] >= v) return bq(ls(x), l, mid, v);
	else return bq(rs(x), mid + 1, r, v);
}
int query(int x, int l, int r, int L, int R, int v) {
	if (mx[x] < v) return 0;
	if (L <= l && r <= R) return bq(x, l, r, v);
	int mid = (l + r) >> 1;
	if (L <= mid) {
		int res = query(ls(x), l, mid, L, R, v);
		if (res) return res;
	}
	else return query(rs(x), mid + 1, r, L, R, v);
}

int main() {
    ios :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n >> m;
    cin >> (s + 1);
    cin >> (t + 1);
    lep (i, 1, n) cin >> w[i], sum[i] += w[i], sum[i] += sum[i - 1];
	//lep (i, 1, n) sum_2[i] = sum_2[i - 1] + sum[i];
    
    lep (i, 1, n) S[i] = s[i];
    S[n + 1] = '#';
    lep (i, 1, n) S[i + 1 + n] = t[i];
    
    z[1] = n;
    int l = 0, r = 0;
    for (int i = 2; i <= n + n + 1; i ++) {
    	if (i <= r) z[i] = min (z[i - l + 1], r - i + 1);
    	else z[i] = 0;
    	while (S[z[i] + 1] == S[i + z[i]]) z[i] ++;
    	if (i + z[i] - 1 > r) r = i + z[i] - 1, l = i;
	}
	
	lep (i, 1, n) p[i] = z[i + 1 + n];

	for (int i = 2, j = 0; i <= n; i ++) {
		while (j && s[j + 1] != s[i]) j = border[j];
		if (s[j + 1] == s[i]) ++ j;
		border[i] = j;
	}

	for (int i = 1; i <= n; i ++)
		sum_2[i] = sum_2[border[i]] + w[i];
	
	lep (i, 1, n) sum_2[i] += sum_2[i - 1];

	lep (i, 1, n) {
		Tsum[i] = Tsum[i - 1] + sum[p[i]];
	}

	static int val[N];
	lep (i, 1, n) val[i] = p[i] + i - 1;
	build (1, 1, n, val);

	//lep (i, 1, n) cerr << p[i] << ' ' ;cerr << endl;
	
	// qry i in [L, R], s[min(r - i + 1), p[i]]

	/*
	
		p[i] <= r - i + 1
		p[i] + i - 1 <= r
		find left i for p[i] + i - 1 >= r
		
		for [i, r] 是S的一个前缀
		for [l, i - 1] p[i] + i - 1 < r
		区间求和 sum[p[i]]
	
	*/
	
	while (m --) {
		int l, r;
		cin >> l >> r;
		i64 ans = 0;
		int pos = query(1, 1, n, l, r, r);
		//cerr << pos << endl;
		if (! pos) {
			ans = Tsum[r] - Tsum[l - 1];
		}
		else {
			ans = Tsum[pos - 1] - Tsum[l - 1];
			ans += sum_2[r - pos + 1];
		}
		//lep (i, l, r) ans += sum[min(p[i], r - i + 1)];
		cout << ans << '\n';
	}
    
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 5716kb

input:

8 5
abbabaab
aababbab
1 2 4 8 16 32 64 128
1 1
2 3
3 5
4 7
1 8

output:

1
3
3
16
38

result:

ok 5 lines

Test #2:

score: -100
Wrong Answer
time: 1ms
memory: 7656kb

input:

15 4
heheheheehhejie
heheheheheheheh
3 1 4 1 5 9 2 6 5 3 5 8 9 7 9
2 3
4 8
2 6
1 15

output:

31
62
62
174

result:

wrong answer 1st lines differ - expected: '3', found: '31'