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


    https://daniu.luogu.org/problemnew/show/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

    思路

    使用线段树,维护最大值,最小值,平方和,乘积;

    对于一段区间如果(最大值-最小值==区间长度-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果然我做题太少了。。。

  • 相关阅读:
    磁盘512n,512e,4k原生磁盘的区别和操作系统支持
    TLB与内存寻址,内存读取,虚拟内存的相关原理
    文件系统逻辑块与磁盘物理扇区的关系
    DBA的工作职责和每日工作
    理解数据库中的undo日志、redo日志、检查点
    React Native 常用插件案例
    React Native 学习资料
    React Native开源项目案例
    nginx rewrite 指令
    nginx反向代理配置
  • 原文地址:https://www.cnblogs.com/J-william/p/8043103.html
Copyright © 2020-2023  润新知