首页 > 其他分享 >CF1743F Intersection and Union 题解

CF1743F Intersection and Union 题解

时间:2022-11-14 21:37:02浏览次数:49  
标签:end 覆盖 Union 题解 线段 times bmatrix Intersection ll

更好体验
线段的贡献不好统计,考虑统计每一个点在不同情况中的被覆盖次数,那么每个点的被覆盖次数总和即为答案。
设 \(f_{i,j,0/1}\) 表示 \(i\) 点在扫描到线段 \(j\) 时是否被覆盖的情况数量,朴素的转移是暴力枚举每一条线段,方程如下。

当线段 \(j\) 可覆盖点 \(i\) 时

\[f_{i,j,0}=f_{i,j-1,0}+f_{i,j-1,1} \]

\[f_{i,j,1}=2\times f_{i,j-1,0}+2\times f_{i,j-1,1} \]

第一条柿子中,如果 \(i\) 尚未被覆盖,那么必须使用且运算,如果已被覆盖,那么就必须用取反。第二条柿子同理,当 \(i\) 尚未被覆盖,那么可以用或和取反,如果被覆盖,则可以用且和或。

当线段不覆盖 \(i\) 时

\[f_{i,j,0}=3\times f_{i,j-1,0}+f_{i,j-1,1} \]

\[f_{i,j,1}=2\times f_{i,j-1,1} \]

在第一个柿子中,如果 \(i\) 尚未覆盖,三种运算都合法,如果被覆盖就必须且运算。在第二个柿子中只能从已覆盖中转移而来,此时可以用或和取反。


此时留意到这个柿子转移方式一定,符合动态 dp 的形式,考虑用动态 dp 维护。去掉第二维,可将 dp 方程改写为矩阵形式。

\[\begin{bmatrix} f_{i,0}&f_{i,1}\end{bmatrix} =\begin{bmatrix} f_{i-1,0}&f_{i-1,1}\end{bmatrix} \times \begin{bmatrix}1&2\\1&2\\\end{bmatrix} \]

\[\begin{bmatrix} f_{i,0}&f_{i,1}\end{bmatrix} =\begin{bmatrix} f_{i-1,0}&f_{i-1,1}\end{bmatrix} \times \begin{bmatrix}3&0\\1&2\\\end{bmatrix} \]

其中第一个是点被覆盖,第二个是点不被覆盖,
用一个类似差分的方式记录线段的覆盖情况,在端点处修改对应线段的矩阵即可,具体可看代码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
typedef long long ll;
using namespace std;
const ll mod=998244353,N=3e5+100;
vector<ll>inc[N],decd[N];
ll n,m,nn,ans,t1,t2;

struct matrix{
	ll a[3][3];
	void clear(){memset(a,0,sizeof(a));}
	void one(){
		for(ll i=1;i<=2;i++){
			for(ll j=1;j<=2;j++){
				if(i==j)a[i][j]=1;
				else a[i][j]=0;
			}
		}
	}
	
	matrix operator *(const matrix&tmp )const{
		matrix c;
		c.clear();
		for(ll i=1;i<=2;i++)
			for(ll j=1;j<=2;j++)
				for(ll k=1;k<=2;k++)
					(c.a[i][j]+=a[i][k]*tmp.a[k][j]%mod)%=mod;
		return c;
	}
}D,ini;

struct EX_segment_tree{
	matrix f[N<<2];
	
	void modify(ll l,ll r,ll o,const ll &x,const matrix &d){
		if(l==r)f[o]=d;
		else {
			ll mid=(l+r)>>1;
			if(mid>=x)modify(l,mid,o<<1,x,d);
			else modify(mid+1,r,o<<1|1,x,d);
			f[o]=f[o<<1]*f[o<<1|1];
		}
	}
}T;

void non(){
	D.a[1][1]=3,D.a[1][2]=0;
	D.a[2][1]=1,D.a[2][2]=2;
}

void yeh(){
	D.a[1][1]=1,D.a[1][2]=2;
	D.a[2][1]=1,D.a[2][2]=2;
}

int main(){
	cin>>n;
	for(ll i=1;i<=n;i++){
		ll a1,a2;
		scanf("%lld%lld",&a1,&a2);
		if(i==1)t1=a1,t2=a2;
		else {
			inc[a1].push_back(i-1);
			decd[a2+1].push_back(i-1);
		}
		nn=max(nn,a2);
	}
	non();
	for(ll i=1;i<n;i++)T.modify(1,n-1,1,i,D);
	for(ll i=0;i<=nn;i++){
		ini.clear();
		if(i>=t1&&i<=t2)ini.a[1][2]=1;
		else ini.a[1][1]=1;
		yeh();
		for(ll j=0;j<inc[i].size();j++){
			ll x=inc[i][j];
			T.modify(1,n-1,1,x,D);
		}
		non();
		for(ll j=0;j<decd[i].size();j++){
			ll x=decd[i][j];
			T.modify(1,n-1,1,x,D);
		}
		ini=ini*T.f[1];
		(ans+=ini.a[1][2])%=mod;
	}
	cout<<ans;
}

标签:end,覆盖,Union,题解,线段,times,bmatrix,Intersection,ll
From: https://www.cnblogs.com/caijiLYC/p/16890460.html

相关文章

  • LG5283 [十二省联考 2019] 异或粽子 题解
    口胡一个异或经典问题LG5283[十二省联考2019]异或粽子给定一个长为\(n\)的序列,序列一段子区间\([l,r]\)的值为\([l,r]\)范围内所有数异或起来的值。现在求出前......
  • 题解 HDU4035 【Maze】
    postedon2022-08-1712:33:51|under题解|sourceproblemhttps://vjudge.net/problem/HDU-4035SHY在一棵树上随机游走,从根节点出发,每次有\(k_u\)的几率回到根节......
  • ARC 103 /\/\/\/ 题解
    前缀和一下,就好了#include<bits/stdc++.h>usingnamespacestd;typedefunsignedlonglongull;constintN=1e5+99;inta[N],odd[N],even[N];structcmp{ boolo......
  • CSP-S 2022 题解
    T1假期计划\(\ttloj3899\)/\(\ttuoj773\)首先数据规模是\(n\le2500\),提示我们用\(\mathcalO\left(n^2\right)\)的算法。既然是选择\(4\)个互不相同的点,不妨......
  • 题解:【ABC245F】Endless Walk
    题目链接本题解适合像我这样的不具备思维能力的选手。首先根据题意,一个点如果符合要求,那它必然在一个点数大于\(2\)的强联通分量里,因为如果只有一个点它就哪里都去不了......
  • Codeforces 722 F Cyclic Cipher 题解 (同余方程,two-pointers)
    题目链接前两天做过一个题意类似但做法不类似的题在这里首先做这道题需要一个结论:(一元)同余方程组有解的充要条件是方程组中的所有方程两两联立有解。证明两个同......
  • CF1650G 『Counting Shortcuts』 题解
    从洛谷博客那里搬过来的(图论专题本来打算先挑最简单的做,结果做了两个多小时(题意就是让你找从起点\(s\)到终点\(t\)的最短路以及次短路个数,本题次短路长度指的是最短......
  • Codeforces 833 题解
    A\(n\)是奇数时恰好可以用完,\(n\)是偶数时多出来的一块没用,所以直接输出\((n+1)/2\)即可。B每个字符出现次数都小于等于字符总数,令\(\Sigma\)是字符集大小,那显然......
  • CF1292E Rin and The Unknown Flower 题解
    IO交互题fflush(stdout)害人不浅!!1注意到如果我们发起询问C和O就可以花费2的代价知道整个串,不过代价过高,所以我们考虑减小点代价。考虑发起询问CO,CH,CC,这样我......
  • TheNameCalculator题解
    TheNameCalculator题解题目链接:TheNameCalculator题解首先看程序开启的保护,有Canary和NX栈不可执行。IDA打开程序,shift+F12查看字符串,发现有"Hereisyourflag:"。点......