zoukankan      html  css  js  c++  java
  • BZOJ4373 算术天才⑨与等差数列(线段树)

      看上去很难维护,考虑找一些必要条件。首先显然最大值-最小值=k*(r-l)。然后区间内的数需要模k同余。最后区间内的数两两不同(k=0除外)。冷静一下可以发现这些条件组合起来就是充分的了。

      考虑怎么维护。最大值最小值非常简单。模k同余相当于区间内相邻两数的差都是k的倍数,可以维护差分数组的gcd。两两不同相当于区间内没有出现次数>1的数,对每个数用set维护上一个和他相同的数的位置,线段树维护,区间查询max,如果<l则说明不存在。

      开始判断是否不同的写出锅了,结果删掉竟然过了23333

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<set>
    #include<cassert> 
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 300010
    #define ll long long
    int n,m,a[N],b[N],lst,cnt;
    map<int,int> f;
    set<int> pre[N<<1];
    int L[N<<2],R[N<<2],mn[N<<2],mx[N<<2],GCD[N<<2],last[N<<2];
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    void up(int k)
    {
        mn[k]=min(mn[k<<1],mn[k<<1|1]);
        mx[k]=max(mx[k<<1],mx[k<<1|1]);
        last[k]=max(last[k<<1],last[k<<1|1]);
        GCD[k]=gcd(GCD[k<<1],GCD[k<<1|1]);
    }
    void build(int k,int l,int r)
    {
        L[k]=l,R[k]=r;
        if (l==r) 
        {
            mn[k]=mx[k]=a[l];GCD[k]=b[l];
            last[k]=*(--pre[f[a[l]]].find(l));
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        up(k);
    }
    void modify(int k,int p,int x,int op)
    {
        if (L[k]==R[k])
        {
            if (op==0) mn[k]=mx[k]=x;
            else if (op==1) GCD[k]=x;
            else last[k]=x;
            return;
        }
        int mid=L[k]+R[k]>>1;
        if (p<=mid) modify(k<<1,p,x,op);
        else modify(k<<1|1,p,x,op);
        up(k);
    }
    int qmax(int k,int l,int r)
    {
        if (L[k]==l&&R[k]==r) return mx[k];
        int mid=L[k]+R[k]>>1;
        if (r<=mid) return qmax(k<<1,l,r);
        else if (l>mid) return qmax(k<<1|1,l,r);
        else return max(qmax(k<<1,l,mid),qmax(k<<1|1,mid+1,r)); 
    }
    int qmin(int k,int l,int r)
    {
        if (L[k]==l&&R[k]==r) return mn[k];
        int mid=L[k]+R[k]>>1;
        if (r<=mid) return qmin(k<<1,l,r);
        else if (l>mid) return qmin(k<<1|1,l,r);
        else return min(qmin(k<<1,l,mid),qmin(k<<1|1,mid+1,r)); 
    }
    int qgcd(int k,int l,int r)
    {
        if (L[k]==l&&R[k]==r) return GCD[k];
        int mid=L[k]+R[k]>>1;
        if (r<=mid) return qgcd(k<<1,l,r);
        else if (l>mid) return qgcd(k<<1|1,l,r);
        else return gcd(qgcd(k<<1,l,mid),qgcd(k<<1|1,mid+1,r)); 
    }
    int qlast(int k,int l,int r)
    {
        if (L[k]==l&&R[k]==r) return last[k];
        int mid=L[k]+R[k]>>1;
        if (r<=mid) return qlast(k<<1,l,r);
        else if (l>mid) return qlast(k<<1|1,l,r);
        else return max(qlast(k<<1,l,mid),qlast(k<<1|1,mid+1,r)); 
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
        freopen("bzoj4373.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();
        for (int i=1;i<=n;i++)
        {
            a[i]=read(),b[i]=abs(a[i]-a[i-1]);
            if (f.find(a[i])==f.end()) f[a[i]]=++cnt,pre[cnt].insert(0);
            pre[f[a[i]]].insert(i);
        }
        build(1,1,n);
        while (m--)
        {
            int op=read();
            if (op==1)
            {
                int p=read()^lst,x=read()^lst;
                int t=f[a[p]];set<int>::iterator it=++pre[t].find(p);
                if (it!=pre[t].end()) modify(1,*it,*(--pre[t].find(p)),2);
                pre[t].erase(p);
                a[p]=x;modify(1,p,x,0);
                modify(1,p,abs(a[p]-a[p-1]),1);
                if (p<=n) modify(1,p+1,abs(a[p+1]-a[p]),1);
                if (f.find(a[p])==f.end()) f[a[p]]=++cnt,pre[cnt].insert(0);
                t=f[a[p]];it=pre[t].lower_bound(p);
                if (it!=pre[t].end()) modify(1,*it,p,2);
                it--;modify(1,p,*it,2);pre[t].insert(p);
            }
            else
            {
                int l=read()^lst,r=read()^lst,d=read()^lst;
                if (qmax(1,l,r)-qmin(1,l,r)==1ll*d*(r-l)&&(d==0||l==r||((qgcd(1,l+1,r)%d==0)&&qlast(1,l,r)<l))) lst++,printf("Yes
    ");
                else printf("No
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    String、StringBuffer与StringBuilder之间区别
    Java String之String和CharSequence、StringBuilder和StringBuffer的区别(1)
    Rational Rose2007(v7.0)下载地址、安装及激活详解教程
    FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和XmlWebApplicationContext简介
    洛克菲勒
    NOIP提高组DAY1T2——信息传递(最小环)
    洛谷P2016——战略游戏(树形)
    数字转换(树上直径)
    洛谷P2014——选课(树形dp)
    没有上司的舞会(简单树形dp)
  • 原文地址:https://www.cnblogs.com/Gloid/p/9866430.html
Copyright © 2011-2022 走看看