JRKSJ subtask 3 求调
查看原帖
JRKSJ subtask 3 求调
399475
_XHY20180718_楼主2024/8/16 11:00

WA on sub3 第一个点。

思路就是将零散的区间合并,如果区间长度<3直接忽略,接下来将整块区间直接剖分:

设 SS 为区间长度,则此区间总价值:

S=3n,value=3n3S=3n,value=3^\frac{n}{3} S=3n+1,value=4×3n3−1S=3n+1,value=4\times 3^{\frac{n}{3}-1} S=3n+2,value=2×3n−23S=3n+2,value=2\times 3^{\frac{n-2}{3}}

然后区间有时候衔接长度<3,此时做出特殊处理。

#include<bits/stdc++.h>
#define int long long
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
const int N=3e5+5,P=998244353;
int n,m,a[N],ans;
struct node{
	int l,r,len;
	bool operator<(const node &t)
	const {return l<t.l;}
}sq[N];
vector<node>msq;
inline int fpm(int x,int y){
	int res=1;
	for(;y;y>>=1,(x*=x)%=P)
		if(y&1)(res*=x)%=P;
	return res;
}
signed main(){
	cin>>n>>m;ans=1;
	for(int i=1; i<=n; ++i)cin>>a[i];
	for(int i=1; i<=m; ++i){
		cin>>sq[i].l>>sq[i].r,sq[i].len=sq[i].r-sq[i].l+1;
		if(sq[i].len<3)--i,--m;
	}
	sort(sq+1,sq+1+m);
	int nl=sq[1].l,nr=sq[1].r;
	for(int i=2; i<=m; ++i){
		if(nr<sq[i].l){
			msq.push_back({nl,nr,nr-nl+1});
			nl=sq[i].l,nr=sq[i].r;
		}else nr=max(nr,sq[i].r);
	}
	msq.push_back({nl,nr,nr-nl+1});
	bool fl=0;
	for(int i=0; i<msq.size(); ++i){
		if(fl)continue;node ssq=msq[i];
		if(msq[i].r-msq[i+1].l<3&&msq[i].r-msq[i+1].l>=0){
			if(msq[i].len%3==0)
				ssq=msq[i];
			else if(msq[i+1].len%3==0){
				swap(msq[i],msq[i+1]);
				ssq=msq[i];
			}
		}
		if(ssq.len%3==0)(ans*=fpm(3,ssq.len/3))%=P;
		if(ssq.len%3==1)(ans*=4*fpm(3,ssq.len/3-1))%=P;
		if(ssq.len%3==2)(ans*=2*fpm(3,ssq.len/3))%=P;
	}
	cout<<ans<<'\n';
	return 0;
}
2024/8/16 11:00
加载中...