제출 #737814

#제출 시각아이디문제언어결과실행 시간메모리
737814arnold518Tourism (JOI23_tourism)C++17
28 / 100
5064 ms24940 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int MAXN = 1e5;
const int SQ = 300;

int N, M, Q;
vector<int> adj[MAXN+10];
int A[MAXN+10];

struct Data
{
	int l, r, k;
};
Data B[MAXN+10];

multiset<pii> S;

int dfn[MAXN+10], cnt, par[MAXN+10][30], dep[MAXN+10];
void dfs(int now, int bef, int d)
{
	dfn[now]=++cnt;
	dep[now]=d;
	par[now][0]=bef;
	for(auto nxt : adj[now])
	{
		if(nxt==bef) continue;
		dfs(nxt, now, d+1);
	}
}

int lca(int u, int v)
{
	if(dep[u]>dep[v]) swap(u, v);
	for(int i=20; i>=0; i--) if(dep[u]<=dep[par[v][i]]) v=par[v][i];
	if(u==v) return u;
	for(int i=20; i>=0; i--) if(par[u][i]!=par[v][i]) u=par[u][i], v=par[v][i];
	return par[u][0];
}

int dist(int u, int v)
{
	return dep[u]+dep[v]-dep[lca(u, v)]*2;
}

int ans=0, ans1[MAXN+10];

void push(int x)
{
	auto it=S.lower_bound({dfn[x], x});
	set<pii>::iterator lt, rt;
	if(it==S.end()) lt=prev(it), rt=S.begin();
	else if(it==S.begin()) rt=it, lt=prev(S.end());
	else rt=it, lt=prev(it);
	S.insert({dfn[x], x});
	ans-=dist(rt->second, lt->second);
	ans+=dist(rt->second, x);
	ans+=dist(lt->second, x);
	//printf("PUSH %d %d\n", x, ans);
}

void pop(int x)
{
	auto it=S.lower_bound({dfn[x], x});
	set<pii>::iterator lt, rt;
	if(it==S.begin()) lt=prev(S.end());
	else lt=prev(it);
	if(it==prev(S.end())) rt=S.begin();
	else rt=next(it);
	S.erase(S.find({dfn[x], x}));
	ans+=dist(rt->second, lt->second);
	ans-=dist(rt->second, x);
	ans-=dist(lt->second, x);
	//printf("POP %d %d\n", x, ans);
}

int main()
{
	scanf("%d%d%d", &N, &M, &Q);
	for(int i=1; i<N; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	for(int i=1; i<=M; i++) scanf("%d", &A[i]);
	for(int i=1; i<=Q; i++) scanf("%d%d", &B[i].l, &B[i].r), B[i].k=i;

	sort(B+1, B+Q+1, [&](const Data &p, const Data &q)
	{
		if(p.l/SQ==q.l/SQ) return p.r<q.r;
		return p.l/SQ<q.l/SQ;
	});

	dfs(1, 1, 1);
	for(int j=1; j<=20; j++) for(int i=1; i<=N; i++) par[i][j]=par[par[i][j-1]][j-1];

	int l=1, r=1;
	S.insert({dfn[A[1]], A[1]});
	for(int i=1; i<=Q; i++)
	{
		while(r<B[i].r) push(A[++r]);
		while(B[i].l<l) push(A[--l]);
		while(r>B[i].r) pop(A[r--]);
		while(l<B[i].l) pop(A[l++]);
		ans1[B[i].k]=ans/2;
	}
	for(int i=1; i<=Q; i++) printf("%d\n", ans1[i]+1);	
}

컴파일 시 표준 에러 (stderr) 메시지

tourism.cpp: In function 'int main()':
tourism.cpp:83:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   83 |  scanf("%d%d%d", &N, &M, &Q);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~
tourism.cpp:87:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   87 |   scanf("%d%d", &u, &v);
      |   ~~~~~^~~~~~~~~~~~~~~~
tourism.cpp:91:31: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   91 |  for(int i=1; i<=M; i++) scanf("%d", &A[i]);
      |                          ~~~~~^~~~~~~~~~~~~
tourism.cpp:92:31: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   92 |  for(int i=1; i<=Q; i++) scanf("%d%d", &B[i].l, &B[i].r), B[i].k=i;
      |                          ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...