思路就是正常的暴力。维护一个单调递增数列,一旦后面有比前面小的,就把前面的所有大于这个数的都削成这个数。最后得到一个{l,r,x}结构体数组,数组中的每个元素表示需要从l到r共削x次。要是几个点都TLE我也认了,关键是还有错的,想不通为什么枚举还能有错,所以想着是代码里有写错的地方,有没有大佬帮忙看看,帮帮可怜的蒟蒻QWQ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<unordered_map>
#include<cstdlib>
using namespace std;
typedef long long LL;
const LL N=200010,MOD=998224353,INF=0x7f7f7f7f;
int a[N],n;
int q[N];
struct Node{
int l,r,x;
}node[N];
int tot;
int get(int l,int r,int x){
while(l<r){
int mid=l+r>>1;
if(q[mid]<x) l=mid+1;
else r=mid;
}
return l;
}
void split(int l,int r,int x){
while(q[l]==x&&l<=r) l++;
if(l>r) return;
// cout<<l<<' '<<r<<endl;
node[tot++]={l,r,q[l]-x};
int ll=l,k=q[l];
for(int i=l;i<=r;i++){
if(q[i]==k){
q[i]=x;
ll=i;
}
}
split(ll+1,r,k);
}
void prt(int l,int r,int& mar){
if(mar&&l<r){
cout<<l<<' '<<l<<endl;
mar-=1;
prt(l+1,r,mar);
}else{
cout<<l<<' '<<r<<endl;
}
}
void solve(){
int m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
a[n+1]=0;
q[1]=a[1];
for(int i=2;i<=n+1;i++){
if(a[i]>=q[i-1]){
q[i]=a[i];
}else{
int l=get(1,i-1,a[i]);
split(l,i-1,a[i]);
q[i]=a[i];
}
}
LL cnt_minn=0,cnt_maxx=0;
for(int i=0;i<tot;i++){
// cout<<node[i].l<<' '<<node[i].r<<' '<<node[i].x<<endl;
cnt_minn+=node[i].x;
cnt_maxx+=(node[i].r-node[i].l+1)*node[i].x;
}
// cout<<cnt_minn<<' '<<cnt_maxx<<endl;
if(m<cnt_minn||m>cnt_maxx){
cout<<-1<<endl;
}else{
int mar=m-cnt_minn;
// cout<<mar<<endl;
for(int i=0;i<tot;i++){
int l=node[i].l,r=node[i].r,x=node[i].x;
for(int j=0;j<x;j++){
prt(l,r,mar);
}
}
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0);
int t;
// cin>>t;
t=1;
while(t--){
solve();
}
return 0;
}
全部评论
(1) 回帖