昨天打牛客的小白惨不忍睹,今天发挥的还是惨不忍睹,但是还行,迟到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