Educational Codeforces Round 67 (Rated for Div. 2) A B C

题目链接http://codeforces.com/contest/1187/problem


Problem A

我们要先想出最糟糕的情况是取完    只有1 和 只有2   中较大的,才取到另一种

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#define ll long long
#define debug(x) printf("----Line%s----\n",#x)

using namespace std;

const int N = 1e5+5;

int main()
{
    int T;scanf("%d",&T);while (T--){
    //int n;while (~scanf("%d",&n)){}
        ll n,s,t;
        scanf("%I64d %I64d %I64d",&n,&s,&t);
        ll gg = (s+t-n);
        ll ans = max(s-gg,t-gg)+1;
        printf("%I64d\n",ans);
    }
    return 0;
}

Problem B

记录主串每个字母第几次出现的位置

每次询问统计询问串所有出现的字母的个数,在主串中找,取最大的

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#include<vector>
#define ll long long
#define debug(x) printf("----Line%s----\n",#x)
#define pb push_back
using namespace std;

const int N = 2e5+5;

char s[N];
vector<int>ve[30];///ve[i][j]代表字符i对应的
#define idx(i) i-96
int cnt[30];

int main()
{
    //int T;scanf("%d",&T);while (T--){}
    int n;while (~scanf("%d",&n)){
        for (int i=1;i<=26;i++) ve[i].clear();
        scanf("%s",s);
        for (int i=0;s[i];i++)
            ve[idx(s[i])].pb(i+1);
        int q;
        scanf("%d",&q);
        while (q--){
            memset(cnt,0,sizeof cnt);
            scanf("%s",s);
            for (int i=0;s[i];i++)
                cnt[idx(s[i])]++;
            int ans = 0;
            for (int i=1;i<=26;i++)
                if (cnt[i]) ans = max(ans,ve[i][cnt[i]-1]);
            printf("%d\n",ans);
        }

    }
    return 0;
}

Problem C

线段树维护递增的线段,是线段,不是区间内的数!

其他东西都在代码中

注释第三行的意思是初始:n,n-1,.......,3,2,1

//Educational Codeforces Round 67 (Rated for Div. 2)
//http://codeforces.com/contest/1187/problem/C
///贪心的思想:尽可能制造处理必须递增的递增,其他都递减的情况,所以初始情况为递减
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid int m = l+r>>1
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define tl tree[rt<<1]
#define tr tree[rt<<1|1]

using namespace std;

const int N = 1e3+5;

int tree[N<<2];///维护递增的线段
bool increase[N];///increase[i] = true 表示区间[i,i+1]递增 ,increase[i] = false 表示区间(i,i+1]递减,但是只有一段区间的话只有一个数,因为下段递增,所以重新排列
int op[N],l[N],r[N];

void push_up(int rt)
{
    tree[rt] = tl+tr;
}

void push_down(int rt,int len)
{
    tl = len-len/2;
    tr = len/2;
}

void update(int L,int R,int rt,int l,int r)///记得R-1
{
    if (tree[rt]==r-l+1) return ;
    if (L<=l && r<=R){
        for (int i=l;i<=r;i++) increase[i]=true;
        tree[rt] = r-l+1;
        return ;
    }
    if (tree[rt]==r-l+1) push_down(rt,r-l+1);
    mid;
    if (L<=m) update(L,R,lson);
    if (R >m) update(L,R,rson);
    push_up(rt);
}

bool flag;///表示当前是否可以存在该递减区间
void query(int L,int R,int rt,int l,int r)///判断询问的线段是否全在递增区间,记得R-1
{
    if (flag) return ;
    if (L<=l && r<=R){
        if (tree[rt]!=r-l+1) flag = true;
        return ;
    }
    if (tree[rt]==r-l+1) push_down(rt,r-l+1);
    mid;
    if (L<=m) query(L,R,lson);
    if (R >m) query(L,R,rson);
}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for (int i=1;i<=m;i++){
        scanf("%d %d %d",op+i,l+i,r+i);
    }

    for (int i=1;i<=m;i++)
        if (op[i]==1) update(l[i],r[i]-1,1,1,n);
    flag = true;///防止一次也没出现
    for (int i=1;i<=m;i++){
        if (op[i]==0){
            flag = false;
            query(l[i],r[i]-1,1,1,n);
            if (!flag) break;
        }
    }

    if (!flag) printf("NO\n");
    else {
        bool blank = false;
        printf("YES\n");
        int now = n;
        for (int i=1;i<n;i++){
            if (increase[i]){
                int renow = now;
                now -= 2;

                while (increase[i+1]){now--;i++;}
                for (int j=now+1;j<=renow;j++){
                    if (!blank) blank = true;
                    else printf(" ");
                    printf("%d",j);
                }
            }

            else if (!increase[i]){
                if (!increase[i-1]){
                    if (!blank) blank = true;
                    else printf(" ");
                    printf("%d",now--);
                }
                if (i==n-1) printf(" %d",now--);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43768644/article/details/94411394