neuoj1472 yuki的氪金之旅(倒置树状数组
Posted wzgg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了neuoj1472 yuki的氪金之旅(倒置树状数组相关的知识,希望对你有一定的参考价值。
这题一直re不造为啥。。后来yww大神把树状数组“倒过来”就过了,倒过来的好处是算sum(d[i]+1)就行,不涉及除法,不用求逆元。
题意:初始手牌颜值是0,一共抽卡n次,第i次抽卡有pi的概率能抽到颜值为di的卡,若di>当前手牌颜值,则替换,最后问改变手牌次数的期望。
做法:树状数组维护前缀概率积。先把di离散化,di作为下标,pi作为值,逆元用费马小定理那个推论,本质就是求每次改变手牌的概率,第i次就是pi(1-pj)(1-pk)...(其中j,k<i),即p[i]*sum(d[i]+1)。
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<ctime> #include<functional> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<stack> #include<bitset> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef double db; typedef long double ldb; typedef pair<int,int> pii; typedef pair<ll,ll> pll; void open(const char *s) #ifndef ONLINE_JUDGE char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout); #endif void open2(const char *s) #ifdef DEBUG char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout); #endif template <class T> int upmin(T &a, const T &b)return (b<a?a=b,1:0); template <class T> int upmax(T &a, const T &b)return (b>a?a=b,1:0); namespace io const int SIZE=(1<<20)+1; char ibuf[SIZE],*iS,*iT; char obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1; int getc() (iS==iT?iS=ibuf,iT=ibuf+fread(ibuf,1,SIZE,stdin):0); return iS==iT?EOF:*(iS++); int f; char c; template <class T> void get(T &x) f=1; for(c=getc();(c<‘0‘||c>‘9‘)&&c!=‘-‘;c=getc()); (c==‘-‘?f=-1,c=getc():0); x=0; for(;c>=‘0‘&&c<=‘9‘;c=getc()) x=x*10+c-‘0‘; x*=f; void flush() fwrite(obuf,1,oS-obuf,stdout); oS=obuf; void putc(char x) *(oS++)=x; if(oS==oT) flush(); int a[55],t; template <class T> void put(T x) if(!x) putc(‘0‘); x<0?putc(‘-‘),x=-x:0; while(x) a[++t]=x%10; x/=10; while(t) putc(a[t--]+‘0‘); void space() putc(‘ ‘); void enter() putc(‘\n‘); struct flusher ~flusher() flush(); io_flusher; const int infi=0x3fffffff; const ll infll=0x3fffffffffffffffll; const int N=100010; const ll p=1000000007; ll fp(ll a,ll b) ll s=1; for(;b;b>>=1,a=a*a%p) if(b&1) s=s*a%p; return s; const ll inv100=fp(100,p-2); ll a[N],d[N]; int b[N],c[N]; int n,t; void add(int x,ll v) for(;x;x-=x&-x) d[x]=d[x]*v%p; ll sum(int x) ll res=1; for(;x<=t;x+=x&-x) res=res*d[x]%p; return res; void solve() scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld%d",&a[i],&b[i]); a[i]=a[i]*inv100%p; c[i]=b[i]; sort(c+1,c+n+1); t=unique(c+1,c+n+1)-c-1; for(int i=1;i<=n;i++) b[i]=lower_bound(c+1,c+t+1,b[i])-c; for(int i=1;i<=n;i++) d[i]=1; ll ans=0; for(int i=1;i<=n;i++) ans=(ans+a[i]*sum(b[i]+1))%p; add(b[i],1-a[i]); ans=(ans%p+p)%p; printf("%lld\n",ans); int main() int t; scanf("%d",&t); while(t--) solve(); return 0;
以上是关于neuoj1472 yuki的氪金之旅(倒置树状数组的主要内容,如果未能解决你的问题,请参考以下文章