BZOJ 4523: [Cqoi2016]路由表

還以爲要可持久化Trie

簡單分析一下發現就是Trie+單調棧

查詢的時候從根向下在Trie上走,每次找到當前節點上滿足條件的最小時間點加到棧裏去

棧中時間點爲遞增序

答案就是棧裏元素的數量

(lower_bound好慢啊,是不是可以直接暴力啊)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define mmt(a,v) memset(a,v,sizeof(a))
#define tra(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
const int N=1000000+5;
int ch[N*32][2],sz,hash[N*32],tot;
vector<int>val[N];
int build(int u){
	if(hash[u])return hash[u];
	return hash[u]=++tot;
}
int find(int u){return hash[u];}
void insert(int *s,int n,int ti){
	int u=0;
	rep(i,1,n){
		if(!ch[u][s[i]])ch[u][s[i]]=++sz;
		u=ch[u][s[i]];
	}
	val[build(u)].push_back(ti);
}
int st[N],tp;
void push(int x){
	while(tp&&x<st[tp])tp--;
	st[++tp]=x;
}
int work(int *s,int n,int a){
	int u=0,last=0;
	rep(i,1,n){
		if(!ch[u][s[i]])return last;
		u=ch[u][s[i]];
		if(find(u)&&val[find(u)][0]<a)last=i;
	}
	return last;
}
int solve(int *s,int n,int a,int b){
	tp=0;
	int u=0,l=work(s,n,a);
	rep(i,1,n){
		if(!ch[u][s[i]])break;
		u=ch[u][s[i]];
		if(i>l&&find(u)){
			int v=find(u);
			int k=lower_bound(val[v].begin(),val[v].end(),a)-val[v].begin();
			if(k!=(int)val[v].size()&&val[v][k]<=b)
			push(val[v][k]);
		}
	}
	return tp;
}
int s[40];
int main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	int n,m=0,a,b,c,d,l,r;scanf("%d",&n);
	char opt[5];
	rep(t,1,n){
		scanf("%s",opt);
		if(opt[0]=='A'){
			scanf("%d.%d.%d.%d/%d",&a,&b,&c,&d,&l);
			per(i,8,1)s[i]=a&1,a>>=1;
			per(i,16,9)s[i]=b&1,b>>=1;
			per(i,24,17)s[i]=c&1,c>>=1;
			per(i,32,25)s[i]=d&1,d>>=1;
			insert(s,l,++m);
		}else{
			scanf("%d.%d.%d.%d %d %d",&a,&b,&c,&d,&l,&r);
			per(i,8,1)s[i]=a&1,a>>=1;
			per(i,16,9)s[i]=b&1,b>>=1;
			per(i,24,17)s[i]=c&1,c>>=1;
			per(i,32,25)s[i]=d&1,d>>=1;
			printf("%d\n",solve(s,32,l,r));
		}
	}
	return 0;
}


發佈了293 篇原創文章 · 獲贊 3 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章