CF上的3道小题

终于调完了啊....


T1:CF702E Analysis of Pathes in Functional Graph

题意:你获得了一个n个点有向图,每个点只有一条出边。第i个点的出边指向fi,边权为wi。分别求从每个点出发走k步经过的边权和以及最小的边权值。

分析:倍增嘛...f[i][j]表示j走$2^i$步到达哪个点,然后用这个求出h[i][j]表示j走$2^i$步边权最小值,g[i][j]表示j走$2^i$步边权和。

然后把K二进制拆分一下即可。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
#define N 100050
int f[44][N],g[44][N],n;
ll h[44][N],K;
int main() {
// freopen("today.in","r",stdin);
// freopen("today.out","w",stdout);
scanf("%d%lld",&n,&K);
int i,x,j;
for(i=1;i<=n;i++) {
scanf("%d",&f[0][i]); f[0][i]++;
}
for(i=1;i<=n;i++) {
scanf("%d",&x); g[0][i]=h[0][i]=x;
}
for(i=1;(1ll<<i)<=K;i++) {
for(j=1;j<=n;j++) {
f[i][j]=f[i-1][f[i-1][j]];
g[i][j]=min(g[i-1][j],g[i-1][f[i-1][j]]);
h[i][j]=h[i-1][j]+h[i-1][f[i-1][j]];
}
}
for(i=1;i<=n;i++) {
ll t=K;
int x=i;
int ans1=1<<30;
ll ans2=0;
for(j=0;j<=40;j++) {
if(t&(1ll<<j)) {
ans1=min(ans1,g[j][x]);
ans2+=h[j][x];
x=f[j][x];
}
}
printf("%lld %d\n",ans2,ans1);
}
}
/*
7 3
2 3 4 5 4 3 7
6 3 1 4 2 2 3
*/

T2:CF671B Robin Hood

题意:你拥有n堆石子,第i堆石子有ai个,你要操作k次,每次从有最多石子的堆拿出一个石子放入有最少石子的堆。求操作后石子最多的堆和石子最少的堆的石子差。

分析:考虑二分最大值/最小值,然后判断能否铺平(将小于/大于的部分加起来和K比)。

注意所有石子都相等的时候要停止,以及一堆特判。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 500050
typedef long long ll;
int n,a[N],K,b[N],c[N],d[N];
bool check1(int x) {
int i,re=0;
for(i=1;i<=n;i++) {
if(a[i]>x) re+=a[i]-x;
if(re>K) return 0;
}
return 1;
}
bool check2(int x) {
int i,re=0;
for(i=1;i<=n;i++) {
if(a[i]<x) re+=x-a[i];
if(re>K) return 0;
}
return 1;
}
ll Abs(ll x) {return x>0?x:-x;}
int main() {
// freopen("problem.in","r",stdin);
// freopen("problem.out","w",stdout);
scanf("%d%d",&n,&K);
int i;
ll sum=0;
ll cha=0;
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
sum+=a[i]; sum%=n;
}
for(i=1;i<=n;i++) cha+=Abs(a[i]-sum/n);
sum%=n;
if(!sum&&2*K>=cha) {
puts("0"); return 0;
}
int flg=0;
for(i=2;i<=n;i++) if(a[i]!=a[i-1]) flg=1;
if(!flg) {
printf("%d\n",0); return 0;
}
// sort(a+1,a+n+1);
int l=0,r=1<<30;
while(l<r) {
int mid=(l+r)>>1;
if(check1(mid)) r=mid;
else l=mid+1;
}
int ans1=l;
l=0,r=1<<30;
while(l<r) {
int mid=(l+r)>>1;
if(check2(mid)) l=mid+1;
else r=mid;
}
int ans2=l-1;
// if(ans1>ans2) swap(ans1,ans2);
if(ans1<=ans2) {
printf("%d\n",sum?1:0);
}else
printf("%d\n",ans1-ans2);
}

T3:CF671C Ultimate Weirdness of an Array

题意:给你一个长度为n的序列,定义f(i,j)表示把序列的i到j这段扣掉后序列选出两个数做gcd的最大值。

求$\sum\limits_{i=1}^{n}\sum\limits_{j=i}^{n} f(i,j)$。

分析:设$h(i$)表示有多少对$l,r$使得$f(l,r)<=i$,nxt[j]表示使得$f(j,k)<=i$成立的最小的$k$。

于是$h(i)=\sum\limits_{j=1}^{n}n-nxt[j]+1$,且答案$=\sum\limits_{i=1}^{maxn}i*(h(i)-h(i-1))$

考虑从h(i)->h(i-1)会发生什么,发生变化的一定是原来nxt的位置上的数是i的倍数的那些数。

把是i的倍数那些位置的第一个,第二个,倒数第二个和倒数第一个拿出来,然后分析一通。

发现这其实是区间取max,同时维护区间和。

并且nxt随i的减小单调不降,故每次修改相当于区间覆盖。

线段树维护nxt即可。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
#define N 200050
#define ls p<<1
#define rs p<<1|1
typedef long long ll;
int mx[N<<2],mn[N<<2],cov[N<<2],n;
ll sum[N<<2],h[N];
int a[N],cnt[N],fs[N],se[N],lst[N],cls[N];
vector<int>v[N];
void pushup(int p) {
mx[p]=max(mx[ls],mx[rs]); mn[p]=min(mn[ls],mn[rs]); sum[p]=sum[ls]+sum[rs];
}
void pushdown(int l,int r,int p) {
if(cov[p]) {
int mid=(l+r)>>1;
int d=cov[p];
mn[ls]=mx[ls]=d; sum[ls]=1ll*d*(mid-l+1); cov[ls]=d;
mn[rs]=mx[rs]=d; sum[rs]=1ll*d*(r-mid); cov[rs]=d;
cov[p]=0;
}
}
void build(int l,int r,int p) {
if(l==r) {
mx[p]=mn[p]=sum[p]=l; return ;
}
int mid=(l+r)>>1;
build(l,mid,ls); build(mid+1,r,rs);
pushup(p);
}
void update(int l,int r,int x,int y,int v,int p) {
if(mn[p]>=v) return ;
if(x<=l&&y>=r&&mx[p]<=v) {
mn[p]=mx[p]=v; sum[p]=1ll*(r-l+1)*v; cov[p]=v; return ;
}
pushdown(l,r,p);
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,v,ls);
if(y>mid) update(mid+1,r,x,y,v,rs);
pushup(p);
}
int main() {
scanf("%d",&n);
int i,maxn=0,j;
for(i=1;i<=n;i++) scanf("%d",&a[i]),maxn=max(maxn,a[i]);
for(i=1;i<=maxn;i++) {
for(j=0;j<=maxn;j+=i) {
v[j].push_back(i);
}
}
for(i=1;i<=n;i++) {
int lim=v[a[i]].size();
for(j=0;j<lim;j++) {
int tmp=v[a[i]][j];
cnt[tmp]++;
cls[tmp]=lst[tmp];
lst[tmp]=i;
if(cnt[tmp]==1) fs[tmp]=i;
if(cnt[tmp]==2) se[tmp]=i;
}
}
ll tot=n*(n+1);
build(1,n,1); h[maxn]=tot-sum[1];
ll ans=0;
for(i=maxn;i;i--) {
if(cnt[i]>=2) {
// printf("%d %d %d %d\n",fs[i],se[i],cls[i],lst[i]);
update(1,n,se[i]+1,n,n+1,1);
update(1,n,fs[i]+1,se[i],lst[i],1);
update(1,n,1,fs[i],cls[i],1);
}
h[i-1]=tot-sum[1];
// printf("%lld\n",h[i-1]);
ans+=i*(h[i]-h[i-1]);
}
// puts("________________");
// for(i=1;i<=20;i++) printf("%lld\n",h[i]);
// for(i=1;i<maxn;i++) ans+=(i)*(h[i+1]-h[i]);
printf("%lld\n",ans);
}

CF上的3道小题(1)的更多相关文章

  1. CF上的3道小题(2)

    CF上的3道小题(2) T1:CF630K Indivisibility 题意:给出一个数n,求1到n的数中不能被2到9中任意一个数整除的数. 分析:容斥一下,没了. 代码: #include < ...

  2. 关于SQL的几道小题详解

    关于SQL的几道小题详解 当我们拿到题目的时候,并不是急于作答,那样会得不偿失的,而是分析思路,采用什么方法,达到什么目的,还要思考有没有简单的方法或者通用的方法等等,这样才会达到以一当十的效果,这样 ...

  3. 逛园子,看到个练习题,小试了一把(淘宝ued的两道小题)

    闲来无事,逛园子,充充电.发现了一个挺有意思的博文,自己玩了一把. 第一题:使用 HTML+CSS 实现如图布局,border-widht 1px,一个格子大小是 60*60,hover时候边框变为橘 ...

  4. 【cpp上】课后正误小题

    State whether each of the following is true or false. If false, explain why. Assume the state ment u ...

  5. 清橙A1206.小Z的袜子 && CF 86D(莫队两题)

    清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...

  6. 各位大佬Python的第一部分道基础题已经整理好了,希望大家面试的时候能用的上。

    Python的第一部分道基础题,希望大家面试的时候能用的上. 1.为什么学习Python? Python是目前市面上,我个人认为是最简洁.最优雅.最有前途.最全能的编程语言,没有之一. 2.通过什么途 ...

  7. lettcode 上的几道哈希表与链表组合的数据结构题

    目录 LRU缓存 LFU缓存 全O(1)的数据结构 lettcode 上的几道哈希表与链表组合的数据结构题 下面这几道题都要求在O(1)时间内完成每种操作. LRU缓存 LRU是Least Recen ...

  8. 常让人误解的一道js小题

    一道小题引发的深思 今天无意中看到一个js笔试题,不由得想起初学js那会被各种题目狂虐的心酸,虽说现在也会被笔试题所虐,但毕竟比之前好了很多,下面就是我的个人理解,欢迎拍砖.指正: var x = 1 ...

  9. [2]十道算法题【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

随机推荐

  1. hdu 2126背包问题

    /*有n件物品,旅客一共有m块大洋.第一个问题,旅客最多可以买多少件物品?请注意,这里是多少件,不是价值最大.所以这个非常好求,将所有的物品按照价值排序,先买便宜的,再买贵的.贪心的思想.这个地方有些 ...

  2. Eclipse安装插件长时间停留在calculating requirements and dependencies

    如果安装插件的时候,Eclipse花费了很长的时间calculating requirements and dependencies(计算需求和依赖性 ) 这个问题通常就是在点击安装之后显示" ...

  3. [NOIP2002] 提高组 洛谷P1033 自由落体

    题目描述 在高为 H 的天花板上有 n 个小球,体积不计,位置分别为 0,1,2,….n-1.在地面上有一个小车(长为 L,高为 K,距原点距离为 S1).已知小球下落距离计算公式为 d=1/2*g* ...

  4. Codeforces914E. Palindromes in a Tree

    n<=100000的树,每个点上有个字母a-t之一,问有多少这样的链经过每个点:它的某一个排列的字母串起来是回文的. 就是有最多一个字母是奇数个啦..这样点分算一波即可..细节较多详见代码 #i ...

  5. eslint (js代码检查)

    eslint 是一个应用广泛的javascript代码检查工具. 能检测变量名重复等等... 1.安装 npm install -g eslint 2.初始化 会在当前目录下生成一个.eslintrc ...

  6. ViewPager与Fragment刷新数据

    唉,每次都忘记怎么写,还是老老实实记一下吧! public class MDTabViewPagerAdapter extends FragmentStatePagerAdapter { privat ...

  7. Spring Cloud(8):Sleuth和Zipkin的使用

    场景: 某大型电商网站基于微服务架构,服务模块有几十个. 某天,测试人员报告该网站响应速度过慢.排除了网络问题之后,发现很难进一步去排除故障. 那么:如何对微服务的链路进行监控呢? Sleuth: 一 ...

  8. Java实验--继承与多态

    ---恢复内容开始--- 题目如下: [实验任务一]:面积计算(设计型). 1. 实验要求: 实验报告中要求包括程序设计思想.程序流程图.源代码.运行结果截图.编译错误分析等内容. 2.实验内容: ( ...

  9. RESTful API设计规范收集

    说明:其实没有绝对的规范,达到90%即可. 理解RESTful架构:http://www.ruanyifeng.com/blog/2011/09/restful.html RESTful API 设计 ...

  10. SQL根据某一父节点查询所有子节点,无限

    ;with cte as( select id,ParentCategoryId from Category where id = 17 union all select a.id,a.ParentC ...