今天终于有时间补题了。。06神数论没补。
01:贪心的思路,扫3遍,尽量找右区间小的
02:这里用的是kuangbin神的黑科技,并查集,把一个点拆成一个奇数点和偶数点,每次连边就奇数边和偶数边连,如果出现一个点自己的奇数和偶数点在一个集合中就是有奇环,如果在加一条边的时候,这条边已经在一个集合了,那么肯定会出现偶环(如果本来是奇环,加一条边进去必然出现偶环)
03:和官方题解一个思路,主要要想到最终答案其实就一种情况而已,就很好计算了,跟概率无关
04:这题线段树的方法挺机智了,自己只想到了nlog(n)log(n)看了官方题解才焕然大悟,可以利用括号的增加的单调性在线段树中进行二分查找
05:约瑟夫环公式+背包,比较水的一题
07:这题官方题解是折半搜,我是用了DP的思路,然后加一些剪枝,因为如果一个性格只出现一次,这个必然要选,那么相应的长相也要选,如果长相有必须选两次,必然就没有答案了,那么这些必然要选的筛走,在剩下的人物中做背包,利用map存状态,dp[i][s][b]表示的是第i个人,性格集合为s,异或和为b的情况数,第一维可以滚动掉
08:树剖,要利用一个性质,处理子树其实就是利用dfs序,一个子树必然是一个连续区间,剩下就树链剖分搞搞了
09:搜过去了。。每条边只走一次,这样复杂度是O(E),官方题解的方法比较科学。。就是先并查集缩点,然后在连有向边拓扑找环
10:每次一个区间,相应数字变成和这个区间的lcm,然后最后求出了数组,在去和原询问判断一下,如果完全一样就是解
代码:
01:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 4294967296LL;
int t, n, a, b, c, d;
ll l, r, x, y;
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%I64d%I64d%d%d%d%d", &n, &l, &r, &a, &b, &c, &d);
int cnt = 0;
ll pre;
for (int k = 0; k < 3; k++) {
ll Minr = MOD;
x = l, y = r;
for (int i = 0; i < n; i++) {
if (x > y) {
if (k == 0 || y > pre)
Minr = min(Minr, x);
} else {
if (k == 0 || x > pre)
Minr = min(Minr, y);
}
x = (ull)x * a % MOD + b;
if (x > MOD) x -= MOD;
y = (ull)y * c % MOD + d;
if (y > MOD) y -= MOD;
}
if (Minr != MOD) cnt++;
else break;
pre = Minr;
}
if (cnt == 3) printf("YES\n");
else printf("NO\n");
}
return 0;
}
02:
#include <cstdio>
#include <cstring>
const int N = 200005;
int t, n, m;
int parent[N];
int find(int x) {
if (parent[x] == x) return x;
return parent[x] = find(parent[x]);
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < 2 * n; i++) parent[i] = i;
int u, v;
int ans1 = 0, ans2 = 0;
while (m--) {
scanf("%d%d", &u, &v);
u--; v--;
int pu = find(u * 2);
int pv = find(v * 2 + 1);
if (pu == pv) ans2 = 1;
if (pu != pv) {
parent[pu] = pv;
parent[find(u * 2 + 1)] = find(v * 2);
}
}
for (int i = 0; i < n; i++) {
if (find(i * 2) == find(i * 2 + 1)) {
ans1 = 1;
break;
}
}
printf("%s\n%s\n", ans1 ? "YES" : "NO", ans2 ? "YES" : "NO");
}
return 0;
}
03:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 55;
int t, n, m;
int a[N], b[N];
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) scanf("%d", &a[i]);
for (int i = 0; i < m; i++) scanf("%d", &b[i]);
sort(a, a + m);
sort(b, b + m);
int flag = 0;
for (int i = 0; i < m; i++) {
if (a[i] > b[i]) {
flag = 1;
break;
}
}
if (flag) printf("Stupid BrotherK!\n");
else {
int ans = max(a[0] - 1, n - b[m - 1]);
for (int i = 1; i < m; i++)
ans = max(ans, a[i] - b[i - 1] - 1);
printf("%.6f\n", ans * 1.0);
}
}
return 0;
}
04:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200005;
int t, n, q;
#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)
struct Node {
int l, r, cnt[2];
} node[N * 4];
char str[N];
void pushup(int x) {
int tmp = min(node[lson(x)].cnt[0], node[rson(x)].cnt[1]);
node[x].cnt[0] = node[lson(x)].cnt[0] - tmp + node[rson(x)].cnt[0];
node[x].cnt[1] = node[rson(x)].cnt[1] - tmp + node[lson(x)].cnt[1];
}
void build(int l, int r, int x = 0) {
node[x].l = l; node[x].r = r;
if (l == r) {
node[x].cnt[0] = node[x].cnt[1] = 0;
node[x].cnt[str[l] == ')'] = 1;
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
}
void modify(int v, int x = 0) {
if (node[x].l == node[x].r) {
swap(node[x].cnt[0], node[x].cnt[1]);
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (v <= mid) modify(v, lson(x));
else modify(v, rson(x));
pushup(x);
}
int ln, rn, flag;
void query(int l, int r, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
int tmp = min(ln, node[x].cnt[1]);
ln += node[x].cnt[0] - tmp; rn += node[x].cnt[1] - tmp;
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (l <= mid) query(l, r, lson(x));
if (r > mid) query(l, r, rson(x));
}
void get1(int l, int r, int k, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
int tmp = min(ln, node[x].cnt[1]);
if (node[x].l == node[x].r) {
if (rn + node[x].cnt[1] - tmp == k) {
flag = node[x].l;
return;
}
}
if (rn + node[x].cnt[1] - tmp >= k) {
get1(l, r, k, lson(x));
if (flag) return;
get1(l, r, k, rson(x));
return;
}
rn += node[x].cnt[1] - tmp;
ln += node[x].cnt[0] - tmp;
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (l <= mid) {
get1(l, r, k, lson(x));
if (flag) return;
}
if (r > mid) get1(l, r, k, rson(x));
}
void get2(int l, int r, int k, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
int tmp = min(rn, node[x].cnt[0]);
if (node[x].l == node[x].r) {
if (ln + node[x].cnt[0] - tmp == k) {
flag = node[x].l;
return;
}
}
if (ln + node[x].cnt[0] - tmp >= k) {
get2(l, r, k, rson(x));
if (flag) return;
get2(l, r, k, lson(x));
return;
}
rn += node[x].cnt[1] - tmp;
ln += node[x].cnt[0] - tmp;
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (r > mid) {
get2(l, r, k, rson(x));
if (flag) return;
}
if (l <= mid)
get2(l, r, k, lson(x));
}
inline void scanf_(int &num)//无负数
{
char in;
while((in=getchar()) > '9' || in<'0') ;
num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
num*=10,num+=in-'0';
}
int main() {
scanf("%d", &t);
while (t--) {
scanf_(n); scanf_(q);
scanf("%s", str + 1);
build(1, n);
int tp, x, l, r, k;
while (q--) {
scanf("%d", &tp);
if (tp == 1) {
scanf_(x);
modify(x);
} else {
scanf_(l); scanf_(r); scanf_(k);
ln = 0, rn = 0;
query(l, r);
if (k > ln + rn) printf("-1\n");
else {
int tl = ln, tr = rn;
ln = rn = flag = 0;
if (k > tr) get2(l, r, tl + tr - k + 1);
else get1(l, r, k);
printf("%d\n", flag);
}
}
}
}
return 0;
}
05:
#include <cstdio>
#include <cstring>
const int N = 205;
int t, n, m, a[N];
int dp[N][N];
int ans[N], an;
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++)
scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
dp[1][0] = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < i; k++) {
if (dp[i][k]) dp[i + 1][(k + a[j]) % (i + 1)] = 1;
}
}
}
an = 0;
for (int i = 0; i < n; i++) {
if (dp[n][i]) ans[an++] = i;
}
printf("%d\n", an);
for (int i = 0; i < an; i++)
printf("%d%c", ans[i] + 1, i == an - 1 ? '\n' : ' ');
}
return 0;
}
06:没写
07:
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
const int N = 35;
int n;
typedef long long ll;
struct SB {
int c, m;
SB() {}
SB(int c, int m) {
this->c = c;
this->m = m;
}
};
int t;
vector<SB> g[N], gg[N];
int to[N], tn;
typedef pair<ll, int> pii;
map<pii, ll> dp[2];
map<pii, ll>::iterator it;
int must[N];
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
g[i].clear();
gg[i].clear();
must[i] = 0;
}
int a, b, c;
tn = 0;
memset(to, -1, sizeof(to));
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &a, &b, &c);
if (to[b] == -1) to[b] = tn++;
g[a].push_back(SB(b, c));
gg[b].push_back(SB(a, c));
}
int flag = 0;
ll s1 = 0; int s2 = 0;
for (int i = 1; i <= n; i++) {
if (gg[i].size() == 1) {
if (must[gg[i][0].c] == 1) {
flag = 1;
break;
}
s1 |= (1LL<<to[i]);
s2 ^= gg[i][0].m;
must[gg[i][0].c] = 1;
}
}
if (flag) {
printf("0\n");
continue;
}
int pre = 0, now = 1;
dp[now].clear(); dp[now][make_pair(s1, s2)] = 1;
for (int i = 1; i <= n; i++) {
if (g[i].size() == 0 || must[i]) continue;
swap(now, pre);
dp[now] = dp[pre];
for (it = dp[pre].begin(); it != dp[pre].end(); it++) {
pii x = it->first;
ll w = it->second;
for (int j = 0; j < g[i].size(); j++) {
pii xx = x;
xx.first |= (1LL<<(to[g[i][j].c]));
xx.second ^= g[i][j].m;
dp[now][xx] += w;
}
}
}
printf("%I64d\n", dp[now][make_pair((1LL<<tn) - 1, 0)]);
}
return 0;
}
08:
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100005;
const int M = 200005;
#pragma comment(linker, "/STACK:1024000000,1024000000")
void scanf_(int &num) {
char in;
bool neg=false;
while(((in=getchar()) > '9' || in<'0') && in!='-') ;
if(in=='-')
{
neg=true;
while((in=getchar()) >'9' || in<'0');
}
num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
num*=10,num+=in-'0';
if(neg)
num=0-num;
}
int dep[N], fa[N], son[N], sz[N], top[N], id[N], idx, to[N], val[N], val2[N];
int head[N], nxt[M], edge[M], en;
void init() {
en = 0;
idx = 0;
memset(head, -1, sizeof(head));
}
void add_Edge(int u, int v) {
edge[en] = v;
nxt[en] = head[u];
head[u] = en++;
}
void dfs1(int u, int f, int d) {
dep[u] = d;
sz[u] = 1;
fa[u] = f;
son[u] = 0;
for (int i = head[u]; i + 1; i = nxt[i]) {
int v = edge[i];
if (v == f) continue;
dfs1(v, u, d + 1);
sz[u] += sz[v];
if (sz[son[u]] < sz[v])
son[u] = v;
}
}
void dfs2(int u, int tp) {
id[u] = ++idx;
val2[idx] = val[u];
top[u] = tp;
if (son[u]) dfs2(son[u], tp);
for (int i = head[u]; i + 1; i = nxt[i]) {
int v = edge[i];
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
to[u] = idx;
}
int t, n;
#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)
struct Node {
int l, r, sum, lazy;
void gao() {
sum = 0;
lazy = 1;
}
} node[N * 4];
void pushup(int x) {
node[x].sum = node[lson(x)].sum + node[rson(x)].sum;
}
void pushdown(int x) {
if (node[x].lazy) {
node[lson(x)].gao();
node[rson(x)].gao();
node[x].lazy = 0;
}
}
void build(int l, int r, int x = 0) {
node[x].l = l; node[x].r = r; node[x].lazy = 0;
if (l == r) {
node[x].sum = val2[l];
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
}
void add(int l, int r, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
node[x].gao();
return;
}
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
if (l <= mid) add(l, r, lson(x));
if (r > mid) add(l, r, rson(x));
pushup(x);
}
void add2(int v, int w, int x = 0) {
if (node[x].l == node[x].r) {
node[x].sum += w;
return;
}
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
if (v <= mid) add2(v, w, lson(x));
if (v > mid) add2(v, w, rson(x));
pushup(x);
}
int query(int l, int r, int x = 0) {
if (node[x].l >= l && node[x].r <= r) return node[x].sum;
int mid = (node[x].l + node[x].r) / 2;
int ans = 0;
pushdown(x);
if (l <= mid) ans += query(l, r, lson(x));
if (r > mid) ans += query(l, r, rson(x));
pushup(x);
return ans;
}
void gaoadd(int u, int v) {
int tp1 = top[u], tp2 = top[v];
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
add(id[tp1], id[u]);
u = fa[tp1];
tp1 = top[u];
}
if (dep[u] > dep[v]) swap(u, v);
add(id[u], id[v]);
}
int gaoquery(int u, int v) {
int ans = 0;
int tp1 = top[u], tp2 = top[v];
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans += query(id[tp1], id[u]);
u = fa[tp1];
tp1 = top[u];
}
if (dep[u] > dep[v]) swap(u, v);
ans += query(id[u], id[v]);
return ans;
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
init();
for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
int u, v;
for (int i = 1; i <= n - 1; i++) {
scanf_(u);
scanf_(v);
add_Edge(u, v);
add_Edge(v, u);
}
dfs1(1, 1, 0);
dfs2(1, 1);
build(1, n);
int qn;
scanf("%d", &qn);
int ans = 0;
while (qn--) {
int tp, a, b;
scanf("%d%d", &tp, &a);
if (tp == 1) {
scanf("%d", &b);
ans += gaoquery(a, b);
gaoadd(a, b);
} else if (tp == 2) {
if (query(id[a], id[a]) == 0) {
add2(id[a], val2[id[a]]);
ans -= val2[id[a]];
}
}
else if (tp == 3) {
ans += query(id[a], to[a]);
add(id[a], to[a]);
}
printf("%d\n", ans);
}
}
return 0;
}
09:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N = 1000005;
int t;
int n, m1, m2, vis[3 * N], vis2[N], vv[N];
struct Edge {
int v, tp;
Edge() {}
Edge(int v, int tp) {
this->v = v;
this->tp = tp;
}
} edge[N * 3];
int head[N], nxt[N * 3], en;
inline void scanf_(int &num) {
char in;
while((in=getchar()) > '9' || in<'0') ;
num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
num*=10,num+=in-'0';
}
void add(int u, int v, int tp) {
vis[en] = 0;
edge[en] = Edge(v, tp);
nxt[en] = head[u];
head[u] = en++;
}
bool dfs(int u) {
if (vis2[u]) return true;
vv[u] = 1;
vis2[u] = 1;
for (int i = head[u]; i + 1; i = nxt[i]) {
if (vis[i]) continue;
int v = edge[i].v;
int tp = edge[i].tp;
if (tp == 1) vis[i] = vis[i^1] = 1;
else vis[i] = 1;
if (dfs(v)) return true;
if (tp == 1) vis[i] = vis[i^1] = 0;
else vis[i] = 0;
}
vis2[u] = 0;
return false;
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d%d", &n, &m1, &m2);
en = 0;
for (int i = 1; i <= n; i++) {
head[i] = -1;
vis2[i] = 0;
vv[i] = 0;
}
int u, v;
while (m1--) {
scanf_(u);
scanf_(v);
add(u, v, 1);
add(v, u, 1);
}
while (m2--) {
scanf_(u);
scanf_(v);
add(u, v, 0);
}
int flag = 0;
for (int i = 1; i <= n; i++)
if (!vv[i] && dfs(i)) {
flag = 1;
break;
}
printf("%s\n", flag ? "YES" : "NO");
}
return 0;
}
10:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1005;
int t, n, q;
ll a[N];
ll gcd(ll a, ll b) {
if (!b) return a;
return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
return a / gcd(a, b) * b;
}
int l[N], r[N];
ll ans[N];
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; i++) a[i] = 1;
for (int i = 0; i < q; i++) {
scanf("%d%d%I64d", &l[i], &r[i], &ans[i]);
for (int j = l[i]; j <= r[i]; j++)
a[j] = lcm(a[j], ans[i]);
}
int flag = 1;
for (int i = 0; i < q; i++) {
ll tmp = 0;
for (int j = l[i]; j <= r[i]; j++)
tmp = gcd(tmp, a[j]);
if (tmp != ans[i]) {
flag = 0;
break;
}
}
if (flag) {
for (int i = 1; i <= n; i++)
printf("%I64d%c", a[i], i == n ? '\n' : ' ');
} else printf("Stupid BrotherK!\n");
}
return 0;
}