CF1327F AND Segments
CF1327F AND Segments
不难想到按位考虑,把每一位选到最后的答案乘起来。
可以发现,假如一段区间 ,对于第 位,假如 ,那么这一段必须这一位都是 ,否则至少要有一个 。
那么我们先枚举第 位,那么如何确定 的第 位是必须 还是?我们发现,这东西就是个区间覆盖+覆盖完查询,无脑差分即可。
做到这里我就不会了,因为我想到 ,设 为到第 个数字,上一个 的下标是 。
但不会转移。
我们考虑,对于每一个点 ,它的上一个 肯定不能乱选,且上一个 是单调不降的。
考虑 的操作这一位为 ,那么对于 来说,它上一个 可以选择 ,那么至少就是 。
考虑记 表示 的上一个 至少在 处。
考虑转移 ,枚举 。
1.
2. 这里是因为这一段的假如 填 ,那么上一个 应该是 ,所以只能填 ,从前面转移即可。
3. 假如上一个就是它本身,显然当前就是 。
那么,这样会 ,怎么优化呢?
我们发现,实际上很多状态都是承接作用而已。干脆改下定义 为匹配到第 个数字,上一个 的下标是 ,那么每一个按 3 转移即可。注意 前面提到过单调不降,维护个清 0 指针维护操作 1。对于操作 2,因为定义改了,所以这一位不可能是 1。对于这一位强制必须 0 的情况,赋 0 即可。
要学到什么,对于二进制有关的题可以拆位看看,区间覆盖+全局查可以差分,状态太多无用可以考虑改定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include <cstdio> #include <algorithm> #include <iostream> #include <cstring> #include <vector> #include <cmath> #include <queue> #include <map> #define ll long long using namespace std; int rd() { int f=1,sum=0; char ch= getchar (); while (! isdigit (ch)) { if (ch== '-' ) f=-1;ch= getchar ();} while ( isdigit (ch)) {sum=(sum<<3)+(sum<<1)+ch- '0' ;ch= getchar ();} return sum*f; } ll lrd() { ll f=1,sum=0; char ch= getchar (); while (! isdigit (ch)) { if (ch== '-' ) f=-1;ch= getchar ();} while ( isdigit (ch)) {sum=(sum<<3)+(sum<<1)+ch- '0' ;ch= getchar ();} return sum*f; } const int N=( int )(5e5+5),mod=998244353; struct node { int l,r,x; }P[N]; ll f[N],ans=1; int pos[N],a[N],n,K,m; ll sol( int wei) { memset (pos,0, sizeof (pos)); memset (a,0, sizeof (a)); memset (f,0, sizeof (f)); for ( int i=1;i<=m;i++) if ((P[i].x>>wei)&1) a[P[i].l]++,a[P[i].r+1]--; else pos[P[i].r+1]=max(pos[P[i].r+1],P[i].l); for ( int i=2;i<=n+1;i++) a[i]+=a[i-1],pos[i]=max(pos[i],pos[i-1]); f[0]=1; ll sum=1,l=0; for ( int i=1;i<=n+1;i++) { while (l<pos[i]) sum-=f[l],f[l++]=0,sum%=mod; if (a[i]) f[i]=0; else f[i]=sum; sum+=f[i]; sum%=mod; // cout<<f[i]<<endl; } //cout<<f[n+1]<<endl; return f[n+1]; } int main() { n=rd(); K=rd(); m=rd(); for ( int i=1;i<=m;i++) P[i].l=rd(),P[i].r=rd(),P[i].x=rd(); for ( int i=0;i<K;i++) ans=ans*sol(i)%mod; ans=(ans%mod+mod)%mod; printf ( "%lld" ,ans); return 0; } |
__EOF__

本文作者:F x o r G
本文链接:https://www.cnblogs.com/xugangfan/p/15135585.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/xugangfan/p/15135585.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】