博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #376 (Div. 2) C D F
阅读量:7093 次
发布时间:2019-06-28

本文共 4314 字,大约阅读时间需要 14 分钟。

在十五楼做的cf..一会一断...比赛的时候做出了ABCF 就没有时间了 之后没看题解写出了D..E是个神奇的博弈(递推或者dp?)看了题解也没有理解..先写了CDF..

C 有n个袜子 每个袜子都有颜色 给出m天穿的两只袜子编号 要求现在进行涂色 保证后m天每天的两只袜子都是一个颜色

可以想到和同一只袜子一起穿过的两只袜子 a == b && c == b 那就a == b 了 这样可以推出有关系的袜子都应该是一个颜色(连通分量)

由于要求出来最小涂多少只 那就bfs求一下连通分量大小 再减去其中最多的颜色 就是这个连通分量中要进行的涂色个数了 需要注意的是 有些袜子不会被穿 那就不管

..比赛的时候写错了一句话 wa了好几次..因为怕重边太多终测超时 加了个map判断又交一次 赛后发现有重边跑的比判重还快...

D 有n个序列 每个序列有len[i]个数字 每次可以进行一次操作 把所有的序列里面的所有的数字都加一 如果增加后等于c+1就变成1

求出进行ans次操作之后 这些序列符合字典序(即将这个序列变成string 满足a[i]<=a[i+1])

n和len都达到了50w c也达到了100w 存是肯定存不下 那就滚动数组来弄 只需要保证经过转动之后每一个序列比前一个大或者等于就可以了

由给出的字典序的定义可以看出 两个字符串的相同前缀不做考虑 只考虑第一个不同的 不同的数字肯定会在操作一定次数之后 关系变成前者小于后者 这时候 可以得出一个区间 

最后会得出n-1个区间 求一个次数 在所有的区间中  

其实是比较好想的 模拟就是了 但是有个trick是 如果前者大于后者 那么只会得出来一个区间 l是前者为1次数 r是后者为1次数-1

但是如果前者小于后者 就有可能会出现两个区间 但是这两个区间的维度是一样的 这两个在n-1个区间中同属于一个区间

所以不能简单的比较最大的l和最小的r 应该用一个计算当前数字在多少个区间内的方法判断这个数是否可行 

F 有n个数的集合 在这n个数中选一个子集(可以直接选这个集合) 在这个子集中选出一个基准数 把其他的数全部变为 基准数*(x/基准数) 然后得出res为这个子集的sum 问res最大是多少

wa着C的时候看见好多人过F..不知所措..于是过了C之后就去看这个了

想了想 把这n个数去重sort之后 当我们选择a[i]之后 可以往后面卡出z个区间a[i] - 2*a[i]-1,2*a[i] - 3*a[i]-1,....一直到k*a[i] - (k+1)*a[i]-1 当k*a[i] > a[cnt]的时候break

由于a[i] 最大也是20w 所以对于每个数 假设进行的操作是x次 那么总共的次数加起来是玄学的不会超时的...

时间复杂度最差的时候是123...20w 这时候 1是20w 2是10w ... 1000是200次 那么即使1000之前全部20w 1000之后全部200 也只是1000*20w + 20w * 200 其实也只是十的八次方 怎么会超..

当然寻找这z个区间内有多少个数我是手写的二分...后来怎么看时间复杂度都是炸了的..

后来看了一下题解..别人都是直接暴力的..QAQ 

D

#include
#include
#include
#include
#include
#include
#include
using namespace std;#define L long longint n ;int c;int a[2][500050];int len[2];struct node{ int l,r;};node b[2000050];int l[1000050];int r[1000050];int main(){ scanf("%d%d",&n,&c); int cnt = 1; int res = 0; int tot = 0; bool ok = true; for(int i=1;i<=n;i++){ cnt ^= 1; res ^= 1; scanf("%d",&len[res]); bool js = false; for(int k=1;k<=len[res];k++){ scanf("%d",&a[res][k]); if(i == 1){ continue; } if(js == true){ continue; } if(k > len[cnt]){ continue; } if(a[res][k] == a[cnt][k]){ continue; } else if(a[res][k] > a[cnt][k]){ tot ++ ; b[tot].l = 0; b[tot].r = c - a[res][k]; if(a[cnt][k] != 1){ tot ++ ; b[tot].r = c - 1; b[tot].l = c - 1 - (a[cnt][k] - 2); } js = true; } else { tot ++ ; b[tot].l = c - a[cnt][k] + 1; b[tot].r = c - a[res][k]; js = true; } } if(i == 1){ continue; } if(js == false){ if(len[res] < len[cnt]){ ok = false; } else { tot ++ ; b[tot].l = 0; b[tot].r = c-1; } } } if(n == 1){ printf("0\n"); return 0; } if(ok == false){ printf("-1\n"); return 0; } for(int i=0;i<=c;i++){ l[i] = r[i] = 0; } for(int i = 1; i<= tot;i++){ l[b[i].l] ++ ; r[b[i].r] ++ ; //printf("%d %d\n",b[i].l,b[i].r); } int sum = 0; int i; for(i=0;i
= n-1){ printf("%d\n",i); break; } sum -= r[i]; } if(i == c){ printf("-1\n"); }}

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std ;#define L long longint n ;L a[200050];L b[200050];L num[200050];L sum[200050];int cnt ;int zerfen(int l,int r ,L Lx,L Rx){ int res = -1; while(l<=r){ int mid = (l+r)/2; if(b[mid]>=Lx && b[mid] <= Rx){ res = mid ; r = mid-1; } else { if(b[mid] < Lx){ l = mid +1; } else { r = mid -1; } } } return res;}int yerfen(int l,int r ,L Lx,L Rx){ int res = -1; while(l<=r){ int mid = (l+r)/2; // printf(" L R Mid: %d %d %d\n",l,r,mid); if(b[mid]>=Lx && b[mid] <= Rx){ res = mid ; l = mid+1; } else { if(b[mid] < Lx){ l = mid +1; } else { r = mid -1; } } } return res;}int main(){ scanf("%d",&n); memset(num,0,sizeof(num)); cnt = 0; for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); if(num[a[i]] == 0){ cnt ++ ; b[cnt ]= a[i]; } num[a[i]] ++; } sort(b+1,b+1+cnt); L ans = 0; sum[0] = 0; for(int i=1;i<=cnt ;i++){ sum[i] = sum[i-1] + num[b[i]]; } sum[n+1] = sum[n]; for(int i=1;i<=cnt;i++){ /// i = base L res = 0; for(int k= 1;b[i]*(k) <=b[cnt];k++){ int l = i; int r = cnt ; L Lx = b[i]*k; L Rx = b[i]*(k+1); int zer = zerfen(l,r,Lx,Rx-1); int yer = yerfen(l,r,Lx,Rx-1); //printf("zhi : %lld %lld \n",Lx,Rx); //printf("%d %d\n",zer,yer); if(zer == -1 || yer == -1){ continue; } else { L z = sum[yer] - sum[zer -1]; res += (z * b[i] * k); } } if(res > ans){ ans = res ; } //printf("-------------------------\n"); } printf("%lld\n",ans);}

转载于:https://www.cnblogs.com/rayrayrainrain/p/5974720.html

你可能感兴趣的文章
Js用正则表达式验证字符串
查看>>
大疆农业专家在线空开课直播课件知识
查看>>
怎样快速搜索自己所需的资料?(90%的人不会使用此方法)[转]
查看>>
POJ_2411_Mondriaan's Dream_状态压缩dp
查看>>
694. Number of Distinct Islands - Medium
查看>>
vue打包后出现的.map文件
查看>>
前端应用框架(三)
查看>>
多线程的死锁
查看>>
定时任务框架Quartz-(一)Quartz入门与Demo搭建
查看>>
css导航栏
查看>>
洛谷3195(HNOI2008)玩具装箱
查看>>
智能公交报站系统RFID解决方案
查看>>
计算最长英语单词链(单词接龙)
查看>>
vsftp虚拟用户配置
查看>>
oracle11g与oracle10g字符集子集与超集的对应关系表
查看>>
登录注册D
查看>>
deepin-wine-tim 字体发虚
查看>>
windows多线程没那么难
查看>>
ID3决策树算法原理及C++实现(其中代码转自别人的博客)
查看>>
linux之SQL语句简明教程---WHERE
查看>>