51nod算法马拉松14
Posted tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod算法马拉松14相关的知识,希望对你有一定的参考价值。
这次太丢人了只搞出来了A到D,那就将就写一写A到D。。。
脑筋急转弯题,不难发现每一次两个人只能染白奇数个格子,所以数数有奇数还是偶数个白格子就行了。
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; return x*f; } typedef long long ll; const int maxn=110; int n,m; void solve() { n=read();m=read();int is=0; rep(i,1,n) rep(j,1,m) is+=read(); puts((is&1)?"yadang":"xiawa"); } int main() { dwn(T,read(),1) solve(); return 0; }
不难发现b=1*a,c=1*b,即c=1*1*a,这里都是数论卷积。
预处理1*1,然后对于每个修改暴力更改影响的ci,期望每次修改是O(logn)的。
但是这道题卡常数。但是这道题卡常数。但是这道题卡常数。
最后上uoj拿来一份高级IO优化才过2333。
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) using namespace std; typedef long long ll; const int BufferSize=1<<16; char buffer[BufferSize],*head,*tail; inline char Getchar() { if(head==tail) { int l=fread(buffer,1,BufferSize,stdin); tail=(head=buffer)+l; } return *head++; } inline int read() { int x=0,f=1;char c=Getchar(); for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘; return x*f; } #define S 1200000 char pf[S],*o1=pf,*o2=pf+S; #define ot(x) (o1==o2?fwrite(pf,1,S,stdout),*(o1=pf)++=x:*o1++=x) inline void print(ll x){static char s[20],*b;b=s;if(!x)*b++=48;for(;x;*b++=x%10+48,x/=10);for(;b--!=s;ot(*b));} const int maxn=1000010; int n,q; ll B[maxn],ans[maxn]; int main() { n=read();q=read(); rep(i,1,n) for(int j=i;j<=n;j+=i) B[j]++; while(q--) { int t=read(),x=read(); if(t==2) print(ans[x]),ot(‘\n‘); else { int v=read(); for(int i=x;i<=n;i+=x) ans[i]+=v*B[i/x]; } } fwrite(pf,1,o1-pf,stdout); return 0; }
明显的01分数规划,二分一下答案然后问题就转化成计算有多少连续子序列和>0,离散一下树状数组算一下就行了。
注意精度问题。
#include<cstdio> #include<cstring> #include<cctype> #include<cmath> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; return x*f; } typedef long long ll; const int maxn=100010; const double eps=1e-12; ll k; int n,A[maxn],C[maxn]; int sumv[maxn]; void add(int x) {for(;x<=n+1;x+=x&-x) sumv[x]++;} int sum(int x) {int res=0;for(;x;x-=x&-x) res+=sumv[x];return res;} double B[maxn],tmp[maxn]; ll check(double x) { memset(sumv,0,sizeof(sumv)); rep(i,1,n) B[i]=(A[i]-x)*1e10; rep(i,1,n) B[i]+=B[i-1]; rep(i,1,n) tmp[i]=B[i];tmp[n+1]=0.0; sort(tmp+1,tmp+n+2); rep(i,1,n+1) if(fabs(tmp[i]-tmp[i-1])<eps) tmp[i]=tmp[i-1]; rep(i,0,n) C[i]=lower_bound(tmp+1,tmp+n+2,B[i])-tmp; ll ans=0; rep(i,1,n) { add(C[i-1]); ans+=sum(C[i]); } return ans; } int main() { n=read();scanf("%lld",&k); double l=0.0,r=0.0; rep(i,1,n) r=max(r,(double)(A[i]=read())); while(r-l>1e-10) { double mid=(l+r)*0.5; if(check(mid)>=k) l=mid; else r=mid; } printf("%.6lf\n",l); return 0; }
手(da)推(biao)公(da)式(fa)得g(n)=n*d(n),其中d(n)表示n的约数个数。
设n=∏(pi^ci),则d(n)=∏(ci+1)。
然后这个问题就简单了,因为数的范围是[1,10^7],暴力搞搞循环节,线性筛一下最小质因子就行了。
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) using namespace std; typedef long long ll; inline ll read() { ll x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; return x*f; } const int maxn=10000010; const int mod=1000000007; int pow(ll n,ll m) { ll ans=1; for(;m;m>>=1,(n*=n)%=mod) if(m&1) (ans*=n)%=mod; return ans; } int pri[maxn/10],d[maxn],cnt; bool vis[maxn]; void init(int n) { d[1]=1; rep(i,2,n) { if(!vis[i]) pri[++cnt]=i,d[i]=i; rep(j,1,cnt) { if(i*pri[j]>n) break; vis[i*pri[j]]=1; if(i%pri[j]==0) {d[i*pri[j]]=d[i];break;} d[i*pri[j]]=pri[j]; } } } int x1,a,b,c,k,A[maxn]; ll m; int main() { m=read();x1=read();a=read();b=read();c=read(); init(c);A[x1]=1;int x=x1; ll ans=1;(ans*=x1)%=mod; do { k++; x=((ll)x*a+b)%c+1;A[x]++;(ans*=x)%=mod; }while(A[x]==1&&k<m-1); if(k<m-1) { A[x]--;(ans*=pow(x,mod-2))%=mod; while(x1!=x) k--,m--,x1=((ll)x1*a+b)%c+1; ll t=m/k,ct=1;m-=t*k;t--; do { (A[x]+=t%mod)%=mod;if(m) A[x]++,m--,(ans*=x)%=mod; (ct*=x)%=mod; x=((ll)x*a+b)%c+1; }while(x!=x1); (ans*=pow(ct,t))%=mod; } dwn(i,c,2) { if(d[i]==i) (ans*=A[i]+1)%=mod; else (A[i/d[i]]+=A[i])%=mod,(A[d[i]]+=A[i])%=mod; } printf("%lld\n",ans); return 0; }
以上是关于51nod算法马拉松14的主要内容,如果未能解决你的问题,请参考以下文章
51Nod 算法马拉松12 Rikka with sequences