小白月赛-9
本场新生赛和今晚的小白月赛
本次比赛还是暴力了自己很大的问题,代码量和思维量都明显不够,只会暴力和找规律,遇到稍微思维量大一点的
代码题就没办法。
优点是,比赛完后立马补题,效果最好。
A-签到
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 const ll mod = 1e9+7; 8 const int maxx = 1e5+7; 9 struct node 10 { 11 ll x,y; 12 }p[maxx]; 13 ll qpow(ll a,ll b) 14 { 15 ll ans=1; 16 while(b) 17 { 18 if(b&1) 19 { 20 ans=ans*a%mod; 21 } 22 a=a*a%mod; 23 b/=2; 24 } 25 return ans; 26 } 27 int main() 28 { 29 ll n; 30 while(~scanf("%lld",&n)) 31 { 32 for (int i=1; i<=n; i++) 33 { 34 scanf("%lld%lld",&p[i].x,&p[i].y); 35 } 36 ll ans=1; 37 ll a=1; 38 ll b=1; 39 for(int i=1; i<=n; i++) 40 { 41 a=a*(p[i].y-p[i].x)%mod; 42 b=b*qpow(p[i].y,mod-2)%mod; 43 } 44 ans=(1-a*b%mod+mod)%mod; 45 printf("%lld\n",ans); 46 } 47 return 0; 48 }
本题最开始我想错了,正解是每层楼掉东西的概率p[i]=a[i]/b[i],那么不掉东西的概率应该是
p=sigma((b[i]-a[i])/b[i])
那么掉东西的概率就是1-p,那么·这个题再求逆元,就很好办了。
B-法法
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #define ll long long int main(){ int t; scanf("%d",&t); long long n; while(t--){ scanf("%lld",&n); if (n==1 || n==2)printf("1\n"); else printf("0\n"); } return 0; }
水题:特判1,2即可
E-换个角度思考
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxx = 1e5+7; int n,m,ans[maxx]; struct node { int val; int id; } s[maxx]; bool cmpnode(node x,node y) { return x.val<y.val; } struct Query { int l,r; int h; int id; } q[maxx]; bool cmpQuery(Query x,Query y) { return x.h < y.h; } int tree[maxx]; int lowbit(int x) { return x&(-x); } void add(int i,int x) { while(i<maxx) { tree[i]+=x; i+=lowbit(i); } } int sum(int i) { int sum=0; while(i>0) { sum+=tree[i]; i-=lowbit(i); } return sum; } int query(int l,int r) { return sum(r)-sum(l-1); } int main() { memset(tree,0,sizeof(tree)); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ scanf("%d",&s[i].val); s[i].id=i; } sort(s+1,s+1+n,cmpnode);//按值进行排序 for (int i=1;i<=m;i++){ scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h); q[i].id=i; } sort(q+1,q+1+m,cmpQuery);//按照询问的右区间进行排序 int top=1;//对于每个值,如果这个数在某个区间 for (int i=1;i<=m;i++){ while(top<=n && s[top].val<=q[i].h)//这个值小于x { add(s[top].id,1);//这个位置+1等价于,这个询问后面的询问一定会询问到这个数,如果下一个询问k,依然可以比这个值小,那么后面依然可以询问道。 top++; } ans[q[i].id]=query(q[i].l,q[i].r);//那么我只需要统计这个位置就行了 } for (int i=1;i<=m;i++){ printf("%d\n",ans[i]); } return 0; } /* 5 3 1 2 3 4 5 1 4 3 3 4 5 1 5 4 */
这个题目数据有问题,暴力能过。。。。
查询区间小于等于某个数的个数,如果强制在线的话要写主席树之类的……
然而允许离线,那么可以直接用套路做题了
首先把询问拆成和,同时打上对答案产生贡献的标记(前者是,后者是)
那么现在问题就成了:查询前缀小于等于的个数
把所有询问按照右端点(实际上是)排序,然后转化为一开始给定一个空序列,每次往序列末端添加一个数,同
时支持查询这个序列小于等于的元素个数
数据范围才,树状数组维护一下就好了
H-论如何出一道水题
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int main(){ long long n; while(~scanf("%lld",&n)){ if(n==1)printf("2\n"); else printf("%lld\n",2*n-1); } return 0; }
水题,MAX(i,j),且i,j互质。
那么问题很简单,i=n-1,j=n,即可。但是要特判1;
有不懂欢迎咨询
QQ:1326487164(添加时记得备注)