2020.2.7比赛

电路图一系列。

这套题真的respect。

第一眼看到题的时候真的头都大了。再加上明明在家放假。真是一点想做它的欲望也没有。

结果只把第一题弄出来了QAQ。还好大家都只ac了这一道hhh。


电路图A

 

         

这道题看着很复杂很难搞的样子。实际上确实有点难搞orz。

我盯了它好久好久才终于看出来这是道组合数学,一开始真的没什么思路。

然后就比较好办了,就推推推,把公式规律推出来,就ok了。

数据范围有点大,多模一模,开long long也就问题不大了。

ans1=C(n,n/2-2).

ans2=C(n/2+1,4)*2+C(n/2+1,3).

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1000000007;
ll f[100000005];
ll st(ll a,ll b)
{
    ll ans=1;
    a%=mod;
    while(b)
    {
        if(b&1)ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
ll C(ll n,ll m)
{
    return f[n]*st(f[m],mod-2)%mod*st(f[n-m],mod-2)%mod;
}
int main()
{
    ll n;
    scanf("%d",&n);
    f[0]=1;
    for(ll i=1;i<=n;i++)
    f[i]=f[i-1]*i%mod;
    ll m=n/2+2;    
    cout<<C(n,m)<<endl;
    cout<<(2*C(m-1,4)%mod+C(m-1,3))%mod;
}

电路图B

 

考试的时候花了好长的时间才回忆起初中物理讲的串并联知识。

串联:R=R1+R2.

并联:R=R1*R2/(R1+R2).

 

然后很明显要用线段树来做。

然后我半个小时把这个题打了出来。然后样例都过不了orz。然后我就开始调试、找错,然后又打了一个多小时。然后我看到大佬们都交了两三道题了,我就有点慌。然后我真的不知道为什么哪里错了我就是连样例都过不了orz。然后不知不觉比赛就结束了QAQ。

据说直接线段树有70分,我有点难受。

比赛完了上网搜题解的时候,看到要用神奇的线段树(?)才能A掉这道题。

对于一个函数(a,b,c,d)表示一个R=(a*x+b)/(c*x+d)。

串联就可表示成(1,R,0,1),并联就可表示成(R,0,1,R)。

合并时,原电阻(a,b,c,d)与另一电阻(a',b',c',d')合并可得新电阻表示为(a'*a+b'*c,a'*b+b'*d,c'*a+d'*c,c'*b+d'*d)。

题目虽然精度不限,但大佬说保存10以下精度过不了?我没试过,就直接保存10精度了。

#include<bits/stdc++.h>
using namespace std;
#define ld long double
int n,g[250010],m,op,ql,qr,md;
ld ans;

struct ahj
{
    ld a,b,c,d,mx,mn;
}s[1000010];

void merge(ahj &x,ahj y)
{
    x.mn=(x.mn*y.a+y.b)/(x.mn*y.c+y.d);
    x.mx=(x.mx*y.a+y.b)/(x.mx*y.c+y.d);
    ld a=y.a*x.a+y.b*x.c;
    ld b=y.a*x.b+y.b*x.d;
    ld c=y.c*x.a+y.d*x.c;
    ld d=y.c*x.b+y.d*x.d;
    x=(ahj){1,b/a,c/a,d/a,x.mx,x.mn};
}

void clear(ahj &x)
{
    x.a=x.d=1;
    x.b=x.c=0;
}

void pd(int x)
{
    merge(s[x*2],s[x]);
    merge(s[x*2+1],s[x]);
    clear(s[x]);
}

void build(int x,int l,int r)
{
    clear(s[x]);
    if(l==r)
    {
        s[x].mn=s[x].mx=g[l];
        return;
    }
    int mid=(l+r)/2;
    build(x*2,l,mid);build(x*2+1,mid+1,r);
    s[x].mn=min(s[x*2].mn,s[x*2+1].mn);
    s[x].mx=max(s[x*2].mx,s[x*2+1].mx);
}

ld calc(ld x,ld y)
{
    return (x*y)/(x+y);
}

void q(int x,int l,int r)
{
    if(l!=r)pd(x);
    if(qr<l||r<ql) return;
    if(ql<=l&&r<=qr)
    {
        if(op==1)ans=max(ans,s[x].mx);
        if(op==2)ans=min(ans,s[x].mn);
        if(op==3) s[x]=(ahj){1,md,0,1,s[x].mx+md,s[x].mn+md};
        if(op==4) s[x]=(ahj){md,0,1,md,calc(s[x].mx,md),calc(s[x].mn,md)};
        return;
    }
    int mid=(l+r)/2;
    q(x*2,l,mid);q(x*2+1,mid+1,r);
    if(op>=3)
    {
        s[x].mn=min(s[x*2].mn,s[x*2+1].mn);
        s[x].mx=max(s[x*2].mx,s[x*2+1].mx);
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&g[i]);
    build(1,1,n);
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d%d%d",&op,&ql,&qr);
        if(op==1||op==2)
        {
            if(op==1) ans=-1e15;
            else ans=1e15;
            q(1,1,n);
            printf("%.10Lf\n",ans);
        }
        else
        {
            scanf("%d",&md);
            q(1,1,n);
        }
    }
}

电路图C实在肝不出来,就只能先这样交上来了,等以后来填坑吧。

 

posted @ 2020-02-08 20:26  mgtnb  阅读(166)  评论(0编辑  收藏  举报