B2 n=2e5
dfs连通分量/并查集
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
#define rep(i,a,n) for(int i=a;i<=n;i++)
ll q,n,x,to[maxn],vis[maxn],num[maxn];
void init(){
rep(i,1,n){
vis[i]=0;
num[i]=0; //环的大小
to[i]=0;
}
}
/*void dfs(ll x,ll cnt){ dfs(i,0)
if(vis[x])
{
num[x]=cnt;
return;
}
vis[x]=1;
dfs(to[x],cnt+1);
num[x]=num[to[x]];
}*/
ll dfs(ll x,ll cnt) //点的编号 环的大小
{
vis[x]=1;
if(vis[to[x]]){
num[x]=cnt;
return cnt;
}
num[x]=dfs(to[x],cnt+1);
return num[x];
}
int main(){
cin>>q;
while(q--){
init();
cin>>n;
rep(i,1,n){
cin>>x;
to[i]=x;
}
for(int i=1;i<=n;i++){
if(!vis[i])
dfs(i,1); //连通分量
}
rep(i,1,n){
cout<<num[i]<<" ";
}
cout<<endl;
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
#define rep(i,a,n) for(int i=a;i<=n;i++)
ll q,n,x,pre[maxn],ran[maxn],num[maxn];
void init(ll n){
rep(i,1,n){
num[i]=1;
pre[i]=i;
ran[i]=1;
}
}
ll find(ll x){
return x==pre[x]?x:pre[x]=find(pre[x]);//x的父亲变成根 直接连根
}
void unit(ll x,ll y){
ll px=find(x),py=find(y);
if(px==py)
return;
if(ran[px]<ran[py]){
pre[px]=py;
num[py]+=num[px];
}
else{
pre[py]=px;
num[px]+=num[py];
if(ran[px]==ran[py])
ran[px]++;
}
}
int main(){
cin>>q;
while(q--){
cin>>n;
init(n);
rep(i,1,n){
cin>>x;
unit(i,x);
}
rep(i,1,n){
cout<<num[find(i)]<<" ";
}
cout<<endl;
}
return 0;
}
C2 n<=1e18 38次 m用3的不同次幂表示 >=n 的最小的m
转成3进制
7 21 12 1p[0] i=1 为2 ans=0 num[2]=1 ptr++ 121 1p[2]=9
15=9+6 120 27 0221 ptr=4
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
ll n,num[maxn],q,a[maxn];
int main(){
a[0]=1;
for(int i=1;i<=38;i++){
a[i]=a[i-1]*3;
}
// cout<<a[38]<<endl;
cin>>q;
while(q--){
cin>>n;
ll ptr=0,ans=0;
memset(num,0,sizeof num);
while(n){
num[ptr++]=n%3;
n=n/3;
}
for(int i=0;i<ptr;i++){ //转3进制 15 120 021
if(num[i]>1){
ans=0;
num[i+1]++;
if(i==ptr-1)
ptr++;
}
else{
ans+=num[i]*a[i]; //1*a[3]=27
}
}
cout<<ans<<endl;
}
return 0;
}
E dp
楼梯等电梯花费为c
n层 2种方式 楼梯a[i] 电梯b[i]
到第i层 最短时间 dp[1][0]=0
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const ll inf=2e18;
#define rep(i,a,n) for(int i=a;i<=n;i++)
ll q,n,c;
ll dp[maxn][2],a[maxn],b[maxn];
int main(){
cin>>n>>c;
rep(i,1,n-1){
cin>>a[i];
}
rep(i,1,n-1){
cin>>b[i];
}
for(int i=1;i<=n;i++){
dp[i][0]=dp[i][1]=inf;
}
dp[1][0]=0;//1-1走楼梯 花费0
dp[1][1]=c; //等电梯花费为c
for(int i=2;i<=n;i++){
dp[i][0]=min(dp[i][0],dp[i-1][0]+a[i-1]);
dp[i][0]=min(dp[i][0],dp[i-1][1]+a[i-1]);//电梯->楼梯
dp[i][1]=min(dp[i][1],dp[i-1][0]+c+b[i-1]);//楼梯->电梯 等
dp[i][1]=min(dp[i][1],dp[i-1][1]+b[i-1]);
}
cout<<0<<" ";
for(int i=2;i<=n;i++){
cout<<min(dp[i][0],dp[i][1]);
if(i!=n)
cout<<" ";
}
cout<<endl;
return 0;
}