Submission #216734

#TimeUsernameProblemLanguageResultExecution timeMemory
216734aintaHarvest (JOI20_harvest)C++17
100 / 100
828 ms128592 KiB
#include<cstdio>
#include<algorithm>
#include<vector>
#define N_ 201000
#define pli pair<long long, int>
using namespace std;
int n, m, QC, Nxt[N_], Deg[N_], Q[N_];
long long L, CC, A[N_], B[N_], NL[N_];
vector<long long>G[N_];
struct Query {
	int num;
	long long t;
};
vector<Query>QQ[N_];
struct Edge {
	int e;
	long long d;
};
vector<Edge>E[N_];
int Num[N_], Ed[N_], cnt;
long long Res[N_];
vector<long long>TT;


struct RMQ {
	vector<pli>w;
	vector<int>rr;
	int n;
	vector<vector<long long>>IT;
	void Make(int nd, int b, int e) {
		for (int i = b; i <= e; i++)IT[nd].push_back(rr[i]);
		sort(IT[nd].begin(), IT[nd].end());
		if (b == e)return;
		int m = (b + e) >> 1;
		Make(nd * 2, b, m);
		Make(nd * 2 + 1, m + 1, e);
	}
	void build(vector<long long>&inp) {
		n = inp.size();
		w.resize(n);
		rr.resize(n);
		for (int i = 0; i < n; i++)w[i] = { inp[i],i };
		sort(w.begin(), w.end());
		for (int i = 0; i < n; i++)rr[w[i].second] = i;
		int sz = 1;
		while (sz < n)sz *= 2;
		IT.resize(sz * 2);
		for (int i = 0; i < sz * 2; i++)IT[i].clear();
		Make(1, 0, n - 1);
	}
	int Gap(int nd, int b, int e, int s, int l, int g) {
		if (s > l)return 0;
		if (s <= b && e <= l) return lower_bound(IT[nd].begin(), IT[nd].end(), g) - IT[nd].begin();
		int m = (b + e) >> 1, r=0;
		if (s <= m)r += Gap(nd * 2, b, m, s, l, g);
		if (l > m)r += Gap(nd * 2 + 1, m + 1, e, s, l, g);
		return r;
	}
	int Get(int b, int e, long long t) {
		int pv = lower_bound(w.begin(), w.end(), pli(t + 1,0 )) - w.begin();
		return Gap(1, 0, n - 1, b, e, pv);
	}
}PT;

long long Dep[N_];
vector<int>TV;
void DFS(int a, long long d) {
	Num[a] = TT.size();
	TV.push_back(a);
	Dep[a] = d;
	for (auto &t : G[a]) {
		TT.push_back(t + d);
	}
	for (auto &t : E[a]) {
		DFS(t.e, d + t.d);
	}
	Ed[a] = TT.size();
}
long long SS[N_];
long long Calc(long long T, long long tot) {
	int pv = lower_bound(TT.begin(), TT.end(), T + 1)-TT.begin();
	if (pv == 0)return 0ll;
	long long res = pv;
	res += (T / tot)*pv - SS[pv - 1];
	res -= pv - PT.Get(0, pv - 1, T%tot);
	return res;
}
void Do(int a) {
	vector<int>V;
	int t = a;
	long long tot = 0;
	while (1) {
		tot += NL[t];
		Deg[t] = 0;
		V.push_back(t);
		t = Nxt[t];
		if (t == a)break;
	}
	int sz = V.size();
	int i;
	for (i = 1; i < sz; i++) {
		E[V[i]].push_back({ V[i - 1],NL[V[i - 1]] });
	}
	TT.clear();
	TV.clear();
	int rt = V[sz - 1];
	DFS(rt, 0);
	if (TT.empty())return;
	PT.build(TT);
	for (auto &v : TV) {
		for (auto &q : QQ[v]) {
			Res[q.num] += PT.Get(Num[v], Ed[v] - 1, q.t + Dep[v]);
		}
	}

	t = rt;
	long long ss = 0;
	sort(TT.begin(), TT.end());
	vector<long long>TMod;
	for (i = 0; i < TT.size(); i++) {
		TMod.push_back(TT[i] % tot);
		SS[i] = TT[i] / tot;
		if (i)SS[i] += SS[i - 1];
	}
	PT.build(TMod);
	while (1) {
		ss += NL[t];
		t = Nxt[t];
		for (auto &z : QQ[t]) {
			Res[z.num] += Calc(z.t - ss, tot);
		}
		if (t == rt)break;
	}
}
int main() {
	//freopen("input.txt", "r", stdin);
	int i;
	scanf("%d%d%lld%lld", &n, &m, &L, &CC);
	for (i = 1; i <= n; i++) {
		scanf("%lld", &A[i]);
	}
	for (i = 1; i <= n; i++) {
		long long x = (A[i] - CC + CC*L)%L;
		int pv = lower_bound(A + 1, A + n + 1, x + 1) - A;
		pv--;
		if (pv == 0)pv = n;
		Nxt[i] = pv;
		NL[i] = A[i] - A[pv];
		if (NL[i] < CC) NL[i] += (CC - NL[i] + L - 1) / L * L;
		Deg[Nxt[i]]++;
	}
	for (i = 1; i <= m; i++) {
		scanf("%lld", &B[i]);
		int pv = lower_bound(A + 1, A + n + 1, B[i] + 1) - A;
		pv--;
		if (pv == 0)pv = n;
		long long t = B[i] - A[pv];
		if (t < 0)t += L;
		G[pv].push_back(t);
	}
	int head = 0, tail = 0;
	for (i = 1; i <= n; i++)if (!Deg[i])Q[++tail] = i;
	while (head < tail) {
		int x = Q[++head];
		Deg[Nxt[x]]--;
		E[Nxt[x]].push_back({ x,NL[x] });
		if (!Deg[Nxt[x]])Q[++tail] = Nxt[x];
	}
	scanf("%d", &QC);
	for (i = 1; i <= QC; i++) {
		int a;
		long long t;
		scanf("%d%lld", &a, &t);
		QQ[a].push_back({ i,t });
	}
	for (i = 1; i <= n; i++) {
		if (Deg[i]) {
			Do(i);
		}
	}
	for (i = 1; i <= QC; i++)printf("%lld\n", Res[i]);
}

Compilation message (stderr)

harvest.cpp: In function 'void Do(int)':
harvest.cpp:120:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (i = 0; i < TT.size(); i++) {
              ~~^~~~~~~~~~~
harvest.cpp: In function 'int main()':
harvest.cpp:138:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d%lld%lld", &n, &m, &L, &CC);
  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
harvest.cpp:140:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld", &A[i]);
   ~~~~~^~~~~~~~~~~~~~~
harvest.cpp:153:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld", &B[i]);
   ~~~~~^~~~~~~~~~~~~~~
harvest.cpp:169:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &QC);
  ~~~~~^~~~~~~~~~~
harvest.cpp:173:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%lld", &a, &t);
   ~~~~~^~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...