Codeforces Round #756 (Div. 3)

比赛链接

Codeforces Round #756 (Div. 3)

E2. Escape The Maze (hard version)

Vlad built a maze out of n rooms and n1 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 xi, and no two friends are in the same room (that is, xixj for all ij ). 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(1t104) - 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(1k<n2105) - the number of rooms and friends, respectively.
The next line of the test case contains k integers x1,x2,,xk(2xin) - numbers of rooms with friends. All xi are different.
The next n1 lines contain descriptions of the corridors, two numbers per line vj and uj(1uj,vjn) - 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 2105.

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 ai is positive, then the student credits that amount of money via ATM. Otherwise, the student withdraws |ai| 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(1t104) - the number of test cases.
Each test case consists of two lines. The first one contains integers n and s(1n2105;0s109) the length of the a array and the initial amount of rubles in the ATM. The second contains n integers a1,a2,,an(109ai109) elements of the a array. Note that ai can be zero.
It is guaranteed that the sum of the values n over all test cases does not exceed 2105.

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 开始,到 j1 结束,即 x+xi+xi+1++xj<0,即 x+sjsi1<0,即 xsi1<sj,其中 ji 的右边第一个满足此不等式的下标,即要找 i 的左边第一个 sj 大于 xsi1j,其贡献为 ji,可用线段树求解,当然这里没有修改操作,直接转换为 + 求解即可

  • 时间复杂度: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; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16257488.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

支付宝打赏