• 2019 ICPC南昌邀请赛网络赛比赛过程及题解


    解题过程


    中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了。然后lfw读完M题(shl的电脑终于打开了,然后输入密码,密码错误。。。自闭),说AC 自动机板题,然后找板子,,,突然发现自己读错题目。后来不知道怎么A的。shl copy了一遍密码终于登上账号。然后lfw一个人用单调栈和前缀和st表A掉了I题;byf 秒了H题;

    shl和byf读j题,读完吧题意告诉lfw,lfw说水题,然后树链剖分加线段树离线就过了。同时byf在想K题,然后推出式子,利用前缀和就过了(听说好多对TLE了,应该没用前缀和维护);然后还有一个多小时,,,shl和byf看D题,lfw看C题,然后shl和byf没啥想法,lfw调C调了一万年,最后也没过。。。这场每一题都是一下就过了,罚时较少。(这场shl全场OB,没碰键盘,状态极差...)

    C题要注意一下,java 的BigInteger运算比c++用数组模拟高精度快,lfw被卡住了,c++要几分钟预处理,java几乎1s出来,所以最后用java,但是看错题没看到要字典序最小,没时间改

    第二天改好了,最后java也超时。。。要矩阵乘法预处理出28个数。。。


    题解


    先放代码,题解后面更新。

    A. PERFECT NUMBER PROBLEM

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        printf("6
    ");
        printf("28
    ");
        printf("496
    ");
        printf("8128
    ");
        printf("33550336
    ");
        return 0;
    }
    View Code

    B. Greedy HOUHO

    Unsolved.

    C. Angry FFF Party

    Unsolved.

    lfw的题解链接 https://blog.csdn.net/liufengwei1/article/details/89522815

    import java.lang.reflect.Array;
    import java.util.*;
    import java.math.*;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    public class Main
    {
        public static BigInteger[][] multi(BigInteger [][]a,BigInteger [][]b)
        {
            BigInteger [][]c= new BigInteger[3][3];
            for(int i=1;i<=2;i++)
                for(int j=1;j<=2;j++)
                    c[i][j]=BigInteger.ZERO;
            for(int i=1;i<=2;i++)
                for(int j=1;j<=2;j++)
                    for(int k=1;k<=2;k++) {
                        c[i][k] = c[i][k].add(a[i][j].multiply(b[j][k]));
                    }
            return c;
        }
        public static BigInteger qp(int b)
        {
            BigInteger ans[][]=new BigInteger[3][3];
            BigInteger cnt[][]=new BigInteger[3][3];
            ans[1][1]=BigInteger.ONE;ans[1][2]=BigInteger.ZERO;
            ans[2][1]=BigInteger.ZERO;ans[2][2]=BigInteger.ONE;
            cnt[1][1]=BigInteger.ZERO;cnt[1][2]=BigInteger.ONE;
            cnt[2][1]=BigInteger.ONE;cnt[2][2]=BigInteger.ONE;
            while(b>0)
            {
                if(b%2==1)
                    ans=multi(ans,cnt);
                cnt=multi(cnt,cnt);
                b>>=1;
            }
            return ans[2][2];
        }
        public static void main(String args[])
        {
            int []f=new int [100];
            int []ans=new int[100];
            int up=0,cnt=3;
            f[1]=1;f[2]=1;
            for(int i=3;i<=28;i++)
                f[i] = f[i - 2] + f[i - 1];
            //PrintStream ps=new PrintStream("B.");
            BigInteger []num=new BigInteger[30];
            BigInteger a,b,w,sum=BigInteger.ZERO,tmp=BigInteger.ZERO;
            a=BigInteger.ONE;
            b=BigInteger.ONE;
            num[1]=BigInteger.ONE;
            num[2]=BigInteger.ONE;
            num[3]=BigInteger.ONE;
            Scanner input=new Scanner(System.in);
            int id=0;
            //System.out.println("a[1]=1;");
            //System.out.println("a[2]=1;");
            //System.out.println("a[3]=1;");
            id=4;
            for(int i=4;i<=28;i++)
                num[i]=qp(f[i]-1);
            int t,anscnt;
            t=input.nextInt();
            while(t>0)
            {
                t--;sum=BigInteger.ZERO;
                w=input.nextBigInteger();
                anscnt=0;
                for(int i=28;i>=1;i--)
                {
                    tmp=sum.add(num[i]);
                    if(tmp.compareTo(w)<=0) {
                        sum = tmp;
                        ans[++anscnt] = i;
                    }
                }
                if(sum.equals(w))
                {
                    if(ans[anscnt]==5)
                    {
                        ans[anscnt]=1;ans[++anscnt]=2;ans[++anscnt]=3;
                        ans[++anscnt]=4;
                    }
                    else if(ans[anscnt]==4)
                    {
                        ans[anscnt]=1;
                        ans[++anscnt]=2;
                    }
                    else if(ans[anscnt]==3)
                    {
                        if(ans[anscnt-1]==4)
                        {
                            ans[anscnt-1]=3;
                            ans[anscnt]=1;
                            ans[++anscnt]=2;
                        }
                        else
                            ans[anscnt]=1;
                    }
                    else if(ans[anscnt]==2)
                    {
                        if(ans[anscnt-1]==3)
                        {
                            ans[anscnt - 1] = 1; ans[anscnt] = 2;
                        }
                    }
    
                    Arrays.sort(ans,1,anscnt+1);
                    for(int j=1;j<=anscnt;j++)
                    {
                        if(j>1)
                            System.out.print(" ");
                        System.out.print(ans[j]);
                    }
                    System.out.println("");
                }
                else
                    System.out.println("-1");
            }
        }
    }
    View Code

     D. Match Stick Game

    Unsolved.

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    const int num[10]={6,2,5,5,4,5,6,3,7,6};
    ll f[2][15][75];
    inline void init()
    {
        for (int i=0;i<15;i++)
            for (int j=0;j<75;j++)
                f[1][i][j]=-1e10;//max
        memset(f[0],INF,sizeof(f[0]));//min
        f[0][0][0]=0;
        f[1][0][0]=0;
        for (int i=1;i<=10;i++)
            for (int j=1;j<=i*7;j++)
                for (int k=0;k<=9;k++)
                {
                    if(j<num[k]) continue;
                    f[0][i][j]=min(f[0][i][j],f[0][i-1][j-num[k]]*10+k);
                    f[1][i][j]=max(f[1][i][j],f[1][i-1][j-num[k]]*10+k);
                }
    }
    ll dp[105][705];
    char s[105];
    int nums[105];
    int main()
    {
        init();
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            int tot=0;
            scanf("%d%s",&n,s);
            for(int i=0;i<=n;i++)
                for(int j=0;j<=n*7;j++)
                    dp[i][j]=-1e12;//dao di i kuai haisheng j gen de max
            int last=-1,cnt=0;
            for(int i=0;s[i];++i)//tongji mubang de  numbers
            {
                if(s[i]=='+'||s[i]=='-')
                {
                    nums[cnt++]=i-last-1;
                    last=i;
                }
                if(s[i]=='+') tot+=2;
                else if(s[i]=='-') tot+=1;
                else tot+=num[s[i]-'0'];
            }
            nums[cnt++]=strlen(s)-1-last;
            for(int i=1;i<=min(nums[0]*7,tot);++i)
                dp[0][tot-i]=max(dp[0][tot-i],f[1][nums[0]][i]);
            for(int i=1;i<cnt;++i)
                for(int j=0;j<=tot;++j)
                    for(int k=2;k<=min(nums[i]*7+2,j);++k)
                    {
                        dp[i][j-k]=max(dp[i][j-k],dp[i-1][j]-f[0][nums[i]][k-1]);//-
                        dp[i][j-k]=max(dp[i][j-k],dp[i-1][j]+f[1][nums[i]][k-2]);//+
                    }
            printf("%lld
    ",dp[cnt-1][0]);
        }
        return 0;
    }
    View Code

     E. Card Game

    Unsolve.

    F. Information Transmitting

    Unsolved.

    G. tsy's number

    byf题解 南昌网络赛tsy's number(莫比乌斯反演&线性递推)

     H. Coloring Game

    #include<bits/stdc++.h>
    #define int long long 
    using namespace std;
    const int mod=1e9+7;
    int quick_pow(int a,int b)
    {
        int ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return ans;
    }    
    int32_t main()
    {
        int n;
        scanf("%lld",&n);
        if(n==1) {printf("1
    ");return 0;}
        printf("%lld
    ",2*2*quick_pow(3,n-2)%mod);
        return 0;
    }
    View Code

     I. Max answer

    #include<bits/stdc++.h>
    #define maxl 500010
    using namespace std;
    
    int n,top,lg;
    long long ans=0;
    long long s[maxl];
    long long a[maxl],sum[maxl],dol[maxl],dor[maxl];
    long long mini[20][maxl],mx[20][maxl];
    map <long long,int> mp;
    map <long long,int> :: iterator it;
    
    inline void prework()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];
        top=0;int l=0,r=0;
        while(l<=n && r<=n)
        {
            while(a[l]<=0 && l<=n)
                l++;
            if(a[l]>0)
            {
                r=l;
                while(a[r+1]>0)
                    r++;
                top=0;s[0]=l-1;
                for(int i=l;i<=r;i++)
                {
                    while(top>0 && a[i]<a[s[top]])
                    {
                        dor[s[top]]=i;
                        top--;
                    }
                    s[++top]=i;dol[i]=s[top-1];
                }
                while(top>0)
                    dor[s[top]]=r+1,top--;
                for(int i=l;i<=r;i++)
                    ans=max(ans,(sum[dor[i]-1]-sum[dol[i]])*a[i]);
            }
            else r=l;
            l=r+1;
        }
    }
    
    inline void mainwork()
    {
        int lg=log2(n),t;
        for(int i=0;i<=n;i++)
            mx[0][i]=mini[0][i]=sum[i];
        for(int i=1;i<=lg;i++)
            for(int j=0;j<=n;j++)
            {
                mx[i][j]=max(mx[i-1][j],mx[i-1][j+(1<<(i-1))]);
                mini[i][j]=min(mini[i-1][j],mini[i-1][j+(1<<(i-1))]);
            }
        long long mxx,mii;
        for(int i=1;i<=n;i++)
        if(a[i]<0)
        {
            t=log2(i-0+1);
            mxx=max(mx[t][0],mx[t][i-(1<<t)+1]);
            t=log2(n-i+1);
            mii=min(mini[t][i],mini[t][n-(1<<t)+1]);
            ans=max((mii-mxx)*a[i],ans);
        }
    }
    
    inline void print()
    {
        printf("%lld",ans);
    }
    
    int main()
    {
        prework();
        mainwork();
        print();
        return 0;
    }
    View Code

     J. Distance on the tree

    #include<bits/stdc++.h>
    #define maxl 200010
    #define inf 2000000001 
    using namespace std;
    
    int n,nn,q,cnt=0,nodecnt=0,num=0;
    int a[maxl],dep[maxl],tot[maxl],son[maxl],top[maxl],fa[maxl],ehead[maxl];
    int idx[maxl],dy[maxl],ans[maxl];
    struct ed
    {
        int to,nxt;
    }e[maxl<<1];
    struct node
    {
        int l,r,sum;
    }tree[maxl<<2];
    struct qu
    {
        int u,v,w,id;
    }que[maxl],edg[maxl<<1];
    char ch[maxl];
    
    inline void adde(int u,int v)
    {
        e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt;
    }
    
    void dfs1(int u,int f)
    {
        int v;
        dep[u]=dep[f]+1;fa[u]=f;tot[u]=1;
        for(int i=ehead[u];i;i=e[i].nxt)
        {
            v=e[i].to;
            if(v==f) continue;
            dfs1(v,u);
            tot[u]+=tot[v];
            if(tot[v]>tot[son[u]])
                son[u]=v;
        }
    }
    
    void dfs2(int u,int topf)
    {
        int v;
        idx[u]=++nodecnt;dy[nodecnt]=u;
        top[u]=topf;
        if(!son[u]) return;
        dfs2(son[u],topf);
        for(int i=ehead[u];i;i=e[i].nxt)
        {
            v=e[i].to;
            if(idx[v]) continue;
            dfs2(v,v);
        }
    }
    
    void build(int k,int l,int r)
    {
        tree[k].l=l;tree[k].r=r;
        if(l==r)
        {
            tree[k].sum=0;
            return;
        }
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    }
    
    inline bool cmp(const qu &x,const qu &y)
    {
        return x.w<y.w;
    }
    
    inline void prework()
    {
        scanf("%d%d",&n,&q);
        int u,v,w;num=n;
        nn=n;
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            num++;edg[i]=qu{u,v,w,num};
            adde(u,num);adde(num,v);
            adde(v,num);adde(num,u);
        }
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d%d",&que[i].u,&que[i].v,&que[i].w);
            que[i].id=i;;
        }
        sort(edg+1,edg+1+n-1,cmp);
        sort(que+1,que+1+q,cmp);
        n=num;
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
    }
    
    void add(int k,int l)
    {
        if(tree[k].l==tree[k].r)
        {
            tree[k].sum++;
            return;
        }
        int mid=(tree[k].l+tree[k].r)>>1;
        if(l<=mid)
            add(k<<1,l);
        else
            add(k<<1|1,l);
        tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    }
    
    int getsum(int k,int l,int r)
    {
        if(tree[k].l==l && tree[k].r==r)
            return tree[k].sum;
        int mid=(tree[k].l+tree[k].r)>>1;
        if(l>mid)
            return getsum(k<<1|1,l,r);
        else
        if(r<=mid)
            return getsum(k<<1,l,r);
        else
            return getsum(k<<1,l,mid)+getsum(k<<1|1,mid+1,r);
    }
    
    inline int gettreesum(int x,int y)
    {
        int ans=0;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=getsum(1,idx[top[x]],idx[x]);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        ans+=getsum(1,idx[x],idx[y]);
        return ans;
        //printf("%d
    ",ans);
    }
    
    inline void mainwork()
    {
        //int x,y;
        /*scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            scanf("%s",ch);
            scanf("%d%d",&x,&y);
            if(ch[0]=='C')
            {
                a[x]=y;
                add(1,idx[x]);
            }
            else if(ch[1]=='S')
                gettreesum(x,y);
            else
                gettreemax(x,y);
        }*/
        int edind=0;
        for(int i=1;i<=q;i++)
        {
            while(edind<nn-1 && edg[edind+1].w<=que[i].w)
                ++edind,add(1,idx[edg[edind].id]);
            ans[que[i].id]=gettreesum(que[i].u,que[i].v);
        }
    }
    
    inline void print()
    {
        for(int i=1;i<=q;i++)
            printf("%d
    ",ans[i]);
    }
    
    int main()
    {
        prework();
        mainwork();
        print();
        return 0;
    }
    View Code

    K. MORE XOR

    #include<bits/stdc++.h>
    using namespace std;
    const int size=1e5+5;
    #define int long long 
    int sum[4][size];
    int arr[size];
    int32_t main()
    {
        int t;
        scanf("%lld",&t);
        int n;
        while(t--)
        {
            scanf("%lld",&n);
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=n;i++)
            {
                scanf("%lld",&arr[i]);
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<=3;j++)
                {
                    sum[j][i]=sum[j][i-1];
                }
                sum[i%4][i]=sum[i%4][i]^arr[i];
            }
            int q;
            scanf("%lld",&q);
            int l,r;
            while(q--)
            {
                scanf("%lld%lld",&l,&r);
                int len=r-l+1;
                if(len%4==0) printf("0
    ");
                else if(len%4==1)
                {
                    int b=l%4;
                    printf("%lld
    ",sum[b][l-1]^sum[b][r]);
                }
                else if(len%4==2)
                {
                    int b=l%4,c=(l+1)%4;
                    printf("%lld
    ",sum[b][l-1]^sum[b][r]^sum[c][l-1]^sum[c][r]);
                }
                else if(len%4==3)
                {
                    int c=(l+1)%4;
                    printf("%lld
    ",sum[c][l-1]^sum[c][r]);
                }
            }
        }
        return 0;
    }
                    
            
    View Code

     L. qiqi'tree

    Unsolved.

    M. Subsequence

    #include<bits/stdc++.h>
    #define maxl 100010
    
    int slen,tlen,n;
    int nxt[maxl][27];
    int nxtind[27];
    char s[maxl],t[maxl];
    
    inline void prework()
    {
        scanf("%s",s+1);
        slen=strlen(s+1);
        for(int i=0;i<26;i++)
            nxtind[i]=maxl-1;
        for(int i=slen;i>=1;i--)
        {
            for(int j=0;j<26;j++)
                nxt[i][j]=nxtind[j];
            nxtind[s[i]-'a']=i;
        }
        for(int j=0;j<26;j++)
            nxt[0][j]=nxtind[j];
    }
    
    inline bool check()
    {
        tlen=strlen(t+1);
        int u=0;
        for(int i=1;i<=tlen;i++)
        {
            u=nxt[u][t[i]-'a'];
            if(u==0 || u>slen)
                return false;
        }
        return true;
    }
    
    inline void mainwork()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",t+1);
            if(check())
                puts("YES");
            else    
                puts("NO");    
        }
    }
    
    int main()
    {
        prework();
        mainwork();
        return 0;
    }
    View Code

    shl聚菜。%lfw.%byf.

  • 相关阅读:
    getBoundingClientRect介绍
    【vue移动端架子】vue-h5-template
    【vue】openshopping-vue
    【vuex】vue2-happyfri
    Google浏览器插件之闪存过滤器
    跟我一起写一个chrome扩展程序
    Windows Server AppFabric 安装文档
    提高entity framework 性能,要注意哪些事情.
    [Entity Framework]获取部分字段的查询
    EF多表查询方式
  • 原文地址:https://www.cnblogs.com/csushl/p/10743353.html
Copyright © 2020-2023  润新知