修仙录 3.10

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41709770/article/details/88382586

今天又回来了
寝室还不错。

没有课程所以就随便练题
结果谜之卡常wa掉,一下午简直绝望
明明代码都是一样的
大佬们忙着考试只有下次再问了

但是还是自学了一波回文树
所以今天就不改那道题了,把回文树记下来
反正思路挺简单的,就是代码莫名其妙(感觉我被std骗了)
快乐


回文树

–其实和kmp呀,ac自动机很像,可以说是一摸一样了
重点也是那个fail指针,其实整体难度不大
留下一个很清晰的博客
http://blog.csdn.net/u013368721/article/details/42100363

附加自己打的板子

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=3e5+5;

struct plr_tree{
	int next[MAXN][26],fail[MAXN],len[MAXN],sum[MAXN],num[MAXN],s[MAXN];
	int last,n,p;
	int add(int l){
		for(int i=0;i<26;i++) next[p][i]=0;
		sum[p]=num[p]=0,len[p]=l;
		return p++;
	}
	void init(){
		p=n=last=0,s[n]=-1,fail[0]=1;
		add(0),add(-1);
	}
	int get_fail(int x){
		while(s[n-len[x]-1]!=s[n]) x=fail[x];
		return x;
	}
	void extend(int c){
		s[++n]=c;
		int cur=get_fail(last);
		if(!next[cur][c]){
			int now=add(len[cur]+2);
			fail[now]=next[get_fail(fail[cur])][c];
			next[cur][c]=now,num[now]=num[fail[now]]+1;
		}
		last=next[cur][c],sum[last]++;
	}
	void count(){
		for(int i=p-1;i>=0;i--) sum[fail[i]]+=sum[i];
	}
}pt;

char s[MAXN];
int l;
long long ans;

int main(){
	scanf("%s",s);
	l=strlen(s),pt.init();
	for(int i=0;i<l;i++) pt.extend(s[i]-'a');
	pt.count();
	for(int i=0;i<pt.p;i++) ans=max(ans,1ll*pt.sum[i]*pt.len[i]);
	cout<<ans;
	return 0;
}

jzoj 4754 矩阵

http://172.16.0.132/senior/#contest/show/2657/1

–真的要把人气死。
显然,因为权值非负,一个矩阵的权值肯定不比其子矩阵小。那么建立一个堆,开始把
所有最小的和谐矩阵加入堆,每次从堆中取出最小的和谐矩阵,同时扩展出最多2个新的和
谐矩阵(左右二选一,上下二选一),注意判重,重复 k 次即可。
时间复杂度 O(NM+klog(n^2+2k))。

问题就在这个判重,hash,map,set能打的都打了,还是玄学错误

留下两个代码(一个超时,一个wa)
呵呵

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int MAXN=1e3+5;

int n,m,mina,minb,k;
long long ma[MAXN][MAXN];
struct matrix{
	long long sum;
	int x,y,a,b;
	matrix(){x=y=a=b=sum=0;}
	matrix(int x,int y,int a,int b,long long sum):x(x),y(y),a(a),b(b),sum(sum){}
	bool operator <(matrix t)const{
		return sum>t.sum;
	}
};
priority_queue<matrix>q;
typedef pair<int,int>p1;
typedef pair<p1,p1>p2;
map<p2,bool> hash;

long long calc(int x,int y,int a,int b){
	return ma[a][b]-ma[a][y-1]-ma[x-1][b]+ma[x-1][y-1];
}

int main(){
	cin>>n>>m>>mina>>minb>>k;
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
		scanf("%lld",&ma[i][j]);
		ma[i][j]+=ma[i-1][j]+ma[i][j-1]-ma[i-1][j-1];
	}
	for(int i=1;i<=n-mina+1;i++) for(int j=1;j<=m-minb+1;j++){
		int a=i+mina-1,b=j+minb-1;
		q.push(matrix(i,j,a,b,calc(i,j,a,b)));
	}
	k--;
	while(k--){
		matrix t=q.top();q.pop();
		p2 p=make_pair(make_pair(t.x,t.y),make_pair(t.a,t.b));
		while(hash[p]) t=q.top(),q.pop(),p=make_pair(make_pair(t.x,t.y),make_pair(t.a,t.b));
		hash[p]=1;
		if(t.a<n) q.push(matrix(t.x,t.y,t.a+1,t.b,calc(t.x,t.y,t.a+1,t.b)));
		if(t.b<m) q.push(matrix(t.x,t.y,t.a,t.b+1,calc(t.x,t.y,t.a,t.b+1)));
	}
	cout<<q.top().sum;
	return 0;
}

第二个

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int MAXN=1e3+5;

int n,m,mina,minb,k;
long long ma[MAXN][MAXN];
struct matrix{
	long long sum;
	int x,y,a,b;
	matrix(){x=y=a=b=sum=0;}
	matrix(int x,int y,int a,int b,long long sum):x(x),y(y),a(a),b(b),sum(sum){}
	bool operator <(matrix t)const{
		return sum>t.sum;
	}
};
priority_queue<matrix>q;
typedef pair<int,int>p1;
typedef pair<p1,p1>p2;
map<p2,bool> hash;

long long calc(int x,int y,int a,int b){
	return ma[a][b]-ma[a][y-1]-ma[x-1][b]+ma[x-1][y-1];
}

p2 mp(int x,int y,int a,int b){
	return make_pair(make_pair(x,y),make_pair(a,b));
}

bool isu(p2 t){
	if(hash[t]) return 1;
	hash[t]=1;
}

int main(){
	cin>>n>>m>>mina>>minb>>k;
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
		scanf("%lld",&ma[i][j]);
		ma[i][j]+=ma[i-1][j]+ma[i][j-1]-ma[i-1][j-1];
	}
	for(int i=1;i<=n-mina+1;i++) for(int j=1;j<=m-minb+1;j++){
		int a=i+mina-1,b=j+minb-1;
		q.push(matrix(i,j,a,b,calc(i,j,a,b)));
		hash[mp(i,j,a,b)]=1;
	}
	k--;
	while(k--){
		matrix t=q.top();q.pop();
		if(t.a<n&&!isu(make_pair(make_pair(t.x,t.y),make_pair(t.a+1,t.b)))) q.push(matrix(t.x,t.y,t.a+1,t.b,calc(t.x,t.y,t.a+1,t.b))); 
		if(t.b<m&&!isu(make_pair(make_pair(t.x,t.y),make_pair(t.a,t.b+1)))) q.push(matrix(t.x,t.y,t.a,t.b+1,calc(t.x,t.y,t.a,t.b+1)));
	}
	cout<<q.top().sum;
	return 0;
}

jzoj 4744 同余

http://172.16.0.132/senior/#main/show/4744
竟然是做过的
快乐
观察到,其实要求的是某⼀范围内 kp + q 的个数,当 p 较⼤时,k 的取值范围很⼩。不妨
设“较⼤”的界限是 > K。
考虑将问题拆开来并排序,这样每个问题就变成了询问 1 ∼ r 中有多少个 kp + q。维护⼀
个哈希数组,h[i] 表示 i 有多少个;以及⼀个模数数组 g[i][j],表示模 i 为 j 有多少个。
每次指针向右移,直到移动到当前询问的位置,每移⼀次就将这个数分别在两个数组内标
记,复杂度总体是 O (nK)。
每次询问时,对于较⼩的 p 直接在 g 中查询,对于较⼤的 p 枚举 k 并在 h 中查询,复杂度
是 O(m*ai/K)。
可以看出 K =√ai = 100 时最优。

lower_bound大法好

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=1e5+5;

int n,m;
int a[MAXN];
vector<int>v_a[10005],v_b[105][105];
int l,r,p,v;
int ans;

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		v_a[a[i]].push_back(i);
	}
	for(int i=1;i<=100;i++)
		for(int j=1;j<=n;j++)
			v_b[i][a[j]%i].push_back(j);
	int k=0;
	while(m--){
		scanf("%d%d%d%d",&l,&r,&p,&v);
		int L,R;
		if(p<=100){
			if(!v_b[p][v].size()){
				printf("0\n");
				continue;
			}
			L=lower_bound(v_b[p][v].begin(),v_b[p][v].end(),l)-v_b[p][v].begin();
			R=lower_bound(v_b[p][v].begin(),v_b[p][v].end(),r)-v_b[p][v].begin();
			if((!R&&v_b[p][v][R]>r)||L>=v_b[p][v].size()){
				printf("0\n");
				continue;
			}
			while(R>=v_b[p][v].size()||r<v_b[p][v][R])
				R--;
			printf("%d\n",R-L+1);
		}
		else{
			ans=0;
			for(v;v<=10000;v+=p){
				if(!v_a[v].size())
					continue;
				L=lower_bound(v_a[v].begin(),v_a[v].end(),l)-v_a[v].begin();
				R=lower_bound(v_a[v].begin(),v_a[v].end(),r)-v_a[v].begin();
				if((!R&&v_a[v][R]>r)||L>=v_a[v].size())
					continue;
				while(R>=v_a[v].size()||r<v_a[v][R])
					R--;
				ans+=R-L+1;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}

剩下的时间在看省选的题
结果最后都是转去百度补学各种模板。
QAQ
还没打完,但有在学

猜你喜欢

转载自blog.csdn.net/qq_41709770/article/details/88382586
今日推荐