2022.11.20

坐在这里就开始困。

去洛谷上报了个比赛,四个题都戳了戳,都不大会,暴力也写的很丑,于是乖乖回去复习我的知识点。

$ $

为了一首歌下了一个软件,然后这首歌要收费!!!

果断卸载,咱不听了。

$ $

中午睡了不到一个小时,没睡醒。

考试……

考试的时间过得好快啊!

挺划的。

%%% ZXS

冒泡排序

神奇的 memset。

知道 memset 的常数大,没想这么大。

/*
Date:
Source:
knowledge:
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#define orz cout << "AK IOI" << "\n";

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 T, n, a[maxn], sum[maxn]; 
int main()
{
//    freopen("bubble.in", "r", stdin);
//    freopen("bubble.out", "w", stdout);
    T = read();
      while(T--) 
      {
        n = read();
        for(int i = 1; i <= n; i++) sum[i] = 0; 
          for(int i = 1; i <= n; i++) a[i] = read();
        for(int i = 1; i <= n; i++) 
        {
              if (i == a[i]) continue;
              int l = Min(i, a[i]), r = Max(i, a[i]);
              sum[l]++, sum[r + 1]--;
        } 
        for(int i = 1; i <= n; i++) sum[i] += sum[i - 1];
        int ans = 0;
        for(int i = 1; i <= n; i++) if(sum[i]) ans++;
        printf("%d\n", ans);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

异或国度

40 pts, 思路也很朴素,求出任何两点之间的距离。

其实考场思路已经是 60 pts 了。

但是wa 了两点,调了调wa了另外俩点。

/*
Date:2022.11.20
Source:模拟赛 
knowledge:树上差分吗  调半天一个sb错误 
    没有可供调试的小样例 
*/
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#define orz cout << "AK IOI" << "\n";

using namespace std;
const int maxn = 5e5 + 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, w[maxn], dis[1010][1010]; 
struct node{
    int u, v, nxt;
}e[1000010 << 1];
int js, head[maxn];
void add(int u, int v)
{
    e[++js] = (node){u, v, head[u]};
    head[u] = js;
}
void dfs(int u, int fa, int top)
{ 
    for(int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].v;
        if(v == fa) continue;
        dis[top][v] = dis[top][u] ^ w[v];
        dfs(v, u, top); 
    }
}
int main()
{
    n = read(), q = read();
    for(int i = 1; i <= n; i++) w[i] = read();
    for(int i = 1; i <= n - 1; i++)
    {
        int u = read(), v = read();
        add(u, v), add(v, u); 
    }
    for(int i = 1; i <= n; i++) dis[i][i] = w[i], dfs(i, 0, i);
    for(int i = 1; i <= q; i++)
    {
        int u = read(), v = read(), k = read(), flag = 0;
        for(int j = 1; j <= n; j++)
        {
            if(j == u || j == v) continue;
            if((dis[u][j] ^ dis[j][v]) == k) 
            {
                puts("Yes"); flag = 1;
                break;
            }
        }
        if(flag == 0) puts("No");
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

简单的写一写吧

u 到 x 和 u到 y 路径的公共部分会异或两遍,所以这两条路的权值的异或和其实是 \(s_{u, x}\) ^ \(s_{u, y}\) ^ \(w_z\) = \(k\) ,移项 \(s_{u, x}\) ^$ s_{u, y}$ ^ $k = w_z $

那么就将问题转换成了是否存在点 \(z\) 使该式子成立。

$ $

!没明白, 不会写,不改了!

青岛地铁

爆搜 35 pts 有锅,懒得调了。

/*
Date:2022.11.20
Source:模拟赛 
knowledge:
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#define int long long
#define orz cout << "AK IOI" << "\n";

using namespace std;
const int maxn = 15;
const int maxm = 1e5 + 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, m, ans, a[maxn][maxm], c[maxn], u[maxn][maxm], num[maxn]; 
signed main()
{
	//freopen("metro.in", "r", stdin); 
	//freopen("metro.out", "w", stdout);
	n = read(), m = read();
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++) a[i][j] = read();
	for(int i = 1; i <= n; i++)
	{
		c[i] = read();
		for(int j = 1; j <= c[i]; j++) u[i][j] = read();
	}
	for(int i = 1; i <= n; i++) num[i] = i;
	int ans = 1e18, res = 0;
	for(int i = 1; i <= n; i++) //线路 
	{
		for(int j = 1; j <= c[i]; j++) res +=  a[num[i]][u[i][j]];
	}
	ans = Min(ans, res);
	while(next_permutation(num + 1, num + n + 1))
	{
		res = 0;
		for(int i = 1; i <= n; i++) //线路 
		{
			for(int j = 1; j <= c[i]; j++) res += a[num[i]][u[i][j]];
		}
		ans = Min(ans, res);
	}
	print(ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
1 3  
4 1 5
2 1 2
*/

根据数据范围能看出来用状压。

我不会,跑路了。

数列问题

50pts 朴素的暴力

/*
Date:2022.11.20
Source:模拟赛 
knowledge: 先码的线段树,发现有错,而且调不出来
			so,区间最值为什么不用st 表 
*/
#include <cstdio>
#include <iostream>
#define orz cout << "AK IOI" << "\n";
#define lson rt << 1
#define rson rt << 1 | 1

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, ans, a[maxn], mp[6010][6010];
int st[maxn][21], st2[maxn][21], lg[maxn];
void init()
{
	for(int i = 1; i <= n; i++) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
}
void ST()
{
	for(int j = 1; j <= 20; j++)
	{
		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 j = 1; j <= 20; j++)
	{
		for(int i = 1; i + (1 << j) - 1 <= n; i++)
		st2[i][j] = Min(st2[i][j - 1], st2[i + (1 << (j - 1))][j - 1]);
	}
}
int query_Max(int l, int r)
{
	int k = lg[r - l + 1] - 1;
	return Max(st[l][k], st[r - (1 << k) + 1][k]);
}
int query_Min(int l, int r)
{
	int k = lg[r - l + 1] - 1;
	return Min(st2[l][k], st2[r - (1 << k) + 1][k]);
}
int main()
{
	n = read();
	for(int i = 1; i <= n; i++) a[i] = read(), st[i][0] = st2[i][0] = a[i];
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++) mp[a[j]][i] = mp[a[j]][i - 1];
		mp[a[i]][i] = mp[a[i]][i - 1] + 1;
	}
	init(), ST();
	for(int l = 1; l <= n; l++)
	{
		for(int r = l; r <= n; r++)
		{
			int maxx = query_Max(l, r), minn = query_Min(l, r), flag = 0;
			if((maxx + minn) * (maxx - minn + 1) / 2 != (r - l + 1)) continue; 
			for(int i = minn; i <= maxx; i++)
				if(mp[i][r] - mp[i][l - 1] != i) flag = 1;
			if(flag == 0) ans++;
		}
	}
	print(ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

这是有多想不开搁着补题!

摆!

posted @ 2022-11-21 21:34  _程门立雪  阅读(35)  评论(0编辑  收藏  举报