P3792 由乃与大母神原型和偶像崇拜

给你一个序列a

每次两个操作:

1.修改x位置的值为y

2.查询区间l,r是否可以重排为值域上连续的一段

输入输出格式

输入格式:

第一行两个数n,m

第二行n个数表示a[i]

后面m行每行三个数opt x y,或者opt l r,代表操作

输出格式:

如果可以,输出“damushen”

否则输出“yuanxing”

输入输出样例

输入样例#1: 复制
5 5
1 2 3 4 5
2 1 5
2 2 3
2 3 3
1 3 6
2 3 5
输出样例#1: 复制
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;
}

 

posted @ 2018-10-11 22:26  GSHDYJZ  阅读(227)  评论(0编辑  收藏  举报