暴力出奇跡ios
原題:數組
0≤Q≤50000ide
0≤a≤300ui
0≤b,c≤108spa
0≤x0<d≤1083d
1≤ui,vi≤N×Mcode
恩首先容易看出來這個棋盤直接模擬搞出來就好了,不用反演矩陣乘之類的奇怪的東西blog
而後又容易發現只須要遍歷從1~n*m的數儘可能答案裏塞就是最優答案 = =|||ci
而後貪心搞一下,從1~n*m遍歷,對於每個n記錄一個top和一個bottom表示第i行能取第bottom[i]到top[i]列的數get
容易發現暴力維護的複雜度是資瓷的 = =|||
易證不會存在由於以前欽定選擇某些數致使後面選不夠n+m-1個數的狀況
而後暴力搞就能夠辣
由於2.5e7的數組只能開兩個因此有一個要重複使用……
注意答案的長度是2n…………
注意一開始遞推的姿式,好比兩個int和一個longlong相乘要先int乘longlong再乘int之類的
代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define ll long long 8 int rd(){int z=0; char ch=getchar(); 9 while(ch<'0'||ch>'9') ch=getchar(); 10 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 11 return z; 12 } 13 ll a,b,c,d,n,m,o; int x[25000001]; int nm; 14 int T[25000001],tp[5100],bt[5100]; 15 int ans[11000],ast=0; 16 int main(){//freopen("ddd.in","r",stdin); 17 int l,r; 18 cin>>x[0]>>a>>b>>c>>d>>n>>m>>o; nm=n*m; 19 for(int i=1;i<=nm;++i) x[i]=((((x[i-1]*a)%d)*x[i-1])%d+(x[i-1]*b)%d+c)%d; 20 for(int i=1;i<=nm;++i) T[i]=i; 21 for(int i=1;i<=nm;++i) swap(T[i],T[x[i]%i+1]); 22 while(o--) l=rd(),r=rd(),swap(T[l],T[r]); 23 for(int i=1;i<=nm;++i) x[T[i]]=i-1; 24 for(int i=1;i<=n;++i) tp[i]=m,bt[i]=1; 25 for(int i=1;i<=nm;++i){ 26 l=x[i]/m+1,r=x[i]%m+1; 27 if((r>=bt[l])&(r<=tp[l])){ 28 for(int j=1;j<l;++j)if(r<tp[j]) tp[j]=r; 29 for(int j=l+1;j<=n;++j)if(r>bt[j]) bt[j]=r; 30 ans[++ast]=i; 31 if(ast==n+m-1) break; 32 } 33 } 34 for(int i=1;i<ast;++i) printf("%d ",ans[i]); 35 cout<<ans[ast]; 36 return 0; 37 }