当前位置:网站首页>2022.7.22 simulation match
2022.7.22 simulation match
2022-07-24 13:50:00 【lAWTYl】
T1 tree
First , Thank you, the author /wx

It is required to find out the number of schemes that divide a tree into several connected parts .
First of all, it's easy to think of , Points out the “ subtree ” Size d d d Is to meet d ∣ n d | n d∣n Of . That is to say, we only need to judge each d d d If it is feasible , among d d d The number of is equal to σ 0 ( n ) < n \sigma_0(n) < \sqrt{n} σ0(n)<n Of .
It is quite simple to judge whether it is feasible , You only need to write one d f s dfs dfs Just simulate the process of tree splitting , therefore c h e c k check check Namely O ( n ) O(n) O(n) Of . Then the total complexity is less than O ( n n ) O(n\sqrt{n}) O(nn) Of .
#include<bits/stdc++.h>
using namespace std;
#define in read()
#define MAXN 2002000
#define MAXM MAXN << 2
#define MOD 998244353
inline int read(){
int x = 0; char c = getchar();
while(c < '0' or c > '9') c = getchar();
while('0' <= c and c <= '9'){
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
int n = 0;
int cnt = 0;
int d[MAXN] = {
0 };
int tot = 0;
int first[MAXN] = {
0 };
int nxt[MAXM] = {
0 };
int to[MAXM] = {
0 };
inline void add(int x, int y){
nxt[++tot] = first[x];
first[x] = tot; to[tot] = y;
}
int sz[MAXN] = {
0 };
void prework(int x, int fa){
sz[x]++;
for(int e = first[x]; e; e = nxt[e]){
int y = to[e];
if(y == fa) continue;
prework(y, x);
sz[x] += sz[y];
}
}
int check(int x, int fa, int w){
int siz = 1;
for(int e = first[x]; e; e = nxt[e]){
int y = to[e];
if(y == fa) continue;
if(sz[y] >= w){
// Greater than continue down first
int f = check(y, x, w);
if(f == -1) return -1;
siz += f; // Add the following contributions
}
else siz += sz[y];
if(siz > w) return -1; // All wood is big
}
if(siz == w) return 0; // It's equivalent to cutting directly Not a contribution
return siz;
}
int main(){
// freopen("a.in", "r", stdin);
n = in; int ans = 0;
for(int i = 1; i < n; i++){
int x = in, y = in;
add(x, y), add(y, x);
} prework(1, 0);
for(int i = 1; i * i <= n; i++)
if(n % i == 0) d[++cnt] = i;
for(int i = cnt; i >= 1; i--)
if(n / d[i] != d[i]) d[++cnt] = n / d[i];
// for(int i = 1; i <= cnt; i++) cout << d[i] << ' '; puts("");
for(int i = 1; i <= cnt; i++)
if(check(1, 0, d[i]) != -1) ans = (ans + 1) % MOD;
cout << ans << '\n';
return 0;
}
But this kind of writing seems to T T T fall 2 , 3 2,3 2,3 A little bit , So we have to continue to see if there is any nature .
We consider finding s i z e size size yes d d d The key point of the multiple of ( Because we just looked for these points when simulating tree demolition ). We consider finding the upper limit of these points , We extract these key points , Of leaf nodes in the new tree s i z e size size At least d d d, And non leaf node s i z e size size It must be better than all its sons s i z e size size And to be big , And at least big d d d. So obviously, the upper limit of the number of key points is n d \frac nd dn.
If we happen to find n d \frac nd dn A key point , It means that each point is exactly one with the size of d d d The root of the subtree of , And these subtrees do not contain each other . in other words , If there is n d \frac nd dn A key point , The requirements of the topic can be established . So we can rewrite it through this c h e c k ( ) check() check() Function can A A A 了 .
#include<bits/stdc++.h>
using namespace std;
#define in read()
#define MAXN 1001000
#define MAXM MAXN << 2
inline int read(){
int x = 0; char c = getchar();
while(c < '0' or c > '9') c = getchar();
while('0' <= c and c <= '9'){
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
int n = 0;
int d[MAXN] = {
0 };
int tot = 0;
int first[MAXN] = {
0 };
int nxt[MAXM] = {
0 };
int to[MAXM] = {
0 };
inline void add(int x, int y){
nxt[++tot] = first[x];
first[x] = tot; to[tot] = y;
}
int siz[MAXN] = {
0 };
int cnt[MAXN] = {
0 };
void prework(int x, int fa){
siz[x]++;
for(int e = first[x]; e; e = nxt[e]){
int y = to[e];
if(y == fa) continue;
prework(y, x);
siz[x] += siz[y];
}
cnt[siz[x]]++;
}
bool check(int d){
int num = 0;
for(int i = d; i <= n; i += d)
num += cnt[i];
return num == (n / d);
}
int main(){
n = in; int ans = 0;
for(int i = 1; i < n; i++){
int x = in, y = in;
add(x, y), add(y, x);
} prework(1, 0);
for(int i = 1; i <= n; i++)
if(n % i == 0) ans += check(i);
cout << ans << '\n';
return 0;
}
T2 seq
30 p t s 30pts 30pts It's a simple one d p dp dp. We make f i , j f_{i, j} fi,j Before presentation i i i A digital , And then finally j j j The minimum value of , So there are :
f i , j = min j = a i A { min k = a i − 1 A { f i − 1 , k + c ∣ j − k ∣ + ( a i − j ) 2 } } f_{i, j} = \min_{j = a_i}^A \{\min_{k = a_{i - 1}}^A\{ f_{i - 1, k} + c|j - k| + (a_i - j)^2 \}\} fi,j=j=aiminA{ k=ai−1minA{ fi−1,k+c∣j−k∣+(ai−j)2}}
Initialization is f 1 , j = ( j − a 1 ) 2 j ∈ [ a i , A ] f_{1, j} = (j - a_1)^2 \quad j \in[a_i, A] f1,j=(j−a1)2j∈[ai,A], among A A A yes a i a_i ai Range of values . The time complexity of doing this is O ( n A 2 ) O(nA^2) O(nA2) Of .
#include<bits/stdc++.h>
using namespace std;
#define in read()
#define MAXN 1010
#define INFI 1 << 30
inline int read(){
int x = 0; char c = getchar();
while(c < '0' or c > '9') c = getchar();
while('0' <= c and c <= '9'){
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
int a[MAXN] = {
0 };
int n = 0; int c = 0;
int f[MAXN][MAXN] = {
0 };
int main(){
n = in; c = in; int A = 0, ans = INFI;
for(int i = 1; i <= n; i++) a[i] = in, A = 101;
memset(f, 0x3f, sizeof(f));
for(int j = a[1]; j <= A; j++) f[1][j] = (j - a[1]) * (j - a[1]);
for(int i = 2; i <= n; i++)
for(int j = a[i]; j <= A; j++)
for(int k = a[i - 1]; k <= A; k++)
f[i][j] = min(f[i][j], f[i - 1][k] + c * abs(j - k) + (j - a[i]) * (j - a[i]));
for(int i = 1; i <= A; i++) ans = min(ans, f[n][i]);
cout << ans << '\n';
return 0;
}
We consider optimizing this approach . Let's change the above formula slightly :
f i , j = min j = a i A { min k = a i − 1 A { f i , k + c ∣ j − k ∣ } + ( a i − j ) 2 } f_{i, j} = \min_{j = a_i}^A \{ \min_{k = a_{i - 1}}^A \{ f_{i, k} + c|j - k| \} + (a_i - j)^2 \} fi,j=j=aiminA{ k=ai−1minA{ fi,k+c∣j−k∣}+(ai−j)2}
Then if we order s i , j = min k = a i − 1 A { f i , k + c ∣ j − k ∣ } s_{i, j} = \min\limits_{k = a_{i - 1}}^A \{ f_{i, k} + c|j - k| \} si,j=k=ai−1minA{ fi,k+c∣j−k∣}, And the s i , j s_{i, j} si,j Preprocess it , Then we can enumerate less once A A A, The equation can be written like this :
f i , j = min j = a i A { s i , j + ( a i − j ) 2 } f_{i, j} = \min_{j = a_i}^A \{ s_{i, j} + (a_i - j)^2 \} fi,j=j=aiminA{ si,j+(ai−j)2}
Now let's consider how to preprocess s i , j s_{i, j} si,j. We consider that if we take the absolute value apart, it is good to transfer , That's our s i , j s_{i, j} si,j If it is equal to min k = a i − 1 A { f i , k + c ( j − k ) } \min\limits_{k = a_{i - 1}}^A \{ f_{i, k} + c(j - k) \} k=ai−1minA{ fi,k+c(j−k)} That's a lot easier to deal with , Because we can :
min { f i , k + c ( j − k ) } = min { min { f i , k + c ( j − 1 − k ) } + c , f i − 1 , j } \min \{ f_{i, k} + c(j - k) \} = \min \{ \min \{f_{i, k} + c(j - 1 - k) \} + c, f_{i - 1, j} \} min{ fi,k+c(j−k)}=min{ min{ fi,k+c(j−1−k)}+c,fi−1,j}
in other words :
s i , j = min { s i , j − 1 + c , f i − 1 , j } s_{i, j} = \min \{ s_{i, j - 1} + c, f_{i - 1, j} \} si,j=min{ si,j−1+c,fi−1,j}
But there is an absolute value here , So we'll think about scanning it directly and then scanning it backwards , In this way, the problem of absolute value can be solved ( Note that here we need to use a scrolling array to avoid space explosion ). In this way, the time complexity becomes O ( n A ) O(nA) O(nA) Of course. .
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define in read()
#define MAXN 100100
#define MAXA 101
#define INFI 1e18
inline int read(){
int x = 0; char c = getchar();
while(c < '0' or c > '9') c = getchar();
while('0' <= c and c <= '9'){
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
int a[MAXN] = {
0 };
int n = 0; int c = 0;
int f[MAXN][MAXA] = {
0 };
int g1[MAXN] = {
0 };
int g2[MAXN] = {
0 };
signed main(){
n = in; c = in; int A = 0, ans = INFI;
for(int i = 1; i <= n; i++) a[i] = in, A = max(A, a[i]);
memset(f, 0x3f, sizeof f);
for(int j = a[1]; j <= A; j++) f[1][j] = 1ll * (j - a[1]) * (j - a[1]);
for(int i = 2; i <= n; i++){
for(int j = 0; j <= A + 1; j++) g1[j] = g2[j] = INFI;
for(int j = A; j >= a[i]; j--)
g1[j] = min(g1[j], min(g1[j + 1] + c, f[i - 1][j]));
for(int j = a[i - 1]; j <= A; j++)
g2[j] = min(g2[j], min(g2[j - 1] + c, f[i - 1][j]));
for(int j = a[i]; j <= A; j++)
f[i][j] = min(f[i][j], min(g1[j], g2[j]) + 1ll * (j - a[i]) * (j - a[i]));
}
for(int i = 1; i <= A; i++) ans = min(ans, f[n][i]);
cout << ans << '\n';
return 0;
}
T3 color
Feeling T 3 T3 T3 Is the simplest problem ( It seems that the original T 3 T3 T3 Replaced ).
Brain pumping in the examination room , The idea has been wrong , Push :
a n s = ∑ S ⊂ U ∣ ∑ i ∈ S a i − ∑ i ∈ C U S a i ∣ = ∑ S ⊂ U ∣ 2 ∑ i ∈ S a i − X ∣ X = ∑ i = 1 n a i \begin{aligned} ans = & \sum_{S \subset U} \bigg| \sum_{i \in S}a_i - \sum_{i \in C_US}a_i \bigg| \\ = & \sum_{S \subset U} \bigg| 2\sum_{i \in S}a_i - X \bigg| \\ X = & \sum_{i = 1}^na_i \end{aligned} ans==X=S⊂U∑∣∣i∈S∑ai−i∈CUS∑ai∣∣S⊂U∑∣∣2i∈S∑ai−X∣∣i=1∑nai
It was supposed to be this step , The solution will come out soon , Then I began to get sick :
X = ∑ i = 1 n a i a n s = ∑ S ⊂ U ∣ ∑ i ∈ S a i − ∑ i ∈ C U S a i ∣ = ∑ S ⊂ U ∣ 2 ∑ i ∈ S a i − X ∣ = ∑ S ⊂ U ( 2 ∑ i ∈ S a i − X ) [ 2 ∑ i ∈ S a i ≥ X ] − ∑ S ⊂ U ( 2 ∑ i ∈ S a i − X ) [ 2 ∑ i ∈ S a i < X ] = ( 2 ∑ S ⊂ U ∑ i ∈ S a i − ∑ S ⊂ U X ) [ 2 ∑ i ∈ S a i ≥ X ] − ( 2 ∑ S ⊂ U ∑ i ∈ S a i − ∑ S ⊂ U X ) [ 2 ∑ i ∈ S a i < X ] \begin{aligned} X = & \sum_{i = 1}^na_i \\\\ ans = & \sum_{S \subset U} \bigg| \sum_{i \in S}a_i - \sum_{i \in C_US}a_i \bigg| \\ = & \sum_{S \subset U} \bigg| 2\sum_{i \in S}a_i - X \bigg| \\ = & \sum_{S \subset U}\left( 2\sum_{i \in S}a_i - X \right)[2\sum_{i \in S}a_i \geq X] - \sum_{S\subset U}\left( 2\sum_{i \in S}a_i - X \right)[2\sum_{i \in S}a_i < X] \\\\ = & \left(2\sum_{S \subset U}\sum_{i \in S}a_i - \sum_{S\subset U}X\right)[2\sum_{i \in S}a_i \geq X] - \left(2\sum_{S \subset U}\sum_{i \in S}a_i - \sum_{S\subset U}X\right)[2\sum_{i \in S}a_i < X] \end{aligned} X=ans====i=1∑naiS⊂U∑∣∣i∈S∑ai−i∈CUS∑ai∣∣S⊂U∑∣∣2i∈S∑ai−X∣∣S⊂U∑(2i∈S∑ai−X)[2i∈S∑ai≥X]−S⊂U∑(2i∈S∑ai−X)[2i∈S∑ai<X](2S⊂U∑i∈S∑ai−S⊂U∑X)[2i∈S∑ai≥X]−(2S⊂U∑i∈S∑ai−S⊂U∑X)[2i∈S∑ai<X]
Then I can't push it .
In fact, the above formula can already be done . We make f j f_j fj Represents the selected subset S S S in ∑ i ∈ S a i = j \sum\limits_{i \in S}a_i = j i∈S∑ai=j The number of sets of . So obviously now this is a backpack . We have :
f j = ∑ a k ≤ j f j − a k f_j = \sum_{a_k \leq j}f_{j - a_k} fj=ak≤j∑fj−ak
Just transfer the backpack directly , Complexity is O ( n S ) O(nS) O(nS).
Then the answer is obvious :
a n s = ∑ i = 1 X f i ∣ 2 i − X ∣ ans = \sum_{i = 1}^Xf_i|2i - X| ans=i=1∑Xfi∣2i−X∣
#include<bits/stdc++.h>
using namespace std;
#define in read()
#define MAXN 100100
#define MOD 998244353
inline int read(){
int x = 0; char c = getchar();
while(c < '0' or c > '9') c = getchar();
while('0' <= c and c <= '9'){
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
int T = 0;
int x = 0; int n = 0;
int w[MAXN] = {
0 };
int f[MAXN] = {
0 };
int main(){
T = in;
while(T--){
x = in; n = in; int ans = 0;
f[0] = 1;
for(int i = 1; i <= x; i++) f[i] = 0;
for(int i = 1; i <= n; i++) w[i] = in;
for(int i = 1; i <= n; i++)
for(int j = x; j >= w[i]; j--)
f[j] = (f[j] + f[j - w[i]]) % MOD;
for(int i = 0; i <= x; i++) ans = (ans + 1ll * f[i] * abs(2 * i - x) % MOD) % MOD;
cout << ans << '\n';
}
return 0;
}
T4 mex
It seems that I have done the same problem before …
Portal :P4587 [FJOI2016] Mysterious number
Unfortunately, I didn't remember it in the examination room , There is no time to write .
T J TJ TJ I have written one before , Now move over directly .
Find the number that cannot be represented by the subset with the smallest interval .
Consider an interval [ l , r ] [l, r] [l,r], Sort this paragraph in ascending order , Set the numbers after sorting as a l ≤ a l + 1 ≤ ⋯ ≤ a r a_l \leq a_{l+1} \leq \cdots \leq a_r al≤al+1≤⋯≤ar, For now a l a_l al If not equal to 1 1 1, Then you can output directly 1 1 1. If it is equal to the 1 1 1 Let's consider a simple d p dp dp.
Now use p o s pos pos Indicates that the current number that can be expressed belongs to the interval [ 1 , p o s ] [1, pos] [1,pos]( Obviously, this interval includes 1 1 1), For the next number a i a_i ai, Now there are two situations :
- If a i ≤ p o s + 1 a_i \leq pos + 1 ai≤pos+1, Then the set of numbers that can be expressed now is [ 1 , p o s ] ⋃ [ 1 + a i , p o s + a i ] = [ 1 , p o s + a i ] [1, pos] \bigcup [1 + a_i, pos + a_i] = [1, pos + a_i] [1,pos]⋃[1+ai,pos+ai]=[1,pos+ai].
- If a i > p o s + 1 a_i> pos + 1 ai>pos+1, Then the set of numbers that can be expressed now is [ 1 , p o s ] ⋃ [ 1 + a i , p o s + a i ] [1, pos] \bigcup [1 + a_i, pos + a_i] [1,pos]⋃[1+ai,pos+ai], Obviously, this set does not contain p o s + 1 pos + 1 pos+1, So the answer is p o s + 1 pos + 1 pos+1.
The time complexity of doing this for each inquiry is O ( n log n ) O(n\log n) O(nlogn) Of , So we should consider optimizing this practice .
If the current value range is [ 1 , p o s ] [1, pos] [1,pos], Now the answer should be p o s + 1 pos + 1 pos+1. Remember that it is less than or equal to a n s ans ans The sum of the numbers is r e s res res, If r e s ≥ a n s res \geq ans res≥ans, Then it means that you must have chosen ( Choose the sum of some numbers as a n s ans ans) And less than or equal to a n s ans ans The number of exists , Now let a n s = r e s + 1 ans = res + 1 ans=res+1. If not satisfied r e s ≥ a n s res \geq ans res≥ans That means the answer is a n s ans ans, direct b r e a k break break Just fine , be aware ∑ a i < 1 e 9 \sum a_i < 1e9 ∑ai<1e9, Therefore, we can consider using the chairman tree to maintain the interval value range and .
#include<bits/stdc++.h>
using namespace std;
#define in read()
#define MAXN 100100
#define INFI 1 << 30
inline int read(){
int x = 0; char c = getchar();
while(c < '0' or c > '9') c = getchar();
while('0' <= c and c <= '9'){
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
int a[MAXN] = {
0 };
int n = 0; int m = 0;
struct Tnode{
int dat;
int ls, rs;
}t[MAXN << 5];
int tot = 0;
int root[MAXN] = {
0 };
inline void up(int p) {
t[p].dat = t[t[p].ls].dat + t[t[p].rs].dat; }
int update(int now, int l, int r, int x, int val){
int p = ++tot; t[p] = t[now];
if(l == r) {
t[p].dat += val; return p; }
int mid = (l + r) >> 1;
if(x <= mid) t[p].ls = update(t[p].ls, l, mid, x, val);
else t[p].rs = update(t[p].rs, mid + 1, r, x, val);
up(p); return p;
}
int query(int p, int q, int l, int r, int ql, int qr){
if(ql <= l and r <= qr) return t[p].dat - t[q].dat;
int mid = (l + r) >> 1, ans = 0;
if(ql <= mid) ans += query(t[p].ls, t[q].ls, l, mid, ql, qr);
if(qr > mid) ans += query(t[p].rs, t[q].rs, mid + 1, r, ql, qr);
return ans;
}
int main(){
n = in;
for(int i = 1; i <= n; i++) a[i] = in;
for(int i = 1; i <= n; i++) root[i] = update(root[i - 1], 1, INFI, a[i], a[i]);
m = in;
while(m--){
int l = in, r = in, ans = 1;
while(true){
int res = query(root[r], root[l - 1], 1, INFI, 1, ans);
if(res >= ans) ans = res + 1;
else break;
}
cout << ans << '\n';
}
return 0;
}
边栏推荐
- Statistical table of competition time and host school information of 2022 national vocational college skills competition (the second batch)
- Swarm intelligence collaborative obstacle avoidance method inspired by brain attention mechanism
- CSDN garbage has no bottom line!
- Detailed explanation of MSTP protocol for layer 3 switch configuration [Huawei ENSP experiment]
- R语言使用epiDisplay包的tableStack函数制作统计汇总表格(基于目标变量分组的描述性统计、假设检验等)、设置by参数为目标变量、设置percent参数配置是否显示百分比信息
- 三层交换机配置MSTP协议详解【华为eNSP实验】
- CSP2021 T3 回文
- 关于不定方程解的个数的问题
- Network security -- man in the middle attack penetration test
- Group intelligence decision-making in an open environment: concepts, challenges and leading technologies
猜你喜欢

为什么函数式接口 Comparator 中有 “两个抽象方法”?

Network security - file upload penetration test

OWASP ZAP安全测试工具使用教程(高级)

Sringboot plugin framework implements pluggable plug-in services

Network security - filtering bypass injection

Network security - function bypass injection

CSDN garbage has no bottom line!

Kunyu installation details

网络安全——文件上传白名单绕过

The scroll bar in unity ugui is not displayed from the top when launching the interface in the game
随机推荐
一些简单命令
Simple order management system small exercise
SQL Server 启停作业脚本
数据湖系列文章
Chapter VI bus
数据类型二进制字符串类型
在EXCEL表格中如何进行快速换行
JS execution mechanism
Flink容错机制(五)
软链接、硬链接
网络安全——文件上传黑名单绕过
【无标题】
Ansible服务常用命令模块详细解析
网络安全——过滤绕过注入
R语言使用epiDisplay包的dotplot函数通过点图的形式可视化不同区间数据点的频率、使用by参数指定分组参数可视化不同分组的点图分布、使用cex.Y.axis参数指定Y轴分组标签文本的大小
R language uses the statstack function of epidisplay package to view the statistics (mean, median, etc.) of continuous variables and the corresponding hypothesis test in a hierarchical manner based on
Sringboot plugin framework implements pluggable plug-in services
The R language uses the sort function to sort vector data and return the actually sorted data (ascending by default)
Overview of multi view learning methods based on canonical correlation analysis
网络安全——Cookie注入