[COGS1767] [NOI2014]随机数生成器

来源:互联网 发布:如何打开端口8081 编辑:程序博客网 时间:2024/04/30 15:48
  • ALG :贪心 + BL ???

首先尽量快地求出A矩阵,嗯,没错直接求出来 = =


然后从1开始枚举到K,每次判断这个数能否被选取,这样选取出来的序列一定是字典序最小的


然后卡常数卡内存吧


全剧终


/****************************************\* Author : ztx* Title  : [cogs] 1767. [NOI2014]随机数生成器* ALG    : 贪心 + BL ???* CMT    : * Time   :\****************************************/#include <cstdio>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define rep(i,l,r) for(i=(l);i< (r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)#define rev(i,r,l) for(i=(r);i> (l);i--)typedef long long ll ;typedef double lf ;/*char Stream[1048576LL] , *ptr = Stream , Strlen ;#define  Getchar()  (*ptr++)*/#define  Getchar()  getchar()int CH , NEG ;template <typename TP>inline void read(TP& ret) {    ret = NEG = 0 ;    ret = 0 ;    while (CH=Getchar() , CH<'!') ;    if (CH == '-') NEG = true , CH = Getchar() ;    while (ret = ret*10+CH-'0' , CH=Getchar() , CH>'!') ;    if (NEG) ret = -ret ;}template <typename TP>inline void readc(TP& ret) {    while (ret=Getchar() , ret<'!') ;    while (CH=Getchar() , CH>'!') ;}template <typename TP>inline void reads(TP *ret) {    ret[0]=0;while (CH=Getchar() , CH<'!') ;    while (ret[++ret[0]]=CH,CH=Getchar(),CH>'!') ;    ret[ret[0]+1]=0;}#define  maxn  5010LL#define  maxk  25000010LLint N , M , Q , K ;int left[maxn] , right[maxn] ;int T[maxk] , F[maxk] ;inline void Exchange(int&x,int&y) { if (x!=y) x^=y,y^=x,x^=y; }inline void Cover(int x,int y) {    int i ;    Rep (i,1,x-1)        if (y < right[i]) right[i] = y ;    Rep (i,x+1,N)        if (y > left[i]) left[i] = y ;}int main() {int i , j , x , y ;ll a , b , c , d ;    #define READ    #ifdef  READ        freopen("random_2014.in" ,"r",stdin ) ;        freopen("random_2014.out","w",stdout) ;    #endif    /* read */    read(x) , read(a) , read(b) , read(c) , read(d) ;    read(N) , read(M) , read(Q) ;    K = N*M ;    /* pre */    Rep (i,1,K) T[i] = i ;    F[0] = x ;    Rep (i,1,K)        F[i] = (F[i-1] * (a * F[i-1] + b) + c) % d ;    Rep (i,1,K)        Exchange(T[i],T[F[i]%i+1]) ;    Rep (i,1,Q) {        read(a) , read(b) ;        Exchange(T[a],T[b]) ;    }    K = 0 ;    Rep (i,1,N) {        left[i] = 1 , right[i] = M ;        Rep (j,1,M)            ++ K , F[T[K]] = K ;    }    /* go */    j = 0 ;    Rep (i,1,K) {        y = (F[i] - 1) % M + 1 ;        x = (F[i] - y) / M + 1 ;        if (y<left[x] || y>right[x]) continue ;        printf("%d ", i) ;        Cover(x,y) ;        if (++j == N+M-1) break ;    }    puts("") ;    #ifdef  READ        fclose(stdin) ; fclose(stdout) ;    #else        Getchar() ; Getchar() ;    #endif    return 0 ;}
0 0
原创粉丝点击