暑假集训七[One,砖块,数字,甜圈]

暑假集训七

您总算更新当天的东西了啊。

题面

A.One

典型的约瑟夫问题,t<10n1e7数据范围需要我们用线性算法。

考虑每次去掉一个人后都重新编号,把编号改为 [0,n) 计算,最后剩下的那个数当前的编号一定为 0

倒推,考虑一个个复活,,所以可以推出来上一轮当前点 x 的编号为 (ni+i+x)%i,这样就可以递推推到第一轮。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int t, n, pos;
inline int read(){
int x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
int main(){
t = read();
while(t--){
pos = 0;
n = read();
for(register int i = 2; i <= n; i++)
pos = (pos + n - i + 1) % i;
printf("%d\n", pos + 1);
}
return 0;
}

B.砖块

模拟,不是很麻烦,考场代码贼长,最后 ctrl c,ctrl v 的时候少粘了两行,100 pts → 10 pts。

Code

#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Pair pair< int, int >
#define Make(x, y) make_pair(x, y)
using namespace std;
const int INF = 2147483647;
const int SIZE = 110, MAXN = 1010;
int n, k, len, shape, x, y, num;
int min_x, min_y, max_x, max_y;
char s[SIZE];
map< Pair, int> m;
inline int max(register int &a, register int &b){
return a > b ? a : b;
}
inline int min(register int &a, register int &b){
return a < b ? a : b;
}
void Modify_N(){
int size;
if(shape == 1){ //立着
x = x, y = y + 1; //x 不变, y 向前了 1
size = y + k - 1;
for(register int i = y; i <= size; i++){
Pair p = Make(x, i);
m[p] ++;
}
shape = 3;
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
}
else if(shape == 2){ //横着
x = x, y = y + 1;
size = x + k - 1;
for(register int i = x; i <= size; i++){
Pair p = Make(i, y);
m[p] ++;
}
shape = 2;
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
}
else if(shape == 3){ //竖着
x = x, y = y + k;
m[Make(x, y)] ++;
shape = 1;
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
}
}
void Modify_S(){
int size;
if(shape == 1){
x = x, y = y - k;
size = y + k - 1;
for(register int i = y; i <= size; i++){
Pair p = Make(x, i);
m[p] ++;
}
shape = 3;
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
}
else if(shape == 2){
x = x, y = y - 1;
size = x + k - 1;
for(register int i = x; i <= size; i++){
Pair p = Make(i, y);
m[p] ++;
}
shape = 2;
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
}
else if(shape == 3){
x = x, y = y - 1;
m[Make(x, y)] ++;
shape = 1;
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
}
}
void Modify_W(){
int size;
if(shape == 1){
x = x - k, y = y;
size = x + k - 1;
for(register int i = x; i <= size; i++){
Pair p = Make(i, y);
m[p] ++;
}
shape = 2;
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
}
else if(shape == 2){
x = x - 1, y = y;
m[Make(x, y)] ++;
shape = 1;
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
}
else if(shape == 3){
x = x - 1, y = y;
size = y + k - 1;
for(register int i = y; i <= size; i++){
Pair p = Make(x, i);
m[p] ++;
}
shape = 3;
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
}
}
void Modify_E(){
int size;
if(shape == 1){
x = x + 1, y = y;
size = x + k - 1;
for(register int i = x; i <= size; i++){
Pair p = Make(i, y);
m[p] ++;
}
shape = 2;
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
}
else if(shape == 2){
x = x + k, y = y;
m[Make(x, y)] ++;
shape = 1;
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
}
else if(shape == 3){
x = x + 1, y = y;
size = y + k - 1;
for(register int i = y; i <= size; i++){
Pair p = Make(x, i);
m[p] ++;
}
shape = 3;
min_x = min(min_x, x);
max_x = max(max_x, x + k - 1);
min_y = min(min_y, y);
max_y = max(max_y, y + k - 1);
}
}
void Clear(){
num = 0;
m.clear();
min_x = min_y = INF;
max_x = max_y = -INF;
}
int main(){
scanf("%d", &n);
while(n--){
Clear();
scanf("%d", &k);
scanf("%s", s + 1);
shape = 1; //1 是立着,2 是横着躺,3是竖着躺
x = 0, y = 0; //矩形左下角的坐标
m[Make(x, y)] ++;
len = strlen(s + 1);
for(register int i = 1; i <= len; i++){
if(s[i] == 'N') //向北走
Modify_N();
else if(s[i] == 'S')
Modify_S();
else if(s[i] == 'W')
Modify_W();
else if(s[i] == 'E')
Modify_E();
}
for(register int i = min_x; i <= max_x; i++){
for(register int j = min_y; j <= max_y; j++)
num = max(num, m[Make(i, j)]);
}
if(shape == 1)
printf("%d\n%d\n", x, y);
else if(shape == 2){
int size = x + k - 1;
for(register int i = x; i <= size; i++)
printf("%d ", i);
puts("");
for(register int i = 1; i <= k; i++)
printf("%d ", y);
puts("");
}
else if(shape == 3){
int size = y + k - 1;
for(register int i = 1; i <= k; i++)
printf("%d ", x);
puts("");
for(register int i = y; i <= size; i++)
printf("%d ", i);
puts("");
}
printf("%d\n", num);
}
return 0;
}

C.数字

不会,可以去看这里

D.甜圈

用线段树维护哈希值。

考场上想到了,但是就剩十五分钟了没打完。

1,...,n 当做一个序列,同样,把每个甜甜圈经历的工序也当成一个序列,只有当两个序列哈希值相同的时候才算合法。

区间修改哈希值可以看做区间加法,当然需要修改的只有叶子节点,可以pushdown解决,再pushup更新区间内有多少合法的序列。

同时需要下放的还有新加的序列的长度,维护哈希值的时候要用。当更新了哈希值后不合法的序列还要减去。

最后记得扫一遍没下放下去的lazy标记。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ULL unsigned long long
using namespace std;
const int Base = 233;
const int MAXN = 2e5 + 10;
int n, k, t;
ULL hash_std;
ULL power[MAXN];
inline int read(){
int x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
ULL Get_Hash(int k){
ULL res = 1;
for(register int i = 1; i <= k; i++)
res = res * Base + i;
return res;
}
void init(){
power[0] = 1;
for(register int i = 1; i <= n; i++)
power[i] = power[i - 1] * Base;
}
struct Segment_Tree{
struct Tree{
int l, r;
int sum;
ULL val;
ULL lazy_val;
int lazy_num;
}tr[MAXN << 2];
inline int lson(int rt){
return rt << 1;
}
inline int rson(int rt){
return rt << 1 | 1;
}
inline void Pushup(int rt){
tr[rt].sum = tr[lson(rt)].sum + tr[rson(rt)].sum;
}
inline void Pushdown(int rt){
if(tr[rt].lazy_val || tr[rt].lazy_num){
tr[lson(rt)].lazy_num += tr[rt].lazy_num;
tr[rson(rt)].lazy_num += tr[rt].lazy_num;
tr[lson(rt)].val = tr[lson(rt)].val * power[tr[rt].lazy_num] + tr[rt].lazy_val;
tr[rson(rt)].val = tr[rson(rt)].val * power[tr[rt].lazy_num] + tr[rt].lazy_val;
tr[lson(rt)].lazy_val = tr[lson(rt)].lazy_val * power[tr[rt].lazy_num] + tr[rt].lazy_val;
tr[rson(rt)].lazy_val = tr[rson(rt)].lazy_val * power[tr[rt].lazy_num] + tr[rt].lazy_val;
if(tr[lson(rt)].l == tr[lson(rt)].r && tr[lson(rt)].val == hash_std)
tr[lson(rt)].sum++;
if(tr[rson(rt)].l == tr[rson(rt)].r && tr[rson(rt)].val == hash_std)
tr[rson(rt)].sum++;
if(tr[lson(rt)].l == tr[lson(rt)].r && tr[lson(rt)].val != hash_std && tr[lson(rt)].sum)
tr[lson(rt)].sum--;
if(tr[rson(rt)].l == tr[rson(rt)].r && tr[rson(rt)].val != hash_std && tr[rson(rt)].sum)
tr[rson(rt)].sum--;
tr[rt].lazy_val = 0;
tr[rt].lazy_num = 0;
}
}
void Build(int rt, int l, int r){
tr[rt].l = l;
tr[rt].r = r;
if(l == r){
tr[rt].val = 1;
tr[rt].sum = 0;
return;
}
int mid = (l + r) >> 1;
Build(lson(rt), l, mid);
Build(rson(rt), mid + 1, r);
Pushup(rt);
}
void Update(int rt, int l, int r, int data){
if(tr[rt].l >= l && tr[rt].r <= r){
tr[rt].lazy_num += 1;
tr[rt].val = tr[rt].val * Base + data;
tr[rt].lazy_val = tr[rt].lazy_val * Base + data;
if(tr[rt].l == tr[rt].r && tr[rt].val == hash_std)
tr[rt].sum++;
return;
}
Pushdown(rt);
int mid = (tr[rt].l + tr[rt].r) >> 1;
if(l <= mid) Update(lson(rt), l, r, data);
if(r > mid) Update(rson(rt), l, r, data);
Pushup(rt);
}
void Get_Sum(int rt){
if(tr[rt].l == tr[rt].r){
if(tr[rt].val == hash_std)
tr[rt].sum = 1;
else if(tr[rt].sum)
tr[rt].sum = 0;
return;
}
Pushdown(rt);
Get_Sum(lson(rt));
Get_Sum(rson(rt));
Pushup(rt);
}
}S;
int main(){
n = read(), k = read();
t = read();
init();
hash_std = Get_Hash(k);
S.Build(1, 1, n);
for(register int i = 1; i <= t; i++){
int l, r, x;
l = read(), r = read(), x = read();
S.Update(1, l, r, x);
}
S.Get_Sum(1);
printf("%d\n", S.tr[1].sum);
return 0;
}
posted @   TSTYFST  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示