A,B,C就不说了,又被D题卡住了.....

感觉怎么说呢,就是题解中的三个提示都已经想到了,就是不知道该怎么解决....

D. Integers Have Friends

简述题意:题目要求你找一个区间\([l,r]\)使得\(a_l\)%m=\(a_{l+1}\)%m=...=\(a_r\)%m。且m>=2,要求能找到的最大区间是多少。

看到取模我的想法就是将其最原本的式子写\(a_l\)=c1m+k,\(a_{l+1}\)=c2m+k,...,\(a_r\)=cn*m+k,考虑他们之间的关系,发现有个相同的余数k,我们做个差分数组,这样他们的k就都抵消了..于是我们惊奇的发现m是他们差分数组的gcd,这样后我们就知道一个区间合法当且仅当这个区间的差分数组的gcd>=2,这样的话我们直接在原数组上做差分。长度变为n-1,题目转化成,我们需要找到一个区间,使得他们的gcd>=2,且长度最大。.....

昨天到这就gg了....找区间的话,无外乎就是固定左端点最最远的右端点,尺取法等操作,考虑尺取法的话确实发现右端点是单调递增的,但左端点移动时我们无法去除左端点的影响,这个方法暂时告歇...接着考虑我们学过的一些数据结构,gcd符合区间加法的原则(广义上的区间加法,即知道了左区间的gcd,右区间的gcd,我们就可以计算出整个区间的gcd了)。这样的话我们就可以用各种结构进行优化试试,首先我们右端点是朴素的从左向右扫的,倍增能不能呢?好像可以,只需要预处理一下就可以了。线段树作为区间之王,行不行?貌似也可以,比如说给定一个l,我们先进入l这个叶子节点,等回溯时,一点点尝试将区间往上叠加,先将右区间全部叠加上看行不行,不行的话再向下搜寻就大概可以了(我码一下试试.).

倍增+ST表

//不等,不问,不犹豫,不回头.
#include
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define RE register
#define P 1000000007
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair
#define PII pair
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(RE int x=y;x<=z;++x)
#define fep(x,y,z) for(RE int x=y;x>=z;--x)
#define go(x) for(RE int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=2e5+10;
int n;
ll a[N],b[N],f[N][22];//f[i][j]表示从第i个数开始,一共2^j个数的gcd的值. inline ll read()

{

ll x=0,ff=1;

char ch=getchar();

while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}

while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}

return x*ff;

} inline ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
int main()

{

// freopen("1.in","r",stdin);

int get(T);

while(T--)

{

get(n);

rep(i,1,n) get(a[i]);

rep(i,1,n-1) b[i]=abs(a[i+1]-a[i]); //注意这里用绝对值,防止出现负数.

rep(i,1,n-1) f[i][0]=b[i];

rep(j,1,20)

rep(i,1,n-1)

{

if(i+(1<<j)-1>n-1) break;

f[i][j]=gcd(f[i][j-1],f[i+(1<<(j-1))][j-1]);

}

ll ans=1;

rep(i,1,n-1)//从i为起点开始向后找.

{

ll gcc=f[i][0],now=i+1;

if(gcc<2) continue;

fep(j,20,0)

{

if(now+(1<<j)-1>n-1) continue;

if(gcd(gcc,f[now][j])>=2)

{

gcc=gcd(gcc,f[now][j]);

now=now+(1<<j);

}

}

ans=max(ans,now-i+1);

}

put(ans);

}

return (0_0);

}

//以吾之血,铸吾最后的亡魂.

线段树由于有巨大的常数,就T掉了,不过打出来还是比较考验码力的...

线段树上二分

//不等,不问,不犹豫,不回头.
#include
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define RE register
#define P 1000000007
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair
#define PII pair
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(RE int x=y;x<=z;++x)
#define fep(x,y,z) for(RE int x=y;x>=z;--x)
#define go(x) for(RE int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=2e5+10;
int n;
ll a[N],b[N];
struct Tree
{
int l,r;
ll dat;//存一个区间所有值得gcd.
#define l(p) t[p].l
#define r(p) t[p].r
#define d(p) t[p].dat
}t[N<<2]; inline ll read()

{

ll x=0,ff=1;

char ch=getchar();

while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}

while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}

return x*ff;

} inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline void build(int p,int l,int r)

{

l(p)=l;r(p)=r;

if(l==r) {d(p)=b[l];return;}

int mid=l+r>>1;

build(ls,l,mid);

build(rs,mid+1,r);

d(p)=gcd(d(ls),d(rs));

} inline int ask(int p,int k,ll &v)

{

if(v0)

{

if(l(p)r(p))

{

v=d(p);

return l(p);

}

int mid=l(p)+r(p)>>1,id=0;

if(k<=mid) id=ask(ls,k,v);

else id=ask(rs,k,v);

if(idr(ls))

{

if(gcd(v,d(rs))>=2)

{

v=gcd(v,d(rs));

return r(rs);

}

else return ask(rs,k,v);

}

else return id;

}

else

{

if(gcd(v,d(p))>=2)

{

v=gcd(v,d(p));

return r(p);

}

else if(l(p)r(p)) return l(p)-1;

else if(gcd(v,d(ls))<2) return ask(ls,k,v);

else

{

v=gcd(v,d(ls));

return ask(rs,k,v);

}

}

}
int main()

{

// freopen("1.in","r",stdin);

int get(T);

while(T--)

{

get(n);

rep(i,1,n) get(a[i]);

rep(i,1,n-1) b[i]=abs(a[i+1]-a[i]);

if(n-1>=1) build(1,1,n-1);

ll ans=1;

rep(i,1,n-1)//枚举每一个左端点。

{

if(b[i]<2) continue;

ll v=0;

ll p=ask(1,i,v);

ans=max(ans,p-i+2);

}

putl(ans);

}

return 0;

}

//以吾之血,铸吾最后的亡魂.

E. The Three Little PigsE. The Three Little Pigs

我脑子有坑...还是读错题了,...每次袭击都一定会袭击x个...我以为每个方案都要袭击若干次...

既然如此那就好办了,我们可以枚举大灰狼在哪一分钟袭击了,然后在这一分钟选出x个就行了,具体来说对于一个询问x而言答案为\(\sum_{i=0}^{n} C_{3*i}^x\)

可这里有q个询问...怎么搞....一般来说,遇到这种数学式子的问题且是组合数,我们需要找到递推式来快速找到答案。因为组合数的种种优美性质,求多个组合数的和时总是能找到递推预处理,然后O(1)的输出答案。一般的我们可以考虑我们已经知道了当前数x的答案,我们思考怎么根据已有的数据快速得到x+1的答案,具体的我们令\(f(x,j)表示\sum_{i=1}^{n} C_{3*i+j}^{x}\),显然\(f(x,0)\)就是每个x的答案,由于\(C_{3*i+j}^{x}=C_{3*i+j-1}^{x}+C_{3*i+j-1}^{x-1}\)

所以有\(f(x,1)=f(x,0)+f(x-1,0)\)

\(f(x,2)=f(x,1)+f(x-1,1)\)

通过简单的容斥(一点都不简单...)发现\(f(x,0)+f(x,1)+f(x,2)=\sum_{i=1}^{n}C_{3*i+0}^{x}+\sum_{i=1}^{n}C_{3*i+1}^{x}+\sum_{i=1}^{n}C_{3*i+2}^{x}=\sum_{i=1}^{n}(C_{3*i+0}^{x}+C_{3*i+1}^{x}+C_{3*i+2}^{x})=\sum_{i=3}^{3*n+2} C_{i}^{x}\)

到这里就停止了吗?不,路还在前方,我们把式子展开一下试试:\(C_x^x+C_{x+1}^x+C_{x+2}^x+...+C_{3*n+2}^x\)我们可以发现\(C_x^x+C_{x+1}^x=C_{x+1}^{x+1}+C_{x+1}^x=C_{x+2}^{x+1}\)哇,这样可以一直合并下去啊!最后的结果呢,就是\(C_{3*n+3}^{x+1}\)

经过一番努力我们得到了\(f(x,0)+f(x,1)+f(x,2)=C_{3*n+3}^{x+1}\)

结合之上的两条\(f(x,1)=f(x,0)+f(x-1,0)\)

\(f(x,2)=f(x,1)+f(x-1,1)\)

我们找出递推式:\(f(x,0)=\frac{C_{3n+3}^{x+1}-f(x-1,1)-2*f(x-1,0)}{3}\)

\(f(x,1)=f(x,0)+f(x-1,0)\)

\(f(x,2)=f(x,1)+f(x-1,1)\)

初值\(f(0,0)=f(0,1)=f(0,2)=n+1\)

目标为\(ans(x)=f(x,0)\)经过离线就可以O(n)解决问题了。

最后来个总结:题目要求\(\sum_{i=0}^{n} C_{3*i}^{x}\)的值,我们肯定不能直接求,显然要利用组合数的一些公式进行化简,但观察组合数的x是不变的,变化的是3*i,我们一方面可以想到他们都是相差3的,我们可以将其中的1,2补齐变成连续的,一方面可以思考组合数的化简公式\(C_n^m=C_{n-1}^{m-1}+C_{n-1}^m\)可以发现下面的n都要变成n-1,这就提示我们要设出\(f(x,j)\)为\(\sum C_{3*i+j}^x\)这样的话我们就可以找到关系了。至于初值为什么要赋成n+1,i=0确实要考虑。

查看代码

//不等,不问,不犹豫,不回头.
#include
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair
#define PII pair
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(int x=y;x<=z;++x)
#define fep(x,y,z) for(int x=y;x>=z;--x)
#define go(x) for(RE int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=1e6+10,P=1e9+7;
int n,m;
ll jc[3*N],inv_jc[3*N],f[N*3][3]; inline int read()

{

int x=0,ff=1;

char ch=getchar();

while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}

while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}

return x*ff;

} inline ll power(ll a,int b)

{

ll ans=1;

while(b)

{

if(b&1) ans=ansa%P;

b>>=1;

a=a
a%P;

}

return ans%P;

} inline void prework()

{

jc[0]=1;inv_jc[0]=1;

int t=3n+3;

rep(i,1,t) jc[i]=jc[i-1]
i%P;

inv_jc[t]=power(jc[t],P-2);

fep(i,t-1,1) inv_jc[i]=inv_jc[i+1]*(i+1)%P;

} inline ll C(int n,int m)

{

if(m>n) return 0;

return jc[n]inv_jc[m]%Pinv_jc[n-m]%P;

}
int main()

{

//freopen("1.in","r",stdin);

get(n);get(m);prework();

f[0][0]=f[0][1]=f[0][2]=n+1;

ll inp=power(3,P-2);

rep(i,1,3n)

{

f[i][0]=((C(3
n+3,i+1)-f[i-1][1]-2f[i-1][0])%P+P)%Pinp%P;

f[i][1]=(f[i][0]+f[i-1][0])%P;

f[i][2]=(f[i][1]+f[i-1][1])%P;

}

rep(i,1,m)

{

int get(x);

putl(f[x][0]);

}

return (0_0);

}

//以吾之血,铸吾最后的亡魂.

PS:此题卡常,请将常数尽可能的减小,当处理1-n的阶乘及逆元时,可以先将n的阶乘的逆元求出来,之后就可以O(n)的预处理逆元了。

Codeforces Round #736 (Div. 2)的更多相关文章

  1. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  2. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  3. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  4. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  5. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  6. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  7. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

  8. Codeforces Round #371 (Div. 1)

    A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...

  9. Codeforces Round #268 (Div. 2) ABCD

    CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...

随机推荐

  1. 学习PHP弱引用的知识

    之前的文章中,我们已经学习过引用和引用传值相关的知识.我们知道,PHP 中没有纯引用(指针),不管是对象,还是用引用符号 & 赋值的变量,都是对一个符号表的引用.而今天,我们要学习的是另一种引 ...

  2. Django边学边记——中间件

    特点 Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,用于全局修改Django的输入或输出. 每个中间件组件负责做一些特定的功能.中间件全部注册在sett ...

  3. js模块化开发 AMD CMD Commonjs

    在es6全面实行开来之前  js实现模块开发方案有: 1.AMD 异步模块开发定义  依赖前置,requireJs应用了这一规范 require([module], callback); 加载完后回调 ...

  4. prometheus+grafana实现服务监控

    一.安装prometheus: 下载相应的版本 :https://prometheus.io/download/ 解压: Linux:tar -zxvf XXX.tar.gz windows:直接下载 ...

  5. 『GoLang』语法基础

    标识符 字母或下划线开头 之后只能出现数字.字母.下划线 大小写敏感 Go语言关键字 break default func interface select case defer go map str ...

  6. centos7 设置dns

    查看当前网络连接 nmcli connection show NAME UUID TYPE DEVICE eth0 5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03 802-3 ...

  7. 纯代码实现wordpress图片本地化【5.2.2版本可用】

    最近用wordpress做了个网站,想复制些新闻过来用,但图片是别人的,就想怎么本地化,在网找到了方法,那就保存一下方法. 复制下面的代码,然后粘贴到你当前WordPress主题的模版函数(funct ...

  8. NOIP 模拟 六十八

    咕了十几场了,还是写一写吧.. T1 玩水 发现满足三个人路径不同必须要有2个及以上的斜线相同结构,需要注意如果同一行或者同一列的话必须要相邻才行. #include<bits/stdc++.h ...

  9. 基于ZooKeeper,Spring设计实现的参数系统

    一.简介 基于ZooKeeper服务端.ZooKeeper Java客户端以及Spring框架设计的用于系统内部进行参数维护的系统. 二.设计背景 在我们日常开发的系统内部,开发过程中最常见的一项工作 ...

  10. DL4J实战之三:经典卷积实例(LeNet-5)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...