码迷,mamicode.com
首页 > 其他好文 > 详细

2018 Multi-University Training Contest 2

时间:2018-07-26 14:57:38      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:shu   else   efi   scan   hdu   nbsp   view   ble   tar   

Game

题意:

  Alice和Bob先后手玩游戏,每次可以从一个集合中拿出一个数(初始为1~n),拿出之后,这个数的所有因数都会从这个集合中消失,谁没有数可拿时,就输了。问Alice是否能赢?

分析:

  如果先手拿x为必胜态,那么Alice一定能赢;如果先手拿x为必输态,那么Alice先手拿1,则必输态转移给Bob,所以Alice一定能赢。

代码:

技术分享图片
#include <cmath>
#include <vector>
#include <stdio.h>
#include <iostream>

using namespace std;
#define ll long long
const int maxn=1e5+100;

int main()
{
//    freopen("in.txt","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("Yes\n");
    }
    return 0;
}
View Code

Naive Operations

题意:

  给出b数组,和q次操作。如果为add l r操作,则把a数组【l,r】区间的值都加上一,query l r操作询问【l,r】区间a【i】/b【i】(向下取整)的和。

分析:

  利用线段树存下区间的最大a[i]和最小b[i]值,当a[i]>=b[i]时,说明c[i]的值需要加一(c[i]=a[i]/b[i]),sum存储对应区间的c[i]之和,具体看代码注释。

代码:

技术分享图片
#include <cmath>
#include <vector>
#include <stdio.h>
#include <iostream>

using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=1e5+100;

int n,q,l,r,c;

char s[10];

ll b[maxn];
//add[rt]:延迟标记,rt区间的a[i]值需要加上add[rt]
//sum[rt]:ai/bi的区间和
//minval[rt]:rt区间的最小b[i]值
//maxval[rt]:rt区间的最大a[i]值
ll sum[maxn<<2],add[maxn<<2],minval[maxn<<2],maxval[maxn<<2];

void PushUp(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    minval[rt]=min(minval[rt<<1],minval[rt<<1|1]);
    maxval[rt]=max(maxval[rt<<1],maxval[rt<<1|1]);
}

void PushDown(int rt)
{
    if(add[rt]){
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        maxval[rt<<1]+=add[rt];
        maxval[rt<<1|1]+=add[rt];
        add[rt]=0;
    }
}

void build(int l,int r,int rt)
{
    add[rt]=0;
    if(l==r){
        sum[rt]=0;
        maxval[rt]=0;
        minval[rt]=b[l];
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        maxval[rt]+=c;
        if(maxval[rt]<minval[rt]){
            add[rt]+=c;
            return;
        }
        if(l==r&&maxval[rt]>=minval[rt]){
            sum[rt]++;
            //第i次贡献时,maxval[rt]的值为i*b[l]
            //所以每次maxval[rt]贡献后,minval[rt]的值需要加上b[l]
            minval[rt]+=b[l];
            return;
        }
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(L<=m)    update(L,R,c,lson);
    if(R>m)     update(L,R,c,rson);
    PushUp(rt);
}

ll query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        return sum[rt];
    }
    PushDown(rt);
    ll ans=0;
    int m=(l+r)>>1;
    if(L<=m) ans+=query(L,R,lson);
    if(R>m)  ans+=query(L,R,rson);
    return ans;
}

void debug(int l,int r,int rt)
{
    if(l==r){
        printf("debug:%d %d\n",l,sum[rt]);
        return;
    }
    int m=(l+r)>>1;
    debug(lson);
    debug(rson);
}

int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        for(int i=1;i<=n;i++){
            scanf("%lld",&b[i]);
        }

        build(1,n,1);
        for(int j=1;j<=q;j++){
            scanf("%s%d%d",s,&l,&r);
            if(s[0]==a){
                update(l,r,1,1,n,1);
//                debug(1,n,1);
            } else {
                printf("%lld\n",query(l,r,1,n,1));
            }
        }
    }
    return 0;
}
View Code

 

Swaps and Inversions

题意:

  给出一个序列,如果存在一对逆序对需要花费x元,现在可以对两个相邻的元素进行交换,每次交换需要花费y元,问最少要花费多少钱?

分析:

  首先一次交换能够减少1对逆序对,那么num对逆序对,就需要num次交换。如果交换i次,花费cost=i*y+(num-i)*x=num*x-i*(y-x),不难看出,mincost=min(x,y)*num。

代码:

技术分享图片
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=1e5+100;
int sum[maxn<<2],x[maxn],Hash[maxn];

void PushUp(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void build(int l,int r,int rt)
{
    sum[rt]=0;
    if(l==r){
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}

void update(int p,int add,int l,int r,int rt)
{
    if(l==r){
        sum[rt]+=add;
        return;
    }
    int m=(l+r)>>1;
    if(p<=m)    update(p,add,lson);
    else        update(p,add,rson);
    PushUp(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        return sum[rt];
    }
    int ans=0;
    int m=(l+r)>>1;
    if(L<=m)    ans+=query(L,R,lson);
    if(R>m)     ans+=query(L,R,rson);
    return ans;
}

int main()
{
//    freopen("in.txt","r",stdin);
    int n,costx,costy;
    while(scanf("%d%d%d",&n,&costx,&costy)!=EOF)
    {
        ll cntx=0,cnty=0;
        build(0,n-1,1);
        for(int i=0;i<n;i++){
            scanf("%d",&x[i]);
            Hash[i]=x[i];
        }

        sort(Hash,Hash+n);
        int sz=unique(Hash,Hash+n)-Hash;
        for(int i=0;i<n;i++){
            x[i]=lower_bound(Hash,Hash+sz,x[i])-Hash;
        }

        for(int i=0;i<n;i++){
            cntx+=query(x[i]+1,n-1,0,n-1,1);
            update(x[i],1,0,n-1,1);
        }
        cnty=cntx;

        ll ans=min(cntx*costx,cnty*costy);
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

2018 Multi-University Training Contest 2

标签:shu   else   efi   scan   hdu   nbsp   view   ble   tar   

原文地址:https://www.cnblogs.com/shutdown113/p/9371135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!