답안 #343340

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
343340 2021-01-03T17:42:46 Z Gajowy Traffickers (RMI18_traffickers) C++14
100 / 100
2182 ms 33260 KB
#pragma GCC optimize("Ofast")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

#define mp make_pair
#define eb emplace_back
#define pb push_back
#define e1 first
#define e2 second
#define size(x) (int)x.size()
#define all(r) begin(r),end(r)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define time chrono::high_resolution_clock().now().time_since_epoch().count()
#define satori int testCases; cin>>testCases; while(testCases--)

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

///////////////////
#define DEBUG if(1)
///////////////////

const int MAXN=5e4+10;
const int MAXLEN=20;
const int LG=16;

int d[MAXN];
vector<int> g[MAXN];
int p[MAXN];
int par[LG][MAXN];
int t[MAXLEN][MAXLEN][MAXN];
int id[MAXN],sz[MAXN],idc;

void dfs(int u){
	id[u]=(++idc);
	sz[u]=1;
	for(auto v:g[u])
		if(p[u]!=v)
			par[0][v]=u,p[v]=u,d[v]=d[u]+1,dfs(v),sz[u]+=sz[v];
}

void add(int len,int res,int l,int r){
	for(;l<=idc;l=(l|(l-1))+1)
		t[len][res][l]++;
	r++;
	for(;r<=idc;r=(r|(r-1))+1)
		t[len][res][r]--;
}

void rem(int len,int res,int l,int r){
	for(;l<=idc;l=(l|(l-1))+1)
		t[len][res][l]--;
	r++;
	for(;r<=idc;r=(r|(r-1))+1)
		t[len][res][r]++;
}

int get(int len,int res,int p){
	int ans=0;
	for(;p;p=(p&(p-1)))
		ans+=t[len][res][p];
	return ans;
}

vector<int> path(int u,int v){
	vector<int> lpath,rpath;
	while(d[u]>d[v]){
		lpath.eb(u);
		u=p[u];
	}
	while(d[v]>d[u]){
		rpath.eb(v);
		v=p[v];
	}
	while(u!=v){
		lpath.eb(u);
		rpath.eb(v);
		u=p[u];
		v=p[v];
	}
	lpath.eb(u);
	for(int i=size(rpath)-1;i>=0;i--)
		lpath.eb(rpath[i]);
	return lpath;
}

int leq(int len,int res,int time){
	if(res>time)
		return 0;
	return 1+(time-res)/len;
}

int get_lca(int u,int v){
	if(d[v]>d[u])
		swap(u,v);
	for(int i=LG-1;i>=0;i--)
		if(d[u]-d[v]>=(1<<i))
			u=par[i][u];
	if(u==v)
		return u;
	for(int i=LG-1;i>=0;i--){
		if(par[i][u]!=par[i][v])
			u=par[i][u],v=par[i][v];
	}
	return par[0][u];
}

int count_path(int u,int v,int len,int res){
	int ans=0;
	int lca=get_lca(u,v);
	ans+=get(len-1,res,id[u])+get(len-1,res,id[v])-get(len-1,res,id[lca]);
	if(p[lca]!=0)
		ans-=get(len-1,res,id[p[lca]]);
	return ans;
}

int32_t main(){
	fastio;
	int n;
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].eb(v);
		g[v].eb(u);
	}
	dfs(1);
	for(int j=1;j<LG;j++)
		for(int i=1;i<=n;i++)
			par[j][i]=par[j-1][par[j-1][i]];
	int k;
	cin>>k;
	while(k--){
		int u,v;
		cin>>u>>v;
		vector<int> pth=path(u,v);
		for(int i=0;i<size(pth);i++)
			add(size(pth)-1,i,id[pth[i]],id[pth[i]]+sz[pth[i]]-1);
	}
	int q;
	cin>>q;
	while(q--){
		int type;
		cin>>type;
		if(type==1){
			int u,v;
			cin>>u>>v;
			vector<int> pth=path(u,v);
			for(int i=0;i<size(pth);i++)
				add(size(pth)-1,i,id[pth[i]],id[pth[i]]+sz[pth[i]]-1);
		}
		else
		if(type==2){
			int u,v;
			cin>>u>>v;
			vector<int> pth=path(u,v);
			for(int i=0;i<size(pth);i++)
				rem(size(pth)-1,i,id[pth[i]],id[pth[i]]+sz[pth[i]]-1);
		}
		else{
			ll ans=0;
			int u,v,l,r;
			cin>>u>>v>>l>>r;
			ll cnt1,cnt2;
			for(int i=0;i<MAXLEN;i++){
				for(int j=0;j<=i;j++){
					cnt1=leq(i+1,j,r)-leq(i+1,j,l-1);
					if(cnt1==0)
						continue;
					cnt2=count_path(u,v,i+1,j);
					ans+=cnt1*cnt2;
				}
			}
			cout<<ans<<'\n';
		}
	}
	return 0;
}

Compilation message

traffickers.cpp:2: warning: ignoring #pragma GCC optimization [-Wunknown-pragmas]
    2 | #pragma GCC optimization ("O3")
      | 
traffickers.cpp:3: warning: ignoring #pragma GCC optimization [-Wunknown-pragmas]
    3 | #pragma GCC optimization ("unroll-loops")
      |
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2540 KB Output is correct
2 Correct 6 ms 3564 KB Output is correct
3 Correct 7 ms 3564 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 157 ms 12140 KB Output is correct
2 Correct 148 ms 11244 KB Output is correct
3 Correct 150 ms 12140 KB Output is correct
4 Correct 153 ms 12268 KB Output is correct
5 Correct 157 ms 12268 KB Output is correct
6 Correct 166 ms 12268 KB Output is correct
7 Correct 145 ms 12012 KB Output is correct
8 Correct 143 ms 12396 KB Output is correct
9 Correct 130 ms 12524 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2009 ms 31800 KB Output is correct
2 Correct 1911 ms 32876 KB Output is correct
3 Correct 1880 ms 32492 KB Output is correct
4 Correct 2033 ms 31596 KB Output is correct
5 Correct 2182 ms 31284 KB Output is correct
6 Correct 1898 ms 32620 KB Output is correct
7 Correct 1705 ms 33260 KB Output is correct
8 Correct 1732 ms 32364 KB Output is correct