CodeForces 327A

题意:有n个数,都是0或1,然后必须执行一次操作,翻转一个区间,里面的数0变1,1变0,求最多1的数量

思路:最开始我写的最大字段和,后面好像写搓了,然后我又改成暴力,因为这个范围只有100,写n^3都没事,所以我们第一层枚举左区间,第二层枚举右区间,然后我们第三层记录左边1的数量,中间的0的数量,右边的1的数量即可

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll a[],num,n;
int main(){
scanf("%lld",&n);
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
}
ll mx=;
for(int i=;i<=n;i++){
for(int j=i;j<=n;j++){
ll shu=;
for(int k=;k<i;k++){
if(a[k]) shu++;
}
for(int k=i;k<=j;k++){
if(a[k]==) shu++;
}
for(int k=j+;k<=n;k++){
if(a[k]) shu++;
}
mx=max(shu,mx);
}
}
printf("%lld",mx);
}

CodeForces 854C

题意:有n架飞机,现在因为一些原因飞机都只能拖延到k+1时刻后出发,一个时刻只能出发一架,每架飞机有个晚飞一分钟损失多少,最开始飞机是按顺序安排的时刻表,现在问你怎么排表损失最小

思路:首先我们知道最开始是 1 2 3 4 5,如果k为2,那么我们只能是 3 4 5 6 7 ,但是我们要怎么安排呢,我们能清晰的知道,每个人都是一分钟损耗多少,所以我们肯定是让最大的尽量少损失,因为差值都是固定的  3 4 5 6 7 - 1 2 3 4 5  差值和为10  ,只是我们现在要排列把这个差值给哪些数,我们肯定把差值尽量给损失小的,所以我们排个序,我们找最接近当前数的值,但是我们找又是个问题,一个只能用一次,用完就要删除,而且我们不能遍历找,符合这些要求的有个很好的东西就是 set,我们可以利用log级别的删除,set.lower_bound log级别的查找就能很好解决这个事

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#define maxn 300005
#define mod 1000000007
using namespace std;
typedef long long ll;
struct sss
{
ll id;
ll x;
}a[maxn];
ll n,m;
ll vis[maxn];
set<ll> q;
int cmp(struct sss x,struct sss y){
return x.x>y.x;
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++){
q.insert(i+m);
}
for(int i=;i<=n;i++){
scanf("%lld",&a[i].x);
a[i].id=i;
}
sort(a+,a+n+,cmp);
ll sum=;
for(int i=;i<=n;i++){
ll x=*q.lower_bound(a[i].id);
//set<ll>::iterator t1=q.upper_bound(a[i].x);
sum+=(x-a[i].id)*a[i].x;
vis[a[i].id]=x;
q.erase(x);
}
printf("%lld\n",sum);
for(int i=;i<=n;i++){
printf("%lld ",vis[i]);
}
}

CodeForces 863C

题意:有两个人玩石头剪刀布,最开始两个人会选择出什么,然后两个人都会根据对方和自己现在出的东西而改变下次出的,然后会进行k轮游戏,输出每个人赢得次数

思路:这个k特别大,但是情况最多有9种,也就是说9种过后必定会出现重复的,这个时候说明有循环节,我们把中间周期除掉计算即可

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#define maxn 300005
#define mod 1000000007
using namespace std;
typedef long long ll;
struct sss
{
ll sum1,sum2;
}c[maxn];//记录当前步的比赛状况
ll A[][];
ll B[][];
ll vis[][];
ll chuan(ll a,ll b){
if(a==b) return ;
if(a==&&b==) return -;
if(a==&&b==) return ;
if(a==&&b==) return -;
if(a==&&b==) return ;
if(a==&&b==) return ;
if(a==&&b==) return -;
}
int main(){
ll k,a,b;
scanf("%lld%lld%lld",&k,&a,&b);
for(int i=;i<=;i++){
for(int j=;j<=;j++){
scanf("%lld",&A[i][j]);
vis[i][j]=-;
}
}
for(int i=;i<=;i++){
for(int j=;j<=;j++){
scanf("%lld",&B[i][j]);
}
}
ll sum1=,sum2=;
ll z=,flag=;
while(z<k){
ll w=chuan(a,b);
if(w==) sum1++;
else if(w==-) sum2++;
if(vis[a][b]!=-){//找到循环节
ll len=z-vis[a][b];
ll sy=k-z-;
sum1+=sy/len*(sum1-c[vis[a][b]].sum1);
sum2+=sy/len*(sum2-c[vis[a][b]].sum2);
sy%=len;
k=sy;
flag=;
ll a1=a,b1=b;
a=A[a1][b1];
b=B[a1][b1];
break;
}
c[z].sum1=sum1;
c[z].sum2=sum2;
vis[a][b]=z;
ll a1=a,b1=b;
a=A[a1][b1];
b=B[a1][b1];
z++;
}
z=;
while(flag&&z<k){
ll w=chuan(a,b);
if(w==) sum1++;
else if(w==-) sum2++;
ll a1=a,b1=b;
a=A[a1][b1];
b=B[a1][b1];
z++;
}
printf("%lld %lld",sum1,sum2);
}

CodeForces 749D

题意:最开始有n个人,每个人会选择一个团队,自身带一个价值,然后下面有q次查询,说明这次比拼哪些团队不会参加,然后选获胜团队以及获胜团队里面最低能战胜其他所有人的人的价值

思路:我们首先用vector记录所以人的值,这肯定要做的,然后我们会发现我们要战胜肯定是要把其他所有人的最大值战胜,所以我们用一个set记录所有团队的最大值,我们缺席的话直接暴力

在set里面删除,然后我们再找出当前最大,那就是获胜者,然后找出次大,然后在获胜者团队二分找出正好比他大的值即可

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<set>
#include<utility>
#include<algorithm>
using namespace std;
#define mp make_pair
#define X first
#define Y second
const int N=;
int n,m,q,a[N],b[N];
int ban[N],c[N];
set<int>d[N];
pair<int,int>e[N];
int main(void)
{
int i,p1,p2;
scanf("%d",&n);
for(i=;i<=n;i++){scanf("%d%d",&p1,&p2);b[p1]=p2;d[p1].insert(p2);}
for(i=;i<=n;i++)e[i]=mp(b[i],i);
sort(e+,e++n);
scanf("%d",&q);
while(q--)
{
scanf("%d",&m);
for(i=;i<=m;i++){scanf("%d",c+i);ban[c[i]]=;}
p1=p2=;
for(i=n;i>=;i--)
{
if(==e[i].X)break;
if(ban[e[i].Y])continue;
if(p1){p2=e[i].Y;break;}
else p1=e[i].Y;
}
if(p1==)printf("0 0\n");
else if(p2==)printf("%d %d\n",p1,*d[p1].begin());
else printf("%d %d\n",p1,*d[p1].lower_bound(*(--d[p2].end())));
for(i=;i<=m;i++)ban[c[i]]=;
}
return ;
}

CodeForces 926E

题意:开始有 n个数,然后如果有相同的连续的数x我们要合并,合并之后之前两个数删除然后插入x+1,然后直到不能再合并,下标是左边那个的下标,输出最后结果

思路:我们会发现合并必须要从低到高执行,因为新插入的是x+1,所以我们必须从低到高,然后我们要考虑的问题是,合并后,但是我的数组其实还是一样的位置,比如 1 1 2,我合并第 1 2个数数组里面就会变成  2 0 2 ,0代表这个位置没数了,但是我们下次合并又要怎么知道1 3个数可以合并呢,暴力肯定不现实,这个时候我们又会发现其实每个数也就和他的下个数有关,我们想用删除一个数,又要查询两个数是否相连,有个很适合这个结构,那就是链表,我们清晰的记录下一个下标是谁,然后上面我们合并后又要插入进去,那肯定是使用优先队列了,然后我们相等的值按下标排序,如果当前两个数不匹配,那么说前面这个数的位置肯定确定下来了。因为要么是下标不符合,中间隔了数,肯定不能再合并。要么是值不相等。从低到高,已经没别的合并的机会了

#include<cstdio>
#include<cmath>
#include<queue>
#include<iostream>
#include<algorithm>
#define maxn 200005
#define mod 1000000007
using namespace std;
typedef long long ll;
struct sss{
ll id;
ll next;
friend bool operator <(struct sss x,struct sss y){
if(x.next==y.next){
return x.id>y.id;
}
return x.next>y.next;
}
}a[maxn];
ll n;
priority_queue<struct sss> q;
ll b[maxn],c[maxn];
int main(){
ll n;
cin>>n;
for(int i=;i<=n;i++){
a[i].id=i;
if(i!=n)
a[i].next=i+;
else a[i].next=-;
}
for(int i=;i<=n;i++){
cin>>b[i];
struct sss e;
e.id=i;
e.next=b[i];
q.push(e);
}
ll num=;
while(q.size()>=){
struct sss x,y;
x=q.top();q.pop();
y=q.top();q.pop();
if(a[x.id].next==y.id&&x.next==y.next){
x.next++;
a[x.id].next=a[y.id].next;
q.push(x);
num++;
}
else{
c[x.id]=x.next;
q.push(y);
}
}
if(!q.empty()){
struct sss x=q.top();q.pop();c[x.id]=x.next;
}
if(!q.empty()){
struct sss x=q.top();q.pop();c[x.id]=x.next;
}
cout<<n-num<<"\n";
for(int i=;i<=n;i++){
if(c[i]!=){
cout<<c[i]<<" ";
}
}
}

CodeForces 455C

题意:给定N,M和Q,N表示有N个城市,M条已经修好的路,修好的路是不能改变的,然后是Q次操作,操作分为两种,一种是查询城市x所在的联通集合中,最长的路为多长。二是连接两个联通集合,采用联通之后最长路最短的方案,无环图。

思路:因为一开时的图是不可以改变的,所以一开始用dfs处理出各个联通集合,并且记录住最大值,然后就是Q次操作,用并查集维护,注意因为联通的时候要采用最长路径最短的方案,所以s的转移方程变为s = max(s, (s+1)/2 + (s0+1)/2 + 1),因为两个连通块都记录了树的直径,如果我们其中一条路径是 1-2-3-4-5-6-7,那么这个连通块我肯定选择4点连接,为什么呢,因为如果我选3,那么我就可以走3-4-5-6-7,很明显长度更大,那么最优的肯定是选择中间点,所以我们每次合并的时候就是 选择两个路径的中间点长度再加上新加的那条求一个max

 

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm> using namespace std;
const int maxn = * 1e5 + ;
int N, M, Q, f[maxn], s[maxn];
int root, ans, rec;
vector<int> g[maxn]; int getfar(int x) {
return f[x] == x ? x : f[x] = getfar(f[x]);
} void link (int u, int v) {
int x = getfar(u);
int y = getfar(v); if (x == y)
return; if (s[x] < s[y])
swap(s[x], s[y]); f[y] = x;
s[x] = max(s[x], (s[x] + ) / + (s[y] + ) / + );
} void dfs (int u, int p, int d) {
f[u] = root; if (d > ans) {
ans = d;
rec = u;
} for (int i = ; i < g[u].size(); i++) {
if (g[u][i] != p)
dfs(g[u][i], u, d+);
}
} int main () {
int type, u, v; scanf("%d%d%d", &N, &M, &Q);
for (int i = ; i <= N; i++) {
f[i] = i;
g[i].clear();
} for (int i = ; i < M; i++) {
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
} for (int i = ; i <= N; i++) {
if (f[i] == i) {
root = rec = i;
ans = -;
dfs(i, , ); ans = -;
dfs(rec, , );
s[i] = ans;
}
} for (int i = ; i < Q; i++) {
scanf("%d", &type);
if (type == ) {
scanf("%d", &u);
v = getfar(u);
printf("%d\n", s[v]);
} else {
scanf("%d%d", &u, &v);
link(u, v);
}
}
return ;
}

暑期训练 CF套题的更多相关文章

  1. [CF套题] CF-1163

    CF-1163 传送门 # Penalty A B1 B2 C1 C2 D E F 3 (483) 464 +0 0:06 +1 01:13 +3 01:12 + 01:57 + 01:56 A 第一 ...

  2. [CF套题] CF-1201

    CF-1201 传送门 # = * A 500 B 1000 C 1500 D 2000 E1 2000 E2 1000 1 (2217) 1672 482 00:09 400 01:40 790 0 ...

  3. [小结] 中山纪念中学2018暑期训练小结(划掉)(颓废记)-Day10

    [小结] 中山纪念中学2018暑期训练小结(划掉)(颓废记)-Day10 各位看众朋友们,你们好,今天是2018年08月14日,星期二,农历七月初四,欢迎阅看今天的颓废联编节目 最近发生的灵异事件有 ...

  4. Noip2019暑期训练2 反思

    经过两次测试,通过深刻的反思,我主要发现了以下易犯错误: 1.做题目时过于追求速度,导致好几处代码都出现手误打错的现象!而且,千万不要图快.图方便就复制粘贴,非常容易出错!(例如T3-party中直接 ...

  5. 第46套题【STL】【贪心】【递推】【BFS 图】

    已经有四套题没有写博客了.今天改的比较快,就有时间写.今天这套题是用的图片的形式,传上来不好看,就自己描述吧. 第一题:单词分类 题目大意:有n个单词(n<=10000),如果两个单词中每个字母 ...

  6. Educational Codeforces Round 15 套题

    这套题最后一题不会,然后先放一下,最后一题应该是大数据结构题 A:求连续最长严格递增的的串,O(n)简单dp #include <cstdio> #include <cstdlib& ...

  7. 做了一道cf水题

    被一道cf水题卡了半天的时间,主要原因时自己不熟悉c++stl库的函数,本来一个可以用库解决的问题,我用c语言模拟了那个函数半天,结果还超时了. 题意大概就是,给定n个数,查询k次,每次查询过后,输出 ...

  8. 【套题】qbxt国庆刷题班D1

    Day1 事实上D1的题目还是比较简单的= =然而D1T2爆炸了就十分尴尬--错失一波键盘 看题 T1 传送门 Description 现在你手里有一个计算器,上面显示了一个数\(S\),这个计算器十 ...

  9. Moscow Pre-Finals Workshop 2016. Japanese School OI Team Selection. 套题详细解题报告

    写在前面 谨以此篇题解致敬出题人! 真的期盼国内也能多出现一些这样质量的比赛啊.9道题中,没有一道凑数的题目,更没有码农题,任何一题拿出来都是为数不多的好题.可以说是这一年打过的题目质量最棒的五场比赛 ...

随机推荐

  1. tomcat启动控制台报Exception in thread ''main".......“Could not find the main class:.....Bootstrap”问题

    startup.bat文件打开最后end下一行加pause调试,重新启动tomcat,发现配置没问题,但是依然报错,发现是jdk版本问题,jdk1.6无法与tomcat8适配,重新装个1.7版本的jd ...

  2. Selenium WebDriver 常用API

    public class Demo1 { WebDriver driver; @BeforeMethod public void visit(){ //webdriver对象的声明 System.se ...

  3. Drone 持续集成实践 - 基于 Gogs,以 Golang 为例

    Drone 官方示例 - Example Go project 用 Docker 部署 Go 服务器 Golang 官方示例 - outyet 一个生产环境的例子 用 rsync 复制文件的方式进行部 ...

  4. 第 4 章 前端基础之jquery

    一.jQuery是什么? 1. jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. 2. jQuery是继prototype之后又一 ...

  5. 16/7/8_PHP-书写规范 PHP Coding Standard

    变量命名规范这里感觉 打算采用 匈牙利命名法+驼峰法命名,因为 PHP是弱类型语言,很多时间因为忽略了变量类型而导致犯一些低级错误.所以在前面加上类型名有助于更好的理解代码. 下载是转载 PHP书写规 ...

  6. tp 框架 -文件上传

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?ph ...

  7. JavaScript.InjectedScriptHost

    "use strict"; (function(InjectedScriptHost, inspectedGlobalObject, injectedScriptId) {     ...

  8. [Python3 填坑] 014 类的常用魔术方法举例

    目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 __init__() 2.2 __new__() 2.3 __call__() 2.4 __str__() 2.5 __repr__() ...

  9. Spring Boot 1.x 正式退役,2.x大步向前!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 早在<Spring Boot 2.1.5 正式发布,1.5.x 即将结束使命!>一文中栈长就提醒大家 Sprin ...

  10. How Many Answers Are Wrong (HDU - 3038)(带权并查集)

    题目链接 并查集是用来对集合合并查询的一种数据结构,或者判断是不是一个集合,本题是给你一系列区间和,判断给出的区间中有几个是不合法的. 思考: 1.如何建立区间之间的联系 2.如何发现悖论 首先是如何 ...