1. 程式人生 > >【資料結構】【線段樹】【字串Hash】2018國慶三校聯考D4T3

【資料結構】【線段樹】【字串Hash】2018國慶三校聯考D4T3

題意:

在這裡插入圖片描述

分析:

題解見標籤 (不過這題有非正解方法可以卡過去。。我程式碼附在下面) 正解:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 200010
using namespace std;
typedef unsigned long long ll;
ll seed=233333;
ll tree[MAXN*4]
,tim[MAXN*4],add[MAXN*4]; void pushdown(int l,int r,int id){ if(tim[id]==0) tim[id]=1; if(tim[id]!=1){ if(l!=r){ tim[id*2]*=tim[id]; tim[id*2+1]*=tim[id]; add[id*2]*=tim[id]; add[id*2+1]*=tim[id]; } tim[id]=1; } if(add[id]!=0){ if(l!=r){ add[id*2]+=add[id]; add[id*2+1]+
=add[id]; add[id]=0; } } } void change(int l,int r,int id,int pl,int pr,ll val1,ll val2){ pushdown(l,r,id); if(l>=pl&&r<=pr){ tim[id]=tim[id]*val1; add[id]=add[id]*val1; add[id]=add[id]+val2; return ; } int mid=(l+r)>>1; if(pl<=mid) change(l,mid,id*2,pl,pr,
val1,val2); if(pr>mid) change(mid+1,r,id*2+1,pl,pr,val1,val2); } int Que(int l,int r,int id,ll ans){ pushdown(l,r,id); if(l==r) return add[id]==ans; int mid=(l+r)>>1; return Que(l,mid,id*2,ans)+Que(mid+1,r,id*2+1,ans); } int n,k,m; int l,r,val; int main(){ freopen("deco.in" ,"r",stdin ); freopen("deco.out","w",stdout); SF("%d%d%d",&n,&k,&m); for(int i=1;i<=m;i++){ SF("%d%d%d",&l,&r,&val); change(1,n,1,l,r,seed,val); } ll ans=0; for(ll i=1;i<=k;i++) ans=ans*seed+i; PF("%d",Que(1,n,1,ans)); }

暴力:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 200010
using namespace std;
int n,k,m;
int maxv[MAXN*4],minv[MAXN*4],tag[MAXN*4],add[MAXN*4];
int min1(int x,int y){
	if(x==-1)
		return y;
	if(y==-1)
		return x;
	return min(x,y);	
}
int max1(int x,int y){
	return max(x,y);	
}
void pushdown(int l,int r,int x){
	if(tag[x]==-1){
		if(l!=r){
			tag[x*2]=-1;
			tag[x*2+1]=-1;
		}
		return ;
	}
	if(add[x]!=0){
		if(l!=r){
			maxv[x*2]+=add[x];
			minv[x*2]+=add[x];
			maxv[x*2+1]+=add[x];
			minv[x*2+1]+=add[x];
			add[x*2+1]+=add[x];
			add[x*2]+=add[x];
		}
		add[x]=0;
	}
}
void change(int l,int r,int id,int l1,int r1,int x){
	//PF("{%d %d %d %d %d %d}\n",l,r,id,minv[id],maxv[id],x);
	pushdown(l,r,id);
	if(l>=l1&&r<=r1&&maxv[id]==minv[id]){
		if(maxv[id]!=x){
			maxv[id]=-1;
			minv[id]=-1;
			tag[id]=-1;
		}
		else{
			add[id]++;	
			maxv[id]++;
			minv[id]++;
		}
		return ;
	}
	int mid=(l+r)>>1;
	if(l1<=mid)
		change(l,mid,id*2,l1,r1,x);
	if(r1>mid)
		change(mid+1,r,id*2+1,l1,r1,x);
	minv[id]=min1(minv[id*2],minv[id*2+1]);
	maxv[id]=max1(maxv[id*2],maxv[id*2+1]);
	if(tag[id*2]==-1&&tag[id*2+1]==-1)
		tag[id]=-1;
}
int Que(int l,int r,int id){
	pushdown(l,r,id);
	if(l==r)
		return tag[id]!=-1;
	int mid=(l+r)>>1;
	return Que(l,mid,id*2)+Que(mid+1,r,id*2+1);
}
int main(){
	freopen("deco.in","r",stdin);
	freopen("deco.out","w",stdout);
	int l,r,x;
	SF("%d%d%d",&n,&k,&m);	
	for(int i=1;i<=m;i++){
		SF("%d%d%d",&l,&r,&x);
		change(1,n,1,l,r,x-1);
	}
	change(1,n,1,1,n,k);
	PF("%d",Que(1,n,1));
}