[2016陕西省赛B] Rui and her functions

来源:互联网 发布:安装java linux 编辑:程序博客网 时间:2024/04/30 05:03

2016陕西省赛B
给定n个函数,其中fi(x)=(aibxi+ci)moddi
求对于每个函数最小的 x,使得fi取到最小值
答案保证递增
其中x[1,m]中,n,m<1e5, a,b,c,d<1e9


所以可以整体二分一下
由于答案已经保证递增了,所以就很简单
其实赛上想到了类似做法,但由于答案非严格递增
所以担心出现答案全相等的情况,把这种解法卡成 (nm)
后来赛后想了想,全相等的情况几乎不可能发生
因为随机数据的话,要搞出另一组数据答案等于某个值的概率是1/m
搞出 n组的概率就是 1/(n*m),几乎不可能

#pragma comment(linker, "/STACK:102400000,102400000")#include <cstdio>#include <iostream>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <cctype>#include <map>#include <set>#include <queue>#include <bitset>#include <string>#include <complex>using namespace std;typedef pair<int,int> Pii;typedef long long LL;typedef unsigned long long ULL;typedef double DBL;typedef long double LDBL;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define SQR(a) ((a)*(a))#define PCUT puts("\n----------")#define PRI(x) cout << #x << ":" << x << endl;const int maxn=1e5+10, INF=0x3f3f3f3f;int N,M;int A[maxn], B[maxn], C[maxn], D[maxn];int ans[maxn];int Pow(int,int,int);void solve(int,int,int,int);int main(){    #ifdef LOCAL    freopen("in.txt", "r", stdin);//  freopen("out.txt", "w", stdout);    #endif    int ck=0;    while(~scanf("%d%d", &N, &M))    {        for(int i=1; i<=N; i++) scanf("%d%d%d%d", &A[i], &B[i], &C[i], &D[i]);        solve(1,N,1,M);        printf("Case #%d\n", ++ck);        for(int i=1; i<=N; i++) printf("%d\n", ans[i]);    }    return 0;}void solve(int l, int r, int vl, int vr){    if(r<l) return;    int mid = (l+r)>>1;    int val = Pow(B[mid], vl-1, D[mid]);    ans[mid] = vl-1;    Pii res = {INF, ans[mid]};    for(int i=vl; i<=vr; i++)    {        val = 1LL*val*B[mid]%D[mid];        res = min(res, {(1LL*A[mid]*val+C[mid])%D[mid], i});    }    ans[mid] = res.second;    solve(l, mid-1, vl, ans[mid]);    solve(mid+1, r, ans[mid], vr);}int Pow(int x, int n, int p){    int res=1;    while(n)    {        if(n&1) res = 1LL*res*x%p;        x = 1LL*x*x%p;        n>>=1;    }    return res;}
原创粉丝点击