QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#257112#7748. Karshilov's Matching Problem IIucup-team296#WA 212ms156032kbC++209.4kb2023-11-19 00:17:092023-11-19 00:17:09

Judging History

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

  • [2024-08-25 20:42:18]
  • hack成功,自动添加数据
  • (/hack/789)
  • [2023-11-19 00:17:09]
  • 评测
  • 测评结果:WA
  • 用时:212ms
  • 内存:156032kb
  • [2023-11-19 00:17:09]
  • 提交

answer

#include <bits/stdc++.h>

/**
 * Author: Niyaz Nigmatullin
 *
 */

using namespace std;

string to_string(string s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

struct upinfo {
	int left;
	int right;
	int index = -1;
};

struct node {
	long long sum = 0;
	upinfo updateInfo;

	static node single(long long x) {
		node res;
		res.sum = x;
		return res;
	}

	void apply(int l, int r, upinfo info);

	void apply(int l, int r, int x) {
		*this = single(x);
	}
};

node unite(const node &a, const node &b) {
	node res;
	res.sum = a.sum + b.sum;
	return res;
}

struct update {
	static const int K = 20;
	vector<long long> values;
	int n;
	vector<vector<node>> tt;

	update(vector<long long> values_): values(std::move(values_)), n((int) values.size()), tt(K, vector<node>(n)) {
		for (int i = 0; i < n; i++) {
			tt[0][i] = node::single(values[i]);
		}
		for (int i = 1; i < K; i++) {
			for (int v = 0; v < n; v++) {
				tt[i][v] = unite(tt[i - 1][v], tt[i - 1][(v + (1 << (i - 1))) % n]);
			}
		}
	}

	node get(int start, int len) {
		node res;
		start %= n;
		for (int i = K - 1; i >= 0; i--) {
			if (len >= (1 << i)) {
				len -= 1 << i;
				// debug(i, start, n, tt[i][start]);
				res = unite(res, tt[i][start]);
				start = (start + (1 << i)) % n;
			}
		}
		return res;
	}
};



vector<update> updates;

string to_string(node const &s) {
	return "node{sum=" + to_string(s.sum) + "}";
}
void node::apply(int l, int r, upinfo info) {
	assert(info.left <= l && r <= info.right);
	int start = l - info.left;
	node res = updates[info.index].get(start, r - l + 1);
	res.updateInfo = info;
	*this = res;
}

class segtree {
  public:
	

  inline void push(int x, int l, int r) {
    if (tree[x].updateInfo.index < 0) {
    	return;
    }
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    // push from x into (x + 1) and z
    tree[x + 1].apply(l, y, tree[x].updateInfo);
    tree[z].apply(y + 1, r, tree[x].updateInfo);
/*
    if (tree[x].add != 0) {
      tree[x + 1].apply(l, y, tree[x].add);
      tree[z].apply(y + 1, r, tree[x].add);
      tree[x].add = 0;
    }
*/
  }

  inline void pull(int x, int z) {
    tree[x] = unite(tree[x + 1], tree[z]);
  }

  int n;
  vector<node> tree;

  void build(int x, int l, int r) {
    if (l == r) {
      return;
    }
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    build(x + 1, l, y);
    build(z, y + 1, r);
    pull(x, z);
  }

  template <typename M>
  void build(int x, int l, int r, const vector<M> &v) {
    if (l == r) {
      tree[x].apply(l, r, v[l]);
      return;
    }
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    build(x + 1, l, y, v);
    build(z, y + 1, r, v);
    pull(x, z);
  }

  node get(int x, int l, int r, int ll, int rr) {
    if (ll <= l && r <= rr) {
      return tree[x];
    }
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    push(x, l, r);
    node res{};
    if (rr <= y) {
      res = get(x + 1, l, y, ll, rr);
    } else {
      if (ll > y) {
        res = get(z, y + 1, r, ll, rr);
      } else {
        res = unite(get(x + 1, l, y, ll, rr), get(z, y + 1, r, ll, rr));
      }
    }
    pull(x, z);
    return res;
  }

  template <typename... M>
  void modify(int x, int l, int r, int ll, int rr, const M&... v) {
    if (ll <= l && r <= rr) {
      tree[x].apply(l, r, v...);
      return;
    }
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    push(x, l, r);
    if (ll <= y) {
      modify(x + 1, l, y, ll, rr, v...);
    }
    if (rr > y) {
      modify(z, y + 1, r, ll, rr, v...);
    }
    pull(x, z);
  }

  int find_first_knowingly(int x, int l, int r, const function<bool(const node&)> &f) {
    if (l == r) {
      return l;
    }
    push(x, l, r);
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    int res;
    if (f(tree[x + 1])) {
      res = find_first_knowingly(x + 1, l, y, f);
    } else {
      res = find_first_knowingly(z, y + 1, r, f);
    }
    pull(x, z);
    return res;
  }

  int find_first(int x, int l, int r, int ll, int rr, const function<bool(const node&)> &f) {
    if (ll <= l && r <= rr) {
      if (!f(tree[x])) {
        return -1;
      }
      return find_first_knowingly(x, l, r, f);
    }
    push(x, l, r);
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    int res = -1;
    if (ll <= y) {
      res = find_first(x + 1, l, y, ll, rr, f);
    }
    if (rr > y && res == -1) {
      res = find_first(z, y + 1, r, ll, rr, f);
    }
    pull(x, z);
    return res;
  }

  int find_last_knowingly(int x, int l, int r, const function<bool(const node&)> &f) {
    if (l == r) {
      return l;
    }
    push(x, l, r);
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    int res;
    if (f(tree[z])) {
      res = find_last_knowingly(z, y + 1, r, f);
    } else {
      res = find_last_knowingly(x + 1, l, y, f);
    }
    pull(x, z);
    return res;
  }

  int find_last(int x, int l, int r, int ll, int rr, const function<bool(const node&)> &f) {
    if (ll <= l && r <= rr) {
      if (!f(tree[x])) {
        return -1;
      }
      return find_last_knowingly(x, l, r, f);
    }
    push(x, l, r);
    int y = (l + r) >> 1;
    int z = x + ((y - l + 1) << 1);
    int res = -1;
    if (rr > y) {
      res = find_last(z, y + 1, r, ll, rr, f);
    }
    if (ll <= y && res == -1) {
      res = find_last(x + 1, l, y, ll, rr, f);
    }
    pull(x, z);
    return res;
  }

  segtree(int _n) : n(_n) {
    assert(n > 0);
    tree.resize(2 * n - 1);
    build(0, 0, n - 1);
  }

  template <typename M>
  segtree(const vector<M> &v) {
    n = (int) v.size();
    assert(n > 0);
    tree.resize(2 * n - 1);
    build(0, 0, n - 1, v);
  }

  node get(int ll, int rr) {
    assert(0 <= ll && ll <= rr && rr <= n - 1);
    return get(0, 0, n - 1, ll, rr);
  }

  node get(int p) {
    assert(0 <= p && p <= n - 1);
    return get(0, 0, n - 1, p, p);
  }

  template <typename... M>
  void modify(int ll, int rr, const M&... v) {
    assert(0 <= ll && ll <= rr && rr <= n - 1);
    modify(0, 0, n - 1, ll, rr, v...);
  }

  // find_first and find_last call all FALSE elements
  // to the left (right) of the sought position exactly once

  int find_first(int ll, int rr, const function<bool(const node&)> &f) {
    assert(0 <= ll && ll <= rr && rr <= n - 1);
    return find_first(0, 0, n - 1, ll, rr, f);
  }

  int find_last(int ll, int rr, const function<bool(const node&)> &f) {
    assert(0 <= ll && ll <= rr && rr <= n - 1);
    return find_last(0, 0, n - 1, ll, rr, f);
  }
};

vector<int> zFunction(string const &s) {
	int n = (int) s.size();
	vector<int> z(n);
	int left = 0;
	int right = 0;
	for (int i = 1; i < n; i++) {
		z[i] = i >= right ? 0 : min(right - i, z[i - left]);
		while (i + z[i] < n && s[z[i]] == s[i + z[i]]) {
			++z[i];
		}
		if (i + z[i] > right) {
			left = i;
			right = i + z[i];
		}
	}
	return z;
}

vector<long long> getV(string const &s, vector<int> const &w) {
	int n = (int) s.size();
	vector<int> p(n);
	vector<long long> sum(n);
	int k = -1;
	p[0] = -1;
	sum[0] = w[0];
	for (int i = 1; i < n; i++) {
		while (k > -1 && s[k + 1] != s[i]) {
			k = p[k];
		}
		if (s[k + 1] == s[i]) {
			k++;
		}
		sum[i] = w[i];
		if (k >= 0) {
			sum[i] += sum[k];
		}
	}
	return sum;
}

struct stupidtree {
	vector<long long> s;

	stupidtree(int n) : s(n) {}

	void modify(int left, int right, upinfo info) {
		for (int i = left; i <= right; i++) {
			s[i] = updates[info.index].values[i - left];
		}
	}

	node get(int left, int right) {
		long long ans = 0;
		for (int i = left; i <= right; i++) {
			ans += s[i];
		}
		node res;
		res.sum = ans;
		return res;
	}
};

vector<long long> solveSmart(string const &s, string const &t, vector<int> const &w, vector<pair<int, int>> const &qs) {
	int n = (int) w.size();
	string zs = s + "@" + t;
	vector<int> z = zFunction(zs);
	int lenT = (int) t.size();
	vector<vector<int>> qByL(lenT);
	int queries = (int) qs.size();
	for (int i = 0; i < queries; i++) {
		qByL[qs[i].first].push_back(i);
	}
	updates = {update(getV(s, w))};
	segtree tree(vector<int>(lenT, 0));
	// stupidtree tree(lenT);
	vector<long long> ans(queries);
	for (int i = lenT - 1; i >= 0; i--) {
		int maxLen = z[n + 1 + i];
		if (maxLen > 0) {
			tree.modify(i, i + maxLen - 1, upinfo{i, i + maxLen - 1, 0});
		}
		for (int qid : qByL[i]) {
			int right = qs[qid].second;
			ans[qid] = tree.get(i, right).sum;
		}
	}
	return ans;
}

int main() {
	std::cin.tie(NULL); std::ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	string s, t;
	cin >> s >> t;
	vector<int> w(n);
	for (int &x: w) cin >> x;
	vector<pair<int, int>> qs(m);
	for (auto &e: qs) {
		cin >> e.first >> e.second;
		e.first--;
		e.second--;
	}

	vector<long long> ans = solveSmart(s, t, w, qs);
	for (auto &x : ans) {
		cout << x << '\n';
	}

}

詳細信息

Test #1:

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

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: 0
Accepted
time: 0ms
memory: 3668kb

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:

3
13
13
174

result:

ok 4 lines

Test #3:

score: 0
Accepted
time: 187ms
memory: 156032kb

input:

150000 150000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:

108147037823514
221878585246974
455339807727642
440286198422821
148115747906237
88695249853257
351159618462315
58850354020997
65824434822005
270158033672354
197732558443069
298193894693053
239511187032650
28139154231325
408380171835227
268053430937402
32417121185965
104813548228675
44074926058619
78...

result:

ok 150000 lines

Test #4:

score: -100
Wrong Answer
time: 212ms
memory: 155888kb

input:

150000 150000
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...

output:

503969317928829
112638556022185
503915587474294
2166223193286432
295388515578381
1618048602896769
632231520585472
166322478628783
485038046183630
1166225262583093
1443449684311962
477676900398846
55994169916421
540623785795639
2472139575834189
2294192983107523
2826063325778731
154700081279584
148483...

result:

wrong answer 1st lines differ - expected: '528900815691571', found: '503969317928829'