【CF刷题】14-05-12
Round 236 div.1
A:只需要每个点连接所有比他大的点,知道边用完为止。
//By BLADEVIL
#include <cmath>
#include <cstdio>
#define maxn 25; using namespace std; int main() {
int task; scanf("%d",&task);
while (task--) {
int n,p; scanf("%d%d",&n,&p);
int rest(*n+p);
for (int i=;(i<=n)&&rest;i++)
for (int j=i+;(j<=n)&&rest;j++) printf("%d %d\n",i,j),rest--;
}
return ;
}
B:求出g[i]=gcd(a[1],a[2]....a[i]),那么只需要从后向前贪心的考虑每个g[i]能不能被除掉就好了。
//By BLADEVIL
#include <cstdio>
#include <algorithm>
#define maxn 5010 using namespace std; int n,m;
int a[maxn],b[maxn],g[maxn]; int calc(int x) {
int ans();
for (int i=;i<=m;i++) while (!(x%b[i])) ans--,x/=b[i];
for (int i=;i*i<=x;i++) while (!(x%i)) ans++,x/=i;
if (x>) ans++;
return ans;
} int main() {
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]),g[i]=__gcd(g[i-],a[i]);
for (int i=;i<=m;i++) scanf("%d",&b[i]);
int cur();
for (int i=n;i;i--) {
a[i]/=cur; g[i]/=cur;
if (calc(g[i])<) cur*=g[i],a[i]/=g[i];
}
//for (int i=1;i<=n;i++) printf("%d ",a[i]); printf("\n");
int ans();
for (int i=;i<=n;i++) ans+=calc(a[i]);
printf("%d\n",ans);
return ;
}
Round 238 div.1
A:我们发现其实最后的答案只与a[i][i]有关,那么我们只记录a[i]=a[i][i],根据操作模拟就可以了。
//By BLADEVIL
#include <cstdio>
#define maxn 1010 using namespace std; int n;
int mat[maxn][maxn],a[maxn]; int main() {
//freopen("data.txt","r",stdin);
scanf("%d",&n);
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) scanf("%d",&mat[i][j]);
for (int i=;i<=n;i++) a[i]=mat[i][i];
int ans();
for (int i=;i<=n;i++) ans=(ans+a[i])%;
int task; scanf("%d",&task);
while (task--) {
int x,y; scanf("%d",&x);
if (x==) printf("%d",ans); else {
scanf("%d",&x); ans^=;
}
}
printf("\n");
return ;
}
B:我们可以将每个给定的a[i]-1,查询s-a[i]+1位置是否被占用,被占用我们cnt++,表示和为s-1的数对加一,否则直接输出s-a[i]+1,然后再找出cnt个和为s-1的数对输出。
//By BLADEVIL
#include <cstdio>
#define maxn 1000010
#define s 1000000 using namespace std; int n,tot;
int flag[maxn]; int main() {
scanf("%d",&n);
for (int i=;i<=n;i++) {
int x; scanf("%d",&x);
flag[x]=; if (flag[s+-x]) tot++;
}
printf("%d\n",n);
for (int i=;i<=s;i++) {
if (tot&&!flag[i]&&!flag[s-i+]) {
tot--;
flag[i]=flag[s-i+]=;
printf("%d %d ",i,s-i+);
}
if (flag[i]&&!flag[s-i+]) printf("%d ",s-i+);
}
printf("\n");
return ;
}
C:深搜,同时每个点记录这个点剩下的一条没有被选定的边,枚举这个点的所有儿子,如果儿子的没有被选定的边不为0我们就画连接儿子的边和儿子剩下的边,否则判断这个点是否有剩下的边,有的话输出连接儿子的边和剩下的边,最后返回剩下的边。
//By BLADEVIL
#include <cstdio>
#define maxn 100010
#define maxm 200010 using namespace std; int n,m,l;
int pre[maxm],other[maxm],last[maxn];
int flag[maxn]; void connect(int x,int y) {
pre[++l]=last[x];
last[x]=l;
other[l]=y;
} int dfs(int x,int fa) {
flag[x]=; int cur();
for (int p=last[x];p;p=pre[p]) {
if (other[p]==fa) continue;
if (flag[other[p]]==) continue;
int edge;
if (!flag[other[p]]) edge=dfs(other[p],x); else edge=;
//printf("|%d %d\n",x,edge);
if (edge) printf("%d %d %d\n",x,other[p],edge); else
if (cur) printf("%d %d %d\n",cur,x,other[p]),cur=; else cur=other[p];
}
flag[x]=;
//printf("%d %d\n",x,cur);
return cur;
} int main() {
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++) {
int x,y; scanf("%d%d",&x,&y);
connect(x,y); connect(y,x);
}
if (m&) printf("No solution\n\n"); else dfs(,-);
return ;
}
D:我们将每条线段能看到的最右面的线段设为这个线段的父亲,那么一个询问的答案就是这两个点的lca,对于父亲我们可以维护一个下凸壳来计算。
//By BLADEVIL
#include <cstdio>
#include <iostream>
#include <algorithm>
#define maxn 200010
#define LL long long using namespace std; struct rec {
LL x,y;
}a[maxn]; int n,t,l;
int q[maxn],jump[maxn][];
int pre[maxn],other[maxn],last[maxn],dep[maxn]; void connect(int x,int y) {
pre[++l]=last[x];
last[x]=l;
other[l]=y;
} int lca(int x,int y) {
if (dep[x]>dep[y]) swap(x,y);
int det(dep[y]-dep[x]);
for (int j=;j<=;j++) if (det&(<<j)) y=jump[y][j];
//printf("%d %d\n",x,y);
if (x==y) return x;
for (int j=;j>=;j--)
if (jump[x][j]!=jump[y][j]) x=jump[x][j],y=jump[y][j];
return jump[x][];
} void dfs(int x) {
for (int p=last[x];p;p=pre[p]) {
dep[other[p]]=dep[x]+;
dfs(other[p]);
}
} int main() {
cin>>n;
for (int i=;i<=n;i++) cin>>a[i].x>>a[i].y;
for (int i=n;i;i--) {
//for (int j=1;j<=t;j++) printf("%d ",q[j]); printf("\n");
while (t>&&(a[q[t]].y-a[q[t-]].y)*(a[i].x-a[q[t-]].x)>(a[q[t]].x-a[q[t-]].x)*(a[i].y-a[q[t-]].y)) t--;
jump[i][]=q[t];
q[++t]=i;
}
//for (int i=1;i<=n;i++) printf("%d ",jump[i][0]);
for (int i=;i<=n;i++) connect(jump[i][],i);
dfs();
//for (int i=1;i<=n;i++) printf("%d ",dep[i]); printf("\n");
for (int j=;j<=;j++)
for (int i=;i<=n;i++) jump[i][j]=jump[jump[i][j-]][j-];
int task; cin>>task;
while (task--) {
int x,y; cin>>x>>y;
cout<<lca(x,y)<<' ';
}
cout<<endl;
return ;
}
Round 240 div.1
A:假设n为偶数,奇数时最后一位随意,那么我们最后两个数为k-(n+2)/2和2*(k-(n+2)/2),前n-2个数为不和最后两位相同的连续的数就可以了。
//By BLADEVIL
#include <cstdio>
#define maxn 100010 using namespace std; int n,k;
int a[maxn]; int main() {
scanf("%d%d",&n,&k);
if ((n==)&&(k)) {
printf("-1\n");
return ;
}
if (n-(n&)>*k) {
printf("-1\n");
return ;
}
int cur((n--(n&))/);
k-=cur;
a[n]=+k;
for (int i=,j=;i<=n--(n&);i+=) {
if (j==k) j+=;
if (j+==k) j+=;
if (j==(k<<)) j+=;
if (j+==(k<<)) j+=;
a[i]=j++; a[i+]=j++;
}
a[n-(n&)]=k,a[n--(n&)]=k<<;
for (int i=;i<=n;i++) printf(i==n?"%d\n":"%d ",a[i]);
return ;
}
B:设w[i][j]为第i位为j的方案数,然后转移就可以了。
//By BLADEVIL
#include <cmath>
#include <cstdio>
#define maxn 2010
#define d39 1000000007 using namespace std; int n,k;
int w[maxn][maxn]; int main() {
scanf("%d%d",&n,&k);
for (int i=;i<=n;i++) w[][i]=;
for (int i=;i<=k;i++)
for (int j=;j<=n;j++)
for (int g=;g<=sqrt(j);g++) if (!(j%g)) {
w[i][j]=(w[i][j]+w[i-][g])%d39;
if (g*g!=j) w[i][j]=(w[i][j]+w[i-][j/g])%d39;
}
int ans();
for (int i=;i<=n;i++) ans=(ans+w[k][i])%d39;
printf("%d\n",ans);
return ;
}
C:我们可以将一次翻转看成将左右儿子翻转然后交换左右儿子,我们可以发现每个块内的翻转对块与块之间的答案没有影响,那么我们只需要按照归并的过程求出长度为2^j的块与块合并的时候产生的答案,和交换块产生的答案,那么每次翻转我们就可以看做将j之前的所有当前状态取反,计算代价即可。
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn (1<<20)+100
#define LL long long using namespace std; LL n,len;
LL a[maxn],b[maxn];
LL w[][],flag[]; void work(LL p,LL cur) {
if (p>n) return ;
for (LL i=;i<=len;i+=cur) {
LL k1(i),k2(i+(cur>>)),det();
while ((k1<i+(cur>>))||(k2<i+cur)) {
if ((k1==i+(cur>>))||((a[k2]<a[k1])&&(k2<i+cur))) {
w[p][]+=i+(cur>>)-k1;
b[i+det]=a[k2];
k2++;
} else {
b[i+det]=a[k1];
k1++;
}
det++;
}
k1=i+(cur>>); k2=i;
while ((k1<i+cur)||(k2<i+(cur>>))) {
if ((k1==i+cur)||((a[k2]<a[k1])&&(k2<i+(cur>>)))) {
w[p][]+=i+cur-k1;
k2++;
} else k1++;
}
}
memcpy(a,b,sizeof b);
work(p+,cur<<);
} int main() {
cin>>n; len=;
for (LL i=;i<=n;i++) len*=;
for (LL i=;i<=len;i++) cin>>a[i];
work(,);
LL ans();
for (LL i=;i<=n;i++) ans+=w[i][];
//for (LL i=1;i<=n;i++) printf("%d ",w[i][0]); printf("\n");
//for (LL i=1;i<=n;i++) printf("%d ",w[i][1]); printf("\n");
for (LL i=;i<=n;i++) flag[i]=;
//printf("%d\n",ans);
LL task; cin>>task;
while (task--) {
LL x; cin>>x;
for (LL i=;i<=x;i++) ans+=w[i][flag[i]]-w[i][flag[i]^];
for (LL i=;i<=x;i++) flag[i]^=;
cout<<ans<<endl;
}
return ;
}
Round 245 div.1
A:tree-dp,设w[i][0..1]表示这个节点的状态和最后的相同(1),不相同(0),且每两层的儿子节点都符合这个状态的最小代价,然后转移就可以了,其实这道题相当于两棵互不影响的树,分别做tree-dp。
//By BLADEVIL
#include <cstdio>
#define maxn 100010
#define maxm 200020 using namespace std; int n,l;
int a[maxn],b[maxn];
int other[maxm],last[maxn],pre[maxm];
int que[maxn],dep[maxn];
int w[maxn][]; void connect(int x,int y) {
pre[++l]=last[x];
last[x]=l;
other[l]=y;
} void dfs(int x,int cur) {
if (a[x]^b[x]^(!cur)) printf("%d\n",x),cur^=;
for (int p=last[x];p;p=pre[p]) if (dep[other[p]]>dep[x])
for (int q=last[other[p]];q;q=pre[q]) if (dep[other[q]]>dep[other[p]])
dfs(other[q],cur);
} int main() {
scanf("%d",&n);
for (int i=;i<n;i++) {
int x,y; scanf("%d%d",&x,&y);
connect(x,y); connect(y,x);
}
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<=n;i++) scanf("%d",&b[i]);
int h(),t();
que[]=; dep[]=;
while (h<t) {
int cur=que[++h];
for (int p=last[cur];p;p=pre[p]) {
if (dep[other[p]]) continue;
que[++t]=other[p]; dep[other[p]]=dep[cur]+;
}
}
for (int i=n;i;i--) {
int x=que[i];
for (int p=last[x];p;p=pre[p]) {
if (dep[other[p]]<dep[x]) continue;
//w[x][0]+=w[other[p]][1]; w[x][1]+=w[other[p]][1];
for (int q=last[other[p]];q;q=pre[q]) {
if (dep[other[q]]<dep[other[p]]) continue;
if (a[x]^b[x]) w[x][]+=w[other[q]][]; else w[x][]+=w[other[q]][];
if (a[x]^b[x]) w[x][]+=w[other[q]][]; else w[x][]+=w[other[q]][];
}
}
if (a[x]^b[x]) w[x][]++; else w[x][]++;
}
//for (int i=1;i<=n;i++) printf("%d %d\n",w[i][0],w[i][1]);
int ans(w[][]);
for (int p=last[];p;p=pre[p]) ans+=w[other[p]][];
printf("%d\n",ans);
dfs(,);
for (int p=last[];p;p=pre[p]) dfs(other[p],);
return ;
}
B:记录w[i][j][1..4]表示四个方向到i,j点的最大值,然后枚举相遇的节点就可以了。
//By BLADEVIL
#include <cstdio>
#include <iostream>
#include <algorithm>
#define maxn 1010
#define LL long long using namespace std; LL n,m;
LL a[maxn][maxn];
LL w[][maxn][maxn]; void prepare() {
for (LL i=;i<=n;i++)
for (LL j=;j<=m;j++) w[][i][j]=max(w[][i][j-],w[][i-][j])+a[i][j];
for (LL i=;i<=n;i++)
for (LL j=m;j;j--) w[][i][j]=max(w[][i][j+],w[][i-][j])+a[i][j];
for (LL i=n;i;i--)
for (LL j=;j<=m;j++) w[][i][j]=max(w[][i+][j],w[][i][j-])+a[i][j];
for (LL i=n;i;i--)
for (LL j=m;j;j--) w[][i][j]=max(w[][i+][j],w[][i][j+])+a[i][j];
} int main() {
cin>>n>>m;
for (LL i=;i<=n;i++)
for (LL j=;j<=m;j++) cin>>a[i][j];
prepare();
LL ans();
for (LL i=;i<n;i++)
for (LL j=;j<m;j++)
ans=max(ans,w[][i-][j]+w[][i+][j]+w[][i][j+]+w[][i][j-]),
ans=max(ans,w[][i][j-]+w[][i][j+]+w[][i-][j]+w[][i+][j]);
cout<<ans<<endl;
return ;
}
C:深搜就可以了,有一种贪心不正确但是数据弱可以过去。
#include <cstdio>
#include <iostream>
#include <algorithm>
#define maxn 30 using namespace std; int n;
int w[maxn],p[maxn]; int dfs(int x,int used) {
//printf("%d %d\n",x,used);
if (x>n) return *max_element(p+,p++n)==;
for (int i=;i<=x;i++)
if ((p[i]>w[x]||p[i]==w[x]&&p[i]!=w[i]-)&&((used&(<<p[i])))==) {
p[i]-=w[x];
if (dfs(x+,x+<=n&&w[x]==w[x+]?used:)) return ;
p[i]+=w[x];
used|=<<p[i];
}
return ;
} int main() {
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&w[i]);
sort(w+,w++n,greater<int>());
for (int i=;i<=n;i++) p[i]=w[i]-;
printf(dfs(,)?"YES\n":"NO\n");
}
【CF刷题】14-05-12的更多相关文章
- 第9周cf刷题(dp)
Problems(1300-1600) an ac a day keeps the doctor away Gas Pipeline (1500) 2019.10.28 题意: 管道工人需要在一段凹凸 ...
- CF刷题-Codeforces Round #481-G. Petya's Exams
题目链接:https://codeforces.com/contest/978/problem/G 题目大意:n天m门考试,每门考试给定三个条件,分别为:1.可以开始复习的日期.2.考试日期.3.必须 ...
- CF刷题-Codeforces Round #481-F. Mentors
题目链接:https://codeforces.com/contest/978/problem/F 题目大意: n个程序员,k对仇家,每个程序员有一个能力值,当甲程序员的能力值绝对大于乙程序员的能力值 ...
- CF刷题-Codeforces Round #481-D. Almost Arithmetic Progression
题目链接:https://codeforces.com/contest/978/problem/D 题解: 题目的大意就是:这组序列能否组成等差数列?一旦构成等差数列,等差数列的公差必定确定,而且,对 ...
- (python)leetcode刷题笔记05 Longest Palindromic Substring
5. Longest Palindromic Substring Given a string s, find the longest palindromic substring in s. You ...
- LeetCode刷题总结-哈希表篇
本文总结在LeetCode上有关哈希表的算法题,推荐刷题总数为12题.具体考察的知识点如下图: 1.数学问题 题号:149. 直线上最多的点数,难度困难 题号:554. 砖墙,难度中等(最大最小边界问 ...
- leecode刷题(14)-- 有效的字母异位词
leecode刷题(14)-- 有效的字母异位词 有效的字母异位词 描述: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词. 示例 1: 输入: s = " ...
- leecode刷题(12)-- 整数反转
leecode刷题(12)-- 整数反转 整数反转 描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: - ...
- LeetCode刷题笔记 - 12. 整数转罗马数字
学好算法很重要,然后要学好算法,大量的练习是必不可少的,LeetCode是我经常去的一个刷题网站,上面的题目非常详细,各个标签的题目都有,可以整体练习,本公众号后续会带大家做一做上面的算法题. 官方链 ...
随机推荐
- java 20 - 8 字节流的文件复制以及汉字在计算机中的存储方式
复制文本文件:把当前目录下的FileIntputStream.java文件里面的内容复制到当前目录的b.txt文件中 分析: 数据源: FileIntputStream.java -- 读取数据 -- ...
- ArcGis 中MapControl 框选
void mCtrl_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e) ...
- 一个简单的scrapy爬虫抓取豆瓣刘亦菲的图片地址
一.第一步是创建一个scrapy项目 sh-3.2# scrapy startproject liuyifeiImage sh-3.2# chmod -R 777 liuyifeiImage/ 二.分 ...
- Java 数据类型和变量
1.1 基本类型与引用类型的区别 1.基本类型代表简单的数据类型,比如整数和字符,引用类型所引用的实例能表示任意一种复杂的数据类型. 2.基本类型仅表示数据类型,而引用类型所引用的实例除了表示复杂数据 ...
- 第三章 Models模块属性详解
摘自:http://www.cnblogs.com/xdotnet/archive/2012/03/07/aspnet_mvc40_validate.html 了解了这些就可以对MVC进一步认识,相信 ...
- [Android学习笔记]理解焦点处理原理的相关记录
焦点处理相关记录 以下所涉及的焦点部分,只是按键移动部分,不明确包含Touch Focus部分 需解决问题 控件的下一个焦点是哪? 分析思路 当用户通过按键(遥控器等)触发焦点切换时,事件指令会通过底 ...
- android studio使用说明
一.学习的基本配置文档,搞好各种参数的基本配置,熟练使用. C:\Program Files\Java\jdk1.7.0_09\bin 二.problems meet in weather and ...
- Android Studio使用中的异常
Android studio教程:[4]真机测试 1.连不上手机 Android Studio识别不了手机(最后还是恢复成勾中的状态),重启,Android Studio连接真机没反应? 2.连上手机 ...
- C语言 生成随机数
#include<stdio.h> #include<time.h> #include<Windows.h> void main1(){ //定义一个时间类型 ti ...
- 构架高性能WEB网站的几点知识
前言: 对于构架高性能的web网站大家都很感兴趣,本文从几点粗谈高性能web网站需要考虑的问题. HTML静态化 什么是html静态化? 说得简单点,就是把所有不是.htm或者.html的页面改为.h ...