• [HNOI2010]物品调度


    看似很难

    其实很水

    仔细观察其实是两问。

    第一问确定xi,yi,

    posi=(ci+d*xi+yi) mod n不是白给的。

    其实是同一个d*x+c的环上的所有点通过xi调整找到,yi的作用是更新到另一个环上去。

    暴力枚举yi,每个环上用并查集维护紧跟着下一个可选择的

    如果下一个被删除了,那么这个环已经用完,++yi

    可以过。(因为数据水,zhoutb2333 dalao已经卡掉)

    所以,考虑对环和环之间也用并查集维护一下,这样总的复杂度就是O(N)了

    第二问更水

    类似置换的问题做过很多次了。

    找到置换环之后,由于必须和空位交换,所以含空位的len-1次,不含空位的len+1次(要把空位换进来多一次)

    环与环之间交换是没有必要的。

    一些值得注意的坑是:

    对于这种取模的问题,ci,d上来直接对n取模了事。。

    否则可能比n大,而并查集中未定义,或者直接RE

    代码:(暴力枚举y)

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define numb (ch^'0')
    #define int long long
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=100000+5;
    int n,t,s;
    int pos[N];
    int q,p,m,d;
    int c[N];
    int fa[N];
    int fin(int x){
        return fa[x]==x?x:fa[x]=fin(fa[x]);
    }
    bool dele[N];
    bool vis[N];
    int len;
    int kil;
    void init(){
        for(reg i=0;i<n;++i) fa[i]=i;
        memset(dele,0,sizeof dele);
        memset(pos,0,sizeof pos);
        memset(vis,0,sizeof vis);
        int go=(s+d)%n;
        fa[s]=go;dele[s]=1;
        ++kil;
        len=0;
    }
    int query(int st){
        int k=fin(st);
    //    cout<<" kk "<<st<<" "<<d<<" : "<<k<<" "<<dele[k]<<" "<<(k+d)%n<<" "<<fin((k+d)%n)<<endl;
        if(!dele[k]){
            int lp=fin((k+d)%n);
            if(lp!=k) fa[k]=lp;
            dele[k]=1;
            ++kil;
            return k;
        }
        return -1;
    }
    
    void dfs(int x){
        vis[x]=1;++len;
        if(!vis[pos[x]]) dfs(pos[x]);
    }
    int main(){
        rd(t);
        while(t--){
            rd(n);rd(s);rd(q);rd(p);rd(m);rd(d);
            d%=n;
            init();
            c[0]=0;
            for(reg i=1;i<n;++i) c[i]=((ll)c[i-1]*q+p)%m;
            for(reg i=1;i<n;++i){
                c[i]%=n;
            //    cout<<" ii "<<i<<" "<<kil<<" "<<c[i]<<endl;
                int y=0;
                int tmp=0;
                while((tmp=query((c[i]+y)%n))==-1){
                    ++y;
                    //cout<<tmp<<" "<<y<<endl;
                }
                pos[i]=tmp;
            }
            pos[0]=s;
            int ans=0;
            for(reg i=0;i<n;++i){
                //cout<<pos[i]<<" ";
                if(!vis[i]) {
                    len=0;
                    if(pos[i]!=i){
                        dfs(i);
                        //cout<<" len "<<len<<endl;
                        if(i==0) ans+=len-1;
                        else ans+=len+1;
                    }
                }
            }//cout<<endl;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2018/12/27 14:17:54
    */
    View Code
  • 相关阅读:
    mem系函数总结
    shell----删除文件中的^M
    为tcp的connect设置超时时间
    ue-edit设置显示函数列表
    bep-10翻译
    mysql--慢查询,卡死等处理
    mongodb---js脚本操作速记
    佛主保佑,永无bug
    【php】中【event】之实现方式
    BI任务列表
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10185229.html
Copyright © 2020-2023  润新知