//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

QBXT-FIVE

2023.11.8

T1

我们发现要想集合里面没有能被九整除的数,那么就是选出一堆数,他们加起来模九不是 \(0\).

那么我们可以直接枚举集合内选多少数,然后直接暴力判断。

我这里直接枚举然后判断方案是不是合法,有点长,很麻烦。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-11-09 10:53:34
 * @LastEditTime: 2023-11-09 10:59:53
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T1gai.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include<bits/stdc++.h>

#define int long long
#define N 100010

using namespace std;

inline int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
	while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	return x * f;
}

int n, a[N], c[N], ans, d[N];

inline void dfs(int x)
{
	if(x == 9)
	{
		int cnt = 0;//选的元素个数
		for(int i = 0; i <= 8; i ++) cnt += c[i];
		if(c[0] >= 3) return ;//0不能多于两个
		if(c[0] && c[1] && c[8]) return ;//0+1+8=9
		if(c[0] && c[2] && c[7]) return ;//0+2+7=9
		if(c[0] && c[3] && c[6]) return ;//0+3+6=9
		if(c[0] && c[4] && c[5]) return ;//0+4+5=9
		if(c[1] >= 2 && c[7]) return ;//1+1+7=9
		if(c[1] && c[2] && c[6]) return ;//1+2+6=9
		if(c[1] && c[3] && c[5]) return ;//1+3+5=9
		if(c[1] && c[4] >= 2) return ;//1+4+4=9
		if(c[2] >= 2 && c[5]) return ;//2+2+5=9
		if(c[2] && c[3] && c[4]) return ;//2+3+4=9
		if(c[2] && c[8] >= 2) return ;//2+8+8=18
		if(c[3] >= 3) return ;//3+3+3=9
		if(c[3] && c[7] && c[8]) return ;//3+7+8=18
		if(c[4] && c[6] && c[8]) return ;//4+6+8=18
		if(c[4] && c[7] >= 2) return ;//4+7+7=18
		if(c[5] >= 2 && c[8]) return ;//5+5+8=18
		if(c[5] && c[6] && c[7]) return ;//5+6+7=18
		if(c[6] >= 3) return ;//6+6+6=18
		ans = max(ans, cnt);//不矛盾就直接取max
		return ;
	}
	c[x] = 0;//一个都不选
	dfs(x + 1);
	if(d[x] >= 1)//选一个
	{
		c[x] = 1;
		dfs(x + 1);
	}
	if(d[x] >= 2)//选两个
	{
		c[x] = 2;
		dfs(x + 1);
	}
	if(d[x] >= 3)//选大于等于3个
	{
		c[x] = d[x];
		dfs(x + 1);
	}
	return ;
}

signed main()
{
	n = read();
	for(int i = 1; i <= n; i ++)
		d[read() % 9] ++;
	dfs(0);
	cout << ans << endl;
	return 0;
}

T2

枚举每一个点染成黑的还是白的,然后 check 一下看看满不满足限制,满足就存下当前黑白点数量差的绝对值。

输出的时候 sort 一下,然后用 map 去重。

/*XH_ccs*/
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
inline int read()
{
	int f=1,w=0;char ch=getchar();
	while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){w=w*10+ch-48;ch=getchar();}
	return f*w;
}
int n,q,a[N],b[N],du[N],fa[N],sz[N],cnt[2],dep[N],col[N],son[N],top[N];
set<int> ans;
vector<int> e[N];

// int Find(int x)
// {
// 	if(fa[x]!=x)
// 		return fa[x]=Find(fa[x]);
// 	return x;
// }

void DFS1(int u, int Fa)
{
	fa[u]=Fa;
	dep[u]=dep[Fa] + 1;
	sz[u]=1;
	for (int v : e[u])
	{
		if(v==Fa)
			continue;
		DFS1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]])
			son[u]=v;
	}
}

void work(int u,int Top)
{
	top[u]=Top;
	if(!son[u])
		return ;
	work(son[u],Top);
	for (int v : e[u])
	{
		if(v==son[u] || v==fa[u])
			continue;
		work(v,v);
	}
}

int LCA(int x,int y)
{
	while (top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	return x;
}

void solve()
{
	int tx;
	int ty;
	int root;
	for (int i=1;i<=q;i++)
	{
		tx=a[i];
		ty=b[i];
		root=LCA(tx,ty);
		int c=col[root];
		while (tx!=root)
		{
			if(c!=col[tx])
				return ;
			tx=fa[tx];
		}
		while (ty!=root)
		{
			if(c!=col[ty])
				return ;
			ty=fa[ty];
		}
	}
	cnt[0]=0;
	cnt[1]=0;
	for (int i=1;i<=n;i++)
		++cnt[col[i]];
	ans.emplace(abs(cnt[0]-cnt[1]));
}

void DFS2(int u)
{
	if(u>n)
	{
		solve();
		return ;
	}
	col[u]=0;
	DFS2(u+1);
	col[u]=1;
	DFS2(u+1);
	col[u]=0;
}

int main()
{
	// freopen("ex_paint.in","r",stdin);
	// freopen("T2.out","w",stdout);
	n=read();
	q=read();
    // for (int i=1;i<=n;i++)
    //     fa[i]=i;
	for (int i=1;i<=n-1;i++)
	{
		int u=read();
		int v=read();
		e[u].emplace_back(v);
		e[v].emplace_back(u);
		du[u]++;
		du[v]++;
	}
	DFS1(1,0);
	work(1,1);
	for (int i=1;i<=q;i++)
	{
		a[i]=read();
		b[i]=read();
	}
	DFS2(1);
	for (int i : ans)
		cout<<i<<" ";
	return 0;
}

T3

我们听他的,直接一个数组存序列,然后暴力修改。

查询就直接查询,把他的代码改改粘贴上就好。

#include <bits/stdc++.h>

#define pii pair<int, int>
#define int long long
#define rs (x << 1 | 1)
#define ls (x << 1)
#define endl '\n'
#define N 351000

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, q, a[N];
struct tree{int sum, maxn;}e[N << 2];

inline pii ask(int x, int l, int r) 
{
    if(l == r) return {a[l] , a[l]};
    int mid = (l + r) >> 1;
    int lval = ask(x, l, mid).first; 
    int lsum = ask(x, l, mid).second;
    int rval = ask(x, mid + 1, r).first;
    int rsum = ask(x, mid + 1, r).second;
    return {max(lval, rval), lsum + rsum + max(lval, rval)};
}

inline void p_p(int x)
{
    e[x].maxn = max(e[ls].maxn, e[rs].maxn);
    e[x].sum = e[ls].sum + e[rs].sum + e[x].maxn;
    return ;
}

inline void build(int x, int l, int r)
{
    if(l == r) return e[x] = (tree){a[l], a[l]}, void();
    int mid = (l + r) >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    p_p(x);
    return ;
}

inline int Ask(int x, int l, int r, int nl, int nr)
{
    if(l >= nl && nr >= r) return e[x].sum;
    int mid = (l + r) >> 1, res = 0;
    if(nl <= mid) res += Ask(ls, l, mid, nl, nr);
    if(nr > mid) res += Ask(rs, mid + 1, r, nl, nr);
    return res;
}

inline void work()
{
    build(1, 1, n);
    while(q --)
    {
        int op = read(), l = read(), r = read();
        cout << Ask(1, 1, n, l, r) << endl;
    }
    return ;
}

signed main()
{
    n = read(), q = read();
    for(int i = 1; i <= n; i ++) a[i] = read();
    // work();
    // return 0;
    if(n > 1000) return work(), 0;
    while(q --)
    {
        int op = read(), l = read(), r = read();
        if(op == 1) a[l] = r;
        else cout << ask(1, l, r).second << endl;
    }
    return 0;
}

T4

期望,不会。

posted @ 2023-11-13 22:01  北烛青澜  阅读(2)  评论(0编辑  收藏  举报