L - Intersection and Union Gym - 103993L (线段树)
题意
给定 个区间。
每个区间可以看成包含区间内的数的集合 。
定义集合的操作有 。其中
给定一系列的操作符号
你需要计算对于 所有的可能下
的和。
其中 表示集合的大小(长度)。
也就问:
op可以是交,并,异或,问种情况的长度之和是多少。
思路1
按平时的经验,当求好多种方案的总答案的时候,往往是把某个单独的可以贡献答案的东西取出来,单独看它可以对答案做出多少贡献。
发现元素最多一共3e5种,所以完全可以枚举每一种元素对答案的贡献。
我们考虑,每个数 p 会出现的最后的集合
(因为我们计算的是集合的大小)
我们设集合之前的集合中,有 个集合有p,有 个集合没有p。
如果 中有数字p,
然后我们分别执行三个操作,我们得到:
有p 的集合,经过 后还会有p
没有p的集合经过 也会有。 (注意 中是有 的)
如果 中没有p,我们可以得到
然后一个想法就出来了,我们用矩阵来进行运算。
思路2
虽然直接矩阵是可以计算的,但是,我们漏了一点,就是进行了i次运算可以得到 个集合。
那么
例如,有个p最后一次出现在S_4中。
则,前面一共有 个集合,和 运算后,有 个集合都含有p。
因为后面就没有拥有p的集合了。那么后面,每经过一个集合,含有p的集合数目就会乘以2,也
就是
。
总结一下就是,如果一个数字最后一次出现在集合 中:
- 前面有 个集合
- 后续需要经过 次乘以
就是最终,含有p这个数字的集合个数。
我们用一个区间赋值保留最大值的线段树进行计算即可。
代码
思路2
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; # define int long long const int N=3e5+10; const int mod=998244353; struct node { int l,r; int maxn; int lazy; }tr[N*4]; void build(int u,int l,int r){ tr[u]={l,r,0,0}; if(tr[u].l==tr[u].r) return; int mid=tr[u].l+tr[u].r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } void modify(int u,int l,int r,int val){ if(tr[u].l>=l && tr[u].r<=r){ tr[u].maxn=val; return; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,val); if(r>mid) modify(u<<1|1,l,r,val); } void query(int u,int l ,int &val){//val这里传地址,函数就不用返回最大值了 val=max(val,tr[u].maxn); //如果没有包含这个l值,结果都是0,只有包含的才不是 if(tr[u].r==tr[u].l) return ; int mid=tr[u].l+tr[u].r>>1; if(l<=mid) query(u<<1,l,val); if(l>mid) query(u<<1|1,l,val); } int qmi(int a,int b){ int ans =1; while(b){ if(b&1) ans=ans*a%mod; b>>=1; a=a*a%mod; } return ans; } signed main() { build(1,0,300000); int n;cin>>n; for(int i=1;i<=n;i++){ int l,r; cin>>l>>r; modify(1,l,r,i); } // cout<<"fs"<<endl; int ans=0; for(int i=0;i<=300000;i++){ int val=0,sum=0; query(1,i,val); if(val==0) continue;//没有出现这个值 if(val==1){//在第1段出现了,后面有n-1个符号 sum=qmi(2,n-1); } else{//后面有n-val个符号,前面有3^(val-2)个集合 sum=qmi(2,n-val+1)*qmi(3,val-2)%mod; sum%=mod; } ans+=sum; ans%=mod; } cout<<ans<<endl; return 0; }
原文
严格鸽https://zhuanlan.zhihu.com/p/574614229
beyond+myself
https://blog.csdn.net/qq_54783066/article/details/127619409?spm=1001.2014.3001.5501
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16849142.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-11-01 解决Visua SC的运行时不能输出数据