A:略坑 枚举l-r,看是否能整除k且商的范围是不是在x,y里

#include<bits/stdc++.h>
using namespace std;
int l, r, x, y, k;
int main()
{
cin >> l >> r >> x >> y >> k;
for(int i = l; i <= r; ++i) if(i % k == 0)
{
int t = i / k;
if(t >= x &&t <=y )
{
puts("YES");
return 0;
}
}
puts("NO");
return 0;
}
B:判断一下就行了

#include<bits/stdc++.h>
using namespace std;
double r, d;
int n, ans;
double dis(double x, double y)
{
return sqrt(x * x + y * y);
}
int main()
{
cin >> r >> d >> n;
for(int i = 1; i <= n; ++i)
{
double x, y, R;
scanf("%lf%lf%lf", &x, &y, &R);
double dist = dis(x, y);
if(dist - R >= r - d && dist + R <= r) ++ ans;
}
printf("%d\n", ans);
return 0;
}
C:和一道poi的题有同样的性质,可是那道题我忘了。。。
其实我们发现,每次如果一个数和另一个数的gcd,要么不变,要么至少除以2,所以我们每个节点开个set,保存把一个节点赋0的所有gcd和没有赋过0的gcd,这样其实每个节点能够得到的gcd只有log个,然后我们暴力把自己父亲节点的gcd和这个节点的数做一个gcd,相当于这个节点的值取0,然后一直dfs,最后输出每个节点的set里的最大值

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#include<iostream>
using namespace std;
const int N = 200010;
struct edge {
int nxt, to;
} e[N << 1];
int n, cnt = 1;
int head[N], a[N];
set<int> s[N];
void link(int u, int v)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
}
void dfs(int u, int last, int g)
{
s[u].insert(g); // 这个点为0
// s[u].insert(__gcd(g, a[u]));
for(set<int> :: iterator it = s[last].begin(); it != s[last].end(); ++it) s[u].insert(__gcd(a[u], *it));
for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last) dfs(e[i].to, u, __gcd(g, a[u]));
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for(int i = 1; i < n; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
link(u, v);
link(v, u);
}
s[0].insert(0);
dfs(1, 0, 0);
for(int i = 1; i <= n; ++i) printf("%d ", *(s[i].rbegin()));
return 0;
}
D:比赛时没用trie树各种调不出来。。。看来我对trie树的理解不够深刻。。。
我们可以想到,我们把每个数插入trie树,然后我们维护每个节点的子树是否满了,然后贪心,如果这位为0的子树没满,那么自然向为0的子树走,否则只能向为1的子树走,每次异或一个数我们就在trie树上打标记,像普通splay一样就行了 注意每次要把标记传给两个儿子,不仅仅是交换两个儿子

#include<bits/stdc++.h>
using namespace std;
const int N = 300010;
int n, m, last, cnt = 1;
int vis[N];
struct Trie {
struct node {
int full, ch[2], rev;
} t[N * 10];
void pushdown(int x, int bit)
{
if(!t[x].rev) return;
t[t[x].ch[0]].rev ^= t[x].rev;
t[t[x].ch[1]].rev ^= t[x].rev;
if(t[x].rev & (1 << bit)) swap(t[x].ch[0], t[x].ch[1]);
t[x].rev = 0;
}
void insert(int x, int num, int bit)
{
if(bit == -1) { t[x].full = 1; return; }
int b = (num & (1 << bit)) > 0;
if(t[x].ch[b] == 0) t[x].ch[b] = ++cnt;
insert(t[x].ch[b], num, bit - 1);
t[x].full = t[t[x].ch[0]].full & t[t[x].ch[1]].full;
}
int query(int x, int num, int bit)
{
if(bit == -1) return 0;
pushdown(x, bit);
if(t[t[x].ch[0]].full) return query(t[x].ch[1], num, bit - 1) + (1 << bit);
else return query(t[x].ch[0], num, bit - 1);
}
} trie;
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
{
int x;
scanf("%d", &x);
if(vis[x] == 0)
{
vis[x] = 1;
trie.insert(1, x, 20);
}
}
while(m --)
{
int x;
scanf("%d", &x);
trie.t[1].rev ^= x;
printf("%d\n", trie.query(1, last, 20));
}
return 0;
}
这次cf的题目挺不错的,但是由于自己傻逼trie树写不对滚粗了。。。
来源:https://www.cnblogs.com/19992147orz/p/7462903.html
