zoukankan      html  css  js  c++  java
  • 第一周周练

    中国(北方)大学生程序射击训练赛(第一周)

    官方题解 

    A.Prufer序列

    暴力枚举每一个点,删除改点后生成树计数,但1e8为什么不超时。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int mod=1000000007;
    LL pow_mod(LL a,LL n){
        LL t=a,res=1;
        while(n){
            if(n&1) res=(res*t)%mod;
            t=(t*t)%mod;
            n/=2;
        }
        return res;
    }
    LL inv(LL a,LL m){
        return pow_mod(a,m-2);
    }
    struct Matrix{
        int mat[105][105];
        void init(){
            memset(mat,0,sizeof(mat));
        }
        int det(int n){
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    mat[i][j]=(mat[i][j]%mod+mod)%mod;
            int res=1;
            for(int i=0;i<n;i++){
                for(int j=i;j<n;j++)
                    if(mat[j][i]!=0){
                        for(int k=i;k<n;k++)
                            swap(mat[i][k],mat[j][k]);
                        if(i!=j)
                            res=(-res+mod)%mod;
                        break;
                    }
                if(mat[i][i]==0){
                    res=-1;
                    break;
                }
                for(int j=i+1;j<n;j++){
                    int mut=((LL)mat[j][i]*inv(mat[i][i],mod))%mod;
                    for(int k=i;k<n;k++)
                        mat[j][k]=(mat[j][k]-((LL)mat[i][k]*mut)%mod+mod)%mod;
                }
                res=((LL)res*mat[i][i])%mod;
            }
            return res;
        }
    };
    Matrix ret;
    int g[105][105];
    int in[105];
    int t,n,m;
    void pre(int x){
        ret.init();
        for(int i=0;i<n;i++){
            if(i==x) continue;
            int ii=i;
            if(i>x&&x!=-1) ii--;
            for(int j=0;j<n;j++){
                if(i==j||j==x) continue;
                int jj=j;
                if(j>x&&x!=-1) jj--;
                if(g[i][j]){
                    ret.mat[ii][jj]=-1;
                    ret.mat[ii][ii]++;
                }
            }
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            memset(g,0,sizeof(g));
            memset(in,0,sizeof(in));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                g[u-1][v-1]=1;
                g[v-1][u-1]=1;
                in[u-1]++;
                in[v-1]++;
            }
            pre(-1);
            int temp=ret.det(n-1);
            if(temp<0) temp++;
            int ans=(LL)temp*(n*(n+1)/2)%mod;
            for(int i=0;i<n;i++){
                pre(i);
                int temp=ret.det(n-2);
                if(temp<0) temp++;
                ans-=(LL)(in[i]*(i+1)%mod)*temp%mod;
                if(ans<0) ans+=mod;
            }
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    Psong

    B.埃蒙的时空航道

    最大流,直接不行,反过来求最小割。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    LL n,c;
    LL p[100005];
    LL s[100005];
    LL w[100005];
    int main(){
        scanf("%lld%lld",&n,&c);
        for(LL i=1;i<=n;i++)
            scanf("%lld",&p[i]);
        for(LL i=1;i<=n;i++)
            scanf("%lld",&s[i]);
        LL sum=0,ans=1e18;
        for(LL i=1;i<=n;i++){
            w[i]=p[i]-s[i]+(i-1)*c;
            sum+=s[i];
        }
        sort(w+1,w+1+n);
        for(LL i=1;i<=n;i++){
            sum+=w[i]-(i-1)*c;
            ans=min(ans,sum);
        }
        printf("%lld
    ",ans);
    
        return 0;
    }
    Psong

    C.Shadow of Survival

    D.数学题

    二分答案,尺取判断。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const double eps=1e-8;
    const int N=100005;
    int n,m,k;
    int a[N],b[N];
    bool check(double mid){
        //cout<<"mid="<<mid<<endl;
        int num=0;
        int L=1,R=1;
        while(1){
            if(R>n) break;
            double temp=(1.0*a[L])/b[R];
            //cout<<L<<" "<<R<<" ";
            //cout<<temp<<endl;
            if(mid-temp>eps&&L<n) L++;
            else if(mid-temp>eps&&L==n) R++;
            else{
                num+=n-L+1;
                //cout<<"num="<<num<<endl;
                R++;
            }
            //cout<<endl;
        }
        //cout<<"num="<<num<<endl;
        //system("pause");
        if(num>=k) return true;
        else return false;
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+1+n);
            for(int i=1;i<=m;i++)
                scanf("%d",&b[i]);
            sort(b+1,b+1+m);
            double l=0,r=1.0*a[n]/b[1];
            while(abs(r-l)>eps){
                double mid=(l+r)/2;
                if(check(mid)) l=mid;
                else r=mid;
            }
            printf("%.2lf
    ",l);
        }
    
        return 0;
    }
    Psong

    E.Water Problem

    矩阵快速幂。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const LL s1=1e9+7;
    struct Mat{
        LL a[5][5];
        void init(){
            a[0][0]=5;a[0][1]=3;a[0][2]=0;a[0][3]=0;a[0][4]=1;
            a[1][0]=3;a[1][1]=2;a[1][2]=0;a[1][3]=0;a[1][4]=1;
            a[2][0]=2;a[2][1]=1;a[2][2]=0;a[2][3]=0;a[2][4]=1;
            a[3][0]=1;a[3][1]=1;a[3][2]=0;a[3][3]=0;a[3][4]=0;
            a[4][0]=0;a[4][1]=0;a[4][2]=0;a[4][3]=0;a[4][4]=1;
        }
    };
    Mat operator *(Mat a,Mat b){
        Mat c;
        for(LL i=0;i<5;i++)
        for(LL j=0;j<5;j++){
            c.a[i][j]=0;
            for(LL k=0;k<5;k++)
                c.a[i][j]+=a.a[i][k]*b.a[k][j];
                c.a[i][j]%=s1;
        }
        return c;
    }
    Mat operator ^(Mat p,LL k){
        Mat ans; ans.init();
        while(k){
            if(k&1)
                ans=ans*p;
            k/=2;
            p=p*p;
        }
        return ans;
    }
    int main(){
        LL f1,f2,f3,f4,n;
        while(cin>>f1>>f2>>n){
            f3=f1+f2;
            f4=f2+f3-1;
            Mat x;
            memset(x.a,0,sizeof(x.a));
            x.a[0][0]=f4%s1;
            x.a[1][0]=f3%s1;
            x.a[2][0]=f2%s1;
            x.a[3][0]=f1%s1;
            x.a[4][0]=1;
            Mat a; a.init();
            Mat ans=x;
            if(n>4) ans=(a^((n-1)/4-1))*x;
            for(int i=0;i<5;i++){
                for(int j=0;j<5;j++){
                    //cout<<ans.a[i][j]<<" ";
                }
                //cout<<endl;
            }
            cout<<ans.a[3-(n-1)%4][0]%s1<<endl;
        }
    
        return 0;
    }
    Psong

    F.等差区间

    线段树或者ST表统计区间最大,最小,gcd以及是否有相同的数字。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #define lson (id*2)
    #define rson (id*2+1)
    #define mid ((l+r)/2)
    using namespace std;
    const int N=1e5+5;
    int gcd(int x,int y){
        return y==0?x:gcd(y,x%y);
    }
    struct node{
        int mi,ma,p;
    } tre[N*5];
    void push_up(int id){
        tre[id].ma=max(tre[lson].ma,tre[rson].ma);
        tre[id].mi=min(tre[lson].mi,tre[rson].mi);
        tre[id].p=max(tre[lson].p,tre[rson].p);
    }
    void build(int id,int l,int r){
        if(l==r){
            tre[id].ma=0;
            tre[id].mi=0;
            tre[id].p=0;
            return;
        }
        build(lson,l,mid);
        build(rson,mid+1,r);
        push_up(id);
        return;
    }
    void add(int id,int l,int r,int pos,int tt){
        if(l==r){
            tre[id].ma=tt;
            tre[id].mi=tt;
            return;
        }
        if(pos<=mid)
            add(lson,l,mid,pos,tt);
        else
            add(rson,mid+1,r,pos,tt);
        push_up(id);
        return;
    }
    void add_pos(int id,int l,int r,int pos,int tt){
        if(l==r){
            tre[id].p=tt;
            return;
        }
        if(pos<=mid)
            add_pos(lson,l,mid,pos,tt);
        else
            add_pos(rson,mid+1,r,pos,tt);
        push_up(id);
        return;
    }
    int query_max(int id,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            return tre[id].ma;
        }
        int ans=0;
        if(ql<=mid)
            ans=max(ans,query_max(lson,l,mid,ql,qr));
        if(qr>mid)
            ans=max(ans,query_max(rson,mid+1,r,ql,qr));
        return ans;
    }
    int query_min(int id,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            return tre[id].mi;
        }
        int ans=1e9+7;
        if(ql<=mid)
            ans=min(ans,query_min(lson,l,mid,ql,qr));
        if(qr>mid)
            ans=min(ans,query_min(rson,mid+1,r,ql,qr));
        return ans;
    }
    int query_num(int id,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            return tre[id].p;
        }
        int ans=0;
        if(ql<=mid)
            ans=max(ans,query_num(lson,l,mid,ql,qr));
        if(qr>mid)
            ans=max(ans,query_num(rson,mid+1,r,ql,qr));
        return ans;
    }
    int tre_gcd[N*5];
    void push_up_gcd(int id){
        tre_gcd[id]=gcd(tre_gcd[lson],tre_gcd[rson]);
        return;
    }
    void build_gcd(int id,int l,int r){
        if(l==r){
            tre_gcd[id]=0;
            return;
        }
        build_gcd(lson,l,mid);
        build_gcd(rson,mid+1,r);
        push_up_gcd(id);
        return;
    }
    void add_gcd(int id,int l,int r,int pos,int tt){
        if(l==r){
            tre_gcd[id]=tt;
            return;
        }
        if(pos<=mid)
            add_gcd(lson,l,mid,pos,tt);
        else
            add_gcd(rson,mid+1,r,pos,tt);
        push_up_gcd(id);
        return;
    }
    int query_gcd(int id,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            return tre_gcd[id];
        }
        int ans=-1;
        if(ql<=mid)
            ans=query_gcd(lson,l,mid,ql,qr);
        if(qr>mid){
            if(ans!=-1)
                ans=gcd(ans,query_gcd(rson,mid+1,r,ql,qr));
            else
                ans=query_gcd(rson,mid+1,r,ql,qr);
        }
        return ans;
    }
    int x[N];
    int pos[N*10];
    int main(){
        int n,q;
        while(scanf("%d%d",&n,&q)!=EOF){
            build(1,1,n);
            build_gcd(1,1,n);
            memset(pos,0,sizeof(pos));
            for(int i=1;i<=n;i++){
                scanf("%d",&x[i]);
                add(1,1,n,i,x[i]);
                add_pos(1,1,n,i,pos[x[i]]);
                pos[x[i]]=i;
            }
            for(int i=1;i<n;i++){
                add_gcd(1,1,n-1,i,abs(x[i+1]-x[i]));
            }
            for(int i=1;i<=q;i++){
                int L,R;
                scanf("%d%d",&L,&R);
                int x1=query_max(1,1,n,L,R);
                int x2=query_min(1,1,n,L,R);
                int ok=query_num(1,1,n,L,R);
                //cout<<ok<<endl;
                if(x1==x2||(R-L)<=1){
                    printf("Yes
    ");
                }
                else{
                    if(ok<L){
                        int x3=query_gcd(1,1,n-1,L,R-1);
                        if((x1-x2)==x3*(R-L)) printf("Yes
    ");
                        else printf("No
    ");
                    }
                    else printf("No
    ");
                }
            }
    
        }
    
        return 0;
    }
    Psong
  • 相关阅读:
    git command
    互联网应用架构概览-学习笔记
    机器学习基础概念-阿里大学课程学习笔记
    Python的并行求和例子
    C语言处理CSV数据
    Pattern Evaluation
    Python写的大小写转换小工具
    处理输入为非对角阵的Clustering by fast search and find of density peak代码
    css点击下层穿透上层元素
    浏览器全屏效果
  • 原文地址:https://www.cnblogs.com/N-Psong/p/6558096.html
Copyright © 2011-2022 走看看