1. 程式人生 > 資訊 >馬斯克稱 Neuralink 可以解決病態肥胖問題,專家表態:這實際上是可能的

馬斯克稱 Neuralink 可以解決病態肥胖問題,專家表態:這實際上是可能的

比賽連結

Codeforces Round #756 (Div. 3)

E2. Escape The Maze (hard version)

Vlad built a maze out of \(n\) rooms and \(n-1\) bidirectional corridors. From any room \(u\) any other room \(v\) can be reached through a sequence of corridors. Thus, the room system forms an undirected tree.
Vlad invited \(k\)

friends to play a game with them.
Vlad starts the game in the room 1 and wins if he reaches a room other than 1 , into which exactly one corridor leads. Friends are placed in the maze: the friend with number \(i\) is in the room \(x_{i}\), and no two friends are in the same room (that is, \(x_{i} \neq x_{j}\)
for all \(i \neq j\) ). Friends win if one of them meets Vlad in any room or corridor before he wins.

For one unit of time, each participant of the game can go through one corridor. All participants move at the same time. Participants may not move. Each room can fit all participants at the same time.

Friends know the plan of a maze and intend to win. They don't want to waste too much energy. They ask you to determine if they can win and if they can, what minimum number of friends must remain in the maze so that they can always catch Vlad.

In other words, you need to determine the size of the minimum (by the number of elements) subset of friends who can catch Vlad or say that such a subset does not exist.

Input

The first line of the input contains an integer \(t\left(1 \leq t \leq 10^{4}\right)\) - the number of test cases in the input. The input contains an empty string before each test case.

The first line of the test case contains two numbers \(n\) and \(k\left(1 \leq k<n \leq 2 \cdot 10^{5}\right)\) - the number of rooms and friends, respectively.
The next line of the test case contains \(k\) integers \(x_{1}, x_{2}, \ldots, x_{k}\left(2 \leq x_{i} \leq n\right)\) - numbers of rooms with friends. All \(x_{i}\) are different.
The next \(n-1\) lines contain descriptions of the corridors, two numbers per line \(v_{j}\) and \(u_{j}\left(1 \leq u_{j}, v_{j} \leq n\right)\) - numbers of rooms that connect the \(j\) corridor. All corridors are bidirectional. From any room, you can go to any other by moving along the corridors.
It is guaranteed that the sum of the values \(n\) over all test cases in the test is not greater than \(2 \cdot 10^{5}\).

Output

Print \(t\) lines, each line containing the answer to the corresponding test case. The answer to a test case should be \(-1\) if Vlad wins anyway and a minimal number of friends otherwise.

Example

input

4

8 2
5 3
4 7
2 5
1 6
3 6
7 2
1 7
6 8

8 4
6 5 7 3
4 7
2 5
1 6
3 6
7 2
1 7
6 8

3 1
2
1 2
2 3

3 2
2 3
3 1
1 2

output

-1
2
1
2

解題思路

dfs,倍增

如果存在某個節點上,則根節點到不了以節點為根的子樹的任意一個葉子節點上,將當前所有存在的節點都向上走到極限位置上,即根節點向下走的同時能夠與當前節點相遇的位置,即假設當前節點深度為 \(dep[i]\),根節點深度為 \(1\),則極限位置的深度為 \(dep[i]/2+1\),可以倍增求解,最後從根節點 \(dfs\) 一遍即可,即遇到極限位置則答案加一,否則如果到達葉子節點則答案為 \(-1\)

  • 時間複雜度:\(O(klogn+n)\)

程式碼

// Problem: E2. Escape The Maze (hard version)
// Contest: Codeforces - Codeforces Round #756 (Div. 3)
// URL: https://codeforces.com/contest/1611/problem/E2
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=2e5+5;
int t,n,k,dep[N],f[N][20],tt,a[N],res;
vector<int> adj[N];
bool v[N],ret;
void bfs()
{
	queue<int> q;
	q.push(1);
	dep[1]=1;
	while(q.size())
	{
		int x=q.front();
		q.pop();
		for(int y:adj[x])
		{
			if(!dep[y])
			{
				dep[y]=dep[x]+1;
				f[y][0]=x;
				for(int i=1;i<=tt;i++)f[y][i]=f[f[y][i-1]][i-1];
				q.push(y);
			}
		}
	}
}
void dfs(int x,int fa)
{
	if(v[x])
	{
		res++;
		return ;
	}
	if(x!=1&&adj[x].size()==1)
	{
		ret=true;
		return ;
	}
	for(int y:adj[x])
	{
		if(y==fa)continue;
		dfs(y,x);
	}
}
int main()
{
    help;
    for(cin>>t;t;t--)
    {
    	cin>>n>>k;
    	tt=log(n)/log(2);
		for(int i=1;i<=n;i++)adj[i].clear(),dep[i]=v[i]=0;
		for(int i=1;i<=k;i++)cin>>a[i],v[a[i]]=true;
		for(int i=1;i<n;i++)
		{
			int x,y;
			cin>>x>>y;
			adj[x].pb(y);
			adj[y].pb(x);
		}
		bfs();
		for(int i=1;i<=k;i++)
		{
			int x=a[i];
			int d=dep[x]/2+1;
			for(int j=tt;j>=0;j--)
				if(dep[f[x][j]]>=d)x=f[x][j],v[x]=true;
		} 
		res=ret=0;
		dfs(1,0);
		if(ret)
			puts("-1");
		else
			cout<<res<<'\n';
    }
    return 0;
}

F. ATM and Students

Polycarp started working at a bank. He was assigned to monitor the ATM. The ATM initially contains \(s\) rubles.
A queue of \(n\) students lined up to him. Each student wants to either withdraw a certain amount of money or deposit it into an account. If \(a_{i}\) is positive, then the student credits that amount of money via ATM. Otherwise, the student withdraws \(\left|a_{i}\right|\) rubles.

In the beginning, the ATM is turned off and an arbitrary number of students are not served. At some point, Polycarp turns on the ATM, which has an initial amount of \(s\) rubles. Then, the remaining students start queueing at the ATM. If at some point in time there is less money in the ATM than the student wants to withdraw, then the student is not served and Polycarp turns off the ATM and does not turn it on anymore.
More formally, the students that are served are forming a contiguous subsequence.
Polycarp wants the ATM to serve the maximum number of students. Help him in this matter. Print the numbers of the first and last student, or determine that he will not be able to serve anyone.

In other words, find such a longest continuous segment of students that, starting with the sum of \(s\) at the ATM, all these students will be served. ATM serves students consistently (i.e. one after another in the order of the queue).

Input

The first line of the input contains one integer \(t\left(1 \leq t \leq 10^{4}\right)\) - the number of test cases.
Each test case consists of two lines. The first one contains integers \(n\) and \(s\left(1 \leq n \leq 2 \cdot 10^{5} ; 0 \leq s \leq 10^{9}\right)-\) the length of the \(a\) array and the initial amount of rubles in the ATM. The second contains \(n\) integers \(a_{1}, a_{2}, \ldots, a_{n}\left(-10^{9} \leq a_{i} \leq 10^{9}\right)-\) elements of the \(a\) array. Note that \(a_{i}\) can be zero.
It is guaranteed that the sum of the values \(n\) over all test cases does not exceed \(2 \cdot 10^{5}\).

Output

Print \(t\) lines, each line must contain the answer to the corresponding set of input data: if the answer exists, print the numbers of the first and last served student. If there is no solution, then print \(-1\) on the line.
If there are several possible answers, print any.

Example

input

3
4 10
-16 2 -6 8
3 1000
-100000 -100000 -100000
6 0
2 6 -164 1 -1 -6543

output

2 4
-1
1 2

解題思路

分治

假設開始時權值為 \(x\),從 \(i\) 開始,到 \(j-1\) 結束,即 \(x+x_i+x_{i+1}+\dots + x_j<0\),即 \(x+s_j-s_{i-1}<0\),即 \(x-s_{i-1}<-s_j\),其中 \(j\)\(i\) 的右邊第一個滿足此不等式的下標,即要找 \(i\) 的左邊第一個 \(-s_j\) 大於 \(x-s_{i-1}\)\(j\),其貢獻為 \(j-i\),可用線段樹求解,當然這裡沒有修改操作,直接轉換為 \(倍增+分治\) 求解即可

  • 時間複雜度:\(O(nlogn)\)

程式碼

// Problem: F. ATM and Students
// Contest: Codeforces - Codeforces Round #756 (Div. 3)
// URL: https://codeforces.com/contest/1611/problem/F
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
// #define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=2e5+5;
int t,n,x,res[N];
LL a[N],s[N],b[N],f[N][20];
LL mx(int l,int r)
{
	int k=log(r-l+1)/log(2);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}
int cal(LL x,int l,int r)
{
	if(mx(l,r)<=x)return -1;
	if(l==r)return l;
	int mid=l+r>>1;
	if(mx(l,mid)>x)return cal(x,l,mid);
	return cal(x,mid+1,r);
}
int main()
{
    help;
    for(cin>>t;t;t--)
    {
    	cin>>n>>x;
    	for(int i=1;i<=n;i++)cin>>a[i],s[i]=s[i-1]+a[i],f[i][0]=-s[i];
    	int t=log(n)/log(2);
    	for(int i=1;i<=t;i++)
    		for(int j=1;j+(1<<(i-1))<=n;j++)f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]);
    	int res=0,st=0,en=0;
    	for(int i=1;i<=n;i++)
    	{
    		int pos=cal(x-s[i-1],i,n);
    		if(pos==-1)
    		{
    			if(res<n-i+1)res=n-i+1,st=i,en=n;
    		}
    		else
    		{
    			if(res<pos-i)res=pos-i,st=i,en=pos-1;
    		}
    	}
    	if(res)cout<<st<<' '<<en<<'\n';
    	else
    		puts("-1");
    }
    return 0;
}