• BZOJ 4028 分块


    zrt当年是怎么想到的…….
    思路:
    考虑把序列分块
    对于每块 存xor[i] 表示从本块开头到i的前缀异或和
    把它扔进set里
    存gcd[i]表示从本块开头到i的前缀gcd.
    如果这一块的GCD和整个的gcd的gcd是一样的 从set里找ans
    否则暴力..
    GCD最多log种 所以是复杂度是O(nsqrt(n)logn)的

    //By SiriusRen
    #include <cmath>
    #include <set>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=100050;
    int n,q,a[N],Block,block[N],XOR[N],GCD[N];
    char op[150];
    typedef long long ll;
    set<int>s[320];
    int gcd(int x,int y){return y?gcd(y,x%y):x;}
    signed main(){
        scanf("%d",&n),Block=sqrt(n);
        for(int i=0;i<n;i++)scanf("%d",&a[i]),block[i]=i/Block+1;
        for(int i=0;i<n;i++){
            if(block[i]==block[i-1])XOR[i]=XOR[i-1]^a[i],GCD[i]=gcd(a[i],GCD[i-1]);
            else XOR[i]=a[i],GCD[i]=a[i];
            s[block[i]].insert(XOR[i]);
        }
        scanf("%d",&q);
        while(q--){
            scanf("%s",op);
            if(op[0]=='M'){
                int xx,yy;
                scanf("%d%d",&xx,&yy),a[xx]=yy;
                s[block[xx]].clear();
                int tp=lower_bound(block,block+n,block[xx])-block;
                XOR[tp]=a[tp],GCD[tp]=a[tp];s[block[xx]].insert(XOR[tp]);
                for(int i=tp+1;block[i]==block[tp];i++)
                    XOR[i]=XOR[i-1]^a[i],GCD[i]=gcd(a[i],GCD[i-1]),s[block[xx]].insert(XOR[i]);
            }
            else{
                ll Q;int Gcd=GCD[lower_bound(block,block+n,2)-block-1],Xor=XOR[lower_bound(block,block+n,2)-block-1];
                scanf("%lld",&Q);
                for(int i=0;block[i]==1;i++)
                    if((ll)GCD[i]*XOR[i]==Q){printf("%d
    ",i);goto ed;}
                for(int i=2;i<=block[n-1];i++){
                    if(gcd(GCD[upper_bound(block,block+n,i)-block-1],Gcd)!=Gcd){
                        int tp=lower_bound(block,block+n,i)-block;
                        for(int j=tp;block[j]==block[tp];j++){
                            Gcd=gcd(Gcd,a[j]),Xor^=a[j];
                            if((ll)Gcd*Xor==Q){printf("%d
    ",j);goto ed;}
                        }
                        continue;
                    }
                    ll temp=(Q/Gcd)^Xor;
                    if(s[i].find(temp)!=s[i].end()){
                        int tp=lower_bound(block,block+n,i)-block;
                        for(int j=tp;block[j]==block[tp];j++)
                            if(XOR[j]==temp){printf("%d
    ",j);goto ed;}
                    }
                    Xor^=XOR[upper_bound(block,block+n,i)-block-1];
                }
                puts("no");
            }ed:;
        }
    }
  • 相关阅读:
    我们在囧途之程序员转型记
    项目开发应遵循1+7还是7+1?
    自己用的一款模板解析程序(支持插件和扩展)(思路讨论和使用体验)
    设计的核心任务之一:层次的控制
    【设计 = 编码】 VS 【设计 ≠ 编码】
    从一生的角度看程序员的学习和发展
    编码质量与命名
    软件开发十年小史
    设计的核心任务之三:确保正交性
    国内外软件开发上的差距与分析
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532023.html
Copyright © 2020-2023  润新知