zoukankan      html  css  js  c++  java
  • BZOJ4373: 算术天才⑨与等差数列

    题解:  很显然这个题 等差数列没有办法维护  那么我们考虑一段区间为等差数列 那么应该满足

    1.最大值和最小值的差等于(r-l)*k

    2.任意相邻差值的绝对值的gcd与k的gcd等于k

    3.特判k==0的情况

    3.用set去重

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    const int inf=1e9+7;
    #define ll long long
    using namespace std;
    // struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    // void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
    	ll x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    
    int Gcd[MAXN<<2],pre[MAXN<<2],minn[MAXN<<2],maxx[MAXN<<2],vis[MAXN],a[MAXN],b[MAXN];
    int cnt,tot;
    map<int,int>ma;
    map<int,int>::iterator ite;
    set<int>s[MAXN<<1];
    set<int>::iterator ip,id;
    void up(int x){
    	Gcd[x]=__gcd(Gcd[x<<1],Gcd[x<<1|1]);
    	pre[x]=max(pre[x<<1],pre[x<<1|1]);
    	minn[x]=min(minn[x<<1],minn[x<<1|1]);
    	maxx[x]=max(maxx[x<<1],maxx[x<<1|1]);
    }
    void built(int rt,int l,int r){
    	if(l==r){Gcd[rt]=b[l];minn[rt]=maxx[rt]=a[l];pre[rt]=vis[l];return ;}
    	int mid=(l+r)>>1;
    	built(rt<<1,l,mid);
    	built(rt<<1|1,mid+1,r);
    	up(rt);
    }
    void update1(int rt,int l,int r,int t,int vul){
    	if(l==r){pre[rt]=vul;return ;}
    	int mid=(l+r)>>1;
    	if(t<=mid)update1(rt<<1,l,mid,t,vul);
    	else update1(rt<<1|1,mid+1,r,t,vul);
    	pre[rt]=max(pre[rt<<1],pre[rt<<1|1]);
    }
    void update2(int rt,int l,int r,int t,int vul){
    	if(l==r){Gcd[rt]=abs(vul-a[l-1]);minn[rt]=maxx[rt]=vul;return ;}
    	int mid=(l+r)>>1;
    	if(t<=mid)update2(rt<<1,l,mid,t,vul);
    	else update2(rt<<1|1,mid+1,r,t,vul);
    	up(rt);
    }
    void update3(int rt,int l,int r,int t,int vul){
    	if(l==r){Gcd[rt]=abs(vul-a[l]);return ;}
    	int mid=(l+r)>>1;
    	if(t<=mid)update3(rt<<1,l,mid,t,vul);
    	else update3(rt<<1|1,mid+1,r,t,vul);
    	up(rt);
    }
    int ans;
    void querty1(int rt,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){ans=__gcd(ans,Gcd[rt]);return ;}
    	int mid=(l+r)>>1;
    	if(ql<=mid)querty1(rt<<1,l,mid,ql,qr);
    	if(qr>mid)querty1(rt<<1|1,mid+1,r,ql,qr);
    }
    int ans1,ans2,ans3;
    void querty2(int rt,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){ans1=min(ans1,minn[rt]);ans2=max(ans2,maxx[rt]);ans3=max(ans3,pre[rt]);return ;}
    	int mid=(l+r)>>1;
    	if(ql<=mid)querty2(rt<<1,l,mid,ql,qr);
    	if(qr>mid)querty2(rt<<1|1,mid+1,r,ql,qr);
    }
    int main(){
    	int n,m;n=read();m=read();cnt=tot=0;
    	inc(i,1,n){
    		a[i]=read();
    		if(ma.find(a[i])==ma.end())ma[a[i]]=++cnt,s[cnt].insert(i),vis[i]=0;
    		else{
    			ite=ma.find(a[i]);
    			ip=s[ite->second].lower_bound(i);ip--;vis[i]=(*ip);s[ite->second].insert(i);
    		}
    		b[i]=abs(a[i]-a[i-1]);
    		//cout<<b[i]<<" ";
    	}
    	//cout<<endl;
    	built(1,1,n);int op,l,r,k;
    	inc(i,1,m){
    		op=read();l=read();r=read();l^=tot;r^=tot;
    		if(op==1){
    			update2(1,1,n,l,r);
    			if(l!=n)update3(1,1,n,l+1,r);
    			ite=ma.find(a[l]);ip=s[ite->second].lower_bound(l+1);id=s[ite->second].lower_bound(l);
    			if(ip!=s[ite->second].end()){
    				if(id==s[ite->second].begin())update1(1,1,n,(*ip),0),s[ite->second].erase(id);
    				else {
    					int t=(*ip);ip=id;id--;
    					update1(1,1,n,t,(*id));s[ite->second].erase(ip);
    				}
    			}
    			ite=ma.find(r);
    			if(ite==ma.end())ma[r]=++cnt,s[cnt].insert(l),update1(1,1,n,l,0);
    			else{
    				ip=s[ite->second].lower_bound(l);
    				if(ip!=s[ite->second].end()){update1(1,1,n,(*ip),l);}				
    				if(ip==s[ite->second].begin()){update1(1,1,n,l,0);}
    				else ip--,update1(1,1,n,l,(*ip));
    				s[ite->second].insert(l);
    			}
    			a[l]=r;
    		}
    		else{
    			//cout<<i<<"::::"<<op<<" "<<l<<" "<<r<<endl;
    			k=read();k^=tot;
    			if(l==r){tot++;puts("Yes");continue;}
    			//k^=tot;
    			ans=0;querty1(1,1,n,l+1,r);
    			ans1=inf;ans2=ans3=0;querty2(1,1,n,l,r);
    			//cout<<i<<" "<<k<<"===="<<ans1<<" "<<ans2<<" "<<ans<<endl;
    			if(k==0&&ans1==ans2){tot++;puts("Yes");continue;}
    			else if(k==0&&ans1!=ans2){puts("No");continue;}
    			if(__gcd(ans,k)!=k){puts("No");continue;}
    			int t=(ans2-ans1)%k;int t1=(ans2-ans1)/k;
    			//cout<<t<<" "<<t1<<" "<<i<<endl;
    			if(ans3<l&&t==0&&t1==r-l){tot++;puts("Yes");continue;}
    			else puts("No");
    		}
    	}
    	return 0;
    }
    

      

    4373: 算术天才⑨与等差数列

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2092  Solved: 510
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行包含两个正整数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的个数来进行解密。

    Output

    输出若干行,对于每个询问,如果可以形成等差数列,那么输出Yes,否则输出No。

    Sample Input

    5 3
    1 3 2 5 6
    2 1 5 1
    1 5 4
    2 1 5 1

    Sample Output

    No
    Yes

     

  • 相关阅读:
    excel查找定位操作(for lutai)
    sqlserver检查sql执行时间
    excel操作for(lutai)
    android studio 3.0+发布签名apk注意的情况
    二维码
    svn文件合并
    生成wsdl代理c#代码
    LOCK_TIMEOUT
    支持chrome30下载文件
    miniui处理多重子表级联,一次性提交多表数据的ui要点
  • 原文地址:https://www.cnblogs.com/wang9897/p/9622151.html
Copyright © 2011-2022 走看看