C - AtCoder Magics
https://atcoder.jp/contests/abc354/tasks/abc354_c
思路
首先按照a属性对数列进行排序,大的在前,小的在后, 完成后, 则数列在a参数上是非递增的。
如下图中x轴对应 a 参数, y轴对应c参数,
discard条件,实际上是找出 数列 对于c参数 沿着 a 参数非递减的点,
如下图中两个 非圆圈住的点,
要找出这些点, 可以构造 c 参数的下降曲线, 由下图中 圆圈 点 构成, 利用 最小前缀 存储 prefix_min[n],
最后遍历一遍, 将当前点的c值 跟 前一个 prefix_min 比较, 大于则为目标点,需要discard掉。
Code
https://atcoder.jp/contests/abc354/submissions/53680994
long long n;struct NODE{long long a;long long c;long long i;long long prefix_min; };bool cmp(struct NODE& x, struct NODE& y) {return x.a > y.a; }vector<struct NODE> container;int main() {cin >> n;for(int i=1; i<=n; i++){struct NODE one;cin >> one.a;cin >> one.c;one.i = i;container.push_back(one);}sort(container.begin(), container.end(), cmp);// for(auto one: container){ // cout << "a = " << one.a << endl; // }for(int i=0; i<n; i++){struct NODE& one = container[i];if (i == 0){one.prefix_min = one.c;} else {struct NODE& pre = container[i-1];one.prefix_min = min(one.c, pre.prefix_min);}}vector<bool> drop(n, false);for(int i=1; i<n; i++){if (container[i].a == container[i-1].a){continue;}if (container[i].c > container[i-1].prefix_min){drop[i] = true;}}// vector<struct NODE> left;set<long long> leftidx;for(int i=0; i<n; i++){if (drop[i]){continue;}// left.push_back(container[i]); leftidx.insert(container[i].i);// cout << "a = " << container[i].a << endl; // cout << "i = " << container[i].i << endl; }cout << leftidx.size() << endl;for(auto one: leftidx){cout << one << " ";}cout << endl;return 0; }