关于刚刚 AT 的 G
  • 板块学术版
  • 楼主PurslaneM2GA
  • 当前回复24
  • 已保存回复24
  • 发布时间2022/8/21 21:48
  • 上次更新2023/10/27 14:15:21
查看原帖
关于刚刚 AT 的 G
120947
PurslaneM2GA楼主2022/8/21 21:48

Rt . 我的思路是 , 线段树每个节点维护每个数的个数 , 以及 Ai=x,Aj=y,i<jA_i = x , A_j = y , i<j 的所有有序对 , 记为 calc[x][y]calc[x][y]

为什么会 挂 ? 而且 , 题解为什么只维护逆序对 ?

code :

#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=1e5+10;
struct Segment {
	int tg,tag[4],cnt[4],calc[4][4];
}t[MAXN<<2];
int n,m,Cnt[4],Calc[4][4],v[MAXN],a[MAXN]; //a[i] i->a[i]
void update_point(int k) {
	memset(Cnt,0,sizeof(Cnt)),memset(Calc,0,sizeof(Calc));
	ffor(i,0,2) Cnt[i]=0;
	ffor(i,0,2) ffor(j,0,2) Calc[i][j]=0;
	ffor(i,0,2) Cnt[a[i]]+=t[k].cnt[i];
	ffor(i,0,2) ffor(j,0,2) Calc[a[i]][a[j]]+=t[k].calc[i][j];
	ffor(i,0,2) t[k].cnt[i]=Cnt[i];
	ffor(i,0,2) ffor(j,0,2) t[k].calc[i][j]=Calc[i][j];
	return ;
}
Segment merge(Segment a,Segment b) {
	memset(Cnt,0,sizeof(Cnt)),memset(Calc,0,sizeof(Calc));
	ffor(i,0,2) Cnt[i]=a.cnt[i]+b.cnt[i];
	ffor(i,0,2) ffor(j,0,2) Calc[i][j]=a.calc[i][j]+b.calc[i][j];
	ffor(i,0,2) ffor(j,0,2) Calc[i][j]+=a.cnt[i]*b.cnt[j];
	Segment res; res.tg=res.tag[0]=res.tag[1]=res.tag[2]=0;
	ffor(i,0,2) res.cnt[i]=Cnt[i];
	ffor(i,0,2) ffor(j,0,2) res.calc[i][j]=Calc[i][j];
	return res;
}	
void push_down(int k,int l,int r) {
	if(t[k].tg) {
		ffor(i,0,2) a[i]=t[k].tag[i];
		update_point(k<<1),update_point(k<<1|1);
		t[k<<1].tg=t[k<<1|1].tg=1; ffor(i,0,2) t[k<<1].tag[i]=t[k<<1|1].tag[i]=t[k].tag[i];
		ffor(i,0,2) t[k].tag[i]=0; t[k].tg=0;
		return ;
	}
	return ;
}
void update(int k,int l,int r,int x,int y,int s,int T,int R) {
	if(x<=l&&r<=y) {
		t[k].tg=1; a[0]=s,a[1]=T,a[2]=R;
		t[k].tag[0]=s,t[k].tag[1]=T,t[k].tag[2]=R;
		update_point(k); 
		return ;
	}
	push_down(k,l,r);
	int mid=l+r>>1;
	if(x<=mid) update(k<<1,l,mid,x,y,s,T,R);
	if(y>mid) update(k<<1|1,mid+1,r,x,y,s,T,R);
	t[k]=merge(t[k<<1],t[k<<1|1]);
	return ;
}
Segment Query(int k,int l,int r,int x,int y) {
	if(x<=l&&r<=y) return t[k];
	push_down(k,l,r);
	int mid=l+r>>1;
	if(y<=mid) return Query(k<<1,l,mid,x,y);
	if(x>mid) return Query(k<<1|1,mid+1,r,x,y);
	return merge(Query(k<<1,l,mid,x,y),Query(k<<1|1,mid+1,r,x,y));
}
void build(int k,int l,int r) {
	if(l==r) {t[k].cnt[v[l]]=1; return ;}
	int mid=l+r>>1; 
	build(k<<1,l,mid),build(k<<1|1,mid+1,r);
	t[k]=merge(t[k<<1],t[k<<1|1]);
	return ;
}
signed main() {
	cin>>n>>m;
	ffor(i,1,n) cin>>v[i];
	build(1,1,n);
	ffor(i,1,m) {
		int op;cin>>op;
		if(op==1) {
			int l,r;cin>>l>>r;
			Segment st=Query(1,1,n,l,r);
			int ans=st.calc[1][0]+st.calc[2][0]+st.calc[2][1];
			cout<<ans<<'\n';
		}
		else {
			int l,r,s,t,u;cin>>l>>r>>s>>t>>u;
			update(1,1,n,l,r,s,t,u);	
		}
	}
	return 0;
}
2022/8/21 21:48
加载中...