题意概述:

有一个正整数$N$满足$C$个条件,每个条件都形如“它除以$X$的余数在集合$\{Y_1, Y_2, ..., Y_k\}$中”,所有条件中的$X$两两互质,

你的任务是找出最小的S个解。

数据范围:

$1\leq C\leq9, 1 \leq S \leq 10, X \geq 2, 1 \leq k \leq 100, 0 \leq Y_i \leq X$

分析:

如果每个集合元素个数为1,那么我们直接使用中国剩余定理求解即可。

因此我们想到枚举余数,但是余数的组合最多会有$100^9$种可能,太多了。我们发现加入$k$的积不大的话,使用这种方法是可行的。比如

我们假设每个集合元素都不超过5。而当集合元素增加时,由于可行解是在模$M = \prod X_i$下的在枚举复杂度提高的同时也意味着可行解在

数轴上变得稠密,这意味着我们可以通过从小到大枚举答案并判定的方法解决。为了加快此过程,我们希望不可行的枚举尽快被否定,因此我们

希望首先使用$k$较小并且$X$较大的条件判定,因为这个条件是更强的,于是考虑按照$\frac{k}{X}$从小到大的顺序检验答案$i$是否满足当前

条件。由此问题便可解决。

 #include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <iostream>
#include <assert.h>
#define pi acos(-1.)
using namespace std;
typedef long long ll;
const int int_inf = 0x3f3f3f3f;
const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
const int INT_INF = (int)((1ll << ) - );
const int mod = 1e9 + ;
const double double_inf = 1e30;
typedef unsigned long long ul;
#pragma comment(linker, "/STACK:102400000,102400000")
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define mp make_pair
#define st first
#define nd second
#define keyn (root->ch[1]->ch[0])
#define lson (u << 1)
#define rson (u << 1 | 1)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define type(x) __typeof(x.begin())
#define foreach(i, j) for(type(j)i = j.begin(); i != j.end(); i++)
#define FOR(i, s, t) for(int i = (s); i <= (t); i++)
#define ROF(i, t, s) for(int i = (t); i >= (s); i--)
#define dbg(x) cout << x << endl
#define dbg2(x, y) cout << x << " " << y << endl
#define clr(x, i) memset(x, (i), sizeof(x))
#define maximize(x, y) x = max((x), (y))
#define minimize(x, y) x = min((x), (y))
#define low_bit(x) ((x) & (-x)) inline int readint(){
int x;
scanf("%d", &x);
return x;
} inline int readstr(char *s){
scanf("%s", s);
return strlen(s);
} class cmpt{
public:
bool operator () (const int &x, const int &y) const{
return x > y;
}
}; int Rand(int x, int o){
//if o set, return [1, x], else return [0, x - 1]
if(!x) return ;
int tem = (int)((double)rand() / RAND_MAX * x) % x;
return o ? tem + : tem;
} void data_gen(){
srand(time());
freopen("in.txt", "w", stdout);
int times = ;
printf("%d\n", times);
while(times--){
int r = Rand(, ), a = Rand(, ), c = Rand(, );
int b = Rand(r, ), d = Rand(r, );
int m = Rand(, ), n = Rand(m, );
printf("%d %d %d %d %d %d %d\n", n, m, a, b, c, d, r);
}
} struct cmpx{
bool operator () (int x, int y) { return x > y; }
};
int debug = ;
int dx[] = {-, , , };
int dy[] = {, , -, };
//-------------------------------------------------------------------------
int C, S;
ll mt[][];
ll X[], k[];
ll ans[];
ll buf[];
ll w[], _w[];
ll M;
int id[];
pair<pll, int> _buf[];
const int lim = 1e5; void egcd(ll a, ll b, ll &d, ll &x, ll &y){
if(!b){
d = a, x = , y = ;
return;
}
egcd(b, a % b, d, x, y);
ll x1 = x, y1 = y;
x = y1, y = x1 - a / b * y1;
} void dfs(int pos){
if(pos == C + ){
ll tem = ;
FOR(i, , C) tem += buf[i] * w[i] % M * _w[i] % M, tem %= M;
if(!tem) tem = M;
FOR(i, , S - ) ans[i + S] = tem + M * i;
sort(ans, ans + * S);
return;
}
FOR(i, , k[pos]){
buf[pos] = mt[pos][i];
dfs( + pos);
}
} bool cmp(pair<pll, int> x, pair<pll, int> y){
return x.st.st * y.st.nd < x.st.nd * y.st.st;
} void enu_solve(){
FOR(i, , C) _buf[i] = mp(mp(k[i], X[i]), i);
sort(_buf + , _buf + C + );
FOR(i, , C) id[i] = _buf[i].nd;
int cnt = ;
int bg = ;
while(cnt < S){
int ok1 = ;
FOR(i, , C){
int j = id[i];
int tem = bg % X[j];
int sz = k[j];
int ok = ;
FOR(u, , sz) if(tem == mt[j][u]) { ok = ; break; }
if(!ok) { ok1 = ; break; }
}
if(ok1) ans[cnt++] = bg;
bg++;
}
} void crt_solve(){
M = ;
FOR(i, , C) M *= X[i];
FOR(i, , C) w[i] = M / X[i] % M;
FOR(i, , C){
ll d, x, y;
egcd(w[i], X[i], d, x, y);
_w[i] = (x % X[i] + X[i]) % X[i];
}
clr(ans, ll_inf);
dfs();
} void solve(){
ll num = ;
int ok = ;
FOR(i, , C){
num *= k[i];
if(num > lim){
ok = ;
break;
}
}
if(ok) crt_solve();
else enu_solve();
} //-------------------------------------------------------------------------
int main(){
//data_gen(); return 0;
//C(); return 0;
debug = ;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(debug) freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while(~scanf("%d%d", &C, &S) && C){
FOR(i, , C){
X[i] = readint(), k[i] = readint();
FOR(j, , k[i]) mt[i][j] = readint();
}
solve();
FOR(i, , S - ) printf("%lld\n", ans[i]);
printf("\n");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
return ;
}

code:

Uva 11754 Code Feat的更多相关文章

  1. UVA 11754 - Code Feat(数论)

    UVA 11754 - Code Feat 题目链接 题意:给定一个c个x, y1,y2,y3..yk形式,前s小的答案满足s % x在集合y1, y2, y3 ... yk中 思路:LRJ大白例题, ...

  2. UVA 11754 Code Feat (枚举,中国剩余定理)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud C Code Feat   The government hackers at C ...

  3. uva 11754 Code Feat (中国剩余定理)

    UVA 11754 一道中国剩余定理加上搜索的题目.分两种情况来考虑,当组合总数比较大的时候,就选择枚举的方式,组合总数的时候比较小时就选择搜索然后用中国剩余定理求出得数. 代码如下: #includ ...

  4. UVA 11754 Code Feat 中国剩余定理+枚举

    Code FeatUVA - 11754 题意:给出c个彼此互质的xi,对于每个xi,给出ki个yj,问前s个ans满足ans%xi的结果在yj中有出现过. 一看便是个中国剩余定理,但是同余方程组就有 ...

  5. UVA 11754 Code Feat 中国剩余定理+暴力

    lrj白书例题,真好 #include <stdio.h> #include <iostream> #include <vector> #include <m ...

  6. UVA - 11754 Code Feat (分块+中国剩余定理)

    对于一个正整数N,给出C组限制条件,每组限制条件为N%X[i]∈{Y1,Y2,Y3,...,Yk[i]},求满足条件的前S小的N. 这道题很容易想到用中国剩余定理,然后用求第k小集合的方法输出答案.但 ...

  7. UVA 11557 - Code Theft (KMP + HASH)

    UVA 11557 - Code Theft 题目链接 题意:给定一些代码文本.然后在给定一个现有文本,找出这个现有文本和前面代码文本,反复连续行最多的这些文本 思路:把每一行hash成一个值.然后对 ...

  8. UVa 11754 (中国剩余定理 枚举) Code Feat

    如果直接枚举的话,枚举量为k1 * k2 *...* kc 根据枚举量的不同,有两种解法. 枚举量不是太大的话,比如不超过1e4,可以枚举每个集合中的余数Yi,然后用中国剩余定理求解.解的个数不够S个 ...

  9. UVA11754 - Code Feat

    Hooray!  Agent Bauer has shot the terrorists, blown upthe bad guy base, saved the hostages, exposed ...

随机推荐

  1. Radius session

    1,EAP 中继 client start, NAS require identity, client sent username, NAS sent username to sever, serve ...

  2. iOS 延迟执行

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), ...

  3. Codeforce Round #221 Div2

    每次的CF都是一把辛酸泪! 什么时候能打破这局面,昨天做着睡着了! 有时候有的题目也就差一线! 哎,! A:杠杆原理! B:算最后负的和! B:没弄出来当时就脑短路... C:事后写了个n*log(n ...

  4. UVa10025-The ? 1 ? 2 ? ... ? n = k problem

    分析:因为数字之间只有加减变换,所以-k和k是一样的,都可以当成整数来考虑,只要找到最小的n满足sum=n*(n+1)/2>=k:且sum和k同奇同偶即可,做法是用二分查找,然后在就近查找 因为 ...

  5. 强连通(hdu4635)最多增加几条单向边后满足最终的图形不是强连通

    Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  6. Java基础(53):内部类(转)

    java中的内部类总结 内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类 如同一个人是由大脑.肢体.器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行 ...

  7. Java基础(43):Java中的Object类与其方法(转)

    Object类 java.lang.Object java.lang包在使用的时候无需显示导入,编译时由编译器自动导入. Object类是类层次结构的根,Java中所有的类从根本上都继承自这个类. O ...

  8. ruby初步学习中遇到的错误

    print <<off This is the second way of creating here document ie. multiple line string; off 报错: ...

  9. paper 35 :交叉验证(CrossValidation)方法思想

    交叉验证(CrossValidation)方法思想简介 以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(da ...

  10. . ToString(),Convert.ToString(),(string),as比较:

    http://www.cnblogs.com/chehaoj/archive/2010/02/23/1671955.html 通常 object 到 string 有四种方式(假设有object ob ...