2016陕西省省赛 ACM Rui and her functions B 二分
Rui and her functions
發(fā)布時(shí)間: 2017年3月27日 15:45?? 最后更新: 2017年3月28日 12:43?? 時(shí)間限制: 10000ms?? 內(nèi)存限制: 256M
描述Rui is magnificently gifted. Why does she not play with me tonight? Oh, she is obsessing
about?n?functions with?n?quartette of positive coefficients, denoted by?ai,bi,ci,di(1≤i≤n)
respectively.
The i-th function fi is defined as?fi(x)=(ai×bxi+ci)moddi. She asked Doc to find the
smallest?xi?in?[1,m]?for each function such that?fi(xi)?achieves the minimum of?fi?in?[1,m].
That is say:?fi(xi)=min{x∈[1,m]|fi(x)=mint∈[1,m]{fi(t)}}.
However n is large and Doc told her that possible?xi?for each function is unique (and Rui
is unique as well), and?x1≤x2≤x3≤?≤xn?(and that is as amazing as Rui).
Now she needs to find?xi?by herself.
輸入 There are several test cases (no more than 64) and please process till EOF.
The first line in each case contains two integers?n?and?m,?1≤n,m≤100000. Each of the
following?n?lines contains four integers?ai,bi,ci,di?respectively, where?0<ai,bi,ci≤di≤109.
For each test case, print first the identifier of the test case, then n lines follow. The?i-th
line contains the number?xi?for?i-th function?fi.
然后讓你求出每個(gè)f(x)取得最小值情況下的x,這個(gè)題有點(diǎn)特殊,數(shù)據(jù)保證了x1<=x2<=...<=xn我覺得這個(gè)數(shù)據(jù)不是隨機(jī)出的,而是故意滿足了這個(gè)條件。
由于x的單調(diào)性,我們可以這樣考慮,如果我們先求出了下標(biāo)n/2對應(yīng)的函數(shù)對應(yīng)的x,那么對于所有下標(biāo)小于n/2的f函數(shù),就只需要考慮[1,x[n/2]]之內(nèi)的數(shù)就可以了,因?yàn)檫@些函數(shù)
的最小值對應(yīng)的x不可能大于x[n/2]了,這樣的話,再判斷左右兩邊的f函數(shù)對應(yīng)的x時(shí),要檢索的范圍就縮小了一半。
因此,上來就用二分
void solve(int lp,int rp,int l,int r)//左閉右開 表示的是要求區(qū)間[lp,rp)內(nèi)的函數(shù)對應(yīng)的最小值,這些最小值的取值再[l,r)里面那么我們先求pos = (lp+rp)/2位置的函數(shù),假設(shè)求得了x的下標(biāo)為under
那么下一次分治的時(shí)候,
左邊的區(qū)間變成了[lp,pos) 定義域變成了[l,under+1)因?yàn)閤之間可以相等
右邊的函數(shù)下標(biāo)區(qū)間變成了[pos+1,rp),定義域變成了[under,r)
注意!!!!!
快速冪不能一直使用,否則會(huì)TTTTTTT,555555555我在這地方T了20次!!!歸根到底還是菜啊
解決方案是,在定義域內(nèi)檢索最小值的時(shí)候,先用快速冪求出第一項(xiàng),然后遞歸得到以后的
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; typedef long long LL; const int MAX = 100009; const LL INF = 1e18; LL a[MAX],b[MAX],c[MAX],d[MAX],ans[MAX]; int n,m; LL mod_pow(LL x,LL n,LL mod) {LL res = 1;while(n > 0){if(n&1) res = res*x%mod;x = x*x%mod;n >>= 1;}return res; } /* LL calc(int x,int i) {LL mod = d[i];return ((a[i]%mod*mod_pow(b[i],x,mod))%mod + c[i]%mod) % mod; } */ void solve(int lp,int rp,int l,int r)//左閉右開 {//返回中間位置if(lp >= rp) return ;int pos = (lp + rp) / 2;LL sm = INF;int under;int lb = l;int up = r;LL tmp = mod_pow(b[pos],lb,d[pos]);for(int i = lb;i < up;i++){if(i != lb) tmp = tmp*b[pos]%d[pos];LL cc = ((a[pos]%d[pos]*tmp)%d[pos] + c[pos]%d[pos]) % d[pos];if(sm > cc)sm = cc,under = i;}ans[pos] = under;solve(lp,pos,l,under+1);solve(pos+1,rp,under,r); } main() {int cas = 0;while(~scanf("%d%d",&n,&m)){for(int i = 0;i < n;i++)scanf("%lld%lld%lld%lld",a+i,b+i,c+i,d+i);LL sm = INF;printf("Case #%d\n",++cas);solve(0,n,1,m+1);for(int i = 0;i < n;i++) printf("%lld\n",ans[i]);} return 0;} /* 1 1 373911025 1525760443 652804587 1767005941*/
總結(jié)
以上是生活随笔為你收集整理的2016陕西省省赛 ACM Rui and her functions B 二分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 传真机卡纸怎么解决 传真机卡纸解决方法
- 下一篇: 节操大师 北方大学生程序设计竞赛 南开大