2020ICPC济南区域赛 D.Fight against involution & G.Xor Transformation

D.Fight against involution

  • 题意:给出多名学生每篇论文需要完成的字数区间,然后起初按照右区间的字数将学生进行排名(字数越多,排名越前),但是现在题目的要求就是这些学生很“卷”,希望写的论文字数近可能的少,然后排名又要不能低于原先的排名(可以高于),然后按照上诉要求计算出所有学生需要写的最少字数之和。
  • 思路:区间贪心
  • 解析:首先需将右区间从小到大进行排序,若右区间相等,则左区间按从大到小排序,因为我们需要满足排名不能低于原先排名,所以当右区间相同则意味着这些学生原先的排名应当一样,若左区间取小值,则在右区间相同的其他学生左值则取不到这个小值(若不按这个小值取,则他们的排名就不相等,就不能满足之前相等的条件),当右区间ri, ri + 1不同时,这时要取max(li + 1, 至目前为止左区间最大值),因为必须保证li + 1不能小于之前的取值(不然不能保证他之前的地位),下面举例说明:
    5
    1 3
    3 8
    2 3
    4 6
    5 6
    排序后:
    2 3
    1 3
    5 6
    4 6
    3 8
    模拟过程:第一次取w = 2, 接着因为2 > 1,所以仍然取w = 2,接着因为6 > 3,所以取max(5, 2) = 5,那么此时w = 5,同理下一个w = 5,但接下来我们发现8 > 6,若我们取w = 3(其左区间),则不能满足这个学生原先的排名(rank1),所以我们可以最小只能取w = 5(真的很卷),这时候尽管(5, 6)与(4, 6)这两个学生排名与(3, 8)这个学生一样(均为rank1),但满足题意要求:不低于原先排名。
  • 代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 5;
struct Grade
{
    int l, r;
}g[N];
int n, maxl = 0;
long long res = 0;
bool cmp(Grade a, Grade b)
{
    if(a.r != b.r) return a.r < b.r;
    return a.l > b.l;
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> g[i].l >> g[i].r;
    sort(g + 1, g + n + 1, cmp);
    res = g[1].l, maxl = g[1].l;
    for(int i = 2; i <= n; i++)
    {
        if(g[i].r == g[i-1].r) res += maxl;
        else
        {
            maxl = max(g[i].l, maxl);
            res += maxl;
        }
    }
    cout << res << endl;
    return 0;
}

G.Xor Transformation

  • 题意:给出x、y(y < x),进行操作x = x ^ a(0 <= a < x),经过d(0 <= d <= 5)次后 x = y,求d。
  • 性质:经过观察发现,x ^ y = z, x ^ z = y。
  • 解析:tmp = x ^ y。
    若tmp > x,则x ^ y = tmp(第一次把y看作a),接着X =tmp,这时候tmp(X) ^ x(初始的x,第二次把x看作a),则可使得X = y。
    否则,则可把tmp看作a,x ^ tmp = y,一次则可使x = y。
  • 代码:
#include<iostream>
using namespace std;
typedef long long ll;
ll x, y, tmp;
int main()
{
    cin >> x >> y;
    tmp = x ^ y;
    if(tmp > x) cout << "2" << endl << y << " " << x << endl;
    else cout << "1" << endl << tmp << endl;
    return 0;
}

posted @ 2021-04-10 19:49  ~K2MnO4  阅读(209)  评论(0)    收藏  举报