zoukankan      html  css  js  c++  java
  • Gym.101955: Asia Shenyang Regional Contest(寒假自训第10场)

    C.Insertion Sort

    题意:Q次询问,每次给出N,M,Mod,问你有多少种排列,满足前面M个数字排序之后整个序列的LIS>=N-1。

    思路:我们把数字看成[1,M],[N-M+1,N]两个部分,假设是A和B。分几种情况即可。

    我发现我好像想错了。 https://blog.csdn.net/qq_23502651/article/details/84680151

    另外:长度为N的排列的LIS为N-1的个数=(N-1)^2; 可以推出这个公式。F(i)=F(i-1)+i-1;  F(2)=1; F(3)=F(2)+2...就有了.

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=110;
    int main()
    {
        ll T,N,M,C=0,Mod,ans;
        scanf("%lld",&T);
        while(T--){
            scanf("%lld%lld%lld",&N,&M,&Mod);
            if(M>=N-1){
                ans=1;
                rep(i,1,N) ans=(ll)ans*i%Mod;
            }
            else {
                ans=1; ll t=((N-M)*(N-M-1)+M*(N-M)+1)%Mod; 
                rep(i,1,M) ans=(ll)ans*i%Mod;
                ans=(ll)ans*t%Mod;
            }
            printf("Case #%lld: %lld
    ",++C,ans);
        }
        return 0;
    }

    E .The Kouga Ninja Scrolls

    题意:二维平面上有一些点,现在又几种操作,修改点的位置,修改点的颜色。 询问区间异色的点在最远曼哈顿距离。

    思路:最远曼哈顿距离,想到转化为切比雪夫距离,然后线段树。以为要维护最大次大,最小次小,x,y; 感觉太多太长没敢写。

    我们可以不转化为切比雪夫,直接用之前的k维最远距离,建立2^k棵线段树。 这样的好处是。 一个区间的最小值,等效与补值对应的线段树的最大值的相反数。

     这样我们就没必要维护最小次小了,代码会好看一点。

    本题收获:最大和最小值,我们可以统一;  在合并的情况比较多的时候,开一些全局变量,然后减少情况讨论。 比如query的时候,直接与全局变量的res更新答案。

    好麻烦啊。。。估计转化维切比雪夫的代码会很长。

    #include<bits/stdc++.h>
    #define ll long long
    #define f first
    #define s second
    #define pii pair<ll,ll>
    #define rep(i,w,v) for(int i=w;i<=v;i++)
    using namespace std;
    const int maxn=200010;
    const ll inf=(1LL<<55);
    ll x[maxn],y[maxn],a[maxn][4];int c[maxn];
    pii res[4][2];
    struct in{
        pii Mx[maxn<<2][2]; int idx;
        void pushup(int Now)
        {
            if(Mx[Now<<1][0].s!=Mx[Now<<1|1][0].s){
                if(Mx[Now<<1][0].f>Mx[Now<<1|1][0].f){
                    Mx[Now][0]=Mx[Now<<1][0];
                    Mx[Now][1]=max(Mx[Now<<1][1],Mx[Now<<1|1][0]);
                }
                else {
                    Mx[Now][0]=Mx[Now<<1|1][0];
                    Mx[Now][1]=max(Mx[Now<<1|1][1],Mx[Now<<1][0]);
                }
            }
            else {
                rep(i,0,1)
                Mx[Now][i]=max(Mx[Now<<1][i],Mx[Now<<1|1][i]);
            }
        }
        void build(int Now,int L,int R)
        {
            if(L==R){
                Mx[Now][0].f=a[L][idx]; Mx[Now][0].s=c[L];
                Mx[Now][1].f=-inf; Mx[Now][1].s=-1;
                return ;
            }
            int Mid=(L+R)>>1;
            build(Now<<1,L,Mid);
            build(Now<<1|1,Mid+1,R);
            pushup(Now);
        }
        void update(int Now,int L,int R,int pos)
        {
            if(L==R){
                Mx[Now][0].f=a[L][idx]; Mx[Now][0].s=c[L];
                Mx[Now][1].f=-inf; Mx[Now][1].s=-1;
                return ;
            }
            int Mid=(L+R)>>1;
            if(pos<=Mid) update(Now<<1,L,Mid,pos);
            else update(Now<<1|1,Mid+1,R,pos);
            pushup(Now);
        }
        void query(int Now,int L,int R,int l,int r)
        {
            if(l<=L&&r>=R){
                if(Mx[Now][0].s!=res[idx][0].s){
                    if(Mx[Now][0].f>res[idx][0].f){
                        res[idx][1]=max(res[idx][0],Mx[Now][1]);
                        res[idx][0]=Mx[Now][0];
                    }
                    else {
                        res[idx][1]=max(res[idx][1],Mx[Now][0]);
                    }
                }
                else {
                    rep(i,0,1)
                    res[idx][i]=max(res[idx][i],Mx[Now][i]);
                }
                return ;
            }
            int Mid=(L+R)>>1;
            if(l<=Mid) query(Now<<1,L,Mid,l,r);
            if(r>Mid) query(Now<<1|1,Mid+1,R,l,r);
        }
    }T[4];
    int main()
    {
        int Cas,N,M,Fcy=0,opt,L,R,K,C;ll X,Y;
        scanf("%d",&Cas); rep(i,0,3) T[i].idx=i;
        while(Cas--){
            scanf("%d%d",&N,&M);
            rep(i,1,N) scanf("%I64d%I64d%I64d",&x[i],&y[i],&c[i]);
            rep(i,1,N) {
                a[i][0]=x[i]+y[i];
                a[i][1]=x[i]-y[i];
                a[i][2]=-x[i]+y[i];
                a[i][3]=-x[i]-y[i];
            }
            rep(i,0,3) T[i].build(1,1,N);
            printf("Case #%d:
    ",++Fcy);
            while(M--){
                scanf("%d",&opt);
                if(opt==1){
                    scanf("%d%I64d%I64d",&K,&X,&Y);
                    x[K]+=X; y[K]+=Y;
                    a[K][0]=x[K]+y[K];
                    a[K][1]=x[K]-y[K];
                    a[K][2]=-x[K]+y[K];
                    a[K][3]=-x[K]-y[K];
                    rep(j,0,3) T[j].update(1,1,N,K);
                }
                else if(opt==2){
                    scanf("%d%d",&K,&C); c[K]=C;
                    rep(i,0,3) T[i].update(1,1,N,K);
                }
                else {
                    scanf("%d%d",&L,&R);
                    rep(i,0,3) {
                        res[i][0].f=res[i][1].f=-inf;//mp(-inf,-1);
                        res[i][0].s=res[i][1].s=-1;
                    }
                    rep(i,0,3) T[i].query(1,1,N,L,R);
                    ll ans=0;
                    rep(i,0,3) {
                        if(res[i][0].s!=res[3-i][0].s) ans=max(ans,res[i][0].f+res[3-i][0].f);
                        else {
                            ans=max(ans,res[i][0].f+res[3-i][1].f);
                            ans=max(ans,res[i][1].f+res[3-i][0].f);
                        }
                    }
                    printf("%I64d
    ",ans);
                }
            }
        }
        return 0;
    }

    G .Best ACMer Solves the Hardest Problem

    题意:在二维平面上四种操作: 1,加一个带权的点; 2,删去一个点; 3,给一个点周围欧几里得距离为sqrt(k)的存在的点点权都加w; 4,查询一个到点欧几里得距离为sqrtk的点权和。

    思路:发现到一个点的欧几里得距离为k的点并不多。所以我们暴力即可。 注意用 ll。

    #include<bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    #define mp make_pair
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxm=10000000;
    const int maxn=6010;
    ll a[maxn][maxn];int vis[maxn][maxn],Ca,tot;
    vector<pii>G[maxm+10];
    void init()
    {
        rep(i,0,3200){
            rep(j,0,3200){
                if(i*i+j*j>maxm) break;
                G[i*i+j*j].push_back(mp(i,j));
                tot++;
            }
        }
    }
    void add(int x,int y,int w)
    {
        if(vis[x][y]!=Ca) a[x][y]=0,vis[x][y]=Ca;
        a[x][y]+=w;
    }
    void del(int x,int y)
    {
        vis[x][y]=0; a[x][y]=0;
    }
    void FCY(int x,int y,int w)
    {
        if(x<0||x>6000||y<0||y>6000)  return ;
        if(vis[x][y]==Ca) a[x][y]+=w;
    }
    int query(int x,int y)
    {
        if(x<0||x>6000||y<0||y>6000)  return 0;
        if(vis[x][y]==Ca)  return a[x][y];
        return 0;
    }
    void ADD(int x,int y,int k,int w)
    {
        for(int i=0;i<G[k].size();i++){
            int dx=G[k][i].first,dy=G[k][i].second;
            FCY(x+dx,y+dy,w);
            if(dx!=0) FCY(x-dx,y+dy,w);
            if(dy!=0) FCY(x+dx,y-dy,w);
            if(dx!=0&&dy!=0) FCY(x-dx,y-dy,w);
        }
    }
    ll Query(int x,int y,int k)
    {
        ll res=0;
        for(int i=0;i<G[k].size();i++){
            int dx=G[k][i].first,dy=G[k][i].second;
            res+=query(x+dx,y+dy);
            if(dx!=0) res+=query(x-dx,y+dy);
            if(dy!=0) res+=query(x+dx,y-dy);
            if(dx!=0&&dy!=0) res+=query(x-dx,y-dy);
        } return res;
    }
    int main()
    {
        int T,N,M,x,y,w,k,opt;ll ans;
        init();
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&N,&M); Ca++; ans=0;
            printf("Case #%d:
    ",Ca);
            rep(i,1,N){
                scanf("%d%d%d",&x,&y,&w);
                add(x,y,w);
            }
            rep(i,1,M){
                scanf("%d%d%d",&opt,&x,&y);
                x=(x+ans)%6000+1; y=(y+ans)%6000+1;
                if(opt==1){
                    scanf("%d",&w);
                    add(x,y,w);
                }
                else if(opt==2){
                    del(x,y);
                }
                else if(opt==3){
                    scanf("%d%d",&k,&w);
                    ADD(x,y,k,w);
                }
                else {
                    scanf("%d",&k);
                    printf("%lld
    ",ans=Query(x,y,k));
                }
            }
        }
        return 0;
    }

    K .Let the Flames Begin

    题意:约瑟夫问题,给定N,K,M,问第M个出来的人的编号是。 K或者M<1e6;

    思路:只要知道公式就大概知道怎么做的题。

    我们知道第N个人出来的编号公式是: p=0 ; rep(i,1,N) p=(p+k)%i;    ans=p;(假设从0开始)

    而第M个出来的人的编号,我们可以假设已经进行了N-M轮,但其实我们并不关心他们的位置,我可以做完之后把他们放到对应位置即可。

    所以第M个人的编号是:p=0;rep(i,1,M) p=(p+k)%(i+N-M);

    当M比较小时,可以直接求; 当K比较小时,我们可以利用整除合并的思想做。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(ll i=a;i<=b;i++)
    using namespace std;
    ll solve(ll N,ll M,ll K) //N个人,每K个skip一次,第M次skip的是谁
    {
        if(K==1) return M; ll p=0;
        if(M<=K){
            rep(i,1,M){
                p=(p+K-1)%(i+N-M)+1;
            }
        }
        else {
            ll tM=M;
            rep(i,1,M){
                if(!tM) break;
                if(p+K-1>=i+N-M) tM--,p=(p+K-1)%(i+N-M)+1;//,cout<<i<<":"<<p<<endl;
                else {
                    //p+kx-1<i+x-1+N-M   ->  x<(i-1+N-M-p)/(k-1);
                     ll t=(i+N-M-p)/(K-1),g;
                     if((i+N-M-p)%(K-1)==0) t--;
                     g=min(t,tM);
                     p=p+K*g; tM-=g;
                     i=i+g-1;
                }
            }
        }
        return p;
    }
    int main()
    {
        int T,Ca=0; ll N,M,K;
        scanf("%d",&T);
        while(T--){
            scanf("%lld%lld%lld",&N,&M,&K);
            printf("Case #%d: %lld
    ",++Ca,solve(N,M,K));
        }
        return 0;
    }

    J .How Much Memory Your Code Is Using?

    题意:开了一些变量,问你用了多少内存。

    思路:模拟即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=200010;
    const int mod=1e9+7;
    char c[1000],a[10]={'l','o','n','g',' ','l','o','n','g'};
    char b[12]={'l','o','n','g',' ','d','o','u','b','l','e'};
    ll sum=0;  int L;
    bool check1()
    {
        bool F=true;
        if(L<9) return false;
        rep(i,0,8) if(c[i]!=a[i]) return false;
        return true;
    }
    bool check2()
    {
        bool F=true;
        if(L<11) return false;
        rep(i,0,10) if(c[i]!=b[i]) return false;
        return true;
    }
    void solve()
    {
        ll tmp; L=strlen(c);
        if(c[0]=='b'||c[0]=='c') tmp=1;
        if(c[0]=='i'||c[0]=='f') tmp=4;
        if(check1()||c[0]=='d') tmp=8;
        if(c[0]=='_'||check2()) tmp=16;
        rep(i,0,L-1){
            if(c[i]=='['){
                int k=0;
                rep(j,i+1,L-1) if(c[j]>='0'&&c[j]<='9') k=k*10+c[j]-'0';
                tmp*=k;
                break;
            }
        }
        sum+=tmp;
    }
    int main()
    {
        int T,N,Ca=0;
        scanf("%d",&T);
        while(T--){
            scanf("%d
    ",&N); sum=0;
            rep(i,1,N){
                gets(c);
                solve();
            }
            ll F=sum/1024;  if(sum%1024) F++;
            printf("Case #%d: %lld
    ",++Ca,F);
        }
        return 0;
    }
  • 相关阅读:
    MongoDB安装与配置
    关于dependencies和devDependencies的理解
    npm常用指令小记
    git ssh配置
    浅谈sharding jdbc
    浅谈分布式数据库
    web容量规划
    mysql in()后子查询优化
    负载均衡架构
    领域驱动设计-3-模型的管理
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10363254.html
Copyright © 2011-2022 走看看