首页 > 代码库 > Fixed Point 解题报告
Fixed Point 解题报告
题目总结:
这种数论动规的关键点是在“与上届相等的数的处理”上,只要这个弄懂了,这种题应该就都会做了。
因为和上届相等的数最多只有一个,所以我用一个equal来记录是否有满足条件的上届。而其他小于上届的数用f数组储存。
策略只有取1和取0。
小于上届的数可以随便取。
equal的状态转移要好好想想:
当前位为1:取1则equal保留,取0则equal可以转移到f数组。
当前位为0:取0则equal保留。取1就比上届大了,舍去。
一般性总结:
1.打草稿分析样例很有效果。
2.直接用不加证明的结论这种习惯不好。这道题中以及Coprime Sequence中已经深有体会。
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 6 #define FORD(i,r,l) for(int i=(r);i>=(l);i--) 7 #define rep(i,n) for(int i=0;i<(n);i++) 8 using namespace std; 9 typedef long long LL;10 typedef unsigned int ui;11 ui get2[33];12 13 LL f[33][33];14 LL gao(ui R, ui c, int k, int flag)15 {16 memset(f,0,sizeof(f));17 LL equal=1; int gs0=0;18 FORD (z,31,0)19 {20 //021 if (flag>=0 || !(c&get2[z]))22 {23 FOR (i,1,32-z) f[z][i]=f[z+1][i-1];24 if (R&get2[z]) f[z][gs0+1]+=equal;25 }26 //127 if (flag<=0 || (c&get2[z]))28 {29 FOR (i,0,31-z) f[z][i]+=f[z+1][i];30 }31 if ((R&get2[z]) && !(flag<=0 || (c&get2[z]))) equal=0;32 if (!(R&get2[z]) && !(flag>=0 || !(c&get2[z]))) equal=0;33 gs0+=!(R&get2[z]);34 }35 LL ret=0;36 FOR (i,0,32) if (abs(32-i-i)<=k) ret+=f[0][i];37 if (abs(32-gs0*2)<=k) ret+=equal;//~~38 return ret;39 }40 41 ui L,R,c; int k;42 LL gao0(int flag)43 {44 LL ret=gao(R,c,k,flag);45 if (L) ret-=gao(L-1u,c,k,flag);46 return ret;47 }48 49 int main()50 {51 get2[0]=1; for (int i=1;i<=32;i++) get2[i]=get2[i-1]<<1;52 53 int T; scanf("%d",&T);54 LL ans1,ans2,ans3;55 FOR (z,1,T)56 {57 scanf("%u%u%u%d",&L,&R,&c,&k);58 ans1=gao0(1);59 if (c!=0) ans2=0; else ans2=gao0(0);60 ans3=gao0(-1);61 printf("Case %d: %lld %lld %lld\n",z,ans1,ans2,ans3);62 }63 return 0;64 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。