[洛谷P3792] 由乃與大母神原型和偶像崇拜

https://daniu.luogu.org/problemnew/show/P3792ui

題意提要

給你一個序列aspa

每次兩個操做:code

1.修改x位置的值爲yblog

2.查詢區間l,r是否能夠重排爲值域上連續的一段ip

輸入輸出格式

輸入格式:hash

第一行兩個數n,mit

第二行n個數表示a[i]io

後面m行每行三個數opt x y,或者opt l r,表明操做class

輸出格式:數據

若是能夠,輸出「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

思路

使用線段樹,維護最大值,最小值,平方和,乘積;

對於一段區間若是(最大值-最小值==區間長度-1)&&(平方和or乘積==合法序列的平方和or乘積(這兩個是等價的,爲何都用,hash碰撞QUQ)),

那麼該區間合法。

代碼實現

  1 #include<cstdio>
  2 #include<algorithm>
  3 const int maxn=1e6+10;
  4 const int mod=998244353;
  5 inline int min_(int x,int y){return x<y?x:y;}
  6 inline int max_(int x,int y){return x>y?x:y;}
  7 int n,m;
  8 int f[maxn<<2],g[maxn<<2],s[maxn],x[maxn],opt[maxn];
  9 int in[maxn<<2],ax[maxn<<2],ip[maxn<<2],iq[maxn<<2];
 10 struct nate{int x,ip;}dtt[maxn];
 11 bool comp(nate a,nate b){return a.x>b.x;}
 12 int FP(int x,int y){
 13     int now=1;
 14     while(y){
 15         if(y&1) now=(1ll*now*x)%mod;
 16         x=(1ll*x*x)%mod;
 17         y>>=1;
 18     }
 19     return now;
 20 }
 21 int IE(int x){return FP(x,mod-2);}
 22 void build(int k,int l,int r){
 23     if(l==r){
 24         in[k]=ax[k]=s[l];
 25         iq[k]=s[l];
 26         ip[k]=(1ll*s[l]*s[l])%mod;
 27         return;
 28     }
 29     int mid=l+r>>1,ls=k<<1,rs=ls|1;
 30     build(ls,l,mid);
 31     build(rs,mid+1,r);
 32     in[k]=min_(in[ls],in[rs]);
 33     ax[k]=max_(ax[ls],ax[rs]);
 34     iq[k]=(1ll*iq[ls]*iq[rs])%mod;
 35     ip[k]=(1ll*ip[ls]+ip[rs])%mod;
 36 }
 37 void change(int k,int l,int r,int ap,int at){
 38     if(l==r){
 39         in[k]=ax[k]=ip[k]=at;
 40         iq[k]=at;
 41         ip[k]=(1ll*at*at)%mod;
 42         return;
 43     }
 44     int mid=l+r>>1,ls=k<<1,rs=ls|1;
 45     if(ap<=mid) change(ls,l,mid,ap,at); 
 46     else change(rs,mid+1,r,ap,at);
 47     in[k]=min_(in[ls],in[rs]);
 48     ax[k]=max_(ax[ls],ax[rs]);
 49     iq[k]=(1ll*iq[ls]*iq[rs])%mod;
 50     ip[k]=(1ll*ip[ls]+ip[rs])%mod;
 51 }
 52 int xin,xax,xip,xiq,bj;
 53 void search(int k,int l,int r,int al,int ar){
 54     if(l==al&&r==ar){
 55         xin=min_(xin,in[k]);
 56         xax=max_(xax,ax[k]);
 57         xip=(1ll*xip+ip[k])%mod;
 58         xiq=(1ll*xiq*iq[k])%mod;
 59         return;
 60     }
 61     int mid=l+r>>1,ls=k<<1,rs=ls|1;
 62     if(al<=mid) search(ls,l,mid,al,min_(ar,mid));
 63     if(ar>mid) search(rs,mid+1,r,max_(al,mid+1),ar);
 64 }
 65 bool ok(int l,int r){
 66     xin=mod,xax=0,xip=0,xiq=1;
 67     search(1,1,n,l,r);
 68     if(xax-xin!=r-l) return 0;
 69     bj=(1ll*f[xax]-f[xin-1]+mod)%mod;
 70     if(bj!=xip) return 0;
 71     bj=(1ll*g[xax]*IE(g[xin-1]))%mod;
 72     if(bj!=xiq) return 0;
 73     return 1;
 74 }
 75 int main(){
 76     scanf("%d%d",&n,&m);
 77     for(int i=1;i<=n;i++){
 78         scanf("%d",&s[i]);
 79         dtt[i].x=s[i],dtt[i].ip=i;
 80     }
 81     for(int i=1;i<=m;i++){
 82         scanf("%d%d%d",&opt[i],&x[i],&s[n+i]);
 83         if(opt[i]==1) dtt[n+i].x=s[n+i],dtt[n+i].ip=n+i;
 84     }
 85     int top=1;g[0]=1;
 86     std::sort(dtt+1,dtt+n+m+1,comp);
 87     for(int i=1;dtt[i].x&&i<=n+m;i++){
 88         s[dtt[i].ip]=top;
 89         if(dtt[i+1].x==dtt[i].x-1) top++;
 90         if(dtt[i+1].x<dtt[i].x-1) top+=2;
 91     }
 92     for(int i=1;i<=top;i++) g[i]=(1ll*i*g[i-1])%mod;
 93     for(int i=1;i<=top;i++) f[i]=(1ll*i*i+f[i-1])%mod;
 94     build(1,1,n);
 95     for(int i=1;i<=m;i++){
 96         if(opt[i]==1) change(1,1,n,x[i],s[n+i]);
 97         else{
 98             if(ok(x[i],s[n+i])) puts("damushen");
 99             else puts("yuanxing");
100         }
101     }
102     return 0;
103 }

 

 

 

據說是套路題QUQ果真我作題太少了。。。

相關文章
相關標籤/搜索