1. 程式人生 > >[HNOI2010]物品調度

[HNOI2010]物品調度

sdi ++ == include etc getchar 一次 n) define

看似很難

其實很水

仔細觀察其實是兩問。

第一問確定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\n",ans); } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2018/12/27 14:17:54 */
View Code

[HNOI2010]物品調度