今天没听见学长说用cena不要建子文件夹,手贱建了啊啊啊然后就gg了啊,哭qwq
Ant
问题描述
询问 1~n 中间约数个数最多的数
输入格式
一个数 n
输出格式
输出 1~n 中间约数个数最多的数,如果有多个输出最小的那个
样例输入
1000
样例输出
840
数据规模和约定
10%的数据满足:1≤n≤5000。
30%的数据满足:1≤n≤100000。
100%的数据满足:1≤n≤2000000000。
题解:
做过的原题(不太记得是哪个oj了,说不定是openjudge),好像以前第一次写的时候是直接抄的题解啊……
很简单,首先你要会求一个数的约数个数,其结果为:所有质因数的指数加上1后的乘积。
看到题中还有一个小小的坑:如有多组解输出最小的那个。
这就要求我们分解质因数后,限制较小质因数的指数,必须严格大于比它大的质因数的指数。(感觉说起来好绕口啊)比如,2^3*3^1=24,2^2*3^2=36,24<36。
证明:反证法,如果你有一个已经分解了的数,其中2的指数比3小,那你显然可以找到一个2的指数再加1,3的指数再减1的乘积。这个乘积必定比之前的小,而且计算约数的个数也和之前一样。(顺便%一下机房大佬lyy)
最后限制一下输出。
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #define ll long long 7 using namespace std; 8 inline void Edwina() 9 { 10 freopen("ant.in","r",stdin); 11 freopen("ant.out","w",stdout); 12 } 13 int prime_num[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51}; 14 ll mmax,n,ans; 15 void solve(ll now,int prim,int tot,int up)//now是当前值,tot为约数的个数,up限制指数大小 16 { 17 if(((tot==mmax)&& (now<ans))||(tot>mmax)) 18 ans=now,mmax=tot; 19 //mmax=max(tot,mmax),ans=min(now,ans); 20 int nxt_up=0,l=1,sum_prim; 21 ll i=now; 22 while(nxt_up<up) 23 { 24 nxt_up++;l++; 25 if(n/i<prime_num[prim]) 26 break; 27 sum_prim=tot*l; 28 i*=prime_num[prim]; 29 if(i<=n) 30 solve(i,prim+1,sum_prim,nxt_up); 31 } 32 } 33 int main() 34 { 35 Edwina(); 36 mmax=-1;ans=-1; 37 scanf("%lld",&n); 38 solve(1,1,1,30); 39 printf("%lld",ans); 40 fclose(stdin); 41 fclose(stdout); 42 return 0; 43 }
Red
问题描述
桌面上有 R 张红牌和 B 张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到 1 美元,黑牌则付出 1 美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。
输入格式
一行输入两个数 R、B。
输出格式
在最优策略下平均能得到多少钱。
样例输入
5 1
样例输出
4.166666
数据规模和约定
R,B<=5000
输出答案时,小数点后第六位后的全部去掉,不要四舍五入。
题解:
一看就是期望dp。我们定义f(i,j)为当前状态下,还有i张红牌和j张黑牌没翻的期望受益,转移时两种情况下的结果都要考虑。
于是f[i][j]=max(0,i/(i+j)*(f[i-1][j]+1)+j/(i+j)*(f[i][j-1]-1))
空间注意要用滚动数组。
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #define ans1 ((f[j-1][end]+1)*j/i) 7 #define ans2 ((f[j][end]-1)*(i-j)/i) 8 #define ll long long 9 using namespace std; 10 //const int maxn=5001; 11 inline void Edwina() 12 { 13 freopen("red.in","r",stdin); 14 freopen("red.out","w",stdout); 15 } 16 double f[10009][2];//开滚动数组 17 double mmax(double a,double b){return a>b?a:b;} 18 int main() 19 { 20 Edwina(); 21 int R,B,k=0,end=1; 22 scanf("%d%d",&R,&B); 23 for(int i=1;i<=R+B;i++,end^=1,k^=1) 24 { 25 for(int j=0;j<=i&&j<=R;j++) 26 { 27 if(j==0) 28 f[j][k]=0; 29 else 30 { 31 if(i==j) 32 f[j][k]=j; 33 else 34 f[j][k]=mmax(0,ans1+ans2); 35 //ans1 ((f[j-1][end]+1)*j/i) 36 //ans2 ((f[j][end]-1)*(i-j)/i) 37 } 38 } 39 } 40 printf("%.6lf\n",floor(f[R][end]*1000000)/1000000);//对于小数位的处理 41 //ll ans=(ll)(f[R][end]*1000000); 42 //printf("%lld.%06lld\n",ans/1000000,ans%1000000); 43 fclose(stdin); 44 fclose(stdout); 45 return 0; 46 }
Alone
问题描述
QY 以前曾经同时与一些妹子交往,妹子们之间的关系成一棵树。一开始每个妹子对他都有一个好感度。因为 QY 太神犇了,所以很多人给他出了一些题目,
他每 AC 一道 A 出给他的题目会导致以 A 为根的子树中除了 A 以外所有的妹子对他的好感度下降。
操作 1:QY AC 了 A 出的题目导致以 A 为根的子树中除了 A 以外所有的妹子对他的好感度下降。
操作 2: QY 想要知道以 A 为根的子树中除了 A 以外还有几个对他好感度>0 的。
树根处的妹子编号为 0,她对 QY 的好感度可以看做是无限的。
输入格式
第一行一个整数 N。
代表有 N+1 个妹子,编号分别是 0~N。
接下来 N 行每行两个整数,第一个整数表示编号为 i 的妹子的好感度 H,第二个整数表示第i个妹子在树上的父亲Fi(保证妹子i的父亲的编号小于i)
接下来一行一个整数 Q。
接下来 Q 行,每行一个操作。
第一类操作读入三个参数{1,Ai,Xi}表示 QY使以 Ai 为根的子树中除了 Ai 以外所有的妹子对他的好感度下降 Xi。
第二类操作读入两个参数{2,Ai}表示询问以 Ai 为根的子树中除了 Ai 以外有几个妹子对 QY的好感度>0。
输出格式
对于每一个第二类操作,输出一行一个整数,表示所询问的答案。
样例输入
4
1 0
2 0
2 2
1 2
4
1 2 1
2 2
1 0 1
2 0
样例输出
1
1
数据规模和约定
对于 30%的数据,满足 1<=N<=1000,1<=Q<=1000。
对于另外 20%的数据,保证数据纯随机生成。
对于 100%的数据,满足 1<=N<=10^5,1<=Q<=10^5,0<=Ai<=N,1<=Hi<=10^9,1<=Xi<=10^4,0<=Fi<i。
emmm……先贴上fy学长的std……
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #define N 100010 7 using namespace std; 8 struct treenode 9 { 10 int l,r,lazy,minn,sum,mid; 11 }tree[N*4]; 12 int tot=-1,ver[N],next[N],head[N],first[N],second[N],v[N],tim=0,a,h[N],b,c,n,m,used[2]; 13 void add(int a,int b) 14 { 15 tot++; 16 ver[tot]=b; 17 next[tot]=head[a]; 18 head[a]=tot; 19 } 20 21 void build(int tr,int l,int r) 22 { 23 tree[tr].l=l; 24 tree[tr].r=r; 25 tree[tr].lazy=0; 26 if (l==r) 27 { 28 tree[tr].sum=1; 29 tree[tr].minn=h[v[l]]; 30 return; 31 } 32 int mid=(l+r)/2; 33 build(tr*2,l,mid); 34 build(tr*2+1,mid+1,r); 35 tree[tr].minn=min(tree[tr*2].minn,tree[tr*2+1].minn); 36 tree[tr].mid=(tree[tr].l+tree[tr].r)>>1; 37 tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum; 38 } 39 void change(int tr,int l,int r,int data) 40 { 41 if (tree[tr].l==l&&r==tree[tr].r) 42 { 43 tree[tr].lazy+=data; 44 if (tree[tr].minn<=tree[tr].lazy) 45 { 46 if (tree[tr].l==tree[tr].r) 47 { 48 tree[tr].sum=0; 49 tree[tr].minn=0x3f3f3f3f; 50 tree[tr].lazy=0; 51 } 52 else 53 { 54 change(tr*2,tree[tr].l,tree[tr].mid,tree[tr].lazy); 55 change(tr*2+1,tree[tr].mid+1,tree[tr].r,tree[tr].lazy); 56 tree[tr].lazy=0; 57 tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum; 58 tree[tr].minn=min(tree[tr*2].minn-tree[tr*2].lazy,tree[tr*2+1].minn-tree[tr*2+1].lazy); 59 } 60 } 61 return; 62 } 63 if (tree[tr].lazy) 64 { 65 change(tr*2,tree[tr].l,tree[tr].mid,tree[tr].lazy); 66 change(tr*2+1,tree[tr].mid+1,tree[tr].r,tree[tr].lazy); 67 tree[tr].lazy=0; 68 } 69 if (r<=tree[tr].mid) change(tr*2,l,r,data); 70 else if (l>tree[tr].mid) change(tr*2+1,l,r,data); 71 else 72 { 73 change(tr*2,l,tree[tr].mid,data); 74 change(tr*2+1,tree[tr].mid+1,r,data); 75 } 76 tree[tr].minn=min(tree[tr*2].minn-tree[tr*2].lazy,tree[tr*2+1].minn-tree[tr*2+1].lazy); 77 tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum; 78 } 79 80 int ask(int tr,int l,int r) 81 { 82 if (tree[tr].l==l&&tree[tr].r==r) return tree[tr].sum; 83 int mid=(tree[tr].l+tree[tr].r)/2; 84 if (r<=mid) return ask(tr*2,l,r); 85 else if (l>mid) return ask(tr*2+1,l,r); 86 else return ask(tr*2,l,mid)+ask(tr*2+1,mid+1,r); 87 } 88 89 void dfs(int a) 90 { 91 first[a]=++tim; 92 v[tim]=a; 93 for (int i=head[a];i!=-1;i=next[i]) 94 dfs(ver[i]); 95 second[a]=tim; 96 } 97 98 int main() 99 { 100 freopen("alone.in","r",stdin); 101 freopen("alone.out","w",stdout); 102 cin>>n; 103 memset(head,-1,sizeof(head)); 104 for (int i=1;i<=n;i++) 105 scanf("%d%d",&h[i],&a),add(a,i); 106 h[0]=0x3f3f3f3f; 107 dfs(0); 108 cin>>m; 109 build(1,1,n+1); 110 for (int i=1;i<=m;i++) 111 { 112 scanf("%d",&a); 113 if (a==1) 114 { 115 scanf("%d%d",&b,&c); 116 if (first[b]!=second[b]) change(1,first[b]+1,second[b],c); 117 } 118 else 119 { 120 scanf("%d",&b); 121 if (first[b]!=second[b]) printf("%d\n",ask(1,first[b]+1,second[b])); 122 else printf("0\n"); 123 } 124 } 125 fclose(stdin); 126 fclose(stdout); 127 return 0; 128 }