csp模拟-3
没有题目,没有题解,甚至没有正解,自然不是外漏。
T1 . span
很有趣的一道题,关键是要注意到条件一其实就是棍木,然后排序 + 维护区间最大/小值(我这里用的 st 表)就结束了。
#include <bits/extc++.h>
using namespace std;
using ling = long long;
#define en_ putchar_unlocked('\n')
#define e_ putchar_unlocked(' ')
inline int in() {
int n = 0; char p = getchar_unlocked();
while(p < '-') p = getchar_unlocked();
bool f = p == '-' ? p = getchar_unlocked() : 0;
do n = n*10 + (p^48), p = getchar_unlocked();
while(isdigit(p));
return f ? -n : n;
}
inline void in(int &n) { n = in();}
const int N = 2e5 + 10;
int n;
struct P{
int val, id;
} p[N];
int stk[N], k, f[N][30], lgn[N], f2[N][30];
inline void pre_st() {
for(int i = 2; i <= n; i++) lgn[i] = lgn[i >> 1] + 1;
for(int i = 1; i <= 29; i++)
for(int j = 1; j <= n - (1 << i) + 1; j++) {
f[j][i] = max(f[j][i-1], f[(1<<(i-1))+ j][i-1]);
}
for(int i = 1; i <= 29; i++)
for(int j = 1; j <= n - (1 << i) + 1; j++) {
f2[j][i] = min(f2[j][i-1], f2[(1<<(i-1))+ j][i-1]);
}
}
inline int rmq(int l, int r) {
int t = lgn[r - l + 1];
return max(f[l][t], f[r - (1 << t) + 1][t]);
}
inline int rxq(int l, int r) {
int t = lgn[r - l + 1];
return min(f2[l][t], f2[r - (1 << t) + 1][t]);
}
signed main() {
freopen("span.in","r",stdin);
freopen("span.out","w",stdout);
int l = 0;
in(n), in(k);
for(int i = 1; i <= n; i++) in(p[i].val), p[i].id = i;
sort(p+1, p+1+n, [](P a, P b){return a.val < b.val;});
int xiao = 292929292;
for(int i = 1; i <= n; i++) f2[i][0] = f[i][0] = p[i].id;
pre_st();
p[0].val = - 12321321;
for(int i = 1; i <= n; i++) {
if(p[i].val != p[i-1].val + 1) {
l = 0;
}
l++;
if(l >= k) {
xiao = min(xiao, rmq(i-k+1,i) - rxq(i-k+1,i));
}
}
cout << xiao;
}
T2 . graph
正解是根号分治,看起来也很有意思。不过,还是再说罢,这里是赛时代码( \(60\) pts)。
#include <bits/extc++.h>
using namespace std;
using ling = long long;
#define en_ putchar_unlocked('\n')
#define e_ putchar_unlocked(' ')
inline int in() {
int n = 0; char p = getchar_unlocked();
while(p < '-') p = getchar_unlocked();
bool f = p == '-' ? p = getchar_unlocked() : 0;
do n = n*10 + (p^48), p = getchar_unlocked();
while(isdigit(p));
return f ? -n : n;
}
inline void in(int &n) { n = in();}
const int N = 2e5 + 10;
int to[N*2], nxt[N*2], hd[N], c[N];
int q, n ,m, tot;
signed main() {
freopen("graph.in","r",stdin);
freopen("graph.out","w",stdout);
in(n), in(m), in(q);
for(int i = 1; i <= n; i++) c[i] = i;
for(int i = 1, u, v; i <= m; i++) {
in(u), in(v);
to[++tot] = v;
nxt[tot] = hd[u];
hd[u]=tot;
to[++tot] = u;
nxt[tot] = hd[v];
hd[v]=tot;
}
for(int i = 1, x, lx; i <= q; i++) {
in(x);
if(lx == x) continue;
for(int v = hd[x];v;v=nxt[v]) c[to[v]] = c[x];
lx = x;
}
for(int i = 1; i <= n; i++) {
printf("%d ", c[i]);
}
}
T3 . mod
据说是数学 + 随机化(高概率)。
但是我又不会数学也没看出随机化。
通过观察数据得出模数是个质数,然后就暴力 + 卡时,本以为 \(40\) 结果 \(70\)?
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#include <bits/extc++.h>
using namespace std;
// #define int long long
#define en_ putchar_unlocked('\n')
#define e_ putchar_unlocked(' ')
inline int in() {
int n = 0; char p = getchar_unlocked();
while(p < '-') p = getchar_unlocked();
bool f = p == '-' ? p = getchar_unlocked() : 0;
do n = n*10 + (p^48), p = getchar_unlocked();
while(isdigit(p));
return f ? -n : n;
}
inline void in(int &n) { n = in();}
const int N = 2e5 + 10, V = 1e7 + 10;
inline bool isprime(int n) {
const int l = sqrt(n);
for(int i = 2; i <= l; i++) {
if(n % i == 0) return 0;
}
return 1;
}
// bitset<V> vis;
bool vis[V];
int prime[1000000];
int s[N], v, n, p, tot;
inline void line() {
for (int i = 2; i <= v; i++) {
if (!vis[i])
prime[++tot] = i;
for (int j = 1; j <= tot && i * prime[j] <= v; j++) {
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
}
// __gnu_pbds:: cc_hash_table<int,int> mp;
// unordered_map<int,int> mp;
int mp[V];
signed main() {
freopen("mod.in","r",stdin);
freopen("mod.out","w",stdout);
int cnt2 = 0;
in(n), in(v);
v = min(v, V - 10);
for(int i = 1; i <= n; i++) {
in(s[i]);
}
line();
int ma = 0, MA = 0, I, tim = 0;
for(int i = 1, j, o; i <= tot; i++) {
// mp.clear();
// for(int k = 0; k <= prime[i]; k++) mp[k] = 0;
memset(mp, 0, 4 * (prime[i] + 1));
ma = 0;
if(tim>257222222) break;
for(j = 1; j <= n; j++) {
mp[o = s[j] % prime[i]]++;
if(ma < mp[o]) ma = mp[o];
}
if(ma > MA) MA = ma, I = prime[i];
tim += n;
}
cout << MA << endl << I;
}
T4 . loquat
直说不会,\(1.5h\) 码了个暴力,还行吧,至少不罚坐。
#include <bits/extc++.h>
using namespace std;
#define int long long
#define en_ putchar_unlocked('\n')
#define e_ putchar_unlocked(' ')
inline int in() {
int n = 0; char p = getchar_unlocked();
while(p < '-') p = getchar_unlocked();
bool f = p == '-' ? p = getchar_unlocked() : 0;
do n = n*10 + (p^48), p = getchar_unlocked();
while(isdigit(p));
return f ? -n : n;
}
inline void in(int &n) { n = in();}
const int N = 13000, mod = 1e9 + 7;
struct node {
int v, w;
};
inline int qpow(int i, int k) {
int res = 1;
for(; k; i = i * i % mod, k >>= 1) if(k & 1) res = res * i % mod;
return res;
}
struct T{
vector<node>e[N];
int sz;
int g[15000], dis[15000], siz[15000];
void dfs(int u, int fa) {
siz[u] = 1;
for(node v : e[u]) {
if(v.v != fa) {
dis[v.v] = v.w + dis[u] % mod;
dfs(v.v, u);
siz[u] += siz[v.v];
}
}
}
void dps(int u, int fa) {
for(node op : e[u]) {
int v = op.v, w = op.w;
if(v == fa) continue;
g[v] = g[u] - (siz[v] * w % mod) + ((siz[0] - siz[v]) * w % mod) % mod;
dps(v,u);
}
}
int getdis() {
dfs(0,-1);
for(int i = 0; i < sz; i++) {
g[0] += dis[i];
g[0] %= mod;
}
dps(0, -1);
int res = 0;
// for(int i = 0; i < sz; i++) {
// cout << g[i] << endl;
// }
for(int i = 0; i < sz; i++) res += g[i], res %= mod;
return (res * qpow(2, mod-2)) % mod;
}
}t[301], p;
signed main() {
freopen("loquat.in","r",stdin);
freopen("loquat.out","w",stdout);
int m = in();
t[0].sz = 1;
for(int i = 1, x, y, u, v, w; i <= m; i++) {
in(x), in(y), in(u), in(v), in(w);
t[i] = t[x];
for(int j = 0; j < t[x].sz ; j++) t[i].e[j] = t[x].e[j];
for(int j = 0; j < t[y].sz ; j++) {
t[i].e[j+t[x].sz] = t[y].e[j];
for(uint k = 0; k < t[i].e[j+t[x].sz].size(); k++) t[i].e[j+t[x].sz][k].v += t[x].sz;
}
t[i].e[u].push_back({v+t[x].sz, w});
t[i].e[v + t[x].sz].push_back({u, w});
t[i].sz = t[x].sz + t[y].sz;
}
// t[3].getdis();
for(int i = 1; i <= m; i++) {
cout << t[i].getdis() << '\n';
}
}