zoukankan      html  css  js  c++  java
  • [bzoj4373]算术天才⑨与等差数列

    来自FallDream的博客,未经允许,请勿转载,谢谢。


    算术天才⑨非常喜欢和等差数列玩耍。
    有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。
    他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列。
    当然,他还会不断修改其中的某一项。
    为了不被他鄙视,你必须要快速并正确地回答完所有问题。
    注意:只有一个数的数列也是等差数列。

    第一行包含两个正整数n,m(1<=n,m<=300000),分别表示序列的长度和操作的次数。
    第二行包含n个整数,依次表示序列中的每个数a[i](0<=a[i]<=10^9)。
    接下来m行,每行一开始为一个数op,
    若op=1,则接下来两个整数x,y(1<=x<=n,0<=y<=10^9),表示把a[x]修改为y。
    若op=2,则接下来三个整数l,r,k(1<=l<=r<=n,0<=k<=10^9),表示一个询问。
    在本题中,x,y,l,r,k都是经过加密的,都需要异或你之前输出的Yes的个数来进行解密。

    只想到一个比较麻烦的判断方式

    一个序列合法,当且仅当最小/最大值/权值和合法,没有相同元素且差分的gcd是k。

    除了没有相同元素这个条件,其他的都能线段树求。

    考虑每种权值维护一棵平衡树,然后线段树维护区间 每一个位置和她相同的上一个格子的位置 的最大值,如果这个最大值小于l,那么就没有相同元素。

    常数巨大。

    除了gcd以外其他都是严格nlogn的 区间gcd复杂度我不知道是什么 感觉是nlogn但是不会证。。

    另:300题打卡。

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<set>
    #define ll long long
    #define MN 300000
    #define N 524288
    #define It set<int>::iterator
    using namespace std;
    inline long long read()
    {
        long long x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    struct data{int mx,mn;ll sum;
        friend data operator +(data a,data b){return(data){max(a.mx,b.mx),min(a.mn,b.mn),a.sum+b.sum};}
    };
    struct Tree{int l,r;data x;}T[MN*4+5];
    int t[N*2+5],t2[N*2+5],cnt=0,a[MN+5],last=0,n,m;
    set<int> st[MN*2+5];
    map<int,int> mp;
    inline int gcd(int x,int y){return !y?x:gcd(y,x%y);}
    inline int abs(int x){return x<0?-x:x;}
    
    int Query2(int l,int r)
    {
        int res=0;
        for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
        {
            if(~l&1) res=gcd(res,t2[l+1]);
            if( r&1) res=gcd(res,t2[r-1]);
        }
        return res;
    }
    
    void Modify2(int x,int ad)
    {
        t2[x+=N]=ad;
        for(x>>=1;x;x>>=1) t2[x]=gcd(t2[x<<1],t2[x<<1|1]);
    }
    
    int Query(int l,int r)
    {
        int res=0;
        for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
        {
            if(~l&1) res=max(res,t[l+1]);
            if( r&1) res=max(res,t[r-1]);
        }
        return res;
    }
    
    void Modify(int x,int ad)
    {
        t[x+=N]=ad;
        for(x>>=1;x;x>>=1) t[x]=max(t[x<<1],t[x<<1|1]);
    }
    
    void Build(int x,int l,int r)
    {
        if((T[x].l=l)==(T[x].r=r)) {T[x].x=(data){a[l],a[l],a[l]};return;}
        int mid=l+r>>1;
        Build(x<<1,l,mid);Build(x<<1|1,mid+1,r);
        T[x].x=T[x<<1].x+T[x<<1|1].x;
    }
    
    void Modify(int x,int k,int v)
    {
        if(T[x].l==T[x].r) T[x].x=(data){v,v,v};
        else
        {
            int mid=T[x].l+T[x].r>>1;
            if(k<=mid) Modify(x<<1,k,v);
            else Modify(x<<1|1,k,v);
            T[x].x=T[x<<1].x+T[x<<1|1].x;
        }
    }
    
    data Query(int x,int l,int r)
    {
        if(T[x].l==l&&T[x].r==r) return T[x].x;
        int mid=T[x].l+T[x].r>>1;
        if(r<=mid) return Query(x<<1,l,r);
        else if(l>mid) return Query(x<<1|1,l,r);
        else return Query(x<<1,l,mid)+Query(x<<1|1,mid+1,r);
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;++i)
        {
            !mp[a[i]=read()]?mp[a[i]]=++cnt:0;
            int x=mp[a[i]];
            if(st[x].begin()!=st[x].end()) Modify(i,*(--st[x].end()));
            st[x].insert(i);
            if(i>1) Modify2(i-1,abs(a[i]-a[i-1]));
        }
        Build(1,1,n);
        for(int i=1;i<=m;++i)
        {
            int op=read();
            if(op==1)
            {
                int x=read()^last,y=read()^last;
                if(a[x]==y) continue;
                if(x!=n) Modify2(x,abs(a[x+1]-y));
                if(x!=1) Modify2(x-1,abs(y-a[x-1]));
                int ha=mp[a[x]];
                It it=st[ha].lower_bound(x),it2=it;
                if(++it!=st[ha].end()) Modify(*it,(it2==st[ha].begin()?0:*(--it2)));
                st[ha].erase(--it);
                !mp[y]?mp[y]=++cnt:0;ha=mp[y];
                it=st[ha].lower_bound(x),it2=it;
                if(it!=st[ha].end()) Modify(*it,x);
                if(it2!=st[ha].end()&&it2!=st[ha].begin())
                    Modify(x,*(--it2));
                else Modify(x,0);
                a[x]=y;Modify(1,x,y);st[ha].insert(x);
            }
            else
            {
                int l=read()^last,r=read()^last,k=read()^last;
                data x=Query(1,l,r);bool flag=0;
                if(l==r) {puts("Yes"),++last;continue;}
                if(!k)
                {
                    if(x.mn==x.mx) puts("Yes"),++last;
                    else puts("No");
                    continue;
                }
                if(x.sum!=1LL*x.mn*(r-l+1)+1LL*(r-l+1)*(r-l)/2*k) flag=1;
                else if(x.mx!=x.mn+1LL*(r-l)*k) flag=1;
                else
                {
                    int Gcd=Query2(l,r-1),MxLast=Query(l,r);
                    if(Gcd!=k||MxLast>=l) flag=1;
                }
                if(flag) puts("No");
                else puts("Yes"),++last;
            }
        }
        return 0;
    }
  • 相关阅读:
    JavaScript Patterns 5.7 Object Constants
    JavaScript Patterns 5.6 Static Members
    JavaScript Patterns 5.5 Sandbox Pattern
    JavaScript Patterns 5.4 Module Pattern
    JavaScript Patterns 5.3 Private Properties and Methods
    JavaScript Patterns 5.2 Declaring Dependencies
    JavaScript Patterns 5.1 Namespace Pattern
    JavaScript Patterns 4.10 Curry
    【Android】如何快速构建Android Demo
    【Android】如何实现ButterKnife
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj4373.html
Copyright © 2011-2022 走看看