HDOJ 6795 Little W and Contest(항 전 다 교 2020 제3 차 1005)
par[y]=x;
if(rk[x]==rk[y]) rk[x]++;
rest1 = tot1-cnt1[x]-cnt1[y];// xy 1 2
rest2 = tot2-cnt2[x]-cnt2[y];
ans = cnt2[x]*cnt2[y]*(rest1+rest2);
//x 2,y 2, 1 2
ans += cnt2[x]*cnt1[y]*rest2;
//x 2,y 1, 2
ans += cnt2[y]*cnt1[x]*rest2;
//x 1,y 2, 2
cnt1[x] = cnt1[y]+cnt1[x];
cnt2[x] = cnt2[y]+cnt2[x];// x y
결 과 를 계산 한 후에 Y 조 의 모든 사람 을 x 조,즉 cnt 1[x]에 cnt 1[y],cnt 2[x]에 cnt 2[y]를 더 하 는 것 을 기억 해 야 합 니 다!코드:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
template<class T>inline void read(T &x){x=0;char o,f=1;while(o=getchar(),o<48)if(o==45)f=-f;do x=(x<<3)+(x<<1)+(o^48);while(o=getchar(),o>47);x*=f;}
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
#define ll long long
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repb(i,a,b) for(int i=(a);i>=b;i--)
#define INF 0x3f3f3f3f
#define cendl printf("
")
ll gcd(ll a,ll b){ while(b^=a^=b^=a%=b); return a; }
//#define INF 0x7fffffff
const int MAXN = 1e5+5;
const int Mod = 1e9+7;
int a[MAXN];
int n;
//
int par[MAXN];//
int rk[MAXN];// , ( )
void init(int n){
for(int i=1;i<=n;i++){
par[i]=i;
rk[i]=0;
}
}
int find(int x){// ,
if(par[x]==x) return x;
else return par[x]=find(par[x]);// i
}
ll cnt1[MAXN];
ll cnt2[MAXN];// 1 2
ll tot1,tot2;// 1 2
ll merge(int x,int y){//
ll ans;
ll rest1,rest2;
x=find(x);
y=find(y);
if(x==y) return 0;//
if(rk[x]<rk[y]){
par[x]=y;//x y
rest1 = tot1-cnt1[y]-cnt1[x];
rest2 = tot2-cnt2[y]-cnt2[x];// 1 2
// ans
ans = cnt2[x]*cnt2[y]*(rest1+rest2);//x 2,y 2, 1 2
ans += cnt2[x]*cnt1[y]*rest2;
ans += cnt2[y]*cnt1[x]*rest2;
cnt1[y] = cnt1[y]+cnt1[x];
cnt2[y] = cnt2[y]+cnt2[x];// x y
}
else{
par[y]=x;
if(rk[x]==rk[y]) rk[x]++;
rest1 = tot1-cnt1[x]-cnt1[y];
rest2 = tot2-cnt2[x]-cnt2[y];
// ans
ans = cnt2[x]*cnt2[y]*(rest1+rest2);//x 2,y 2, 1 2
ans += cnt2[x]*cnt1[y]*rest2;
ans += cnt2[y]*cnt1[x]*rest2;
cnt1[x] = cnt1[y]+cnt1[x];
cnt2[x] = cnt2[y]+cnt2[x];// x y
}
return ans;
}
void solve(){
tot1=tot2=0;
cin>>n;
init(n);
rep(i,1,n){
cin>>a[i];
if(a[i]==1) cnt1[i]=1,cnt2[i]=0,tot1++;//
else cnt2[i]=1,cnt1[i]=0,tot2++;
}
ll res = (tot2*(tot2-1)/2*tot1 + tot2*(tot2-1)*(tot2-2)/2/3);
//
cout<<res%Mod<<endl;
int u,v;
rep(i,1,n-1){
cin>>u>>v;
res-=merge(u,v);
cout<<max(res%Mod,(ll)0)<<endl;
}
}
int main(){
int z;
cin>>z;
while(z--) solve();
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
LeetCode(61)UniquePath1제목은 다음과 같습니다. A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.