分糖果
其实题意就是要求x%n的最大值
我们可以吧min(kn-1,r)作为x来求x%n的最大值
k求法就是(l+1)/n向上取整
向上取整就直接分母+1就行
int n, l, r;
cin >> n >> l >> r;
int t = min(r, (l + 1 + n - 1) / n * n - 1);
cout << t % n << endl;
插入排序
用分治来解决
第一维时间天然有序,第二维是元素大小
pair<int,int>
,分治的时候对其做归并,求出每个区间左半部分的修改操作对右半部分询问的贡献。
struct Node {
int x, y, id;
bool operator<(const Node &rhs) const {
if (x == rhs.x) {
if (y == rhs.y) return id < rhs.id;
return y < rhs.y;
}
return x < rhs.x;
}
} a[N];
int c[N];
int ans[N];
void solve(int l, int r) {
if (l == r) return;
int mid = (l + r) / 2;
solve(l, mid);
solve(mid + 1, r);
int p1 = l, p2 = mid + 1, len = r - l + 1;
int now = 0;
for (int i = 0; i < len; i++) {
if (p1 <= mid && (p2 > r || a[p1] < a[p2])) {
if (a[p1].id == -1) now--;
if (a[p1].id == 0) now++;
p1++;
} else {
if (a[p2].id > 0) ans[a[p2].id] += now;
p2++;
}
}
inplace_merge(a + l, a + mid + 1, a + r + 1);
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
int tot = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &c[i]);
a[++tot] = {c[i], i, 0};
}
int qid = 0;
for (int i = 1; i <= m; i++) {
int op, x, y;
scanf("%d", &op);
if (op == 1) {
scanf("%d%d", &x, &y);
a[++tot] = {c[x], x, -1};
c[x] = y;
a[++tot] = {c[x], x, 0};
} else {
scanf("%d", &x);
a[++tot] = {c[x], x, ++qid};
}
}
solve(1, tot);
for (int i = 1; i <= qid; i++) {
printf("%d\n", ans[i]);
}
return 0;
}
网络连接
char s[N], ip[N];
map<LL, int> mp;
int main() {
int n;
scanf("%d", &n);
for (int u = 1; u <= n; u++) {
scanf("%s %s", s, ip);
vector<string> a;
string b, c;
for (int i = 0; ip[i]; i++) {
if (ip[i] == '.' || ip[i] == ':') {
b.push_back(ip[i]);
a.push_back(c);
c.clear();
} else {
c.push_back(ip[i]);
}
}
a.push_back(c);
if (b == "...:") {
int ok = 1;
LL x = 0;
for (int i = 0; i < 5; i++) {
if (a[i].size() == 0 || a[i][0] == '0' && a[i].size() > 1) ok = 0;
LL y = 0;
for (auto t : a[i]) {
y = y * 10 + t - '0';
}
if (i == 4) {
if (y >= 65536) ok = 0;
x = x * 65536 + y;
} else {
if (y >= 256) ok = 0;
x = x * 256 + y;
}
}
if (ok) {
if (s[0] == 'S') {
if (mp[x] == 0) {
mp[x] = u;
puts("OK");
} else {
puts("FAIL");
}
} else {
if (mp[x] == 0) {
puts("FAIL");
} else {
printf("%d\n", mp[x]);
}
}
} else {
puts("ERR");
}
} else {
puts("ERR");
}
}
return 0;
}
小熊的果篮
又是一道模拟题,非常裸的用双向链表维护一下上一个编号和下一个编号,然后每次取出一个水果就是链表的删除操作。还需要用一个
vector
维护每个块的起始位置
int a[N], L[N], R[N];
int main() {
int n;
scanf("%d", &n);
vector<int> b;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (i == 1 || a[i] != a[i - 1]) b.push_back(i);
L[i] = i - 1;
R[i] = i + 1;
}
R[0] = 1, L[n + 1] = n;
a[0] = a[n + 1] = -1;
while (R[0] != n + 1) {
vector<int> c;
for (auto u : b) {
printf("%d ", u);
int x = L[u], y = R[u];
R[x] = y, L[y] = x;
if (a[u] == a[y] && a[u] != a[x]) c.push_back(y);
}
puts("");
swap(b, c);
}
return 0;
}