• [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;
    }
  • 相关阅读:
    让服务器可以下载apk和ipa文件
    MVC第一次访问比较慢的解决方案
    [C#]记录程序耗时的方法【转发】
    uploadify上传带参数及接收参数的方法
    uploadify上传之前判断一个input输入框是否为空
    jgGrid获得的id值是主键的id而不是jqGrid的行号值
    jqGrid删除多行数据问题
    Linux下的微秒级定时器: usleep, nanosleep, select, pselect
    Linux平台延时之sleep、usleep、nanosleep、select比较
    Linux 高精確的時序(sleep, usleep,nanosleep) from:http://blog.sina.com.cn/s/blog_533ab41c0100htae.html
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj4373.html
Copyright © 2020-2023  润新知