萌新妹子求助裸ST表/kk
查看原帖
萌新妹子求助裸ST表/kk
227728
冰糖鸽子TJ鸽子协会楼主2021/8/11 11:40

RT,ST表做的,样例过了,思路在代码下面wq

5RE 5WA Link

代码有不理解的地方请私信或者在下面 @ 鸽子。有QQ也可以QQ说

谢谢/qq


// Problem: P2471 [SCOI2007]降雨量
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2471
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define M 1000005
int n,m,flag,S,T,fk,ind,w[M],y[M];
int emp[M],lg[M],p2[M],ax[M][25],in[M][25];
struct node
{int dy,v;}dt[M];
map<int,int>val,id;
int main()
{
	memset(in,0x3f3f3f3f,sizeof(in));
	cin>>n; for(int i=0;i<=25;i++) p2[i]=pow(2,i); for(int i=0;i<=M-3;i++) lg[i]=log2(i);
	for(int i=1;i<=n;i++) cin>>dt[i].dy>>dt[i].v,y[i]=dt[i].dy,w[i]=dt[i].v,id[dt[i].dy]=i,ax[i][0]=dt[i].v,val[dt[i].dy]=dt[i].v,emp[i]=(dt[i].dy-dt[i-1].dy==1?1:0),in[i-1][0]=emp[i]; cin>>m;
	for(int i=1;i<=n;i++) for(int j=1;j<=16;j++) ax[i][j]=max(ax[i][j-1],ax[i+p2[j-1]][j-1]);
	for(int i=1;i<n;i++) for(int j=1;j<=16;j++) in[i][j]=min(in[i][j-1],in[i+p2[j-1]][j-1]);
	while(m--)
	{
		cin>>S>>T,flag=0;
		if(!id[T]) {cout<<"maybe"<<endl;continue;}
		ind=lower_bound(y+1,y+1+n,S)-y,flag=(y[ind]!=S?1:0);
		S=ind+1,T=id[T]-1,fk=lg[(T-S+1)];
		ind=max(ax[S][fk],ax[T-p2[fk]+1][fk]);
		S--,fk=lg[(T-S+1)];
		flag=max(flag,min(in[S][fk],in[T-p2[fk]+1][fk])^1);
		cout<<(ind>=w[T+1]?"false":(flag?"maybe":"true"))<<endl;
	}
	return 0;
}
/*
离散化,再用一个emp数组记录相邻两年是否相邻(?)  ST维护区间min/max,
每次询问,二分一下找到L的位置,L的值没给就走到后驱,并且把flag标上
如果R的值没给,直接Maybe,否则,先查询emp的区间min,求出是否有空的年份,有的话flag标上
求降水量的区间max,如果max>=v[R],false,否则,如果flag=1,输出maybe,再否则就输出true
呜呜
*/
2021/8/11 11:40
加载中...