给你一个序列a
每次两个操作:
1.修改x位置的值为y
2.查询区间l,r是否可以重排为值域上连续的一段
输入格式:
第一行两个数n,m
第二行n个数表示a[i]
后面m行每行三个数opt x y,或者opt l r,代表操作
输出格式:
如果可以,输出“damushen”
否则输出“yuanxing”
5 5 1 2 3 4 5 2 1 5 2 2 3 2 3 3 1 3 6 2 3 5
damushen damushen damushen damushen
对于30%的数据,n,m<=500
对于60%的数据,n,m<=100000
对于100%的数据,n,m<=500000
值域1e9
2s
这道题主要是要知道一个用平方和来体现哈希的思想。
那就是在区间中最小值到最大值的平方之和是唯一的(立方和一样)。
于是我们就可以用线段树保存区间最大值,最小值和平方和,来进行操作。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define il inline
#define db double
#define max(a,b) ((a>b)?(a):(b))
#define min(a,b) ((a<b)?(a):(b))
using namespace std;
il int gi()
{
int x=0,y=1;
char ch=getchar();
while(ch<‘0‘||ch>‘9‘)
{
if(ch==‘-‘)
y=-1;
ch=getchar();
}
while(ch>=‘0‘&&ch<=‘9‘)
{
x=x*10+ch-‘0‘;
ch=getchar();
}
return x*y;
}
int a[500005],tmax[2000005],tmin[2000005],tsum[2000005];
il void build(int rt,int l,int r)
{
if(l==r)
{
tmax[rt]=tmin[rt]=a[l];
tsum[rt]=a[l]*a[l];
return;
}
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
tmax[rt]=max(tmax[rt<<1],tmax[rt<<1|1]);
tmin[rt]=min(tmin[rt<<1],tmin[rt<<1|1]);
tsum[rt]=tsum[rt<<1]+tsum[rt<<1|1];
}
il int querymax(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
return tmax[rt];
int m=(l+r)>>1,r1=-1e9,r2=-1e9;
if(L<=m)
r1=querymax(rt<<1,l,m,L,R);
if(m<R)
r2=querymax(rt<<1|1,m+1,r,L,R);
return max(r1,r2);
}
il int querymin(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
return tmin[rt];
int m=(l+r)>>1,r1=1e9,r2=1e9;
if(m>=L)
r1=querymin(rt<<1,l,m,L,R);
if(m<R)
r2=querymin(rt<<1|1,m+1,r,L,R);
return min(r1,r2);
}
il int querysum(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
return tsum[rt];
int m=(l+r)>>1,s=0;
if(m>=L)
s+=querysum(rt<<1,l,m,L,R);
if(m<R)
s+=querysum(rt<<1|1,m+1,r,L,R);
return s;
}
il void update(int rt,int l,int r,int pos,int v)
{
if(l==r)
{
tmax[rt]=v;
tmin[rt]=v;
tsum[rt]=v*v;
return;
}
int m=(r+l)>>1;
if(pos<=m)
update(rt<<1,l,m,pos,v);
else
update(rt<<1|1,m+1,r,pos,v);
tmax[rt]=max(tmax[rt<<1],tmax[rt<<1|1]);
tmin[rt]=min(tmin[rt<<1],tmin[rt<<1|1]);
tsum[rt]=tsum[rt<<1]+tsum[rt<<1|1];
}
il int he(int x,int y)
{
int s=0;
for(int i=x;i<=y;i++)
s+=i*i;
return s;
}
int main()
{
memset(tmin,127/3,sizeof(tmin));
int n=gi(),m=gi(),l,r,minx,maxn,sum,vis;
for(int i=1;i<=n;i++)
a[i]=gi();
build(1,1,n);
for(int i=1;i<=m;i++)
{
vis=gi(),l=gi(),r=gi();
if(vis==2)
{
minx=querymin(1,1,n,l,r);
maxn=querymax(1,1,n,l,r);
sum=querysum(1,1,n,l,r);
if(maxn-minx!=r-l)
{
printf("yuanxing\n");
continue;
}
if(he(minx,maxn)==sum)
printf("damushen\n");
else
printf("yuanxing\n");
}
else
update(1,1,n,l,r);
}
return 0;
}
原文:https://www.cnblogs.com/gshdyjz/p/9775487.html