标签:cstring col ffffff 错误 ++ 表示 ... ons 快速
T1
定义 tot=n+m 假设n是较小的
那么每次操作相当于 n=n*2 m=m-(tot-m)=2*m-tot
即直接在mod n+m意义下 快速幂即可
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #include <map> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; inline int read() { char q=getchar();int ans=0; while(q<‘0‘||q>‘9‘)q=getchar(); while(q>=‘0‘&&q<=‘9‘){ans=ans*10+q-‘0‘;q=getchar();} return ans; } ll qpow(ll a,ll ci,ll mod) { ll ans=1; while(ci) { if(ci&1) ans=ans*a%mod; a=a*a%mod; ci>>=1; } return ans; } int ci; ll n,m; int main(){ scanf("%lld%lld%d",&n,&m,&ci); ll tt=n*qpow(2,ci,n+m)%(n+m); cout<<min(tt,n+m-tt); }
我在考试的时候发现了 对于每一个n、m,它们最后不是一个变成0,就是循环
然后我就用了map...
T2
直接预处理出来每一个"坏对"
这个可以通过枚举$a_i$的倍数来实现
不细讲了
我只是忘了判$a_i<=K$...
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #define INF 0x7fffffff #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; inline int read() { char q=getchar();int ans=0; while(q<‘0‘||q>‘9‘)q=getchar(); while(q>=‘0‘&&q<=‘9‘){ans=ans*10+q-‘0‘;q=getchar();} return ans; } const int N=100006; struct son { int l,r; }ji[N*3]; int con; int n,K; int a[N],maxa; int q[N]; vector<int> L[N],R[N]; void chu() { int order; for(int i=1;i<=n;++i) { if(a[i]<=K)//鑰冭瘯娌℃墦鍟婂晩鍟婂晩 { q[a[i]]=i; continue; } order=0; for(int j=K;j<=maxa;j+=a[i]) if(order<q[j]) order=q[j]; if(order) { ++con; ji[con].l=order; ji[con].r=i; } q[a[i]]=i; } for(int i=1;i<=con;++i) { L[ji[i].l].push_back(ji[i].r); R[ji[i].r].push_back(ji[i].l); } } ll work() { ll ans=0; int tt,mx,mn; mx=0; for(int i=1;i<=n;++i) { tt=R[i].size(); for(int j=0;j<tt;++j) if(mx<R[i][j]) mx=R[i][j]; ans+=(i-mx); } /*mn=n+1; for(int i=n;i>=1;--i) { tt=L[i].size(); for(int j=0;j<tt;++j) if(mn>L[i][j]) mn=L[i][j]; ans+=(mn-i); } return ans/2;*/ return ans; } int main(){ //freopen("T2.in","r",stdin); //freopen("T2.out","w",stdout); n=read();K=read(); for(int i=1;i<=n;++i) { a[i]=read(); if(maxa<a[i]) maxa=a[i]; } chu(); cout<<work(); }
T3
$f_{i,j}$ 前i行 第i行用恰好j种颜色的方案数
$$ f_{i,j}=\sum_{k=1}^{a_{i-1}}f_{i-1,j}*C_m^j*g_{a_i,j} - f_{i-1,j}*g_{a_i,j} $$
其中 g_{i,j} 表示 在i个位置里用j种颜色放的方案数
$$g_{i,j}=g_{i-1,j}*(j-1)+g_{i-1,j-1}*j$$
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #include <map> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; inline int read() { char q=getchar();int ans=0; while(q<‘0‘||q>‘9‘)q=getchar(); while(q>=‘0‘&&q<=‘9‘){ans=ans*10+q-‘0‘;q=getchar();} return ans; } const int N=1000006; int prime[N],cnt; bool he[N]; int mn[N]; int n,m,mod; int a[N],maxa; ll g[5006][5006]; ll C[N]; void get_g() { g[1][1]=1;//没有组合意义 for(int i=1;i<=maxa;++i) for(int j=1;j<=i&&j<=m;++j) { g[i][j]=(g[i][j]+g[i-1][j]*(j-1)%mod)%mod; g[i][j]=(g[i][j]+g[i-1][j-1]*j%mod)%mod; } /*printf("\n"); for(int i=1;i<=maxa;++i) { for(int j=1;j<=maxa;++j) printf("%lld ",g[i][j]); printf("\n"); } printf("\n");*/ } int t[N]; inline void jia(int x) { while(x!=1) { ++t[mn[x]]; x/=prime[mn[x]]; } } inline void jian(int x) { while(x!=1) { --t[mn[x]]; x/=prime[mn[x]]; } } inline ll get_get() { ll ans=1; for(int i=1;i<=cnt;++i) if(t[i]) for(int j=1;j<=t[i];++j) ans=ans*prime[i]%mod; return ans; } void chu() { int q1=min(maxa,m); for(int i=2;i<=m;++i) { if(!he[i]) { prime[++cnt]=i; mn[i]=cnt; } for(int j=1;j<=cnt&&prime[j]*i<=m;++j) { he[i*prime[j]]=1; mn[i*prime[j]]=j; if(i%prime[j]==0) break; } } for(int i=0;i<q1;++i) { jia(m-i); jian(i+1); C[i+1]=get_get(); //printf("%lld ",C[i+1]); } //printf("\n"); } ll f[2][1000006]; ll dp() { int pre; int now=0; f[0][0]=1; for(int i=1;i<=n;++i) { now^=1;pre=now^1; for(int j=0;j<=maxa;++j) f[now][j]=0; //printf("now=%d pre=%d\n",now,pre); for(int j=1;j<=a[i];++j) f[now][j]=(f[pre][0]*C[j]%mod*g[a[i]][j]%mod-f[pre][j]*g[a[i]][j]%mod+mod)%mod; f[now][0]=0; for(int j=1;j<=a[i];++j) f[now][0]=(f[now][0]+f[now][j])%mod; } return f[now][0]%mod; } int main(){ //freopen("T3.in","r",stdin); //freopen("kalanchoe6.in","r",stdin); n=read();m=read();mod=read(); for(int i=1;i<=n;++i) { a[i]=read(); if(maxa<a[i]) maxa=a[i]; } get_g(); chu(); cout<<dp(); }
今天真是日了狗了...
第一题,想了半天以为是正解,其实是又犯了老错误
每一个简单题,我都要把它搞复杂,以后要先把原始式子写出来...
而且想到的东西要及时写下来,防止像今天第三题忘了...
以后有价值的题在写blog,太浪费时间了...
标签:cstring col ffffff 错误 ++ 表示 ... ons 快速
原文地址:http://www.cnblogs.com/A-LEAF/p/7668301.html