Codeforces Round #395 (Div. 1)
比赛链接:http://codeforces.com/contest/763
A题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=;
int n,tot,now[N],prep[N<<],son[N<<],c[N],a[N];
void read(int &x){
x=; int f=; char ch;
for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-;
for (;isdigit(ch);ch=getchar()) x=x*+ch-''; x*=f;
}
void add(int u,int v){tot++,prep[tot]=now[u],now[u]=tot,son[tot]=v;}
int main(){
read(n);
for (int u,v,i=;i<n;i++){
read(u),read(v);
add(u,v),add(v,u);
}
for (int i=;i<=n;i++) read(c[i]);
for (int i=;i<=n;i++)
for (int j=now[i],k=son[j];j;j=prep[j],k=son[j]){
if (i<k&&c[i]!=c[k]) a[i]++,a[k]++;
}
int cnt=,id;
for (int i=;i<=n;i++) if (a[i]>=) cnt++,id=i;
if (cnt>) puts("NO");
else if (cnt==){
for (int i=now[id],j=son[i];i;i=prep[i],j=son[i]) if (c[id]!=c[j]) a[j]--;
for (int i=;i<=n;i++) if (i!=id&&a[i]){puts("NO");return ;}
puts("YES"); printf("%d\n",id);
}else{
cnt=;
for (int i=;i<=n;i++) if (a[i]) cnt++,id=i;
if (cnt>) puts("NO");
else if (cnt==) printf("YES\n%d\n",id);
else printf("YES\n%d\n",);
}
return ;
}
题目大意:给定一棵n个节点的树,每个点有个颜色,询问是否能以某个点为树根时,所有节点(树根除外)的子树中的颜色一致,有则输出YES,且输出树根的编号,否则输出NO; n,color[i]<=10^5;
做法:很容易yy出一种做法,就是记录每个点周围与它颜色不一致的节点个数,显然我们把这个值最大的那个点作为树根时最有可能合法嘛,那么找出树根,大力check一下即可。
B题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int main(){
int n,x1,y1,x2,y2;
cin>>n; puts("YES");
while (n--){
cin>>x1>>y1>>x2>>y2;
cout<<(x1&)*+(y1&)+<<endl;
}
return ;
}
题目大意:给你n(n<=500000)个矩形,边长为奇数,矩阵不能相交,但是能相邻(也就是边有交集,且len>0),我们要用4种颜色去给矩形染色,要求相邻的矩形颜色不同,存在方案,则输出YES,并且要输出每个矩形的颜色,1<=color<=4,否则输出NO;
做法:根据数学中的四色定理可知,一定存在某种方案,那么,我们该怎么构造一种方案,这题有个重要的性质,边长为奇数,奇数有什么性质?奇数+奇数=偶数,偶数+奇数=奇数,也就是说一个数加上一个奇数,那么这个数的奇偶性就会发生改变,一种神奇的思路:取矩形的左上端点(x,y)来分类,
1.x为奇数,y为偶数,染为颜色1;
2.x为奇数,y为奇数,染为颜色2;
3.x为偶数,y为偶数,染为颜色3;
4.x为偶数,y为奇数,染为颜色4;
证明:如果两个矩形相邻,设这2个矩形的左上端点为(x1,y1),(x2,y2),由于矩形的边长为奇数,(x1,x2奇偶性不同),(y1,y2奇偶性不同)这两个条件至少成立一个,此时他们一定具有不同的颜色,得证。
E题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#define PI pair<int,int>
#define mp(a,b) make_pair(a,b)
using namespace std;
const int N=,M=N*,K=N*;
int n,k,m,q,wi[K][],fa[M],ans[N],son[M][],smax[M],val[M],smax_id[M],tree[N];
vector <PI> vec[N],a[N];
void read(int &x){
x=; int f=; char ch;
for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-;
for (;isdigit(ch);ch=getchar()) x=x*+ch-''; x*=f;
}
struct T{
int lowbit(int x){return x&(-x);}
void insert(int x,int y){for (int i=x;i<=n;i+=lowbit(i)) tree[i]+=y;}
int query(int x){
int sum=;
for (int i=x;i;i-=lowbit(i)) sum+=tree[i];
return sum;
}
}t;
struct link_cut_tree{
bool rev[M];
int which(int x){return son[fa[x]][]==x;}
bool isroot(int x){return son[fa[x]][]!=x&&son[fa[x]][]!=x;}
void update(int x){
smax[x]=val[x],smax_id[x]=x;
if (son[x][]&&smax[son[x][]]>smax[x]) smax[x]=smax[son[x][]],smax_id[x]=smax_id[son[x][]];
if (son[x][]&&smax[son[x][]]>smax[x]) smax[x]=smax[son[x][]],smax_id[x]=smax_id[son[x][]];
}
void pushdown(int x){
if (!rev[x]) return;
rev[x]^=,swap(son[x][],son[x][]);
if (son[x][]) rev[son[x][]]^=;
if (son[x][]) rev[son[x][]]^=;
}
void relax(int x){
if (!isroot(x)) relax(fa[x]);
pushdown(x);
}
void rotate(int x){
int y=fa[x],d=which(x),dd=which(y);
if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
fa[son[x][d^]]=y,son[y][d]=son[x][d^];
fa[y]=x,son[x][d^]=y,update(y);
}
void splay(int x){
relax(x);
while (!isroot(x)){
if (isroot(fa[x])) rotate(x);
else if (which(x)==which(fa[x])) rotate(fa[x]),rotate(x);
else rotate(x),rotate(x);
}
update(x);
}
void access(int x){for (int p=;x;x=fa[x]) splay(x),son[x][]=p,p=x,update(x);}
void make_root(int x){access(x),splay(x),rev[x]^=;}
void link(int u,int v){make_root(u),fa[u]=v;}
void cut(int u,int v){make_root(u),access(v),splay(v),son[v][]=fa[u]=,update(v);}
int find_root(int x){
access(x),splay(x);
while (){
pushdown(x);
if (son[x][]) x=son[x][];
else return x;
}
}
void split(int u,int v){make_root(u),access(v),splay(v);}
int query(int u,int v){split(u,v);return smax_id[v];}
}lct;
int main(){
read(n),read(k),read(m);
for (int u,v,i=;i<=m;i++){
read(u),read(v); if (u>v) swap(u,v);
vec[u].push_back(mp(v,i)),wi[i][]=u,wi[i][]=v;
}
for (int i=;i<=n;i++) val[i]=,lct.update(i);
for (int i=;i<=m;i++) val[n+i]=wi[i][],lct.update(n+i);
read(q);
for (int l,r,i=;i<=q;i++){
read(l),read(r);
a[l].push_back(mp(r,i));
}
for (int i=n;i>=;i--){
for (int u,v,j=;j<vec[i].size();j++){
int x=vec[i][j].second;
u=wi[x][],v=wi[x][];
if (lct.find_root(u)!=lct.find_root(v)) lct.link(u,x+n),lct.link(v,x+n),t.insert(v,);
else{
int y=lct.query(u,v)-n;
if (wi[y][]>wi[x][]){
t.insert(wi[y][],-);
t.insert(wi[x][],);
lct.cut(y+n,wi[y][]),lct.cut(y+n,wi[y][]);
lct.link(x+n,u),lct.link(x+n,v);
}
}
}
for (int j=;j<(int)a[i].size();j++){
int x=a[i][j].first;
ans[a[i][j].second]=x-i+-t.query(x);
}
}
for (int i=;i<=q;i++) printf("%d\n",ans[i]);
return ;
}
题目大意:给n个点,m条边,然后q个询问,每次询问[l,r]区间中所有点带上其两两点之间的边组成的图的连通分量个数,n,q<=10^5,m<=500000;
做法:
做法1:分治+可持久化并查集,复杂度nlogn^3,这题过不了。
做法2:离线处理+lct维护mst,这种做法很神奇,是我看题解的时候学到的,大致做法如下:将所有询问按照左端点排序,然后按左端点从大到小考虑,做到所有左端点为l的询问时,我们将所有边(u,v),满足u>=l,u<v的边,令其权值为v,即可参与mst的构建,这个过程去lct维护,对于一个询问l,r,答案就是r-l+1-此时mst中权值<=r的边的条数,这个用树状数组维护即可,总复杂度nlogn,十分优秀的做法。
Codeforces Round #395 (Div. 1)的更多相关文章
- Codeforces Round #395 (Div. 2)(A.思维,B,水)
A. Taymyr is calling you time limit per test:1 second memory limit per test:256 megabytes input:stan ...
- Codeforces Round #395 (Div. 2) D. Timofey and rectangles
地址:http://codeforces.com/contest/764/problem/D 题目: D. Timofey and rectangles time limit per test 2 s ...
- Codeforces Round #395 (Div. 2) C. Timofey and a tree
地址:http://codeforces.com/contest/764/problem/C 题目: C. Timofey and a tree time limit per test 2 secon ...
- Codeforces Round #395 (Div. 2)B. Timofey and cubes
地址:http://codeforces.com/contest/764/problem/B 题目: B. Timofey and cubes time limit per test 1 second ...
- Codeforces Round #395 (Div. 2)(未完)
2.2.2017 9:35~11:35 A - Taymyr is calling you 直接模拟 #include <iostream> #include <cstdio> ...
- Codeforces Round #395 (Div. 2)
今天自己模拟了一套题,只写出两道来,第三道时间到了过了几分钟才写出来,啊,太菜了. A. Taymyr is calling you 水题,问你在z范围内 两个序列 n,2*n,3*n...... ...
- 【分类讨论】Codeforces Round #395 (Div. 2) D. Timofey and rectangles
D题: 题目思路:给你n个不想交的矩形并别边长为奇数(很有用)问你可以可以只用四种颜色给n个矩形染色使得相接触的 矩形的颜色不相同,我们首先考虑可不可能,我们分析下最多有几个矩形互相接触,两个时可以都 ...
- 【树形DP】Codeforces Round #395 (Div. 2) C. Timofey and a tree
标题写的树形DP是瞎扯的. 先把1看作根. 预处理出f[i]表示以i为根的子树是什么颜色,如果是杂色的话,就是0. 然后从根节点开始转移,转移到某个子节点时,如果其子节点都是纯色,并且它上面的那一坨结 ...
- Codeforces Round #395 (Div. 2) C
题意 : 给出一颗树 每个点都有一个颜色 选一个点作为根节点 使它的子树各自纯色 我想到了缩点后check直径 当<=3的时候可能有解 12必定有解 3的时候需要check直径中点的组成点里是否 ...
随机推荐
- js 技巧 (五)
//设置光标位置 function getCaret(textbox) { var control = document.activeElement; textbox.focus(); var ran ...
- PHP:Mysqli 基础类
文章来源:http://www.cnblogs.com/hello-tl/p/7592594.html <?php /** * __construct($Mysql_config) 构造函数 $ ...
- Anaconda换源及常用命令
推荐一篇文章:http://www.cnblogs.com/IT-LearnHall/p/9486029.html 另外,记录几个自己遇到的问题 首先是换源.无论是安装包还是安装后更新python包, ...
- Error: Divergence detected in AMG solver: k
** Error: Divergence detected in AMG solver: k A:Since you were working on convergence issue from pa ...
- Spring框架中 配置c3p0连接池
开发准备: 1.导入jar包: ioc基本jar jdbcTemplate基本jar c3p0基本jar 别忘了mysql数据库驱动jar 原始程序代码:不使用配置文件方式(IOC)生成访问数据库对象 ...
- eclipse中自动生成注释
eclipse中自动生成注释 包前缀设置的地方 注释模板设置的地方 Eclipse自动生成方法注释 快捷键 自动生成方法的注释格式,例如 /*** @param str* @return* @thro ...
- ZOJ 3329 期望DP
题目大意: 给定3个已经规定好k1,k2,k3面的3个色子,如果扔到a,b,c则重新开始从1 计数,否则不断叠加所有面的数字之和,直到超过n,输出丢的次数的数学期望 我们在此令dp[]数组记录从当前数 ...
- [网络流24题] 方格取数问题(cogs 734)
«问题描述:在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.«编程任务:对于给定的方格棋 ...
- ELK pipeline
https://www.felayman.com/articles/2017/11/24/1511527532643.html?utm_medium=hao.caibaojian.com&ut ...
- hdu - 1151 Air Raid(有向无环图的最小路径覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=1151 在一个城市里有n个地点和k条道路,道路都是单向的,并且不存在环.(DAG) 现在伞兵需要去n个地点视察,伞 ...