luogu P2354 [NOI2014]隨機數生成器 貪心 卡空間 暴力
阿新 • • 發佈:2020-07-30
LINK:隨機數生成器
觀察資料範圍還是可以把矩陣給生成出來的。
考慮如何求出答案。題目要求把選出的數字從小到大排序後字典序儘可能的小 實際上這個類似於Mex的問題.
所以要從大到小選數字 考慮選擇一個數字後哪些位置不合法 左下右上不合法。
問題之後變成了 一個二維數點問題 最快也就log^2
實際上我們發現每次覆蓋的是一個矩形 可以直接暴力把矩形給標記了。
如果是左下矩形可以暴力從右上到左下進行標記.遇到被標記的就break.
總複雜度還是線性的.
不過這個需要兩個\(n\cdot m\)的陣列 不能多開 不然MLE.
另外一種做法是考慮會修改的數字是\(n+m-1\)個 可以每次修改的時候可以\(O(m)\)
空間複雜度都差不多.真要比的話 前者空間小.
code
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<ctime> #include<cctype> #include<queue> #include<deque> #include<stack> #include<iostream> #include<iomanip> #include<cstdio> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<cctype> #include<cstdlib> #include<queue> #include<deque> #include<stack> #include<vector> #include<algorithm> #include<utility> #include<bitset> #include<set> #include<map> #define ll long long #define db double #define INF 1000000000 #define inf 100000000000000000ll #define ldb long double #define pb push_back #define put_(x) printf("%d ",x); #define get(x) x=read() #define gt(x) scanf("%d",&x) #define gi(x) scanf("%lf",&x) #define put(x) printf("%d\n",x) #define putl(x) printf("%lld\n",x) #define rep(p,n,i) for(RE int i=p;i<=n;++i) #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]]) #define fep(n,p,i) for(RE int i=n;i>=p;--i) #define vep(p,n,i) for(RE int i=p;i<n;++i) #define pii pair<int,int> #define mk make_pair #define RE register #define P 1000000007ll #define gf(x) scanf("%lf",&x) #define pf(x) ((x)*(x)) #define uint unsigned long long #define ui unsigned #define EPS 1e-10 #define sq sqrt #define S second #define F first #define mod 1000000007 #define id(i,j) ((i-1)*m+j) #define max(x,y) ((x)<(y)?y:x) using namespace std; char *fs,*ft,buf[1<<15]; inline char gc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { RE int x=0,f=1;RE char ch=gc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();} return x*f; } const int MAXN=5010,maxn=MAXN*MAXN; int n,m,ww,Q; int x0,A,B,C,D; int a[maxn],b[maxn]; inline int F(int x){return ((ll)A*x%D*x+(ll)b*x+C)%D;} int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); get(x0);get(A);get(B);get(C);get(D); get(n);get(m);get(Q); //cout<<x0<<' '<<A<<' '<<B<<' '<<C<<' '<<D<<endl; rep(1,n*m,i) { x0=((ll)A*x0%D*x0+(ll)B*x0+C)%D; //cout<<x0<<endl; a[i]=i;swap(a[(x0%i)+1],a[i]); } //rep(1,n*m,i)cout<<a[i]<<endl; rep(1,Q,i)swap(a[read()],a[read()]); //rep(1,n*m,i)cout<<a[i]<<endl; rep(1,n*m,i)b[a[i]]=i,a[i]=0; rep(1,n*m,i) { if(a[b[i]])continue; printf("%d ",i); int x=b[i]/m+1,y=b[i]-(x-1)*m; if(!y)--x,y=m; fep(x-1,1,l) { if(a[id(l,y+1)])break; rep(y+1,m,r) { if(a[id(l,r)])break; a[id(l,r)]=1; } } rep(x+1,n,l) { if(a[id(l,y-1)])break; fep(y-1,1,r) { if(a[id(l,r)])break; a[id(l,r)]=1; } } } return 0; }