2020HDU多校第三场

1001.

1002.

1003.

1004.

1005.

思路

先算出总数,再每次相连时减去以上4种情况

const int mod=1e9+7;
const int N=2e6+10;
int n;
ll f[N],a[N],s1[N],s2[N];
int ff(int x){
    if (f[x]==x)return x;
    return f[x]=ff(f[x]);
}
int main(){
    int T;
    cin>>T;
    while (T--){
        scanf("%d",&n);
        ll t1=0,t2=0;
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if (a[i]==1)t1++,s1[i]=1,s2[i]=0;
            else t2++,s2[i]=1,s1[i]=0;
            f[i]=i;
        }
        ll ans;
        if (t2<2)ans=0;
        else if (t2==2)ans=t1;
        else ans=t1*t2*(t2-1)/2+t2*(t2-1)*(t2-2)/6;
        printf("%lld\n",ans%mod);
        int x,y;
        for (int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            int xx=ff(x),yy=ff(y);
            if (xx!=yy){
                ans-=s1[yy]*s2[xx]*(t2-s2[xx]-s2[yy]);
                ans-=s1[xx]*s2[yy]*(t2-s2[xx]-s2[yy]);
                ans-=s2[xx]*s2[yy]*(t2-s2[xx]-s2[yy]);
                ans-=s2[xx]*s2[yy]*(t1-s1[xx]-s1[yy]);
                f[xx]=yy;
                s1[yy]+=s1[xx];s2[yy]+=s2[xx];
            }
            printf("%lld\n",ans%mod);
        }
    }
    return 0;
}

1006.

1007.

1008.

思路:

碰撞次数就是途经边数,分平行x轴的边,60度的边,-60度的边计算碰撞次数

const double eps=1e-8;
int L,x,y,vx,vy,k;
double h,p;
ll check(double t){
    ll ans=0;
    double xx=t*vx+x,yy=t*vy+y;
    if (yy>0)ans+=yy/h;
    if (yy<0)ans+=-yy/h+1;
    double y1=yy/2-xx*p+h/2;//坐标系逆时针旋转60度
    if (y1>0)ans+=y1/h;
    if (y1<0)ans+=-y1/h+1;
    y1=yy/2+xx*p+h/2;//坐标系顺时针旋转60度
    if (y1>0)ans+=y1/h;
    if (y1<0)ans+=-y1/h+1;
    return ans;
}
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        scanf("%d%d%d%d%d%d",&L,&x,&y,&vx,&vy,&k);
        h=sqrt(3)*L/2;
        p=sqrt(3)/2;
        double l=0,r=1e12;
        while (l+eps<r){
            double mid=(l+r)/2;
            if (check(mid)>=k)r=mid;
            else l=mid;
        }
        printf("%.8lf\n",r);
    }
    return 0;
}

1009.

1010.

1011.

猜你喜欢

转载自www.cnblogs.com/rair/p/13393052.html