• 两次考试


    11.6

    T1

    super_gcd

    还是要抓紧复习一下板子...

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int LEN=1006;
    
    int t[LEN],he;
    int cm;
    
    struct bign
    {
        int s[LEN],len;
        bign(){mem(s,0);len=1;}
        void read()
        {
            int i;
            he=0; char q=getchar();
            while(q<'0'||q>'9') q=getchar();
            while(q>='0'&&q<='9') t[++he]=q-'0',q=getchar();
            for(i=he;i;--i) s[he-i+1]=t[i];
            len=he;
        }
        bool operator < (const bign &c) const
        {
            bign x=*this;
            if(x.len==c.len)
            {
                int i;
                for(i=x.len;i;--i)
                {
                    if(x.s[i]==c.s[i]) continue;
                    return x.s[i]<c.s[i];
                }
            }
            else
                return x.len<c.len;
            return 0;
        }
        bign operator - (const bign &c) const
        {
            bign x=*this; int i;
            for(i=1;i<=c.len;++i)
            {
                x.s[i+cm]-=c.s[i];
                if(x.s[i+cm]<0)
                {
                    --x.s[i+cm+1];
                    x.s[i+cm]+=10;
                }
            }
            while(x.len>1&&x.s[x.len]==0)
                --x.len;
            return x;
        }
        void out()
        {
            int i;
            for(i=len;i;--i)
                printf("%d",s[i]);
            puts("");
        }
    };
    
    int T;
    bign A,B;
    
    int gcd()
    {
        while( !(A.len==1&&A.s[1]==0)&&!(B.len==1&&B.s[1]==0) )
        {
            if(A<B)
            {
                cm=B.len-A.len-1;
                if(cm<0) cm=0;
                B=B-A;
            }
            else
            {
                cm=A.len-B.len-1;
                if(cm<0) cm=0;
                A=A-B;
            }
        }
        //A.out(); B.out();
        if(A<B)
        {
            if(B.len==1&&B.s[1]==1&&A.len==1&&A.s[1]==0)
                return 1;
            return 0;
        }
        else
        {
            if(A.len==1&&A.s[1]==1&&B.len==1&&B.s[1]==0)
                return 1;
            return 0;
        }
    }
    
    int main(){
        
        //freopen("T1.in","r",stdin);
        
        //freopen("king.in","r",stdin);
        //freopen("king.out","w",stdout);
        
        read(T);
        while(T--)
        {
            A.read(); B.read();
            //A.out(); B.out();
            if(gcd())
                puts("Yes");
            else
                puts("No");
        }
    }
    T1

    T2

    考试什么都想不出来...

    考虑补集转化,用总方案数减去0、1、2各自不合法的方案数

    因为每个区间只会有一个数超过一半,所以不用容斥

    枚举0、1、2

    把跟它相等的数看做1,不相等的看做-1

    这样统计前缀和中比当前低的位置即可

    $O(n)$

    其实$O(nlogn)$的很好想

    $$pre_r-pre_{l-1}>frac{r-l+1}{2}$$

    $$2*pre_r-r>2*pre_{l-1}-l+1$$

    直接树状数组就行了

    真是菜...

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        x=q-'0';
    }
    const int N=5000006;
    
    int n;
    int cm;
    int aee=5000000;
    int cnt[N<<1],v[N];
    ll ans;
    
    ll get()
    {
        rint i; int tt; ll ans=0,now=aee,ccc=0;
        mem(cnt,0); ++cnt[aee];
        for(i=1;i<=n;++i)
        {
            if(v[i]==cm) ccc+=cnt[now],++now;
            else --now,ccc-=cnt[now];
            ++cnt[now];
            ans+=ccc;
        }
        return ans;
    }
    
    int main(){
        
        //freopen("ex1.in","r",stdin);
        
        rint i;
        
        scanf("%d",&n);
        for(i=1;i<=n;++i) read(v[i]);
        
        /*printf("
    ");
        for(i=1;i<=n;++i)
            printf("%d",v[i]);
        printf("
    ");*/
        
        ans=1LL*n*(n+1)/2;
        for(i=0;i<3;++i)
            cm=i,ans-=get();
        printf("%lld
    ",ans);
    }
    T2

    T3

    $O(n^3)$的dp很简单,但是我根本没想...

    考试打了用堆来贪心取,骗了40

    70分 还可以打网络流

    建图就S向豆干和干脆面连 流量为给出个数费用为0的边

    豆干和干脆面在向每只猫连 一条$1/p_i$ 一条$1/0$ 的边

    正解是wqs二分套wqs二分

    二分两个cost,分别表示选豆干和干脆面各会需要额外的花费

    每次dp记录最优的猫的个数和用掉的豆干和干脆面的个数

    这样一直二分到第一个大于等于给出个数的值

    而且二分出的值不一定可以使得dp结果正好是给出的个数

    就像陈立杰那个黑白树一样(毕竟重打了7遍呢,记忆比较深刻...)

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define eps 0.00000001
    #define dd double
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=100006;
    const ll Inf=1e10;
    
    int n,A,B;
    int now,pr;
    dd p[N],q[N];
    dd f[2];
    int ga[2],gb[2];
    
    void check(dd xp,dd xq)
    {
        rint i,j;
        now=0;
        f[0]=0; ga[0]=gb[0]=0;
        for(i=1;i<=n;++i)
        {
            now^=1; pr=now^1;
            f[now]=-Inf; ga[now]=gb[now]=0;
            if(f[now]<f[pr])
                f[now]=f[pr],ga[now]=ga[pr],gb[now]=gb[pr];
            if(f[now]<f[pr]+p[i]-xp)
                f[now]=f[pr]+p[i]-xp,ga[now]=ga[pr]+1,gb[now]=gb[pr];
            if(f[now]<f[pr]+q[i]-xq)
                f[now]=f[pr]+q[i]-xq,ga[now]=ga[pr],gb[now]=gb[pr]+1;
            if(f[now]<f[pr]+p[i]+q[i]-p[i]*q[i]-xp-xq)
                f[now]=f[pr]+p[i]+q[i]-p[i]*q[i]-xp-xq,ga[now]=ga[pr]+1,gb[now]=gb[pr]+1;
        }
    }
    
    dd work()
    {
        dd l=0,r=1,mid,l2,r2,mid2;
        while(l<r-eps)
        {
            mid=(l+r)/2.0;
            //printf("l=%f r=%f mid=%f
    ",l,r,mid);
            l2=0; r2=1;
            while(l2<r2-eps)
            {
                mid2=(l2+r2)/2.0;
                //printf("l2=%f r2=%f mid2=%f gb[now]=%d
    ",l2,r2,mid2,gb[now]);
                check(mid,mid2);
                if(gb[now]==B)
                    break;
                if(gb[now]<B) r2=mid2;
                else l2=mid2;
            }
            if(ga[now]==A)
                break;
            if(ga[now]<A) r=mid;
            else l=mid;
        }
        return f[now]+mid*A+mid2*B;
    }
    
    int main(){
        
        //freopen("in.in","r",stdin);
        
        //freopen("red8.in","r",stdin);
        
        rint i;
        
        while(~scanf("%d%d%d",&n,&A,&B))
        {
            for(i=1;i<=n;++i) scanf("%lf",&p[i]);
            for(i=1;i<=n;++i) scanf("%lf",&q[i]);
            if(A>n) A=n;
            if(B>n) B=n;
            printf("%.3f
    ",work());
        }
    }
    T3

    11.7

    T1

    T一定可以分解成$S*B^{a}+n1*A*B^{a-1}+n2*A*B^{a-2}...$的形式

    其中n1,n2是系数,可以为0

    这样的话,直接枚举a,在贪心取就行了

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    
    int S,T,A,B;
    int maxk;
    ll P[106];
    
    int main(){
        
        //freopen("T1.in","r",stdin);
        //freopen("T1hh.out","w",stdout);
        
        //freopen("a.in","r",stdin);
        //freopen("a.out","w",stdout);
        
        rint i,j; ll tt,t1; int con,ans=1e9;
        
        read(S); read(T); read(A); read(B);
        
        if(S>T)
        {
            puts("-1");
            return 0;
        }
        
        tt=S; maxk=0;
        while(tt<=T&&maxk<=32) tt*=B,++maxk;
        --maxk; tt/=B;
        
        P[0]=1;
        for(i=1;i<=maxk;++i)
            P[i]=P[i-1]*B;
        
        for(i=maxk;~i;--i)
        {
            tt=S*P[i]; con=i;
            for(j=i;~j;--j)
            {
                t1=(1LL*T-tt)/(1LL*A*P[j]);
                con+=t1; tt+=1LL*t1*A*P[j];
            }
            if(tt==T&&ans>con) ans=con;
        }
        if(ans==1000000000)
            ans=-1;
        printf("%d
    ",ans);
    }
    T1

    T2

    算法1(考试骗分) 90

    先考虑二分ans

    然后二分点对的左端点距离选择的边的左端点的最大值

    然后对右端点做区间交

    $O(nlog^2n)$

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=100006;
    
    int n,m;
    int u[N],v[N],len[N];
    
    int check60(int maxd)
    {
        rint i,j; int mn,mx,t1,t2;
        for(i=1;i<=n;++i)
        {
            mn=1000000; mx=1;
            for(j=1;j<=m;++j)
                if(len[j]>maxd)
                {
                    t1=u[j]-i; if(t1<0) t1=-t1;
                    if(t1>maxd)
                    {
                        mn=1; mx=1000000;
                        break;
                    }
                    t2=maxd-t1;
                    if(mn>v[j]+t2) mn=v[j]+t2;
                    if(mx<v[j]-t2) mx=v[j]-t2;
                }
            if(mx<=mn) return 1;
        }
        return 0;
    }
    
    int work60()
    {
        int l=0,r=n,mid,ans=n;
        while(l<=r)
        {
            mid=(l+r)>>1;
            //printf("l=%d r=%d mid=%d
    ",l,r,mid);
            if(check60(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int check100(int maxd)
    {
        int l=0,r=maxd,mid;
        int mn,mx,t1,t2,tt,l1=n,r1=1;
        rint i,j;
        while(l<=r)
        {
            mid=(l+r)>>1;
            //printf("l2=%d r2=%d mid2=%d
    ",l,r,mid);
            mn=n; mx=1;
            for(i=1;i<=m;++i)
                if(len[i]>maxd)
                {
                    if(mx<u[i]-mid) mx=u[i]-mid;
                    if(mn>u[i]+mid) mn=u[i]+mid;
                }
            //printf("mn=%d mx=%d
    ",mn,mx);
            if(mx>mn) l=mid+1;
            else
            {
                l1=mx,r1=mn,r=mid-1;
                /*if(l1>mx) l1=mx;
                if(r1<mn) r1=mn;
                r=mid-1;*/
                /*if(r1-l1<mn-mx)
                    l1=mx,r1=mn;
                r=mid-1;*/
            }
        }
        if(l1>r1) return 0;
        //printf("l1=%d r1=%d mid=%d
    ",l1,r1,mid);
        for(i=l1;i<=r1;++i)
        {
            t1=n; t2=1;
            for(j=1;j<=m;++j)
                if(len[j]>maxd)
                {
                    tt=u[j]-i; if(tt<0) tt=-tt;
                    tt=maxd-tt;
                    if(t2<v[j]-tt) t2=v[j]-tt;
                    if(t1>v[j]+tt) t1=v[j]+tt;
                }
            //printf("asdsd:: %d %d
    ",t2,t1);
            if(t2<=t1) return 1;
        }
        return 0;
    }
    
    int work100()
    {
        int l=0,r=n,mid,ans=n;
        while(l<=r)
        {
            mid=(l+r)>>1;
            //printf("l=%d r=%d mid=%d
    ",l,r,mid);
            if(check100(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int main(){
        
        //freopen("T2.in","r",stdin);
        //freopen("T2.out","w",stdout);
        
        //freopen("b.in","r",stdin);
        //freopen("b.out","w",stdout);
        
        rint i;
        
        read(n); read(m);
        for(i=1;i<=m;++i)
            read(u[i]),read(v[i]),len[i]=v[i]-u[i];
        if(n<=5000)
            printf("%d
    ",work60());
        else
            printf("%d
    ",work100());
    }
    1

    算法2 100

    其实左端点并不具有二分性质,而是一个横坐标为左端点pos,竖坐标为ans的下凹函数

    那么可以三分套二分

    $O(nlog^2n)$

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=100006;
    
    int n,m;
    int u[N],v[N],len[N];
    
    int check2(int pos,int maxd)
    {
        rint i; int l1=1,r1=n,t1;
        for(i=1;i<=m;++i)
            if(len[i]>maxd)
            {
                t1=u[i]-pos; if(t1<0) t1=-t1;
                if(t1>maxd) return 0;
            }
        for(i=1;i<=m;++i)
            if(len[i]>maxd)
            {
                t1=u[i]-pos; if(t1<0) t1=-t1;
                t1=maxd-t1;
                if(l1<v[i]-t1) l1=v[i]-t1;
                if(r1>v[i]+t1) r1=v[i]+t1;
            }
        if(l1<=r1) return 1;
        return 0;
    }
    
    int check(int pos)
    {
        rint i;
        int l=0,r=n,mid,ans=n;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check2(pos,mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int work()
    {
        int l=1,r=n,mid,midmid,midv,midmidv,ans=n,i;
        while(l<=r-10)
        {
            mid=l+(r-l)/3; midmid=r-(r-l)/3;
            midv=check(mid); midmidv=check(midmid);
            if(midv>midmidv)
            {
                if(ans>midmidv) ans=midmidv;
                l=mid;
            }
            else
            {
                if(ans>midv) ans=midv;
                r=midmid;
            }
        }
        for(i=l;i<=r;++i)
        {
            midv=check(i);
            if(ans>midv) ans=midv;
        }
        return ans;
    }
    
    int main(){
        
        //freopen("T2.in","r",stdin);
        
        rint i;
        
        read(n); read(m);
        for(i=1;i<=m;++i)
            read(u[i]),read(v[i]),len[i]=v[i]-u[i];
        printf("%d
    ",work());
    }
    2

    算法3 100

    二分ans

    对于每一个点对,发现合法的区间映射到二维平面是其实是一个个倾斜45度的正方形

    用$(x+y,x-y)$把正方形旋转成水平的(旋转过程大小会变,但是相对位置不会)

    这样矩形求交就行了

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=100006;
    const int Inf=1e9;
    
    int n,m;
    int u[N],v[N],len[N];
    
    int check(int maxd)
    {
        rint i;
        int l=-Inf,r=Inf,xi=-Inf,sh=Inf;
        int t1,t2;
        int sha,xia,zuo,you;
        for(i=1;i<=m;++i)
            if(len[i]>maxd)
            {
                sha=-Inf; xia=Inf; zuo=Inf; you=-Inf;
                t1=u[i]-maxd+v[i]; t2=u[i]-maxd-v[i];
                if(sha<t2) sha=t2; if(xia>t2) xia=t2;
                if(you<t1) you=t1; if(zuo>t1) zuo=t1;
                t1=u[i]+maxd+v[i]; t2=u[i]+maxd-v[i];
                if(sha<t2) sha=t2; if(xia>t2) xia=t2;
                if(you<t1) you=t1; if(zuo>t1) zuo=t1;
                t1=u[i]+v[i]-maxd; t2=u[i]-(v[i]-maxd);
                if(sha<t2) sha=t2; if(xia>t2) xia=t2;
                if(you<t1) you=t1; if(zuo>t1) zuo=t1;
                t1=u[i]+v[i]+maxd; t2=u[i]-(v[i]+maxd);
                if(sha<t2) sha=t2; if(xia>t2) xia=t2;
                if(you<t1) you=t1; if(zuo>t1) zuo=t1;
                
                if(l<zuo) l=zuo; if(r>you) r=you;
                if(xi<xia) xi=xia; if(sh>sha) sh=sha;
            }
        if(xi<=sh&&l<=r)
            return 1;
        return 0;
    }
    
    int work()
    {
        int l=0,r=n,mid,ans=n;
        while(l<=r)
        {
            mid=(l+r)>>1;
            //printf("l=%d r=%d mid=%d
    ",l,r,mid);
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int main(){
        
        //freopen("T2.in","r",stdin);
        //freopen("T2.out","w",stdout);
        
        rint i;
        
        read(n); read(m);
        for(i=1;i<=m;++i)
            read(u[i]),read(v[i]),len[i]=v[i]-u[i];
        printf("%d
    ",work());
    }
    3

    算法4 100

    其实算法3的check就是求曼哈顿距离可否满足maxd

    那么把曼哈顿距离转化成切比雪夫距离

    这样横纵坐标就独立起来了

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int Inf=1e9;
    const int N=100006;
    
    int n,m;
    int u[N],v[N],len[N];
    
    int check(int maxd)
    {
        rint i; int l=-Inf,r=Inf;
        for(i=1;i<=m;++i)
            if(len[i]>maxd)
            {
                if(l<u[i]+v[i]-maxd) l=u[i]+v[i]-maxd;
                if(r>u[i]+v[i]+maxd) r=u[i]+v[i]+maxd;
            }
        //printf("l1=%d r1=%d
    ",l,r);
        if(l>r) return 0;
        l=-Inf; r=Inf;
        for(i=1;i<=m;++i)
            if(len[i]>maxd)
            {
                if(l<u[i]-v[i]-maxd) l=u[i]-v[i]-maxd;
                if(r>u[i]-v[i]+maxd) r=u[i]-v[i]+maxd;
            }
        //printf("l2=%d r2=%d
    ",l,r);
        if(l>r) return 0;
        return 1;
    }
    
    int work()
    {
        int l=0,r=n,mid,ans=n;
        while(l<=r)
        {
            mid=(l+r)>>1;
            //printf("l=%d r=%d mid=%d
    ",l,r,mid);
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int main(){
        
    //    freopen("T2.in","r",stdin);
        
        rint i;
        read(n); read(m);
        for(i=1;i<=m;++i)
            read(u[i]),read(v[i]),len[i]=v[i]-u[i];
        printf("%d
    ",work());
    }
    4

    T3

    结论:

    不管对手怎么动,只要预先知道了他的行动

    就可以对应的进行行动,总有一种方案使得最后得到结果

    二分即可

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; int ff=1; char q=getchar();
        while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
        x*=ff;
    }
    const int N=300006;
    int first[N],nt[N<<1],ver[N<<1],e;
    void addb(int u,int v)
    {
        ver[e]=v;
        nt[e]=first[u];
        first[u]=e++;
    }
    
    int n,alln;
    int v[N],t[N],pos[N];
    int x[N<<1],y[N<<1];
    
    int dfn[N],low[N],tim,zhan[N],he,sun[N],sum;
    bool flag[N];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tim;
        zhan[++he]=x; flag[x]=1;
        int i;
        for(i=first[x];i!=-1;i=nt[i])
        {
            if(dfn[ver[i]]==-1)
            {
                tarjan(ver[i]);
                if(low[x]>low[ver[i]])
                    low[x]=low[ver[i]];
            }
            else
                if(flag[ver[i]]&&low[x]>dfn[ver[i]])
                    low[x]=dfn[ver[i]];
        }
        if(dfn[x]==low[x])
        {
            i=-1; ++sum;
            while(i!=x)
                i=zhan[he--],flag[i]=0,++sun[sum];
        }
    }
    
    int check(int arr)
    {
        rint i; int tt;
        for(i=0;i<n;++i) t[i]=v[i];
        for(i=1;i<=arr;++i) swap(t[x[i]],t[y[i]]);
        
        /*printf("
    ");
        for(i=0;i<n;++i)
            printf("%d ",t[i]);
        printf("
    ");*/
        
        for(i=0;i<n;++i) pos[t[i]]=i;
        for(i=0;i<n;++i) sun[i]=0,dfn[i]=-1,first[i]=-1;
        e=0; tim=0; he=0; sum=0;
        for(i=0;i<n;++i) addb(i,pos[i]);
        for(i=0;i<n;++i)
            if(dfn[i]==-1)
                tarjan(i);
        tt=0;
        
        /*printf("
    ");
        for(i=1;i<=sum;++i)
            printf("%d ",sun[i]);
        printf("
    ");*/
        
        for(i=1;i<=sum;++i)
            tt+=(sun[i]-1);
        //printf("arr=%d tt=%d
    ",arr,tt);
        return tt<=arr;
    }
    
    int work()
    {
        int l=0,r=alln,mid,ans=alln;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    
    int main(){
        
        //freopen("T3.in","r",stdin);
        
        rint i;
        
        read(n); alln=n<<1;
        for(i=0;i<n;++i)
            read(v[i]);
        for(i=1;i<=alln;++i)
            read(x[i]),read(y[i]);
        printf("%d
    ",work());
    }
    T3
  • 相关阅读:
    有道云笔记隐藏ad控件
    commons-httpclient直接发送内存中byte[]文件
    springboot打包成zip部署,并实现优雅停机
    Java读取相对路径文件时,报FileNotFoundException异常
    Oracle 添加 scott 示例用户
    Usage and Idioms——Exception testing
    Usage and Idioms——Test execution order
    Usage and Idioms——Aggregating tests in suites
    Usage and Idioms——Test runners
    Usage and Idioms——Assertions
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7802180.html
Copyright © 2020-2023  润新知