Codeforces Round #686 (Div. 3)

比赛链接

Codeforces Round #686 (Div. 3)

F. Array Partition

判断是否能将一个长度为 n 的数组分成 3 部分,使得两边的最大值都等于中间的最小值

解题思路

st,二分,前缀最值

可以先处理前缀最值和后缀最值,用后缀最值遍历后部分,中间部分用 st 表维护最小值,将前部分和中间部分满足条件的区间二分出来再判断即可

  • 时间复杂度:O(nlogn)

代码

// Problem: F. Array Partition // Contest: Codeforces - Codeforces Round #686 (Div. 3) // URL: https://codeforces.com/contest/1454/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,a[N],f[N][20],mx[N],mx1[N]; int ask(int l,int r) { int k=log(r-l+1)/log(2); return min(f[l][k],f[r-(1<<k)+1][k]); } signed main() { help; memset(f,0x3f,sizeof f); for(cin>>t;t;t--) { cin>>n; for(int i=1;i<=n;i++)cin>>a[i],f[i][0]=a[i],mx[i]=max(a[i],mx[i-1]); for(int i=n;i>=1;i--)mx1[i]=max(mx1[i+1],a[i]); int c=log(n)/log(2); for(int j=1;j<=c;j++) for(int i=1;i+(1<<(j-1))<=n;i++) f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]); bool fl=false; int x,y,z; for(int i=n;i-2>=1;i--) { z=n-i+1; int rpos=upper_bound(mx+1,mx+i-2+1,mx1[i])-mx-1; int lpos=lower_bound(mx+1,mx+i-2+1,mx1[i])-mx; if(lpos<i-1&&mx[lpos]==mx1[i]) { int l=2,r=i-1; while(l<r) { int mid=l+r+1>>1; if(ask(mid,i-1)<=mx1[i])l=mid; else r=mid-1; } if(l>=2&&l<=i-1&&ask(l,i-1)==mx1[i]) { int posr=l; int l=2,r=i-1; while(l<r) { int mid=l+r>>1; if(ask(mid,i-1)>=mx1[i])r=mid; else l=mid+1; } int posl=l; if(rpos+1==posl) { x=rpos,y=n-x-z; fl=true; break; } int ll=max(posl,lpos),rr=min(posr,rpos); if(ll<=rr) { if(ll-1>=lpos) { x=ll-1,y=n-x-z; fl=true; break; } if(rr+1<=posr||rr-ll+1>=2) { x=ll,y=n-x-z; fl=true; break; } } } } } if(fl) { puts("YES"); cout<<x<<' '<<y<<' '<<z<<'\n'; } else puts("NO"); for(int i=1;i<=n;i++) mx[i]=mx1[i]=0; for(int j=1;j<=c;j++) for(int i=1;i<=n;i++) f[i][j]=f[i][0]=0x3f3f3f3f; } return 0; }

E. Number of Simple Paths

求一棵基环树的简单路径的数量

解题思路

容斥原理

假设所有点对之间都有两条路径,则数量为 n×(n1),利用容斥原理,减去只有一条路径的点对数量即可,即对于基环上的点,设其子树大小为 sz,子树上的任意两点都只有一条路径,其数量为 sz×(sz1)/2,求环上的点可以利用拓扑排序不断将所有度数为 1 的清除掉,剩下的点即为环上的点// Problem: E. Number of Simple Paths
// Contest: Codeforces - Codeforces Round #686 (Div. 3)
// URL: https://codeforces.com/contest/1454/problem/E
// 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

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 bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }

template 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,de[N],sz[N];
bool v[N];
vector adj[N];
int dfs(int x,int fa)
{
sz[x]=1;
for(int y:adj[x])
{
if(!v[y]||yfa)continue;
dfs(y,x);
sz[x]+=sz[y];
}
return sz[x];
}
int main()
{
for(cin>>t;t;t--)
{
cin>>n;
for(int i=1;i<=n;i++)adj[i].clear(),de[i]=v[i]=sz[i]=0;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
adj[x].pb(y),adj[y].pb(x);
de[x]++,de[y]++;
}
queue q;
for(int i=1;i<=n;i++)
if(de[i]
1)q.push(i),v[i]=1;
while(q.size())
{
int x=q.front();
q.pop();
for(int y:adj[x])
if(--de[y]==1)q.push(y),v[y]=1;
}
LL res=1lln(n-1);
for(int i=1;i<=n;i++)
if(!v[i])
{
int sz=dfs(i,0);
res-=1llsz(sz-1)/2;
}
cout<<res<<"\n";
}
return 0;
}

  • 时间复杂度:O(n)

代码

// Problem: E. Number of Simple Paths // Contest: Codeforces - Codeforces Round #686 (Div. 3) // URL: https://codeforces.com/contest/1454/problem/E // 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,de[N],sz[N]; bool v[N]; vector<int> adj[N]; int dfs(int x,int fa) { sz[x]=1; for(int y:adj[x]) { if(!v[y]||y==fa)continue; dfs(y,x); sz[x]+=sz[y]; } return sz[x]; } int main() { for(cin>>t;t;t--) { cin>>n; for(int i=1;i<=n;i++)adj[i].clear(),de[i]=v[i]=sz[i]=0; for(int i=1;i<=n;i++) { int x,y; cin>>x>>y; adj[x].pb(y),adj[y].pb(x); de[x]++,de[y]++; } queue<int> q; for(int i=1;i<=n;i++) if(de[i]==1)q.push(i),v[i]=1; while(q.size()) { int x=q.front(); q.pop(); for(int y:adj[x]) if(--de[y]==1)q.push(y),v[y]=1; } LL res=1ll*n*(n-1); for(int i=1;i<=n;i++) if(!v[i]) { int sz=dfs(i,0); res-=1ll*sz*(sz-1)/2; } cout<<res<<"\n"; } return 0; }

__EOF__

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