首页 > 代码库 > Codeforces_799

Codeforces_799

A.求两个时间比较一下。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,t,k,d;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> t >> k >> d;
    int tt = n/k;
    if(n%k) tt++;
    int sum1 = tt*t;
    int t1 = 0,t2 = d,now = 0;
    while(now < tt)
    {
        if(t1 < t2) t1 += t;
        else    t2 += t;
        now++;
    }
    int sum2 = max(t1,t2);
    if(sum1 > sum2) cout << "YES" << endl;
    else    cout << "NO" << endl;
    return 0;
}
View Code

B.按价格排序,预记录每种颜色的位置,询问的时候保存前一个可行的位置,线性扫即可。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,m,pos[5][200005],ok[200005] = {0};
struct xx
{
    int p,a,b;
    friend bool operator <(xx a,xx b)
    {
        return a.p < b.p;
    }
}a[200005];

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i = 1;i <= n;i++)   cin >> a[i].p;
    for(int i = 1;i <= n;i++)   cin >> a[i].a;
    for(int i = 1;i <= n;i++)   cin >> a[i].b;
    sort(a+1,a+1+n);
    int cnt[5] = {0};
    for(int i = 1;i <= n;i++)
    {
        int x = a[i].a,y = a[i].b;
        pos[x][++cnt[x]] = i;
        if(x != y)  pos[y][++cnt[y]] = i;
    }
    cin >> m;
    int now[5] = {1,1,1,1,1};
    while(m--)
    {
        int x;
        cin >> x;
        while(ok[pos[x][now[x]]])   now[x]++;
        if(now[x] > cnt[x]) cout << -1 << " ";
        else
        {
            ok[pos[x][now[x]]] = 1;
            cout << a[pos[x][now[x]]].p << " ";
        }
    }
    return 0;
}
View Code

C.分三种情况

1.两堆各取一个,直接遍历取每堆的符合要求的最大b值。

2.在A堆取2个。先按p小到大排序,然后从头到尾枚举一个c,二分符合要求的c-p值最后一个的位置,在这一段rmq找最大的b值,更新最大的和。

3.在B堆取2个,同上。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,c,d;
int maxdp1[100005][20],maxdp2[100005][20];
struct xx
{
    int b,x;
    xx(){};
    xx(int bb,int xx):b(bb),x(xx){};
    friend bool operator <(xx a,xx b)
    {
         return a.x < b.x;
    }
}a[100005],b[100005];

void rmq_init1(int len)
{
    for(int i = 1;i <= len;i++) maxdp1[i][0] = a[i].b;
    for(int j = 1;(1<<j) <= len;j++)
    {
        for(int i = 1;i+(1<<j)-1 <= len;i++)
        {
            maxdp1[i][j] = max(maxdp1[i][j-1],maxdp1[i+(1<<(j-1))][j-1]);
        }
    }
}

void rmq_init2(int len)
{
    for(int i = 1;i <= len;i++) maxdp2[i][0] = b[i].b;
    for(int j = 1;(1<<j) <= len;j++)
    {
        for(int i = 1;i+(1<<j)-1 <= len;i++)
        {
            maxdp2[i][j] = max(maxdp2[i][j-1],maxdp2[i+(1<<(j-1))][j-1]);
        }
    }
}

int rmq_max1(int l,int r)
{
    int k = (int)(log((double)(r-l+1))/log(2.0));
    return max(maxdp1[l][k],maxdp1[r-(1<<k)+1][k]);
}

int rmq_max2(int l,int r)
{
    int k = (int)(log((double)(r-l+1))/log(2.0));
    return max(maxdp2[l][k],maxdp2[r-(1<<k)+1][k]);
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> c >> d;
    int cnt1 = 0,cnt2 = 0;
    for(int i = 1;i <= n;i++)
    {
        int x,y;
        string s;
        cin >> x >> y >> s;
        if(s == "C")
        {
            a[++cnt1].b = x;
            a[cnt1].x = y;
        }
        else
        {
            b[++cnt2].b = x;
            b[cnt2].x = y;
        }
    }
    int maxx = 0;
    int pos1 = -1,max1 = 0;
    for(int i = 1;i <= cnt1;i++)
    {
        if(a[i].x <= c && a[i].b > max1)
        {
            pos1 = i;
            max1 = a[i].b;
        }
    }
    int pos2 = -1,max2 = 0;
    for(int i = 1;i <= cnt2;i++)
    {
        if(b[i].x <= d && b[i].b > max2)
        {
            pos2 = i;
            max2 = b[i].b;
        }
    }
    if(pos1 != -1 && pos2 != -1)    maxx = max1+max2;
    sort(a+1,a+1+cnt1);
    sort(b+1,b+1+cnt2);
    rmq_init1(cnt1);
    rmq_init2(cnt2);
    if(cnt1 > 1 && a[1].x+a[2].x <= c)
    {
        for(int i = 1;i <= cnt1;i++)
        {
            if(a[i].x >= c)  break;
            int t = upper_bound(a+1,a+cnt1+1,xx(0,c-a[i].x))-a-1;
            if(t <= i)  break;
            maxx = max(maxx,a[i].b+rmq_max1(i+1,t));
        }
    }
    if(cnt2 > 1 && b[1].x+b[2].x <= d)
    {
        for(int i = 1;i <= cnt2;i++)
        {
            if(b[i].x >= d)  break;
            int t = upper_bound(b+1,b+cnt2+1,xx(0,d-b[i].x))-b-1;
            if(t <= i)  break;
            maxx = max(maxx,b[i].b+rmq_max2(i+1,t));
        }
    }
    cout << maxx << endl;
    return 0;
}
View Code

还有一种方法,直接树状数组维护最大前缀max。

技术分享
#include <bits/stdc++.h>
using namespace std;

int n,c,d,C[100005],D[100005];

inline int lowbit(int x)
{
    return x & (-x);
}

void update(int tree[],int pos,int x)
{
    while(pos <= 100000)
    {
        tree[pos] = max(tree[pos],x);
        pos += lowbit(pos);
    }
}

int getmax(int tree[],int pos)
{
    int ans = INT_MIN;
    while(pos > 0)
    {
        ans = max(ans,tree[pos]);
        pos -= lowbit(pos);
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> c >> d;
    for(int i = 1;i <= 100000;i++)
    {
        C[i] = INT_MIN;
        D[i] = INT_MIN;
    }
    int ans = 0;
    while(n--)
    {
        int b,p,t;
        string s;
        cin >> b >> p >> s;
        if(s == "C")
        {
            if(p > c)   continue;
            t = max(getmax(C,c-p),getmax(D,d));
            update(C,p,b);
        }
        else
        {
            if(p > d)   continue;
            t = max(getmax(C,c),getmax(D,d-p));
            update(D,p,b);
        }
        ans = max(ans,t+b);
    }
    cout << ans << endl;
    return 0;
}
View Code

D.边长指数增长,我们需要的倍数很少,直接爆搜就可以了。

技术分享
#include <bits/stdc++.h>
using namespace std;

int a,b,w,h,n,A[100005],ans;

void dfs(int x,int y,int now,int nowx,int nowy)
{
    if(nowx >= x && nowy >= y)
    {
        ans = min(ans,now);
        return;
    }
    if(now == n+1)    return;
    if(A[now] == 2)
    {
        while(x > nowx)
        {
            nowx *= 2;
            now++;
        }
        while(y > nowy)
        {
            nowy *= 2;
            now++;
        }
        ans = min(ans,now);
        return;

    }
    if(x > nowx)    dfs(x,y,now+1,nowx*A[now+1],nowy);
    if(y > nowy)    dfs(x,y,now+1,nowx,nowy*A[now+1]);
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> a >> b >> w >> h >> n;
    for(int i = 1;i <= n;i++)   cin >> A[i];
    sort(A+1,A+1+n);
    reverse(A+1,A+1+n);
    ans = n+1;
    dfs((a-1)/h+1,(b-1)/w+1,0,1,1);
    dfs((a-1)/w+1,(b-1)/h+1,0,1,1);
    if(ans == n+1)  cout << -1 << endl;
    else    cout << ans << endl;
    return 0;
}
View Code

 

Codeforces_799