Codeforces Round #602 (Div. 2A,B(线段树),C(暴力),D1(暴力),D2(权值线段树))

昨天打牛客的小白惨不忍睹,今天发挥的还是惨不忍睹,但是还行,迟到20分钟写到了D2,但是C没时间写了。。

题目链接

A 水题一个

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
int main()
{
	int _;cin>>_;while(_--)
	{
	    int n;
	    scanf("%d",&n);

	    int mi,mx;
	    for(int i=1;i<=n;++i)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            if(i==1){
                mi=r,mx=l;
            }
            else{
                mi=min(mi,r);
                mx=max(mx,l);
            }
        }
        if(n==1||mx

B. Box

给出q[i]

q[i]保存的 是前i个a[i]的最大值,

现给出q[i],问能否构造出a[i],输出a[i]

我的做法是写复杂了,有更简单的做法

做法:很显然,当q[i]!=q[i-1]的时候a[i]=q[i],有些a[i]无法确认,那就i从1开始到n,没有被放在a[i]中就在线段树找大于i的且最左边的位置放i

线段树维护最大值,单点更新

 

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
int n;
const int N=1e5+10;
int q[N],ans[N];
int vis[N],mx[4*N];
bool flag;
void up(int id,int l,int r,int val)
{
    if(l==r){

        flag=1;
        ans[l]=val;
        mx[id]=-1;
        return ;
    }
    int mid=l+r>>1;
    if(mx[id<<1]>val&&flag==0) up(id<<1,l,mid,val);
    if(mx[id<<1|1]>val&&flag==0) up(id<<1|1,mid+1,r,val);

    mx[id]=max(mx[id<<1],mx[id<<1|1]);

}
void build(int id,int l,int r)
{
    if(l==r){
        if(ans[l]==-1) {
            //printf("l:%d\n",l);
            mx[id]=q[l];
        }
        else mx[id]=-1;
        return ;
    }
    int mid=l+r>>1;
    build(id<<1,l,mid);
    build(id<<1|1,mid+1,r);
    mx[id]=max(mx[id<<1],mx[id<<1|1]);
}
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%d",&q[i]);
            vis[i]=0;
            ans[i]=0;
        }

        int f=1;
        ans[1]=q[1];
        vis[ans[1]]=1;
        for(int i=2;i<=n;++i){
            if(q[i]!=q[i-1]) {
                ans[i]=q[i];
                vis[ans[i]]=1;
            }
            else ans[i]=-1;
        }
        build(1,1,n);

        for(int i=1;i<=n&&f;++i){
            if(vis[i]) continue;
            vis[i]=1;
            flag=0;
            up(1,1,n,i);
            if(flag==0) f=0;
        }

        if(!f) {
            puts("-1");
            continue;
        }

        for(int i=1;i<=n;++i) printf("%d ",ans[i]);
        puts("");
    }
}
/*
5
5
1 3 3 5 5
*/

C. Messy

暴力构造答案串,

然后暴力匹配,当不匹配,在后面找一个匹配的,逆转一下即可。。

#include
using namespace std;
const int N=2e3+10;
char s[N];
int n,k;
vector >G;
int main()
{
    int _;cin>>_;while(_--)
    {
        G.clear();
        scanf("%d%d%s",&n,&k,s);

        string ans="";
        k--;
        while(k--) ans+="()";
        int id=n-ans.size();
        id/=2;
        for(int i=1;i<=id;++i) ans+="(";
        for(int i=1;i<=id;++i) ans+=")";
        //cout<<"ans: "<

D1. Optimal Subsequences (Easy Version)

优先队列暴力搞一下就可以了

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
const int N=1e3+10;
int a[N],ans[N];
struct node
{
    int id,val;
    bool operator <(const node &o)const {
        if(val==o.val) return o.idval;
    }
};
int n,m;
int main()
{
    scanf("%d",&n);
    priority_queueque;
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        que.push({i,a[i]});
    }
    scanf("%d",&m);
    while(m--)
    {
        int k,pos;
        scanf("%d%d",&k,&pos);
        priority_queuetmp;
        for(int i=1;i<=n;++i) ans[i]=0;
        tmp=que;
        while(k--){
            node t=tmp.top();
            tmp.pop();
            ans[t.id]=t.val;
        }
        for(int i=1;i<=n&&pos>=0;++i){
            if(ans[i]==0) continue;
            pos--;
            if(pos==0) {
                printf("%d\n",ans[i]);
                break;
            }
        }
    }
}

D2. Optimal Subsequences (Hard Version)

题意:给n个数a[i],m次询问

,每次询问输入,k,pos,要求前k个最大值,按照数组原序列 输出第pos个的值。

做法:离线一下,按照k排序,优先队列+权值线段树 查询区间第pos个值(相当于查询第pos大值)

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
const int N=2e5+10;
int a[N],n,m,ans[N];
struct node
{
    int id,val;
    bool operator <(const node &o)const {
        if(val==o.val) return o.idval;
    }
};
struct node1
{
    int k,pos,id;
}q[N];
bool cmp(node1 a,node1 b)
{
    if(a.k==b.k) return a.pos>1;
	if(pos<=mid)
	up(id<<1,l,mid,pos,val);
	else up(id<<1|1,mid+1,r,pos,val);
	pushup(id);
}

void qu(int id,int l,int r,int k,int c)
{
    if(l==r){
       ans[c]=sum[id];
        return ;
    }
    int mid=l+r>>1;
    int cmp=num[id<<1];
    if(cmpque;
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        que.push({i,a[i]});
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i){
        scanf("%d%d",&q[i].k,&q[i].pos);
        q[i].id=i;
    }
    sort(q+1,q+1+m,cmp);
    int tt=0;
    //for(int i=1;i<=m;++i) printf("k:%d pos:%d\n",q[i].k,q[i].pos);

    for(int i=1;i<=m;++i)
    {
        while(tt

 

你可能感兴趣的:(codeforce题解,数据结构---线段树)