XJOI NOIP模拟题2[数论][组合数][树规]
来源:互联网 发布:淘宝手机端图片分辨率 编辑:程序博客网 时间:2024/06/11 14:13
今天玩得有点嗨,嗯冷静冷静。
考试策略很重要,时间分配啊难度的选择啊对拍啊都很重要。建议还是看一遍题,像今天觉得T1好写结果不知不觉卡很久,T3其实是写过的水题就这么没了。
该开始复习数论了不然药丸,组合数,逆元,拓展欧几里得,费马小定理,欧拉函数……
T1:
题意:
给定n,k和两个字符串A,B,求与A相差字母个数为K的所有字符串按字典顺序排好后,B所在的位置。
分析:
若我们外层循环枚举光标在A的位置,内层枚举这个位置的字母,何很容易知道,若被枚举位置的字母不等于被枚举字母也不等于B中该位置字母,这时方案数就等于组合数(n-i-1中取k-1)乘以25的k-1次方。
数论太水,无法生存,好好学习,天天快乐。
#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<set>#include<map>#include<stack>#include<vector>#include<ctime>#define ll long long#define inf 2e8#define clr(x) memset(x,0,sizeof(x))#define maxen(x) memset(x,127,sizeof(x))#define maxer(x) memset(x,31,sizeof(x))#define each(i,n) for(int i=1;i<=n;i++)#define minn(a,b,c) min(a,min(b,c))#define maxx(a,b,c) max(a,max(b,c))#ifdef WIN32#define lld "%I64d"#else#define lld "%lld"#endif#define PROC "string"//for(int i=1;i<=n;i++)//(double) (ll) LL (int)//(double)clock()/CLOCKS_PER_SECusing namespace std;const long long modd=(1e9+7);const int Maxn=1e5+5;char a[Maxn],b[Maxn];int n,k;long long plu[Maxn],ans,ni[Maxn];int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}long long PowerMod(long long a, long long b, long long c){ long long ans = 1; a = a % c; while(b>0){ if(b % 2==1) ans = (ans * a) % c; b = b/2; a = (a * a) % c; } return ans;}void init(){ n=read();k=read(); if(n){ scanf("%s",a); scanf("%s",b); } plu[0]=1; for(int i=1;i<=n;i++){ (plu[i]=plu[i-1]*i)%=modd; ni[i]=PowerMod(plu[i],modd-2,modd); }}long long calc(int n1,int k1){ if(n1==k1||(!k1))return 1; if(k1>n1)return 0; long long lll; return lll=(long long )(((plu[n1]*ni[n1-k1])%modd)*ni[k1])%modd;}void work(){ for(int i=0;i<n;i++) for(int j=0;j<26;j++){ if(b[i]==j+'a'){ if(a[i]!=j+'a')k--; break; } if(a[i]==j+'a')(ans+=calc(n-i-1,k)*PowerMod(25,k,modd))%=modd; else if(k)(ans+=calc(n-i-1,k-1)*PowerMod(25,k-1,modd))%=modd; } printf("%d",(int)ans+1);}void debug(){ //}int main(){ init(); work(); //debug(); return 0;}
T2:
题意:
每个点都从圈上的0处出发,每次前进ai格,求永远不会被踩到格子的个数。
分析:首先,用容斥加上各种鬼畜优化,其实是不会T的。但是,太TM难写了。
然后就是,我们可以思考,如果用普通容斥,一定会有很多数字被重复枚举,因为2^50远远大于max n;
所以我们就可以考虑枚举因数,若这个因数是某一个数步子的倍数(这里要对步数做处理使得以这种步子走一圈就能覆盖所有他能覆盖的点)那么这个因数的倍数一定会被覆盖。然后由于这里我们要去掉的是gcd(i,n)==i的情况数即与n的共同因数只有i的数(why?因为每个数与ngcd的值都是唯一的,所以用这种方法一定不会漏不会重!而且phi(n/i)=情况数,所以就这样了。
phi(n/i)=情况数的证明:
求gcd(n,i)==d的个数,把d除过去:
gcd(n/d,i)==1的个数(因为n/d了,所以不会再有公因数了),所以就互质了,所以就用phi()了……
#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<set>#include<map>#include<stack>#include<vector>#include<ctime>#define ll long long#define inf 2e8#define modd 1e9+7#define clr(x) memset(x,0,sizeof(x))#define maxen(x) memset(x,127,sizeof(x))#define maxer(x) memset(x,31,sizeof(x))#define each(i,n) for(int i=1;i<=n;i++)#define minn(a,b,c) min(a,min(b,c))#define maxx(a,b,c) max(a,max(b,c))#ifdef WIN32#define lld "%I64d"#else#define lld "%lld"#endif#define PROC "T2"//for(int i=1;i<=n;i++)//(double) (ll) LL (int)//(double)clock()/CLOCKS_PER_SECusing namespace std;const int Maxn=4e4+5;int cnt,n,m,num,a[55],d[Maxn];int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int gcd(int a,int b){ return b==0?a:gcd(b,a%b);}void init(){ n=read();m=read(); each(i,m)a[i]=read(),a[i]=gcd(a[i],n); int t=n; for(int i=2;i*i<=n;i++) if(!(t%i)){ d[++cnt]=i; while(!(t%i))t/=i; } if(t>1)d[++cnt]=t;}int phi(int cur){ int flg=cur; each(i,cnt)if(!(cur%d[i])) flg=flg/d[i]*(d[i]-1); return flg;}int solve(int cur){ each(i,m)if(!(cur%a[i])) return phi(n/cur); return 0;}void work(){ for(int i=1;i*i<=n;i++)if(!(n%i)){ num+=solve(i); if(i*i!=n)num+=solve(n/i); } printf("%d",n-num);}void debug(){ //}int main(){ init(); work(); //debug(); return 0;}
T3:
题意:给定一树(n节点),每个点有权值,选一点必选其父节点,所选点数有限制(lim)求最大收益。
分析:TYVJ选课问题几乎照搬,但加强了数据所以必须nLim过,值得高兴的是,我之前写的就是nlim算法。所以具体分析可以翻来看。
废话几句,上次做说到的那道题,对这种做法理解还很艰难,可放了一段时间后反而清晰起来,今天自己没想起来这道题却自然推出了做法,不得不说是一种进步。
所以潜意识默默做的梳理真是重要,不理解的东西就放放吧说不定过一段时间就懂了。
#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<set>#include<map>#include<stack>#include<vector>#include<ctime>#define ll long long#define inf 2e8#define modd 1e9+7#define clr(x) memset(x,0,sizeof(x))#define maxen(x) memset(x,127,sizeof(x))#define maxer(x) memset(x,31,sizeof(x))#define each(i,n) for(int i=1;i<=n;i++)#define minn(a,b,c) min(a,min(b,c))#define maxx(a,b,c) max(a,max(b,c))#ifdef WIN32#define lld "%I64d"#else#define lld "%lld"#endif#define PROC "T3"//for(int i=1;i<=n;i++)//(double) (ll) LL (int)//(double)clock()/CLOCKS_PER_SECusing namespace std;const int Maxn=1e5+5;int fr[Maxn],tov[2*Maxn],des[2*Maxn];int n,lim,sta,fin,w[Maxn],f[Maxn][3005];int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void addedge(int cur){ sta=read();fin=read(); tov[2*cur-1]=fr[sta];fr[sta]=2*cur-1;des[2*cur-1]=fin; tov[2*cur]=fr[fin];fr[fin]=2*cur;des[2*cur]=sta;}void init(){ n=read();lim=read(); each(i,n)w[i]=read(); each(i,n-1)addedge(i); fr[0]=2*n-1;des[2*n-1]=1;}/*void dfs(int u,int fa,int lef){ if(!lef)return; f[u][lef]=w[u]; lef--; for(int i=fr[u];i;i=tov[i]) if(des[i]!=fa){ for(int j=1;j<=lef;j++){ dfs(des[i],u,j); f[u][lef]=max(f[u][lef],f[des[i]][j]+w[u]); } }}*/void dfs(int cur,int lef,int fa){ if(lef<=0)return; for(int i=fr[cur];i;i=tov[i]) if(des[i]!=fa){ for(int j=0;j<lef;j++) f[des[i]][j]=f[cur][j]+w[des[i]]; dfs(des[i],lef-1,cur); for(int j=1;j<=lef;j++) f[cur][j]=max(f[cur][j],f[des[i]][j-1]); }}void work(){ dfs(0,lim,0); printf("%d",f[0][lim]);}void debug(){ //}int main(){ init(); work(); //debug(); return 0;}
- XJOI NOIP模拟题2[数论][组合数][树规]
- NOIP模拟题 2016.11.2 [数论]
- NOIP模拟赛 数论专题 扩展欧几里得 + 组合数 + 容斥原理
- 2015.11.1 [XJOI] NOIP模拟赛总结
- NOIP模拟题[贪心][DP][数论]
- NOIP模拟题[数论}[暴力][拆点]
- 【数论】计算组合数
- JZOJ__Day 2:【NOIP普及模拟】和谐数
- 【NOIP模拟】数格子
- Noip 2016 组合数问题
- 【noip 2016】组合数问题
- Noip 2016 组合数问题
- noip前的一次校内模拟的一个组合题
- 【数论】[NOIP模拟赛]无聊的计算
- ACM数论-求组合数
- [NOIP] [组合数学] NOIP2016Day2 组合数问题
- NOIP模拟题 2016.11.8 (2) [线段树] [动态逆序对] [矩阵快速幂] [数论] [欧拉函数]
- 【NOIP模拟考三】DP+组合数 day1 third 小球游戏
- HTML——基础教程 w3cschool
- 【East!_XVI】九尾妖狐 最小割
- RCNN--对象检测的又一伟大跨越
- 嵌入式软件应用程序开发框架浅见
- MySQL数据库中的Date,DateTime,TimeStamp和Time类型
- XJOI NOIP模拟题2[数论][组合数][树规]
- 从零开始学spring-boot(4)-集成Mybatis
- 替换空格
- Codevs 1169 传纸条/1043 方格取数 2008/2000年NOIP全国联赛提高组 多线程dp
- 图片占位专用
- PullToRefresh
- 网站分析(六)
- 深度 | 一篇文章带你进入无监督学习:从基本概念到四种实现模型(附论文)
- Problem 45 Triangular, pentagonal, and hexagonal (暴力)