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直径中点的组成点里是否 ...
随机推荐
- Java权限管理(授权与认证)
CRM权限管理 有兴趣的同学也可以阅读我最近分享的:Shiro框架原理分析 (PS : 这篇博客里面介绍了使用Shiro框架的方式实现权限管理) https://www.cnblogs.com/y ...
- python3.x Day4 内置方法,装饰器,生成器,迭代器
内置方法,就是python3提供的各种函数,可以认为是关键字,帮助进行一些列的牛x运算. abs()#取绝对值 all([])#可迭代对象中的所有元素都为True 则为True,只要至少一个为Fals ...
- 《机器学习实战》-逻辑(Logistic)回归
目录 Logistic 回归 本章内容 回归算法 Logistic 回归的一般过程 Logistic的优缺点 基于 Logistic 回归和 Sigmoid 函数的分类 Sigmoid 函数 Logi ...
- pyton学习之路
文件操作 打开文件的模式有: r,只读模式(默认). w,只写模式.[不可读:不存在则创建:存在则删除内容:] a,追加模式.[可读: 不存在则创建:存在则只追加内容:] "+" ...
- Spider-scrapy断点续爬
scrapy的每一个爬虫,暂停时可以记录暂停状态以及爬取了哪些url,重启时可以从暂停状态开始爬取过的URL不在爬取 实现暂停与重启记录状态 方法一: 1.首先cd进入到scrapy项目里(当然你也可 ...
- 将cocos2dx 2.x.x从eclipse转移到Android Studio遇到的问题
cocos2dx 2.x.x从eclipse转移到Android Studio遇到的问题 可能我用不太习惯Android Studio才会遇到这么多问题,让老手们见笑了. cocos2dx的最新版本, ...
- Codeforces698C. LRU
n<=20种东西,有个大小k<=n的箱子,每次会以固定的概率从所有东西里选一种,若箱子里有空位且这种东西没出现过就丢进去,若箱子满了且这种东西没出现过就把最早访问过的一个丢掉,(只要在每次 ...
- Linux下汇编语言学习笔记0 --- 前期准备工作
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- CentOS虚拟机与本机同步时间
接着之前的任务,还是为了在VMWare上搭建分布式hadoop集群.搭着搭着注意到虚拟机上的时间和本机是不同步的,而且可以说是乱七八糟,3台虚拟机时间都与本机差了8个小时以上.首先确认不是时区的问题, ...
- Ubuntu12.04之SSH
Ubuntu 12.04 关于SSH的知识 (1)安装完ubuntu系统12.04. (2)查看网络配置,输入命令ip addr后,显示有IP地址. (3)使用SSH终端工具Xshell连接系统,发现 ...