今天小姐姐给了我们说良心很良心,说毒瘤很毒瘤的一套题(小姐姐说是可以AK的)
老师一定刚去看了复联4
据说这是道水题,一个set模拟就好了
来我们看看小姐姐的标程(仅限c++11)
#include <cstdio> #include <set> #include <algorithm> using namespace std; class People { int id, force; People() {} People(int i, int f): id(i), force(f) {}//构造函数,意思是把id赋值为i,把force赋值为f }; bool operator <(People x, People y) { return x.force < y.force; } int n; set <People> s; int main() { scanf("%d", &n); s.insert(People(1, 1000000000)); for (int i = 1, x, y; i <= n; ++i) { scanf("%d%d", &x, &y); auto it1 = s.upper_bound(People(x, y));//找到第一个大于当前能力的人,这里返回的是指针 if (it1 == s.begin()) printf("%d %d\n", x, it1->id);//如果是第一个人,就让他和超人比 else { auto it3 = it1; auto it2 = --it3;//上面的数的前一个数的指针 int a1 = abs(it1->force - y);//与第一个大于其的数的能力值比较 int a2 = abs(it2->force - y);//和it2指向的数的能力值比较 if (a2 <= a1) it1 = it2;//选取最小的(这里依旧是指针) printf("%d %d\n", x, it1->id);//把那个数输出来 } s.insert(People(x, y));//比较完后加入set } return 0; }
bat-man:
60pts:
O(n^2)暴力枚举
80pts:
st表讲解(里面的程序没有加小姐姐的神奇输入输出,但主要部分就是里面的程序辣)
加了小姐姐的输入输出:
#include <cstdio> #include <ctime> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; const int N = 1e7 + 5; long long st[1<<23][23]; int n, m, a[N], ans[N]; int gen, cute1, cute2; int number() { gen = (1LL * gen * cute1) ^ cute2; return (gen & (n - 1)) + 1; } int seach(int l,int r) { int t=log((double)(r-l+1))/log(2.0); return max(st[l][t],st[r-(1<<t)+1][t]); } int main() { scanf("%d%d", &n, &m); scanf("%d%d%d", &gen, &cute1, &cute2); for (int i = 1; i <= n; ++i)//小姐姐的输入输出 a[i] = number(); for(int i=1;i<=n;i++) st[i][0]=a[i]; double sx=log((double) n)/log(2.0); for(int j=1;j<=sx;j++)//剩下的就是st表了qwq { for(int i=1;(i+(1<<j))-1<=n;i++) {st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]); } } for (int i = 1; i <= m; ++i) { int l = number(), r = number(); if (l > r) swap(l, r); ans[i]=seach(l,r); } int sum = 0; for (int i = 1; i <= m; ++i) sum = (1LL * sum * cute1 + ans[i]) % cute2; printf("%d\n", sum); }
100pts:
我们使用并查集。
小姐姐的代码(看不懂QwQ嘤~):
#include <cstdio> #include <ctime> #include <cstdlib> #include <algorithm> using namespace std; const int N = 1e7 + 5; int n, m; int gen, cute1, cute2; int number() { gen = (1LL * gen * cute1) ^ cute2; return (gen & (n - 1)) + 1; } int hd[N], nxt[N], id[N], to[N], cnt; int ans[N], a[N], p[N], q[N]; int add(int x, int y, int i) { ++cnt; nxt[cnt] = hd[x]; to[cnt] = y; id[cnt] = i; hd[x] = cnt; } int getfa(int x, int y) { int fa = x; for (int i = x; i; i = p[i]) if (p[i] < y || p[i] == i) { fa = i; break; } for (int j, i = x; i != fa; i = j) { j = p[i], p[i] = fa; } return fa; } int main() { scanf("%d%d", &n, &m); scanf("%d%d%d", &gen, &cute1, &cute2); for (int i = 1; i <= n; ++i) a[i] = number(); for (int i = 1; i <= m; ++i) { int l = number(), r = number(); if (l > r) swap(l, r); add(l, r, i); } double t1; fprintf(stderr, "%lf\n", t1 = (double)clock()/CLOCKS_PER_SEC); int ind = 0; for (int i = 1; i <= n; ++i) { while (ind && a[q[ind]] <= a[i]) --ind; if (ind) p[i] = q[ind]; else p[i] = i; q[++ind] = i; } for (int i = n; i; --i) { for (int j = hd[i]; j; j = nxt[j]) ans[id[j]] = a[getfa(to[j], i)]; } fprintf(stderr, "%lf\n", (double)clock()/CLOCKS_PER_SEC - t1); int sum = 0; for (int i = 1; i <= m; ++i) sum = (1LL * sum * cute1 + ans[i]) % cute2; printf("%d\n", sum); }