NOI-Online-T1-序列

其实这道题是全场最难的……

我这里给出一种并查集的做法。

首先我们把操作2中的 \(u\) 和 \(v\) 合并

对于操作1我们可以把他转化为操作2来做。

比如我们针对操作1给出 \((u,v)\) 和 \((v,t)\) 两条边,对 \((u,v)\) 进行同增,对 \((v,t)\) 进行同减。

这样就变成了 \(u++,t--\) 了。

然后我们把操作2缩点,然后把操作1的边连到操作2缩的点上。

然后对操作1合并。

此时,图中的每个点的度数最多为一。

那么对于一条边 \((x,y)\) 如果 \(a_{x}-b_{x}=a_{y}-b_{y}\) 那么就是YES;

对于一个自环 \((x,x)\) 如果 \((a_{x}-b_{x})\) 为偶数,那么就是YES;

对于一个度数为零的点 \(x\) 如果 \(a_{x}=b_{x}\) 那么就是YES;

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue> using namespace std; char buf[1 << 21], *p1 = buf, *p2 = buf;
#ifndef ONLINE_JUDGE
#define gc() getchar()
#else
#define gc() (p2 == p1 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
#define is_number (ch >= '0' && ch <= '9') template < typename Type >
void read(Type& a) {
a = 0; bool f = 0; char ch;
while (!(ch = gc(), is_number)) if (ch == '-') f = 1;
while (is_number) a = (a << 3) + (a << 1) + (ch ^ '0'), ch = gc();
a = (f ? -a : a);
} template < typename Type, typename... Args >
void read(Type& t, Args&... args) {
read(t), read(args...);
} const int MAXN = 2e5 + 5;
int T, n, m, vis[MAXN];
int u[MAXN], v[MAXN];
int a[MAXN], b[MAXN];
int nxt[MAXN], to[MAXN];
int head[MAXN], tot;
struct UnionFindSet {
int fa[MAXN]; void init(int n) {
for (int i = 1; i <= n; ++i)
fa[i] = i;
} int find(int x) {
if (x ^ fa[x]) fa[x] = find(fa[x]);
return fa[x];
} void merge(int x, int y) {
int u = find(x);
int v = find(y);
if (u ^ v) {
fa[v] = u;
a[u] += a[v];
b[u] += b[v];
}
}
} ufs; void add(int x, int y) {
to[++tot] = y;
nxt[tot] = head[x];
head[x] = tot;
} signed main() {
for (read(T); T; --T) {
read(n, m);
tot = 0;
memset(head, 0, sizeof head);
ufs.init(n);
for (int i = 1; i <= n; ++i) read(a[i]);
for (int i = 1; i <= n; ++i) read(b[i]);
for (int i = 1, opt; i <= m; ++i) {
read(opt, u[i], v[i]);
if (opt ^ 1) vis[i] = 1, ufs.merge(u[i], v[i]), --i, --m;
}
for (int i = 1; i <= m; ++i) {
add(ufs.find(u[i]), ufs.find(v[i]));
add(ufs.find(v[i]), ufs.find(u[i]));
}
for (int i = 1; i <= n; ++i) {
int t = ufs.find(to[head[i]]);
for (int x = nxt[head[i]]; x; x = nxt[x])
ufs.merge(t, ufs.find(to[x]));
}
for (int i = 1; i <= n; ++i) {
if (head[i]) {
int x = ufs.find(i);
int y = ufs.find(to[head[i]]);
if (x ^ y) {
if ((a[x] - b[x]) ^ (a[y] - b[y])) {
puts("NO");
goto there;
}
}
else {
if ((a[x] - b[y]) & 1) {
puts("NO");
goto there;
}
}
}
else if (ufs.fa[i] == i) {
if (a[i] ^ b[i]) {
puts("NO");
goto there;
}
}
}
puts("YES");
there: ;
}
}

NOI-Online-T2-冒泡排序

这道题我在考场上的做法很玄,本来是奔着40pts的部分分去的,结果爆零了(至今没找到原因)

我们设

\[bigger_{i}=\sum_{j=1}^{i-1}[a_{j}>a_{i}]
\]

显然逆序对数量为 \(\sum bigger\)

于是问题就转化为了动态维护 \(bigger\)。

手玩几组数据后我们可以发现,每轮冒泡 \(bigger\) 都会有一下的变化:

\[bigger_{i}=\max\{bigger_{i}-1,0\}
\]

于是树状数组维护即可

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue> char buf[1 << 21], *p1 = buf, *p2 = buf;
#ifndef ONLINE_JUDGE
#define gc() getchar()
#else
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
#define is() (ch >= '0' && ch <= '9')
template < typename Type >
void read(Type& a) {
a = 0; bool f = 0; char ch;
while (!(ch = gc(), is())) if (ch == '-') f = 1;
while (is()) a = (a << 3) + (a << 1) + (ch ^ '0'), ch = gc();
a = (f ? -a : a);
} template < typename Type, typename... Args >
void read(Type& t, Args&... args) {
read(t), read(args...);
} using namespace std; const int MAXN = 2e5 + 5;
int n, m, bigger[MAXN], bucket[MAXN], a[MAXN];
long long bit[MAXN], init_inver_tot; void Update(int x, long long y) {
for (; x <= n; x += x & -x) bit[x] += y;
} long long GetAnswers(int x) {
long long res = 0;
for (; x; x -= x & -x) res += bit[x];
return res;
} signed main() {
read(n, m);
for (int i = 1; i <= n; ++i) read(a[i]), init_inver_tot += (bigger[i] = i - 1 - GetAnswers(a[i])), bucket[bigger[i]]++, Update(a[i], 1);
memset(bit, 0, sizeof bit), Update(1, init_inver_tot), init_inver_tot = 0;
for (int i = 0; i < n; ++i) init_inver_tot += 1LL * bucket[i], Update(i + 1 + 1, init_inver_tot - n);
for (int i = 0, op, x; i < m; ++i) {
read(op, x);
if (n - 1 < x) x = n - 1;
if (op ^ 2) {
if (a[x + 1] > a[x]) {
swap(a[x], a[x + 1]);
swap(bigger[x], bigger[x + 1]);
Update(1, 1);
Update(bigger[x + 1]++ + 2, -1);
}
else {
swap(a[x], a[x + 1]);
swap(bigger[x], bigger[x + 1]);
Update(1, -1);
Update(--bigger[x] + 2, 1);
}
}
else printf("%lld\n", GetAnswers(x + 1));
}
return 0;
}

NOI-Online-T3-最小环

全场最水的一道题,但是可怕的心理作用还是让我放弃了这道题。

首先有一个显然的结论,我们需要把这 \(n\) 个数分为 \(\gcd(n,k)\) 个环。

虽说是显然但是不画画图还真的玩不动

给一下图示意一下:

图中那个看起来像个五角星的东西其实就是个环

这个图中有 \(\gcd(n,k)\) 个环,这就是我们的结论。

具体到实现,我们采用的是预处理出所有答案。

还有 \(k=0\) 的情况需要特殊处理一下

#include <cstdio>
#include <algorithm>
#include <queue> using namespace std; const int MAXN = 5e5 + 5;
vector < int > integer(MAXN);
vector < long long > ans(MAXN); int gcd(int x, int y) {
return !y ? x : gcd(y, x % y);
} signed main() {
int n, k;
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; ++i) scanf("%d", &integer.at(i)), ans.at(0) += (long long)integer.at(i) * (long long)integer.at(i);
sort(integer.begin() + 1, integer.begin() + 1 + n);
for (int i = 1; i <= (n >> 1); ++i) {
if (!(n % i)) {
int t = n / i;
vector < int > process(MAXN);
int tot = 0;
for (int j = 2; j < t; j += 2) process.at(++tot) = j;
process.at(++tot) = t;
for (int j = t - 1 - (t & 1); j > 0; j -= 2) process.at(++tot) = j;
for (int j = t + 1; j <= n; ++j) process.at(j) = process.at(j - t) + t;
for (int j = 1; j <= n; ++j)
if (!(j % t)) ans.at(i) += (long long)integer.at(process.at(j)) * (long long)integer.at(process.at(j + 1 - t));
else ans.at(i) += (long long)integer.at(process.at(j)) * (long long)(integer.at(process.at(j + 1)));
}
}
for (int i = 0, x; i < k; ++i) scanf("%d", &x), printf("%lld\n", ans.at(x ? gcd(n, x) : 0));
return 0;
}

总结

(其实我不是很会写这玩意儿)

果然心理素质还是不行……错过了T3这样的水题。

总体来说,把握住机会,把题目都当作大白菜(雾)。

然后就是多去做题吧,题量多少都不嫌多。

就这样(

普及组口胡

说了是口胡所以没代码不保证正确/xyx

至于题目难度这是NOIOL不是NOIpOL给了搬出题人放飞自我的空间。

T1:普通NOIp普及难度,各位巨佬随便切

T2: 基础多项式,会的人就很套路。不会的话就n方dp骗骗分

T3: 这道题我不太确定,应该是Floyd+矩阵。

完结撒六花

Solution Set -「NOI Online R1」的更多相关文章

  1. 「NOI十联测」深邃

    「NOI十联测」深邃 要使得最大的连通块最小,显然先二分答案. 先固定1结点为根. 对于一个果实,显然是先处理子树中未分配的点,再向外延伸. 每个结点记录一个\(si[]\),表示子树中未分配的点数, ...

  2. 「NOI十联测」奥义商店

    「NOI十联测」奥义商店 若lzz想花费最少的钱,那么显然要选择数目较少的颜色. 先考虑暴力的写法. 每次向两边统计,每个物品要求被买的概率可以由上一个物品推出. now=1;//now 被买概率 M ...

  3. 「NOI十联测」黑暗

    「NOI十联测」黑暗 \(n\) 个点的无向图,每条边都可能存在,一个图的权值是连通块个数的 \(m\) 次方,求所有可能的图的权值和.(n≤30000,m≤15) 令\(ans[n][m]\)为n个 ...

  4. Solution -「NOI 模拟赛」彩色挂饰

    \(\mathcal{Description}\)   给定一个含 \(n\) 个点 \(m\) 条边的简单无向图,设图中最大点双的大小为 \(s\),则保证 \(s\le6\).你将要用 \(k\) ...

  5. Solution -「NOI 模拟赛」出题人

    \(\mathcal{Description}\)   给定 \(\{a_n\}\),求一个 \(\{b_{n-1}\}\),使得 \(\forall x\in\{a_n\},\exists i,j\ ...

  6. HHHOJ #153. 「NOI模拟 #2」Kotomi

    抽代的成分远远大于OI的成分 首先把一个点定为原点,然后我们发现如果我们不旋转此时答案就是所有位置的\(\gcd\) 如果要选择怎么办,我们考虑把我们选定的网格边连同方向和大小看做单位向量\(\vec ...

  7. HHHOJ #151. 「NOI模拟 #2」Nagisa

    计算几何板子题(我才没有拷板子的说--) 众所周知,三角形的重心坐标是\((\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})\) 然后我们发现如果我们有一个点集 ...

  8. 「NOI十联测」反函数

    30pts 令(为1,)为-1: 暴力枚举每个点为起始点的路径,一条路径是合法的当且仅当路径权值和为0且路径上没有出现过负数. 将所有答案算出. 100pts 使用点分治. 要求知道经过重心root的 ...

  9. 「洛谷 P1801」黑匣子

    好像很久没有更过博客了,因为博主这几周很忙.其实是在搞颓. 题意很难懂,所以就不重复了.其实是懒. 一眼看上去这是个 \(Splay\) 裸题,直接插入一个数,查询区间第 \(K\) 大,但是这样太不 ...

  10. Note -「圆方树」学习笔记

    目录 圆方树的定义 圆方树的构造 实现 细节 圆方树的运用 「BZOJ 3331」压力 「洛谷 P4320」道路相遇 「APIO 2018」「洛谷 P4630」铁人两项 「CF 487E」Touris ...

随机推荐

  1. 关于建立一个Java项目全过程(专对于新手)

    关于建立一个Java项目全过程 一.Java开发环境搭建 1.JDK与JRE JDK = JRE + 开发工具集(例如Javac编译工具等) JRE = JVM + Java SE标准类库 2.JDK ...

  2. [C#] FFmpeg 音视频开发总结

    为什么选择FFmpeg? 延迟低,参数可控,相关函数方便查询,是选择FFmpeg作为编解码器最主要原因,如果是处理实时流,要求低延迟,最好选择是FFmpeg. 如果需要用Opencv或者C#的Emgu ...

  3. JuiceFS 社区版 v1.1- Beta 发布,新增五个实用功能

    我们很高兴地宣布 JuiceFS v1.1-Beta 版本正式发布啦!这是一个功能丰富的版本,带来了许多实用的新功能和改进.在这个版本中我们新增了以下功能: 目录配额:为目录设置配额限制,控制其大小和 ...

  4. 【神经网络】基于GAN的生成对抗网络

    目录 [神经网络]基于GAN的生成对抗网络 随着深度学习的快速发展,神经网络逐渐成为人工智能领域的热点话题.神经网络是一种模仿人脑计算方式的算法,其通过大量数据和复杂的计算模型,能够实现复杂的任务和预 ...

  5. WPF复习知识点记录

    WPF复习知识点记录 由于近几年主要在做Web项目,客户端的项目主要是以维护为主,感觉对于基础知识的掌握没有那么牢靠,趁着这个周末重新复习下WPF的相关知识. 文章内容主要来自大佬刘铁锰老师的经典著作 ...

  6. Leecode SQL

    618 学生地理信息报告 一所学校有来自亚洲.欧洲和美洲的学生.写一个查询语句实现对大洲(continent) 列的透视表操作,使得每个学生按照姓名的字母顺序依次排列在对应的大洲下面.输出的标题应依次 ...

  7. 补充 6-13 《关于SQL SERVER 字段类型char(n) , nchar(n) , varchar(n) , nvarchar(n)》

    今天补充一下<关于SQL SERVER 字段类型char(n) , nchar(n) , varchar(n) , nvarchar(n)>类型的区别 虽然两个字符串一样,但是定义的类型不 ...

  8. 在langchain中使用带简短知识内容的prompt template

    简介 langchain中有个比较有意思的prompt template叫做FewShotPromptTemplate. 他是这句话的简写:"Prompt template that con ...

  9. Django: 'block' tag with name 'header' appears more than once

    错误原因 在同一文件中,重复引用标签多次 解决方案: 删掉重复的标签即可.

  10. Django 组织json格式

    @api_view(['GET', 'POST']) def api_test(request): classes = Classes.objects.all() # classes_data = C ...