由于考试是真彻底结束了,但队友都还没考完,这两天没事只能VP下之前没打的比赛
这场总体感觉题好水,如果不是E想复杂了导致写了1h然后卡常卡了挺久,F看一眼就会了15min就能写完,感觉有机会2h内AK的
签到,贪心让原来分数高的队先得分是最优的
我们可以先重复进行这样一个暴力过程,每次找到 x 下一个能被 y 整除的数,然后变换过去
不发现这个过程在重复 √x 级别后 x 就会变成 1,剩下的部分是个 1→k→1 的循环,可以直接求解
拿个队列维护下当前极长的且未被选择的段,考虑当选中的值之和 ≥l 时直接贪心地划分掉一定是最优的
同时当出现选中的值之和 >r 的情形时从队首弹出元素即可,总复杂度 O(n)
很显然的一个题,不妨令 diff 为初始时两种贡献的差值的绝对值
对于每个 k×k 的子矩阵,可以用二维前缀和求出它内部两种颜色的差值 ci,不难发现每个子矩阵造成的贡献一定是 ci 的倍数
由裴蜀定理,设 g=gcd(ci),则有解的充要条件为 g∣diff,模拟上述过程即可
感觉我又把简单题做复杂了,没去写数位DP去写了个很神秘的东西,最后常数还贼大卡了半天,只能说不愧是我
首先不难想到倍增,假设之前求出了 [0,2m−1] 中,贡献为 0,1,2,…,k 的答案
则后面一段 [2m,2m+1−1] 内部的 贡献为 0,1,2,…,k 的答案后可以直接拿来用,剩下的就是考虑左端点在 [0,2m−1] 中,右端点在 [2m,2m+1−1] 中的贡献了
不妨直接枚举计算贡献 ≤i 的方案数,最后差分计算具体的方案数即可
这个问题等价于在某个区间 [l,r] 中找到最小/最大的 x 满足 bit(x)>i,利用一些二进制的性质我们可以 O(k) 直接求解
最小的就是把 l 的后缀依次改成全 1;最大的就有些麻烦,需要找到 r 中所有 0 出现的位置然后把低位填成 1;这部分的具体实现可以看代码
然后直接做复杂度是单组数据 O(k3) 的,但我们可以把倍增过程预处理一下得到一个 O(k3+t×k2) 的做法,卡卡常数可以通过
#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 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 mod=1e9+7;
int t,k; LL n; array <int,61> f[65]; map <LL,array <int,61>> rst;
inline void inc(int& x,CI y)
{
if ((x+=y)>=mod) x-=mod;
}
inline void dec(int& x,CI y)
{
if ((x-=y)<0) x+=mod;
}
inline int find_lst(const LL& l,const LL& r,CI k)
{
LL x=r; int cnt=__builtin_popcountll(x);
if (cnt>k) return 0;
for (RI i=0;i<60;++i)
if ((x>>i)&1)
{
--cnt; x^=(1LL<<i);
if (cnt+i>k)
{
x|=((1LL<<i)-1);
if (x<l) return (r-l+1)%mod;
else return (r-x)%mod;
}
}
return (r-l+1)%mod;
}
inline int find_fst(const LL& l,const LL& r,CI k)
{
LL x=l; int cnt=__builtin_popcountll(x);
if (cnt>k) return 0;
for (RI i=0;i<60;++i)
{
if ((x>>i)&1) --cnt,x^=(1LL<<i);
if (cnt+i+1>k)
{
x|=((1LL<<i+1)-1);
if (x>r) return (r-l+1)%mod;
else return (x-l)%mod;
}
}
return (r-l+1)%mod;
}
inline void init(void)
{
array <int,61> v={0}; v[0]=1; f[0]=v;
LL x=0; for (RI i,j=1;j<61;x=x*2+1,++j)
{
array <int,61> u={0};
for (u[0]=0,i=1;i<61;++i) u[i]=v[i-1];
for (i=1;i<61;++i) inc(v[i],u[i]);
for (i=1;i<61;++i) u[i]=1LL*find_lst(0,x,i)*find_fst(x+1,x*2+1,i)%mod;
for (i=60;i>=1;--i) dec(u[i],u[i-1]);
for (i=1;i<61;++i) inc(v[i],u[i]);
f[j]=v;
}
}
inline array <int,61> solve(const LL& n)
{
if (rst.count(n)) return rst[n];
int k=__lg(n+1); LL x=(1LL<<k)-1;
if (n==x) return rst[n]=f[k]; else
{
RI i; array <int,61> v=f[k],tmp=solve(n-x-1),u={0};
for (u[0]=0,i=1;i<61;++i) u[i]=tmp[i-1];
for (i=1;i<61;++i) inc(v[i],u[i]);
for (i=1;i<61;++i) u[i]=1LL*find_lst(0,x,i)%mod*find_fst(x+1,n,i)%mod%mod;
for (i=60;i>=1;--i) dec(u[i],u[i-1]);
for (i=1;i<61;++i) inc(v[i],u[i]);
return rst[n]=v;
}
}
int main()
{
for (scanf("%d",&t),init();t;--t)
{
scanf("%lld%d",&n,&k);
array <int,61> tmp=solve(n-1); int ans=0;
for (RI i=0;i<=k;++i) inc(ans,tmp[i]);
printf("%d\n",ans);
}
return 0;
}
很丁真的一个题,我们可以大力维护出数组中所有 ai>ai+1 的位置 i 的集合 S,显然如果不存在这样的位置就说明数组有序
否则令 l=min(S),r=max(S)+1,显然要操作的区间至少得包含 [l,r],不妨令 mn=minl≤i≤rai,mx=maxl≤i≤rai
由于分界点的性质,[1,l−1],[r+1,n] 都是单调不降的连续段,因此最后要保留的前缀/后缀就很好计算了,直接在对应的部分里二分一下即可
单点修改和区间最值查询用线段树维护,总复杂度 O(nlogn)
#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 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=500005,INF=1e9;
int t,n,a[N],q,x,y; set <int> s;
class Segment_Tree
{
private:
int mn[N<<2],mx[N<<2];
public:
#define TN CI now=1,CI l=1,CI r=n
#define LS now<<1,l,mid
#define RS now<<1|1,mid+1,r
inline void updata(CI pos,CI mv,TN)
{
if (l==r) return (void)(mn[now]=mx[now]=mv); int mid=l+r>>1;
if (pos<=mid) updata(pos,mv,LS); else updata(pos,mv,RS);
mn[now]=min(mn[now<<1],mn[now<<1|1]);
mx[now]=max(mx[now<<1],mx[now<<1|1]);
}
inline int query_min(CI beg,CI end,TN)
{
if (beg<=l&&r<=end) return mn[now]; int mid=l+r>>1,ret=INF;
if (beg<=mid) ret=min(ret,query_min(beg,end,LS));
if (end>mid) ret=min(ret,query_min(beg,end,RS));
return ret;
}
inline int query_max(CI beg,CI end,TN)
{
if (beg<=l&&r<=end) return mx[now]; int mid=l+r>>1,ret=-INF;
if (beg<=mid) ret=max(ret,query_max(beg,end,LS));
if (end>mid) ret=max(ret,query_max(beg,end,RS));
return ret;
}
#undef TN
#undef LS
#undef RS
}SEG;
inline void solve(void)
{
if (s.empty()) return (void)(puts("-1 -1"));
int l=*s.begin(),r=*s.rbegin()+1;
int mn=SEG.query_min(l,r),mx=SEG.query_max(l,r);
if (mn<a[1]) l=1; else l=upper_bound(a+1,a+l,mn)-a;
if (mx>a[n]) r=n; else r=lower_bound(a+r+1,a+n+1,mx)-a-1;
printf("%d %d\n",l,r);
}
int main()
{
for (scanf("%d",&t);t;--t)
{
RI i; for (scanf("%d",&n),i=1;i<=n;++i)
scanf("%d",&a[i]),SEG.updata(i,a[i]);
for (s.clear(),i=1;i<n;++i) if (a[i]>a[i+1]) s.insert(i);
for (solve(),scanf("%d",&q),i=1;i<=q;++i)
{
scanf("%d%d",&x,&y);
if (x+1<=n&&a[x]>a[x+1]) s.erase(x);
if (x-1>=1&&a[x-1]>a[x]) s.erase(x-1);
a[x]=y; SEG.updata(x,a[x]);
if (x+1<=n&&a[x]>a[x+1]) s.insert(x);
if (x-1>=1&&a[x-1]>a[x]) s.insert(x-1);
solve();
}
}
return 0;
}
继之前给祁神的几何专题胡了几个题面后,徐神也找我外包字符串的题面了,感觉能编题题面的Gal库存要不足了的说
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2018-07-02 QZEZ第一届“饭吉圆”杯程序设计竞赛
2018-07-02 Luogu P2286 [HNOI2004]宠物收养场