懒狗闪总开完组会不打CF直接滚去睡觉了可海星,感觉我好像退化成我们队训练最少的人了
赛后补了下发现这场题竟然都会做,不过F不知道是我实现有问题常数大得一批加了读优才惊险卡过
签到,找到中位数后面与它相同的数的个数即可
找出最大子段和S后,显然每次就是把S插入到能和原来的最大子段和一起统计的位置
最后答案就是(2k−1)×S+∑ni=1ai
最小值最大一眼二分答案x,考虑如何check
不妨选择任意一个点为根把树变成有根树,考虑从叶子往上贪心,如果存在某个点子树大小≥x就直接砍掉它和父亲的边
不难发现这样一定是最优的,最后检验下是否砍掉了k条边以及最后顶上留下的部分大小是否≥x即可
同时显然这个贪心过程对于任意点为根都能跑出正确的策略,因此可以随便选
经典二进制操作,上来先考虑从高到低依次处理
不难发现对于某个二进制位2p,若序列中这一位为1的数有奇数个,则不管怎么划分最后这一位上一定为1
否则如果这一位为1的数有偶数个,只要把这些数偶数个分为一组即可,由于这题要求划分数量最多,因此显而易见的把相邻的两两合并即可
注意到在任意一个时刻,如果我们凑出了<x的数那么直接退出统计答案一定最优,否则如果前缀相等则还需要往后讨论后面的位带来的影响
暴力处理分组过程,复杂度O(nlogai)
感觉算是我最近见到的最简单的计数题了,一眼秒的那种
首先如果前缀最大最后的位置和后缀最大第一个位置的值不同,则显然无解,同时还有些trivial的无解情况也一起顺手判掉
否则我们可以确定最大数n所在的位置x,首先需要一个把剩下的n−1个数分到两边的方案数,就是Cx−1n−1
然后此时每一边的问题独立,以前缀这一段为例
我们从后往前枚举前缀最大值的位置,显然当前最大的数的位置唯一确定了,但该位置到x这一段中间的数方法是任意的
刚开始傻逼了这里乘了个组合数上去,后面过不了样例才发现原来是还得乘一个随便放顺序的排列数
后缀的处理同理,最后把每部分的方案数乘起来即可
很套路的一个题
首先对于只选一个数的情况特别考虑,然后我们发现对于某个固定的右端点,其合法的左端点选法是log级别的
因此如果我们把以l为开头,r为结尾的选法的方案数统计出来,最后就是个询问[L,R]包含的所有子区间的贡献和,这个是个经典的扫描线问题
现在的问题是如何计算l,r的贡献,这个也很好办,我们对于每个r按照l降序DP一下即可
具体实现看代码,复杂度O(nlog2n)
#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define int long long
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=1e6+5;
int t,n,q,a[N],pos[N],ans[N],l,r; vector <int> frac[N]; vector <pi> evt[N];
#define Tp template <typename T>
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
#define pc(ch) (Ftop!=Fend?*Ftop++=ch:(fwrite(Fout,1,S,stdout),*(Ftop=Fout)++=ch))
char Fin[S],Fout[S],*A,*B,*Ftop,*Fend; int pt[30];
public:
inline FileInputOutput(void) { Ftop=Fout; Fend=Fout+S; }
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
Tp inline void write(T x,const char ch='\n')
{
if (x<0) x=-x,pc('-');
RI ptop=0; while (pt[++ptop]=x%10,x/=10);
while (ptop) pc(pt[ptop--]+48); pc(ch);
}
inline void flush(void)
{
fwrite(Fout,1,Ftop-Fout,stdout);
}
#undef tc
#undef pc
}F;
inline void init(CI n)
{
for (RI i=1;i<=n;++i) for (RI j=i;j<=n;j+=i) frac[j].push_back(i);
}
class Tree_Array
{
private:
int bit[N];
public:
#define lowbit(x) (x&(-x))
inline void init(CI n)
{
for (RI i=1;i<=n;++i) bit[i]=0;
}
inline void add(RI x,CI y)
{
for (;x;x-=lowbit(x)) bit[x]+=y;
}
inline int get(RI x,int ret=0)
{
for (;x<=n;x+=lowbit(x)) ret+=bit[x]; return ret;
}
#undef lowbit
}BIT;
signed main()
{
for (F.read(t),init(1e6);t;--t)
{
RI i,j,k; for (F.read(n),F.read(q),i=1;i<=n;++i)
F.read(a[i]),pos[a[i]]=i,evt[i].clear();
for (i=1;i<=n;++i)
{
vector <int> lpos;
for (auto x:frac[a[i]])
if (pos[x]<i) lpos.push_back(pos[x]);
vector <int> dp(lpos.size());
sort(lpos.begin(),lpos.end());
for (j=(int)lpos.size()-1;j>=0;--j)
for (dp[j]=1,k=j+1;k<lpos.size();++k)
if (a[lpos[k]]%a[lpos[j]]==0) dp[j]+=dp[k];
for (j=0;j<lpos.size();++j)
evt[i].push_back({lpos[j],dp[j]});
}
for (i=1;i<=q;++i) F.read(l),F.read(r),ans[i]=r-l+1,evt[r].push_back({l,-i});
for (BIT.init(n),i=1;i<=n;++i)
for (auto [x,y]:evt[i]) if (y>0) BIT.add(x,y); else ans[-y]+=BIT.get(x);
for (i=1;i<=q;++i) F.write(ans[i]," \n"[i==q]);
}
return F.flush(),0;
}
接下来几天要忙CCPC Final的事情,估计没啥时间写题了的说
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
2018-03-27 BZOJ 1001: [BeiJing2006]狼抓兔子
2018-03-27 Luogu P1231 教辅的组成