Codeforces Round #271 (Div. 2) F ,E, D, C, B, A
前言:最近被线段树+简单递推DP虐的体无完肤!真是弱!
A:简单题,照着模拟就可以,题目还特意说不用处理边界
B:二分查找即可,用lower_lound()函数很好用
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<string>
#include<iostream>
using namespace std;
#define N 200005
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1 int a[N],s[N];
int main()
{
int n;
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&a[i]); for (int i=;i<=n;i++)
a[i]+=a[i-];
int m;
scanf("%d",&m);
while (m--)
{
int x;
scanf("%d",&x);
int p=lower_bound(a+,a+n+,x)-a;
printf("%d\n",p);
}
C:没写,但是是一道比较难处理的模拟题吧,求每个点绕它中轴点顺时针旋转90度,求能形成的最小旋转次数,4^4次,还有面积要大于0这个坑点。
D:简单DP,居然推到数学公式,真是SB,我们要使连续的字符串里面个W个数为x*k;当时想到求排列组合,以为可以化简,结果自己掉坑里!
正确做法,定义一维数组,就是求前导和。
方程:DP[I]=DP[I-1]+DP[I-K];(i>=k);(表示:I不为好的话,和为好的发时的总数)
DP[I]=DP[I-1];
s[i]=s[i-1]+DP[I]; (对前i段累加)
中间有Mod 操作,有很多询问,所以要一次做,然后之间求区间值即可!
#include<bits/stdc++.h>
typedef long long ll;
using namespace std; #define mod 1000000007
#define N 100007
int a[N];
ll s[N]; int main()
{
int k,t;
scanf("%d%d",&t,&k);
a[]=;
for (int i=;i<N;i++)
{
if (i>=k) {a[i]=a[i-]+a[i-k];a[i]%=mod;}
else {a[i]=a[i-];a[i]%=mod;} s[i]=s[i-]+a[i];
s[i]%=mod;
} while (t--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",(s[y]-s[x-]+mod)%mod);
} return ;
E:题目简短,二维可以写出,但会TLE。
然后看到一个神奇骗AC代码,可以看看
include<bits/stdc++.h>
#define N 111111
using namespace std;
typedef long long ll;
int n;
ll h[N],ans[N],next[N];
ll d;
int main()
{
cin>>n>>d;
for (int i=;i<=n;i++)
{
cin>>h[i];
ans[i]=;
next[i]=-;
}
int mx=;
int start=n;
for (int i=n;i>=;i--){
for (int j=i+;j<=min(i+,n);j++)
{
if (abs(h[j]-h[i])>=d&&ans[j]+>ans[i])
{
next[i]=j;
ans[i]=ans[j]+;
}
} if (ans[i]>mx)
{
mx=ans[i];
start=i;
}
} cout<<mx<<endl;
int i=start;
while (i!=-)
{
cout<<i<<" ";
i=next[i];
} return ;
}
它这里限制了第二重循环的次数,实际上可以第二重循环可以弄到300,或者更少,数据太弱吧!
正解:线段树单点跟新+二分!
分析写到代码里吧!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lson l, m,rt<<1
#define rson m+1,r,rt<<1|1
#define N 111111
ll h[N],hh[N],k;
int n;
int pre[N],ss[N];
int sum[N<<];
int dp[N]; void pushup(int rt)//求区间最大值
{
sum[rt]=max(sum[rt<<],sum[rt<<|]);
} void update(int p,int y,int l,int r,int rt)//单点更新
{ if (l==r)
{
if (sum[rt]<y) sum[rt]=y;
return;
}
int m=(l+r)>>;
if (p<=m) update(p,y,lson);
else update(p,y,rson);
pushup(rt);
} //询问L,R区间最大值
int query(int L,int R,int l,int r,int rt)
{
if (R<L) return ;
if (L<=l&&R>=r) return sum[rt]; int m=(l+r)>>;
int ret=;
if (L<=m) ret=query(L,R,lson);
if (m<R) ret=max(ret,query(L,R,rson));
return ret;
} int main()
{
scanf("%d%d",&n,&k);
for (int i=;i<=n;i++)
scanf("%I64d",&h[i]),hh[i]=h[i];
sort(h+,h+n+);
int len=;
for (int i=;i<=n;i++)
if (h[i]!=h[i-]) h[++len]=h[i];//排序处理 int ans=;
//整体说一下思路
//我们先排序出去重,把每个数据抽象变成一个点,然后维护。
//我们知道DP[I]=MAX(DP[J])+1,abs(h[i]-h[j])>=k;
//于是我们在前面找到h[i]-h[j]>=k中左右区间然后跟新,这应该是线段树+DP的共同点
//对H[J]-H[J]>=K同样处理。
for (int i=;i<=n;i++)
{
int l=lower_bound(h+,h+len+,hh[i]+k)-h;//这里的lower_bound与upper_bound不能弄错
int r=len;
int x=query(l,r,,len,);
r=upper_bound(h+,h+len+,hh[i]-k)-h;//求出左右区间,这里得多看看 x=max(x,query(,r-,,len,));
dp[i]=x+;
int y=lower_bound(h+,h+len+,hh[i])-h;
update(y,dp[i],,len,);
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
ll hp=1e17;
int inx=;//输出的处理
for (int i=n;i>=;i--)
{
if (ans==) break;
if (dp[i]==ans&&abs(hh[i]-hp)>=k)
{
hp=hh[i];
ans--;
ss[++inx]=i; }
}
for (int i=inx;i>=;i--) printf("%d ",ss[i]);
return ;
}
F:可以这么认为求出(L,R)区间的GCD,然后问(L,R)有多少个值=GCD();
线段树求GCD()不是难点,
求一段区间有多少值=GCD();要用到神奇处理
int x=upper_bound(a+1,a+n+1,mp(mi,r))-lower_bound(a+1,a+n+1,mp(mi,l));
这里用pair()容器,可以知道有多少个
#include<bits/stdc++.h> #define lson l,m,rt<<1
#define rson m+1,r, rt<<1|1
#define N 111111 #define mp make_pair
using namespace std;
pair<int,int>a[N]; int s[N<<]; int gcd(int x,int y)
{
if (y==) return x;
if (x%y==) return y;
return gcd(y,x%y);
} void pushup(int rt)
{
s[rt]=gcd(s[rt<<],s[rt<<|]);
} void build(int l,int r,int rt)
{
if (l==r)
{
s[rt]=a[l].first;
return;
}
int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
} int query(int L,int R,int l,int r,int rt)
{
if (L<=l&&R>=r)
return s[rt];
int m=(l+r)>>;
int ret=;
if (L<=m) ret=gcd(ret,query(L,R,lson));
if (R>m) ret=gcd(ret,query(L,R,rson));
return ret;
} int main()
{
int n;
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i].first),a[i].second=i;
build(,n,);
sort(a+,a+n+); int Q;
scanf("%d",&Q);
while (Q--)
{
int l,r;
scanf("%d%d",&l,&r);
int mi=query(l,r,,n,);
int x=upper_bound(a+,a+n+,mp(mi,r))-lower_bound(a+,a+n+,mp(mi,l));
printf("%d\n",r-l+-x);
}
return ;
}
Codeforces Round #271 (Div. 2) F ,E, D, C, B, A的更多相关文章
- Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)
题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...
- Codeforces Round #271 (Div. 2) F题 Ant colony(线段树)
题目地址:http://codeforces.com/contest/474/problem/F 由题意可知,最后能够留下来的一定是区间最小gcd. 那就转化成了该区间内与区间最小gcd数相等的个数. ...
- Codeforces Round #271 (Div. 2) F. Ant colony 线段树
F. Ant colony time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Codeforces Round #271 (Div. 2)题解【ABCDEF】
Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces Round #486 (Div. 3) F. Rain and Umbrellas
Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- Codeforces Round #501 (Div. 3) F. Bracket Substring
题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- Codeforces Round #376 (Div. 2)F. Video Cards(前缀和)
题目链接:http://codeforces.com/contest/731/problem/F 题意:有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的 ...
随机推荐
- CKeditor的简单使用
由于项目中要使用ckeditor 做个推荐功能,由于值设定到文本内容,就选择最基本的使用. 使用的版本为当前最新版本4.4.7,你需要下载两部分,一个是前台使用,一个是后台使用, 你可以到我的网盘中下 ...
- Bootstrap 2.3.2学习
1.下载架包,下载编译好的文件,文件目录结构如下所示: bootstrap/ ├── css/ │ ├── bootstrap.css │ ├── bootstrap.min.css ├── js/ ...
- 数据结构学习笔记05图(最小生成树 Prim Kruskal)
最小生成树Minimum Spanning Tree 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 树: 无回路 |V|个顶 ...
- STM32F0xx_PWR低功耗配置详细过程
Ⅰ.概述 今天总结PWR部分知识,请看“STM32F0x128参考手册V8”第六章.提供的软件工程是关于电源管理中的停机模式,工程比较常见,但也是比较简单的一个实例,根据项目的不同还需要适当修改或者添 ...
- uC/OS-II之系统函数20160526
任务管理 1 OSTaskCreate() 建立一个新任务.任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立.中断处理程序中不能 建立任务.一个任务可以为无限循环的结构. 函数原型:I ...
- wpf 在引用外部的资源字典
启动的APP.xaml
- 老工程升级到VS2010或以上时会出现 libc.lib 解决方法
有些网上的工程都比较老,比如用2003之类.一般会有个静态libc.lib.在新版本里已经没有这个库,被微软无情的抛弃. 编译时会出现动态库找不到: 1>LINK : fatal error L ...
- Ubuntu下编译内核
一.下载源代码和编译软件的准备 下载内核源代码:http://www.kernel.org/ 注意,点击2.6.25内核的F版,即完整版. 如果你懒得去网站点联接,运行下列命令: 代码: $cd ~ ...
- JVM学习总结一——内存模型
JVM是java知识体系的基石之一,任何一个java程序的运行,都要借助于他.或许对于我这种初级程序员而言,工作中很少有必要刻意去关注JVM,然而如果能对这块知识有所了解,就能够更清晰的明白程序的运行 ...
- mysql取整,小数点处理函数floor(), round()
mysql数值处理函数floor与round 在mysql中,当处理数值时,会用到数值处理函数,如有一个float型数值2.13,你想只要整数2,那就需要下面的函数floor与round. ...