• BZOJ 4320 Homework


    首先要想清楚一定是按根号分块。对于<根号的直接记录。>根号的怎么办呢?

    设查询的是%y。

    那么我们只要找一个0,y,2y,3y.....的lowerbound就好了。而这是根号的。到此总复杂度n√nlogn,无法通过此题。

    怎么办呢?可以考虑离线。我们维护并查集,每个点的祖先是在数轴上它的右边第一个出现的数。

    那么倒着做就是删数,就可以合并两个集合,就好了。复杂度n√nα(n)。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 400500
    #define inf 1000000007
    using namespace std;
    int n,x;char s[5];
    int mn[maxn],father[maxn],a[maxn],tot=0,mx[maxn];
    struct query
    {
        int type,x,ans;
        query (int type,int x,int ans):type(type),x(x),ans(ans) {}
        query () {}
    }q[maxn];
    int getfather(int x)
    {
        if (x!=father[x]) father[x]=getfather(father[x]);
        return father[x];
    }
    void unionn(int x,int y)
    {
        if (y>300000) return;
        int f1=getfather(x),f2=getfather(y);
        if (f1!=f2) father[f1]=f2;
    }
    int main()
    {
        scanf("%d",&n);
        int top=(int)sqrt(300000)+1;
        for (int i=1;i<=top;i++) mn[i]=inf;
        for (int i=1;i<=n;i++)
        {
            mx[i]=mx[i-1];
            scanf("%s",s);scanf("%d",&x);
            if (s[0]=='A') q[i]=query(1,x,0);
            else q[i]=query(2,x,0);
            if (s[0]=='A')
            {
                for (int j=1;j<=top;j++)
                    mn[j]=min(mn[j],x%j);
                a[++tot]=x;mx[i]=max(mx[i],x);
            }
            else if (x<=top) q[i]=query(2,x,mn[x]);
        }
        sort(a+1,a+tot+1);for (int i=1;i<=300000;i++) father[i]=i;
        int p=1;
        for (int i=1;i<=300000;i++)
        {
            if (a[p]<i) p++;
            father[i]=a[p];
        }
        for (int i=n;i>=1;i--)
        {
            if (q[i].type==1) unionn(q[i].x,q[i].x+1);
            else if (q[i].x>top)
            {
                int ret=inf,kr=q[i].x;
                for (int j=q[i].x;j<=mx[i];j+=q[i].x)
                {
                    int f=getfather(j);
                    ret=min(ret,f%q[i].x);
                }
                ret=min(ret,getfather(1)%q[i].x);
                q[i]=query(2,kr,ret);
            }
        }
        for (int i=1;i<=n;i++)
            if (q[i].type==2) printf("%d
    ",q[i].ans);
        return 0;
    }
  • 相关阅读:
    北航OO第三单元总结
    北航OO第二单元总结
    提问回顾和个人总结
    Unity 制作不规则形状button
    Unity 3D手游对不同分辨率屏幕的UI自适应
    软工结队作业
    CSDN app分析
    软工作业——求交点
    软工第一次作业
    软工热身作业
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6360960.html
Copyright © 2020-2023  润新知