QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#48738#4391. Slayers Comezzxzzx123AC ✓116ms27956kbC++173.5kb2022-09-15 14:02:172022-09-15 14:02:18

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-09-15 14:02:18]
  • Judged
  • Verdict: AC
  • Time: 116ms
  • Memory: 27956kb
  • [2022-09-15 14:02:17]
  • Submitted

answer

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
#define pii pair<ll,ll>
#define x first
#define y second
const int N=1e5+50;
ll a[N],b[N];
ll le[N],ri[N];
pii e[N];
int n,m;
struct node{
	ll val,pos,id;
	bool operator<(const node& a)const {
		return val>a.val;
	}
}li[N],rr[N];
ll g[N];
ll find(ll f[],ll x){
	if(x==f[x])	return x;
	return f[x]=find(f,f[x]);
}
void pre(){
	//提前预处理出这个的况
	for(int i=1;i<=n;i++){
		g[i]=a[i+1]-b[i];//表示的是这个点 
		le[i]=i;
		ri[i]=i;
	}
	//先处理出left
	for(int i=1;i<=m;i++){
		ll now=li[i].val,j=find(le,li[i].pos),id=li[i].id;
		while((j-1)&&now<=g[j-1]){
			int k=find(le,j-1);
			le[j]=k;
			j=k;
		}
		e[id].x=j;
	}
	for(int i=n;i;i--){
		g[i]=a[i-1]-b[i];
	}
	for(int i=1;i<=m;i++){
		ll now=rr[i].val,j=find(ri,rr[i].pos),id=rr[i].id;
		while((j+1<=n)&&now<=g[j+1]){
			int k=find(ri,j+1);
			ri[j]=k;
			j=k;
		}
		e[id].y=j;		
	}
}

struct tree{
	ll l,r,len,flag;
	ll sum,add,mul;//表示的是这个区间的dp值的和 
}t[N<<2];

void sol(tree& a,ll mul,ll add){
	a.sum=(a.sum*mul%mod+add*a.len%mod)%mod;
	a.mul=a.mul*mul%mod;
	a.add=(a.add*mul%mod+add)%mod;
}

void push_down(int p){
	if(t[p].flag){
		sol(t[p<<1],t[p].mul,t[p].add);
		sol(t[p<<1|1],t[p].mul,t[p].add);
		t[p].mul=1,t[p].add=0;
		t[p<<1].flag=t[p<<1|1].flag=1;
		t[p].flag=0;
	}
}//下放的标记 

void push_up(int p){
	t[p].sum=(t[p<<1].sum+t[p<<1|1].sum)%mod;//提供一个答案 
}//只需要进行传递一个操作 

void build(int p,int l,int r){
	//其他的都是只能够不选择
	t[p].flag=t[p].sum=0;
	t[p].add=0;
	t[p].mul=1;//区间乘 
	t[p].l=l,t[p].r=r;
	t[p].len=r-l+1;
	if(l==r){
		return ;
	} 
	int mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	push_up(p);
} 

ll query(int p,int x,int y){
	if(t[p].l>=x&&t[p].r<=y){
		return t[p].sum;
	}
	ll val=0;
	int mid=t[p].l+t[p].r>>1;
	push_down(p);
	if(x<=mid){
		val+=query(p<<1,x,y);
		val%=mod;
	}
	if(y>mid)
	{
		val+=query(p<<1|1,x,y);
		val%=mod;
	}
	return val;
}

void add(int p,int x,ll k)//单点的修改 
{
	if(t[p].l==t[p].r){
		t[p].sum=(t[p].sum+k)%mod;
		return;
	}	
	int mid=t[p].l+t[p].r>>1;
	push_down(p);
	if(x<=mid){
		add(p<<1,x,k);
	}else add(p<<1|1,x,k);
	push_up(p);
}

void update(int p,int x,int y,ll k=2)//区间乘,并且乘的都是2 
{
	if(t[p].l>=x&&t[p].r<=y){
		t[p].flag=1;
		//然后是开始进行相乘
		t[p].mul=t[p].mul*2%mod;
		t[p].add=t[p].add*2%mod;
		t[p].sum=t[p].sum*2%mod; 
		//开始进行操作,打上懒标记
		return; 
	}
	push_down(p);
	int mid=t[p].l+t[p].r>>1;
	if(x<=mid){
		update(p<<1,x,y);
	}
	if(y>mid){
		update(p<<1|1,x,y);
	}
	push_up(p);//记得啊 
}


int main(){
	int tt;
	scanf("%d",&tt);
	while(tt--){
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			scanf("%lld%lld",&a[i],&b[i]);
		}
		ll pos,x,y;
		for(int i=1;i<=m;i++){
			scanf("%lld%lld%lld",&pos,&x,&y);
			li[i]={x,pos,i};
			rr[i]={y,pos,i};
		}
		sort(li+1,li+m+1),sort(rr+1,rr+m+1);
		pre();
		sort(e+1,e+m+1);
		build(1,0,n);
		add(1,0,1);//初始化答案 
		for(int i=1;i<=m;i++){
			int l=e[i].x,r=e[i].y; 
			//对于这个的话都是修改一个恰好的
			//一个是直接加 
			update(1,r,n);//全部都乘上2 
			ll val1=query(1,l-1,r-1);
			add(1,r,val1);//这个是单点修改
			//区间乘
		}
		printf("%lld\n",query(1,n,n));
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 116ms
memory: 27956kb

input:

100
94361 94314
33869598 5185471
618720133 505036749
409602893 40833389
73363932 853969687
132417645 381351032
465347847 676007624
210787499 3355224
991034578 503557482
118882583 12886598
821718576 953581962
979222818 458179522
17341621 962353208
11732262 180321038
947467293 869555337
27442910 91111...

output:

790989612
671747997
0
437770386
293758108
417733173
876589319
754905430
511705067
4194304
908866994
0
362293000
268315788
810816358
587847598
378811885
673322235
478150607
897151370
331537435
714057465
262017639
527438203
922745986
484494985
318652554
331818541
767356752
601981094
34519446
0
5190730...

result:

ok 100 lines