2019.3.2 提高B组T3 SSL-1298 网站计划

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/88078045

D e s c r i t p i o n Descritpion

写一种数据结构,要求支持查询区间最大值并删除它

数据范围:
1 n , m 200000 , 1 L r n , 1 v [ i ] 100000 1\leq n,m\leq 200000,1\leq L\leq r\leq n,1\leq v[i]\leq 100000


S o l u t i o n Solution

区间最大值线段树咯(ST表不能修改呀QWQ)

对于删除,我们只需要记录区间最大值的位置即可

但是本人只打过函数的板子,懒得改成过程。。。

于是乎,带参线段树(结构体+线段树)闪亮登场,十分好用(其实可以用 z k w zkw 啦,但是我菜呀QWQ)

因为我们是用结构体去做的,所以那个最大值的函数也要用结构体传。


40分暴力 C o d e Code

#include<cstdio>
#include<cctype>
using namespace std;int n,a[200001],m,mii,l,r,ans;
inline long long read()
{
    char c;int d=1;long long f=0;
    while(c=getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
signed main()
{
	freopen("1.txt","r",stdin);
	freopen("1.ans","w",stdout);
	n=read();m=read();
	for(register int i=1;i<=n;i++) a[i]=read();
	while(m--)
	{
		l=read();r=read();
		mii=r;
		for(register int i=l;i<r;i++) if(a[i]>a[mii]) mii=i;
		(ans+=(l+r)%2011*a[mii]%2011)%=2011;
		a[mii]=0;
	}
	printf("%d",ans%2011);
}

A c c e p t e d   C o d e Accepted\ Code

#include<cstdio>
#include<cctype>
#include<algorithm>
#define lson (k<<1)
#define rson (k<<1|1)
using namespace std;int n,ans,l,r,m;
struct node{int num,id;}maxn[800001],nmax;
inline long long read()
{
    char c;int d=1;long long f=0;
    while(c=getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
inline node max(node x,node y){if(x.num>y.num||x.num==y.num&&x.id<y.id) return x;else return y;}//定义结构体上的最大值,这里也可以用operator。
inline void up(int k)//向上更新maxn数组。再有相同数的情况下,优先选择左边的。
{
	if(maxn[lson].num>=maxn[rson].num) maxn[k]=maxn[lson];
	else maxn[k]=maxn[rson];
	return;
}
inline void build(int k,int l,int r)//建树,记得上传命令。
{
	if(l==r) {maxn[k].num=read();maxn[k].id=l;return;}
	int mid=l+r>>1;
	build(lson,l,mid);build(rson,mid+1,r);
	up(k);
	return;
}
inline node askmax(int k,int l,int r,int ql,int qr)//查询区间最大值,并返回其值与其位置
{
	if(ql<=l&&r<=qr) return maxn[k];
	int mid=l+r>>1;
	if(qr<=mid) return askmax(lson,l,mid,ql,qr);
	if(ql>mid) return askmax(rson,mid+1,r,ql,qr);
	return max(askmax(lson,l,mid,ql,mid),askmax(rson,mid+1,r,mid+1,qr));
}
inline void del(int k,int l,int r,int x)//删除位于x这个位置的数,时间复杂度logn
{
	if(l==r){if(x==l){maxn[k].num=0;maxn[k].id=l;}up(k);return;}
	int mid=l+r>>1;
	if(x<=mid) del(lson,l,mid,x);else del(rson,mid+1,r,x);
	up(k);
	return;
}
signed main()
{
	freopen("1.txt","r",stdin);
	freopen("1.out","w",stdout);
	n=read();m=read();
	build(1,1,n);
	while(m--)
	{
		l=read();r=read();
		nmax=askmax(1,1,n,l,r);
		(ans+=(l+r)%2011*nmax.num%2011)%2011;
		if(nmax.id) del(1,1,n,nmax.id);
	}
	printf("%d",ans%2011);
}

R a n d   D a t a   A n d   D P   C o d e Rand\ Data\ And\ DP\ Code

#include<ctime>
#include<cstdio>
#include<cstdlib>
using namespace std;int l,r;
signed main()
{
	freopen("1.txt","w",stdout);
	srand(unsigned(time(0)));
	printf("5 5\n");
	for(register int i=1;i<6;i++) printf("%d ",1+rand()%10);
	putchar(10);
	for(register int i=1;i<6;i++)
	{
		l=1+rand()%5;r=1+rand()%5;
		if(l>r) l^=r,r=l^r,l^=r;
		printf("%d %d\n",l,r);
	}
}

#include<ctime>
#include<cstdio>
#include<cstdlib>
using namespace std;
signed main()
{
	while(1)
	{
		system("rand.exe");
		system("wljh.exe");
		system("bl.exe");
		if(system("fc 1.ans 1.out")) return puts("WA")&0;
		
	}
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/88078045