JZOJ-2019-11-5 A组
T1
给定由 n 个点 m 条边组成的无向连通图,保证没有重边和自环。
你需要找出所有边,满足这些边恰好存在于一个简单环中。一个环被称为简单环,当且仅当它包含的所有点都只在这个环中被经过了一次。(即求\(\oplus \{id((u,v)) | (u,v) \in E 且 (u,v)在且仅在一个环上\}\))
注意到这些边可能有很多条,你只需要输出他们编号的异或和即可。
Input
第一行两个数 n, m。
接下来 m 行,每行两个数 ai , bi,表示第 i 条边连接了 ai , bi。
Output
输出一个数,表示所有满足条件的边的编号的异或和。

前置知识
解法1
树上差分, LCA, 巨大码力

解法2
Tarjan 算法求强连通分量
解法1
可以先 dfs 出一棵生成树。
因为是无向图,生成树上的非树边都是返祖边,我们容易发现,若一条边恰好在一个简单环内,那么它满足下面下面两个条件之一:
- 返祖边,且它覆盖的树边不和任何其他返祖边覆盖的树边有公共边。
- 树边且被一条返祖边覆盖,覆盖它的返祖边覆盖的树边不和其他返祖边覆盖的树边有公共
边。
可以先对于每条树边 O(n) 求出被多少条返祖边覆盖,然后对于每条返祖边 O(m) 计算是否跟其他返祖边有重合。时间复杂度 O(nm)。计算被多少返祖边覆盖可以利用树上差分的思想做到 O(m),计算是否有重合相当于链上查询,也可以利用差分做到 O(m)。时间复杂度 O(n + m)。代码贼难写考场上数组开多MLE了血亏100pts
解法2
考虑求出所有的点双连通分量。首先这个点双连通分量里的边要合法的话,那么内部的边数一定大等于点数(因为有环)。其次这个点双连通分量里如果边数大于点数,那么所有边可以由两个不同的环覆盖。
也就是说,我们只需要求出所有的点双连通分量,然后把那些点数等于边数的点双连通分量内部的边标记为合法即可。利用 \(Tarjan\) 算法求强连通分量可以做到 \(O(n + m)\)。
代码
/*code by tyqtyq*/
#include<vector>
#include<cstdio>
#include<iostream>
#define f(i,x,y) for(register int i=x, i##end=y; i<=i##end; ++i)
#define d(i,x,y) for(register int i=y, i##end=x; i>=i##end; --i)
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define _ 2000005
using namespace std;
int read(int& x){x=0; int f=1, ch=getchar(); while(!isdigit(ch)) f=ch=='-'?-1:f, ch=getchar(); while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*=f;}
int read(){int x=0, f=1, ch=getchar(); while(!isdigit(ch)) f=ch=='-'?-1:f, ch=getchar(); while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*f;}
int max(int x, int y){return x>y?x:y;} int min(int x, int y){return x<y?x:y;}
int Next[_], ver[_], head[_], tot=1, dfn[_], low[_], cnt, stack[_], top, vis[_], V[_], ans;
vector<int> dcc, orz;
void add(int u, int v){ver[++tot]=v, Next[tot]=head[u], head[u]=tot;}
void dfs(int x){
for(int i=head[x];i;i=Next[i]){
if(!V[ver[i]]||vis[i]) continue;
vis[i]=vis[i^1]=1;
orz.push_back(i);
dfs(ver[i]);
}
}
void tarjan(int x, int root){
dfn[x] = low[x] = ++cnt;
stack[++top] = x;
int flag=0;
for(int i=head[x];i;i=Next[i]){
int v=ver[i];
if(!dfn[v]){
tarjan(v, root); low[x]=min(low[x], low[v]);
if(low[v] >= dfn[x]){
++flag; int d; do{d=stack[top--]; dcc.push_back(d); V[d]=1;}while(d!=v); dcc.push_back(x); dfs(x) ;
if(orz.size() == dcc.size()) for(auto j:orz) ans^=(j/2),vis[j]=vis[j^1]=0;
for(auto j:dcc) V[j]=0; dcc.clear(); orz.clear();
}
}
else low[x]=min(low[x], dfn[v]);
}
}
int n, m;
int main(){
read(n); read(m);
f(i,1,m) {int x,y; read(x); read(y); add(x,y); add(y,x);}
tarjan(1, 1);
cout<<ans<<endl;
return 0; //拜拜程序~
}
T2
\(Wayne\)喜欢看书,更喜欢买书。
某天\(Wayne\)在当当网上买书,买了很多很多书。\(Wayne\)有一个奇怪的癖好,就是第一本书的价格必须恰为\(X\),而之后买的每一本书,若是比上一本更昂贵,则价格最多多\(A\)元;若是比上一本更便宜,则价格最多少\(B\)元。
\(Wayne\)心血来潮,一口气买了\(N\)本书,但他记不得每本书的价格了,只记得总价格是\(M\)。\(Wayne\)于是很想知道一种可能的书价分布。为了简化问题,我们假定书价的定义域是整数,且每本书与上一本书的价格差,要么恰为\(+A\),要么恰为\(-B\)。
只要给出任意一个合法的书价序列就算正确。
Input
第一行一个正整数N。
第二行四个整数依次是X,A,B,M。
Output
输出一行N个整数,用空格隔开。数据保证有解。
Data Constraint
对于\(100%\)的数据,满足\(1 \leq A, B \leq 10^6,|X| \leq 10^6,N \leq 10^5\),\(M\)可用带符号\(64\)位整型存储。
前置知识
推式子能力
解法
设买书编号为\(0-n\), \(a_i\)表示当前升了几次价格
对于\(a_i\), 总有\(a_i = a_{i-1} + 1\) 或 \(a_i = a_{i-1}\)成立, 且必有\(a_0 = 0\)
有总买书价格为\(\sum_{i=0}^{n} x + a_i \times A - (k-a_i) \times B\) = \(n \times x - B \times \frac{n \times (n+1)}{2} \sum_{i=0}^{n} a_i \times(A+B)\), 整理得\(\sum_{i=0} a_i = \frac{m - n \times x + B \times \frac{n \times (n+1)}{2}}{A+B}\)
因总有\(a_i = a_{i-1} + 1\) 或 \(a_i = a_{i-1}\)成立, 考虑求出差分序列\(\delta(a)\), 总有\(\delta(a)_i = 0\) 或 \(\delta(a)_i = 1\)成立, 做一遍整数拆分即可
代码
/*code by tyqtyq*/
#include<bits/stdc++.h>
#define f(i,x,y) for(register int i=x, i##end=y; i<=i##end; ++i)
#define d(i,x,y) for(register int i=y, i##end=x; i>=i##end; --i)
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define int long long
using namespace std;
int read(int& x){x=0; int f=1, ch=getchar(); while(!isdigit(ch)) f=ch=='-'?-1:f, ch=getchar(); while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*=f;}
int read(){int x=0, f=1, ch=getchar(); while(!isdigit(ch)) f=ch=='-'?-1:f, ch=getchar(); while(isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x*f;}
int max(int x, int y){return x>y?x:y;} int min(int x, int y){return x<y?x:y;}
int n, a, b, m, x, suma, delta[100005];
signed main(){read(n); read(x); read(a); read(b) ; read(m); suma = m - n*x + ((n*(n-1))/2)*b; if((suma)%(a+b)) return puts("-1"), 0; else suma/=(a+b); int xa = 2; while(suma){ while(suma < n-xa+1 && xa<=n) ++xa ; if(xa == n+1) return puts("-1"), 0; else delta[xa] = 1, suma -= n-xa+1, ++xa;}f(i,2,n) { if(delta[i]) delta[i] = delta[i-1] + a; else delta[i] = delta[i-1] - b;} f(i,1,n) printf("%lld ", delta[i]+x) ; puts(""); return 0; /*拜拜程序*/ }
T3

Input
Output
若无解,则输出”Impossible”。
否则第一行输出”Possible”,第二行输出 n 个正整数,依次输出序列 a 中每个数。
Data Constraint
解法
我们可以整理出一堆形如 \(xi − xj ≥ v\) 的式子。拓扑排序判环并求答案即可
注意到暴力连边级别是 \(O(n^2)\) 的。
不过我们可以建一些辅助点来优化一下状态,具体来说,先像线段树一样,每个点表示区间最大值,和子节点之间连长度为 \(0\) 的边。每次一个限制,先找到被 \(k\) 个点分割开的 \(k + 1\) 个区间,每个区间找到线树上对应的 \(O(log n)\) 个区间,然后新建一个点表示这些区间的最大值,与这些点连长度为 \(0\) 的边。最后 \(k\) 个点与这个点连长度为 \(1\) 的边。
这样的连边级别是 \(O(k log n)\) 的
JZOJ-2019-11-5 A组的更多相关文章
- JZOJ 【NOIP2016提高A组集训第16场11.15】兔子
JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...
- 2019.11.9 csp-s 考前模拟
2019.11.9 csp-s 考前模拟 是自闭少女lz /lb(泪奔 T1 我可能(呸,一定是唯一一个把这个题写炸了的人 题外话: 我可能是一个面向数据编程选手 作为一个唯一一个写炸T1的人,成功通 ...
- EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)
传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f( ...
- [New!!!]欢迎大佬光临本蒟蒻的博客(2019.11.27更新)
更新于2019.12.22 本蒟蒻在博客园安家啦!!! 本蒟蒻的博客园主页 为更好管理博客,本蒟蒻从今天开始,正式转入博客园. 因为一些原因,我的CSDN博客将彻底不会使用!!!(带来不便,敬请谅解) ...
- JZOJ2020年8月11日提高组T4 景点中心
JZOJ2020年8月11日提高组T4 景点中心 题目 Description 话说宁波市的中小学生在镇海中学参加计算机程序设计比赛,比赛之余,他们在镇海中学的各个景点参观.镇海中学共有n个景点,每个 ...
- JZOJ2020年8月11日提高组T3 页
JZOJ2020年8月11日提高组T3 页 题目 Description 战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他想让天马在广阔的天空上,举行一场 ...
- JZOJ2020年8月11日提高组T2 宝石
JZOJ2020年8月11日提高组T2 宝石 题目 Description 见上帝动了恻隐之心,天后也想显示一下慈悲之怀,随即从口袋中取出一块魔术方巾,让身边的美神维纳斯拿到后堂的屏风上去试试,屏风是 ...
- JZOJ2020年8月11日提高组T1 密码
JZOJ2020年8月11日提高组T1 密码 题目 Description 在浩浩茫茫的苍穹深处,住着上帝和他的神仆们,他们闲谈着下界的凡人俗事,对人世间表现的聪明智慧,大加赞赏.今天他们正在观赏大地 ...
- JZOJ2020年8月11日提高组反思
JZOJ2020年8月11日提高组反思 T1 看到题 啊这?! 我看错了吗??? 我理解错题了吗?? 好吧没有-- 高精度模板题,不用多说 T2 看到这种矩阵的问题 以为是前缀和搞事情 结果呢 扫描线 ...
随机推荐
- 解题报告:luogu P5020(NOIP 2018 D1T2)
题目链接:P5020 货币系统 \(NOIP\) 的题挺精华啊. 开始感觉自己有隐约的思路,但感觉太暴力,连数据范围都没看,就去看题解了(不会啊). 听说是\(dp\)又是一惊,直接弃疗. 其实只是个 ...
- 014.CI4框架CodeIgniter数据库操作之:查询数据库,并让数据以对象的方式返回查询结果
01. 我们在CI4框架中的Model文件夹新建一个User_model.php的文件,使用的是getResultArray,表示并让数据以数组的方式返回查询结果,代码如下: <?php nam ...
- Redis 详解 (五) redis的五大数据类型实现原理
目录 1.对象的类型与编码 ①.type属性 ②.encoding 属性和 *prt 指针 2.字符串对象 3.列表对象 4.哈希对象 5.集合对象 6.有序集合对象 7.五大数据类型的应用场景 8. ...
- 八十三、SAP中的ALV创建之二,ALV相关的类型池定义
一.与ALV相关的类型都是在TYPE-POOLS:SLIS中.我们来到SE11 二.常用的定义有fieldca和layout等,用于显示字段,和控制信息数据等. 三.我们以VBAK表为例,用ALV输出 ...
- 080-PHP的if与elseif用法
<?php /* 正确的使用方法: */ $a = 10; $b = 20; if ($a > $b): echo $a . "大于" . $b; elseif ($a ...
- 导出execl
string filepath = Utils.GetMapPath("/upload/excel/"); filepath = filepath + fileName + &qu ...
- apache flink源码挖坑 (未完待续)
Apache Flink 源码解读(一) By yyz940922原创 项目模块 (除去.git, .github, .idea, docs等): flink-annotations: flink ...
- SciKit-Learn 数据集基本信息
## 保留版权所有,转帖注明出处 章节 SciKit-Learn 加载数据集 SciKit-Learn 数据集基本信息 SciKit-Learn 使用matplotlib可视化数据 SciKit-Le ...
- js原型链理解(4)-经典继承
经典继承就是组合继承,就是组合构造函数和原型链的优点混合继承. 1.避免引用类型的属性初始化 2.避免相同方法的多次初始化 function Super(name){ this.ages = [100 ...
- c++程序—字符串
C风格字符串:char 变量名[ ]="字符串值 " int main() { char str[] = "hello world!"; cout <&l ...

