zoukankan      html  css  js  c++  java
  • [2019杭电多校第六场]

    1005传送门


    题意:一个二维图上有若干个点,每个点有一个坐标值(xi,yi),以及一个价值(vi) ( -1e9<=xi,yi,vi<=1e9),求一个价值和最大的矩形(只需输出最大价值和)
    题解:离散化后枚举上下边界可以将二维图降维为一个求一维动态最大字段和的问题,在横轴上建立线段树即可维护最大字段和

    #include<bits/stdc++.h>
    using namespace std;
    #define debug(x) cout<<#x<<" is "<<x<<endl;
    typedef long long ll;
    const int maxn=2e3+5;
    struct pot{
        int x;
        int y;
        ll val;
    }p[maxn];
    struct node{
        int l;
        int r;
        ll sum;
        ll maxxval;
        ll maxxpre;
        ll maxxnxt;
    }nod[maxn<<2];
    struct pot2{
        int x;
        ll val;
    };
    vector<struct pot2>g[maxn];
    int xx[maxn],yy[maxn];
    void build(int rt,int l,int r){
        nod[rt].l=l;
        nod[rt].r=r;
        nod[rt].sum=nod[rt].maxxnxt=nod[rt].maxxpre=nod[rt].maxxval=0;
        if(l==r){
            return;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build((rt<<1)|1,mid+1,r);
    }
    void pushup(int rt){
        nod[rt].maxxpre=max(nod[rt<<1].maxxpre,nod[rt<<1].sum+nod[(rt<<1)|1].maxxpre);
        nod[rt].maxxnxt=max(nod[(rt<<1)|1].maxxnxt,nod[rt<<1].maxxnxt+nod[(rt<<1)|1].sum);
        nod[rt].maxxval=max(max(nod[rt<<1].maxxval,nod[(rt<<1)|1].maxxval),max(max(nod[rt<<1].maxxnxt,nod[(rt<<1)|1].maxxpre),nod[rt<<1].maxxnxt+nod[(rt<<1)|1].maxxpre));
        nod[rt].sum=nod[rt<<1].sum+nod[(rt<<1)|1].sum;
    }
    void update(int rt,int l,int r,int x,ll val){
        if(l==r){
            nod[rt].sum+=val;
            nod[rt].maxxval+=val;
            nod[rt].maxxnxt+=val;
            nod[rt].maxxpre+=val;
            return ;
        }
        int mid=(l+r)>>1;
        if(mid>=x)update(rt<<1,l,mid,x,val);
        else update((rt<<1)|1,mid+1,r,x,val);
        pushup(rt);
    }
    ll query(int rt){
        return max(max(nod[rt].maxxval,nod[rt].maxxpre),nod[rt].maxxnxt);
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++){g[i].clear();scanf("%d%d%lld",&p[i].x,&p[i].y,&p[i].val);xx[i]=p[i].x,yy[i]=p[i].y;}
            sort(xx+1,xx+1+n);
            sort(yy+1,yy+1+n);
            int siz1=unique(xx+1,xx+1+n)-(xx+1);
            int siz2=unique(yy+1,yy+1+n)-(yy+1);
            for(int i=1;i<=n;i++){
                p[i].x=lower_bound(xx+1,xx+1+siz1,p[i].x)-xx;
                p[i].y=lower_bound(yy+1,yy+1+siz2,p[i].y)-yy;
                struct pot2 aa;
                aa.x=p[i].x;
                aa.val=p[i].val;
                g[p[i].y].push_back(aa);
            }
            ll ans=0;
            for(int i=1;i<=siz2;i++){
                build(1,1,siz1);
                for(int j=i;j<=siz2;j++){
                    for(int k=0;k<g[j].size();k++){
                        struct pot2 bb=g[j][k];
                        update(1,1,siz1,bb.x,bb.val);
                    }
                    ans=max(ans,query(1));
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    1008传送门


    题意:定义f(n,m)为大于n的第m个与n互质的数,令k=(f(n,m)-n)^n,现在已知k和m的值,输出最小的满足要求的n或者-1(不存在)(k<=1e18,m<=100)
    题解:由于k巨大而m很小,并且由m最大为100可以知道f(n,m)-n一定不太大(打表也可以发现f(n,m)-n始终<2^10),所以可以直接枚举(f(n,m)-n)的值,并且利用k的二进制下的各个值来计算n,检查枚举出的n的f(n,m)是否满足要求。总复杂度应为O(2^10 * 2^10)

    #include<bits/stdc++.h>
    using namespace std;
    //#define debug(x) cout<<#x<<" is "<<x<<endl;
    typedef long long ll;
    ll gcd(ll x,ll y){
        if(y==0)return x;
        return gcd(y,x%y);
    }
    ll k,m;
    bool dfs(ll pos,ll sum1,ll sum2){
        if(pos==0){
            if(gcd(sum1+sum2,sum2)==1){
                int t1=0;
                for(ll i=sum2+1;i<=sum1+sum2;i++){
                    if(gcd(i,sum2)==1)t1++;
                    if(t1>m)return 0;
                }
                if(t1<m)return 0;
                printf("%lld
    ",sum2);
                return 1;
            }
            return 0;
        }
        if((k>>(pos-1))&1){
            if(dfs(pos-1,sum1+(1<<(pos-1)),sum2))return 1;
            return dfs(pos-1,sum1,sum2+(1<<(pos-1)));
        }
        else{
            if(dfs(pos-1,sum1,sum2))return 1;
            return dfs(pos-1,sum1+(1<<(pos-1)),sum2+(1<<(pos-1)));
        }
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%lld%lld",&k,&m);
            ll x=k;
            ll t1=0;
            ll ac=0;
            while(x){
                t1++;
                if(t1>9&&(x%2)){
                    ac+=(1ll<<(t1-1));
                }
                x/=2;
            }
            if(dfs(9ll,0ll,ac)){
                ;
            }
            else{
                printf("-1
    ");
            }
        }
        return 0;
    }
    

    1012传送门


    题意:给出一个小顶堆,两人轮流从叶子处取数同时删除取走的叶子,求二者都最优情况下分别得到的总和
    题解:大顶堆优先队列

    #include<bits/stdc++.h>
    using namespace std;
    //#define debug(x) cout<<#x<<" is "<<x<<endl;
    typedef long long ll;
    const int maxn=1e5+5;
    priority_queue<ll>pq;
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            ll s1=0;
            ll s2=0;
            for(int i=1;i<=n;i++){ll a;scanf("%lld",&a);pq.push(a);}
            for(int i=1;i<=n;i++){
                ll xx=pq.top();pq.pop();
                if(i%2)s1+=xx;
                else s2+=xx;
            }
            printf("%lld %lld
    ",s1,s2);
        }
        return 0;
    }
    
  • 相关阅读:
    Decoration4:分页展示
    Decoration3:增删改的实现
    Decoration2:引入Angularjs显示前台一条数据
    SqlServer 查看被锁的表和解除被锁的表
    Quarz.net 设置任务并行和任务串行
    第三方博客平台足迹
    Oracle PL/SQL Developer 上传下载Excel
    SSRS使用MySql作为数据源遇到的问题。
    "类工厂模式"改写SqlHelper
    Centos7 redis 5.0 服务设置、启动、停止、开机启动
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/11327793.html
Copyright © 2011-2022 走看看