2022.10.26
2022.10.26
ZXS :我明天后天不考试了。
YCC:啊,老吕愿意啊?
ZXS:我就是不交他拿我有什么办法。
YCC:(呆住)。
T2 xor
/*
Date:2022.10.26
Source:模拟赛补题
knowledge:发现其实只改变了异或前缀和中的一个数
想要区间异或和为零,就要前缀和相等。
*/
#include <cstdio>
#include <iostream>
#include <map>
#define orz cout << "AK IOI" << "\n";
#define int long long
using namespace std;
const int maxn = 1e6 + 10;
inline int read()
{
int x = 0, f = 1; char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
inline void print(int X)
{
if(X < 0) X = ~(X - 1), putchar('-');
if(X > 9) print(X / 10);
putchar(X % 10 ^ '0');
return ;
}
inline int Max(int a, int b){
return a > b ? a : b;
}
inline int Min(int a, int b){
return a < b ? a : b;
}
int n, q, ans, a[maxn], sum[maxn];
map<int, int> mp;
signed main()
{
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = read(), q = read();
mp[0]++;//感觉很妙,成功统计了sum[i]=0的情况
for(int i = 1; i <= n; i++)
{
a[i] = read(), sum[i] = sum[i - 1] ^ a[i];
ans += mp[sum[i]];
mp[sum[i]]++;
}
for(int i = 1; i <= q; i++)
{
int p = read(), x = read();
mp[sum[p]]--;
ans -= mp[sum[p]];
sum[p] ^= x;
ans += mp[sum[p]];
mp[sum[p]]++;
print(ans); puts("");
}
//fclose(stdin);
//fclose(stdout);
return 0;
}
T3 string
很好奇我的考场代码怎么能骗到分?
本来很骄傲的短时间写了一个线段树,但是发现有好多错误。
深深的挫败感。
不过时间充足的话可以得 40 分。但是不知道哪里写错了,应该70分。
就这样吧。
/*
Date:
Source:
knowledge: 很像数据结构啊
30颗线段树
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#define orz cout << "AK IOI" << "\n"
#define int long long
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
const int maxn = 100010;
int read()
{
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
void print(int X)
{
if(X < 0) X = ~(X - 1), putchar('-');
if(X > 9) print(X / 10);
putchar(X % 10 ^ '0');
}
int Max(int a, int b){
return a > b ? a : b;
}
int Min(int a, int b){
return a < b ? a : b;
}
int n, m, q, a[35][maxn], ans;
int getnum(char x)
{
if(x == '0') return 0;
if(x == '1') return 1;
if(x == '?') return -0x3f3f3f3f;
}
struct tree{
int l, r, sum, num;
}t[35][maxn << 2];
void push_up(int rt, int num)
{
t[num][rt].sum = t[num][ls].sum + t[num][rs].sum;
t[num][rt].num = t[num][ls].num + t[num][rs].num;
}
void build(int rt, int l, int r, int num)
{
t[num][rt].l = l, t[num][rt].r = r;
if(l == r)
{
t[num][rt].sum = a[num][l];
if(a[num][l] == -0x3f3f3f3f) t[num][rt].num = 1;
return ;
}
int mid = (l + r) >> 1;
build(ls, l, mid, num), build(rs, mid + 1, r, num);
push_up(rt, num);
}
void updata(int rt, int k, int val, int num)
{
if(t[num][rt].l == t[num][rt].r && t[num][rt].l == k)
{
t[num][rt].sum = val;
if(val == -0x3f3f3f3f) t[num][rt].num = 1;
return ;
}
int mid = (t[num][rt].l + t[num][rt].r) >> 1;
if(k <= mid) updata(ls, k, val, num);
else updata(rs, k, val, num);
push_up(rt, num);
}
int query1(int rt, int l, int r, int num)
{
if(t[num][rt].l >= l && t[num][rt].r <= r) return t[num][rt].sum;
int mid = (t[num][rt].l + t[num][rt].r) >> 1, res = 0;
if(l <= mid) res += query1(ls, l, r, num);
if(r > mid) res += query1(rs, l, r, num);
return res;
}
int query2(int rt, int l, int r, int num)
{
if(t[num][rt].l >= l && t[num][rt].r <= r) return t[num][rt].num;
int mid = (t[num][rt].l + t[num][rt].r) >> 1, res = 0;
if(l <= mid) res += query2(ls, l, r, num);
if(r > mid) res += query2(rs, l, r, num);
return res;
}
signed main()
{
// freopen("string.in", "r", stdin);
// freopen("string.out", "w", stdout);
n = read(), m = read(), q = read();
for(int i = 1; i <= m; i++)
{
char s[35];
cin >> s + 1;
for(int j = 1; j <= n; j++) a[j][i] = getnum(s[j]);
}
for(int i = 1; i <= n; i++) build(1, 1, m, i);
for(int i = 1; i <= q; i++)
{
int opt = read();
if(opt == 1)
{
int x = read();
char s[35];
cin >> s + 1;
for(int j = 1; j <= n; j++)
{
int aa = getnum(s[j]);
updata(1, x, aa, j);
}
}
else
{
int x = read(), y = read();
int Ans = 1;
for(int j = 1; j <= n; j++)
{
int f1 = query1(1, x, y, j), f2 = query2(1, x, y, j);
if(f1 == (y - x + 1) || f1 == 0) Ans *= 1;
else if(f1 > 0) Ans *= 0;
else if((f1 + f2 * 0x3f3f3f3f) != (y - x + 1 - f2) && (f1 + f2 * 0x3f3f3f3f) != 0) Ans *= 0;
else if(f2 == (y - x + 1)) Ans *= 2;
else Ans *= 1;
}
ans ^= Ans;
}
}
cout << ans;
// fclose(stdin);
// fclose(stdout);
return 0;
}
T4
也是个头疼的。就这样吧。
T1
《YCC的疑惑》
贺的。
/*
Date:2022.10.25
Source: 模拟赛补题
knowledge:
*/
#include <cstdio>
#include <iostream>
#include <cmath>
#define orz cout << "AK IOI" << "\n";
using namespace std;
inline int read()
{
int x = 0, f = 1; char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
inline void print(int X)
{
if(X < 0) X = ~(X - 1), putchar('-');
if(X > 9) print(X / 10);
putchar(X % 10 ^ '0');
return ;
}
inline int Max(int a, int b){
return a > b ? a : b;
}
inline int Min(int a, int b){
return a < b ? a : b;
}
int x, n, ans;
int main()
{
// freopen("square.in", "r", stdin);
// freopen("square.out", "w", stdout);
x = read(), ans = 0;
n = (3 + sqrt(9.0 + 12.0 * x - 12.0)) / 6;
int sum = 3 * n * (n - 1) + 1;//整圈
ans = 6 * (n + 1);
int k = x - sum, t = 6 * n;
if(t - k >= n + 1)
{
ans--, t -= (n + 1);
if(t - k >= n)
{
ans--, t -= n;
if(t - k >= n)
{
ans--, t -= n;
if(t - k >= n)
{
ans--, t -= n;
if(t - k >= n)
{
ans--, t -= n;
if(t - k >= n - 1) ans--, t -= (n-1);
}
}
}
}
}
print(ans); puts(" ");
// fclose(stdin);
// fclose(stdout);
return 0;
}
T4
对最短路的距离进排序,对于从小到大的 \(x\) 逐条删边,统计答案。
/*
Date:
Source:
knowledge:又是一个写了1.5 h发现读题有偏差的题
*/
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#define orz cout << "AK IOI" << "\n";
#define int long long
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 2e5 + 10;
const int inf = 0x3f3f3f3f3f3f;
inline int read()
{
int x = 0, f = 1; char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
while(ch <= '9' && ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
inline void print(int X)
{
if(X < 0) X = ~(X - 1), putchar('-');
if(X > 9) print(X / 10);
putchar(X % 10 ^ '0');
return ;
}
inline int Max(int a, int b){
return a > b ? a : b;
}
inline int Min(int a, int b){
return a < b ? a : b;
}
int n, m, C, ans = inf, flag[maxn], sum;
struct node{
int u, v, w, nxt;
}e[maxm << 1];
int js, head[maxn];
void add(int u, int v, int w)
{
e[++js] = (node){u, v, w, head[u]};
head[u] = js;
}
struct edge{
int w, now;
bool operator < (const edge &x)const {return w > x.w;}
}dis[maxn];
bool cmp(edge a, edge b)
{
return a.w < b.w;
}
int vis[maxn];
priority_queue<edge> q;
void dij()
{
for(int i = 1; i <= n; i++) dis[i] = (edge){inf, i};
dis[1].w = 0;
q.push((edge){0, 1});
while(!q.empty())
{
int u = q.top().now;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].v;
if(vis[v] || flag[u]) continue;
if(dis[v].w > dis[u].w + e[i].w)
{
dis[v].w = dis[u].w + e[i].w;
q.push((edge){dis[v].w, v});
}
}
}
}
void del(int now, int x)
{
int res = x * C;
vis[now] = 1;
for(int i = head[now]; i; i = e[i].nxt)
{
if(vis[e[i].v]) sum -= e[i].w;
}
res += sum;
res < ans ? ans = res : 0;
}
signed main()
{
//freopen("subway.in", "r", stdin);
//freopen("subway.out", "w", stdout);
n = read(), m = read(), C = read();
for(int i = 1; i <= m; i++)
{
int u = read(), v = read(), w = read();
add(u, v, w), add(v, u, w);
sum += w;
}
dij();
sort(dis + 1, dis + n + 1, cmp);
memset(vis, 0 , sizeof vis);
for(int i = 1; i <= n; i++) del(dis[i].now, dis[i].w);
print(ans);
fclose(stdin);
fclose(stdout);
return 0;
}
关于考试……
两套题都做过呢!
第一套题,我高一做过一次,高二做过一次,高三还要再做一次。
于是,理直气壮的罢考。
虽然也不是都会了,但是……对其他同学不好,是吧。
真相是不想再考试了。
不过,老吕生气怎么办?
那就浅气他一下?气他的机会也不多了。
ZXS 已经准备给大家讲题了。这惊人的先见之明。
嘿嘿嘿。
哦,水过头了,YCC 又在浪费时间,浪费生命。
有不少保龄的,感觉主要是题的问题。
但是老吕不淡定了。