给出一个序列,初始时序列的长度为 n,序列中每个数为 0。
进行 m 次操作,操作有三种:
1 k 在序列开头加入 k 个数字 0
2 k 在序列末尾加入 k 个数字 0
3 b s 给序列中所有数字加上 b+s*(i-1) [i 是该数字在序列中的位置]
你需要在每次操作后输出序列中最小的数字大小和位置,如果有多个最小的数字,输出最靠前的一个
又是一道CF换头题。
正解完全没想到,但是由于考试的时候是随机数据,所以可以使用乱搞方法切掉。
本质上是朴素的暴力,均摊复杂度为\(O(m)\)(尽管可以被卡成\(O(m^2)\))
#include <bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T>inline void read (T &x) {
x=0;T f=1;char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T>inline void write (T x) {
if (x<0) putchar('-'),x*=-1;
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
namespace Project {
#define int long long
const int N=100100;
int n,m,len,top;
pair<int,int> ans,answer[N],tmp[N];
inline void query () {
int ll=0;
ans.second=0x7fffffff;
for (register int i=1; i<=top; ++i) {
if (ans.second>answer[i].second) ans=answer[i],tmp[++ll]=ans;
}
for (register int i=1; i<=ll; ++i) {
answer[i]=tmp[i];
}
top=ll;
}
inline void MAIN () {
read(n),read(m),ans=make_pair(0,0),len=n-1,answer[++top]=ans;
for (register int i=1,op,x,y; i<=m; ++i) {
read(op);
if (op==1) {
read(x),top=1;
answer[top]=ans=make_pair(0,0);
len+=x;
} else if (op==2) {
read(x);
answer[++top]=make_pair(len+1,0);
query();
len+=x;
} else {
read(x),read(y);
for (register int i=1; i<=top; ++i) answer[i].second+=x+y*answer[i].first;
query();
}
write(ans.first+1),putchar(' '),write(ans.second),putchar('\n');
}
}
#undef int
}
int main () {
// freopen("1.in","r",stdin);
// freopen("2.out","w",stdout);
Project::MAIN();
}
Train Car Selection「CF1137E」/序列舞蹈「NOIP多校联考 2019」
原文:https://www.cnblogs.com/ilverene/p/11622392.html