2017/7/27 离线赛
来源:互联网 发布:淘宝店铺客服电话 编辑:程序博客网 时间:2024/05/22 04:31
T1 猴王大道东
70分的数据还是很暴力的
int main(){ dp[1][1]=1; add(1,1,1); sum[c[1][1]]++; add1(n,c[1][1],1); for(int i=2;i<=n;i++){ memset(s,0,sizeof(s)); for(int j=2;j<=m;j++){ dp[i][j]=(dp[i][j]+query(i-1,j-1))%P; dp[i][j]=((dp[i][j]-sum[c[i][j]])%P+P)%P; dp[i][j]=(dp[i][j]+s[c[i][j]])%P; dp[i][j]=(dp[i][j]+query1(m-j+1,c[i][j]))%P; add(i,j,dp[i][j]); sum[c[i][j]]=(sum[c[i][j]]+dp[i][j])%P; s[c[i][j]]=(s[c[i][j]]+dp[i][j])%P; add1(m-j+1,c[i][j],dp[i][j]); } } Pt(dp[n][m]); Pt(dp[n][m]); putchar('\n'); return 0;}
至于100分的解法,我只能去看题解了。用的是CDQ分治,我们可以在行上进行CDQ分治,在列上扫一遍,复杂度是
void Mod_pls(int &a,int b){ if((a+=b)>=P)a-=P;}void Mod_mns(int &a,int b){ if((a-=b)<0)a+=P;}int n,m,k;int c[M][M],dp[M][M],s[M*M];void CDQ(int L,int R){//L~R行 if(L==R)return; int mid=(L+R)>>1; CDQ(L,mid); for(int j=1,tot=0;j<=m;j++){//每一列 for(int i=mid+1;i<=R;i++){ Mod_pls(dp[i][j],tot); Mod_mns(dp[i][j],s[c[i][j]]); } for(int i=L;i<=mid;i++){ Mod_pls(tot,dp[i][j]); Mod_pls(s[c[i][j]],dp[i][j]); } } for(int j=1;j<=m;j++) for(int i=L;i<=mid;i++) s[c[i][j]]=0; CDQ(mid+1,R);}int main(){ Rd(n);Rd(m);Rd(k); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) Rd(c[i][j]); dp[1][1]=1; CDQ(1,n); Pt(dp[n][m]); putchar('\n'); return 0;}
T2 花果山发展
比赛的时候只敲了个60分的暴力,想过要用
typedef pair<int,int> P;map<P,bool>mp;struct node{ int x,L,R,id;}e1[M],e2[M],tmp[M];//竖着和横着bool cmp(node A,node B){ return A.x<B.x;}bool cmp1(node A,node B){ return A.L<B.L;}bool cmp2(node A,node B){ return A.R<B.R;}int n,cnt1,cnt2;int BIT[M],ans[M];ll res;void add(int x,int a){ int i=x; while(i<=100000){ BIT[i]+=a; i+=i&-i; }}int query(int x){ int res=0,i=x; while(i){ res+=BIT[i]; i-=i&-i; } return res;}int main(){ Rd(n); int x1,y1,x2,y2; for(int i=1;i<=n;i++){ Rd(x1);Rd(y1);Rd(x2);Rd(y2); if(x1==x2)e1[++cnt1]=(node){x1,min(y1,y2),max(y1,y2),i}; else{ e2[++cnt2]=(node){y1,min(x1,x2),max(x1,x2),i}; tmp[cnt2]=e2[cnt2]; mp[P(x1,y1)]=1; mp[P(x2,y1)]=1; } } sort(e1+1,e1+cnt1+1,cmp); sort(e2+1,e2+cnt2+1,cmp1); sort(tmp+1,tmp+cnt2+1,cmp2); int p1=1,p2=1; for(int i=1;i<=cnt1;i++){ int x=e1[i].x; while(p1<=cnt2&&e2[p1].L<=x){add(e2[p1].x,1);p1++;} while(p2<=cnt2&&tmp[p2].R<x){add(tmp[p2].x,-1);p2++;} int t=query(e1[i].R)-query(e1[i].L-1); if(mp.find(P(x,e1[i].L))!=mp.end())t--; if(mp.find(P(x,e1[i].R))!=mp.end())t--; res+=t; ans[e1[i].id]=t; } mp.clear(); memset(BIT,0,sizeof(BIT)); for(int i=1;i<=cnt1;i++){ tmp[i]=e1[i]; mp[P(e1[i].x,e1[i].L)]=1; mp[P(e1[i].x,e1[i].R)]=1; } sort(e2+1,e2+cnt2+1,cmp); sort(e1+1,e1+cnt1+1,cmp1); sort(tmp+1,tmp+cnt1+1,cmp2); p1=1,p2=1; for(int i=1;i<=cnt2;i++){ int y=e2[i].x; while(p1<=cnt1&&e1[p1].L<=y){add(e1[p1].x,1);p1++;} while(p2<=cnt1&&tmp[p2].R<y){add(tmp[p2].x,-1);p2++;} int t=query(e2[i].R)-query(e2[i].L-1); if(mp.find(P(e2[i].L,y))!=mp.end())t--; if(mp.find(P(e2[i].R,y))!=mp.end())t--; ans[e2[i].id]=t; } Pt(res);putchar('\n'); for(int i=1;i<=n;i++){ if(i>1)putchar(' '); Pt(ans[i]); } putchar('\n'); return 0;}
T3 猴子与数字
我一开始拘泥于题目要求
ll C[25][25],P[25][25],tmp;int a[10],b[10],v[25];void dfs(int x,int cnt,int rest,ll r){ if(x>9){ r*=P[10-cnt][rest]; if(cnt&1)tmp-=r; else tmp+=r; return; } dfs(x+1,cnt,rest,r); if(b[x]<=rest&&b[x]>=0)dfs(x+1,cnt+1,rest-b[x],r*C[rest][b[x]]);}ll solve(ll x){//[1,x) ll res=0; for(int i=0;i<=9;i++)b[i]=a[i]; int len=0; while(x){v[++len]=x%10;x/=10;} for(int i=1;i<len;i++){//长度为i tmp=0; dfs(0,0,i,1); res+=tmp; tmp=0; b[0]--; dfs(0,0,i-1,1); res-=tmp; b[0]++; } for(int i=len;i>=1;i--){//长度相同时第i位 for(int j=(i==len);j<v[i];j++){ b[j]--; tmp=0; dfs(0,0,i-1,1); res+=tmp; b[j]++; } b[v[i]]--; } return res;}void Init(){ for(int i=0;i<=10;i++){ P[i][0]=1; for(int j=1;j<=20;j++)P[i][j]=P[i][j-1]*i; } C[0][0]=1; for(int i=1;i<=20;i++){ C[i][0]=1; for(int j=1;j<=i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j]; }}int main(){ ll L,R; Init(); Rd(L);Rd(R); for(int i=0;i<10;i++)Rd(a[i]); Pt(solve(R+1)-solve(L)); putchar('\n'); return 0;}
T1的CDQ分治确实值得仔细琢磨一下,既降低了时间复杂度,又节省了空间。T2用的算法我都会,但是就是没想到,有些问题只要排一下序,一遍扫过来即可。T3则是当时觉得太麻烦,也没有转换思路,没有运用前缀和的思想,这个方法化繁为简的确很明显。
- 2017/7/27 离线赛
- 2017/7/15 离线赛
- 2017/7/24 离线赛
- 2017/8/7 离线赛
- 2017-10-27离线赛小结
- 2017/7/29 离线赛 总结
- 2017-10-7离线赛题解
- 2017-10-7离线赛总结
- 2017-11-7离线赛总结
- 2017.10.27离线赛总结
- 2017/8/5 离线赛
- 2017/8/9 离线赛
- 2017/8/11 离线赛
- 2017/8/14 离线赛
- 2017/8/19 离线赛
- 2017/8/20 离线赛
- 2017/8/26 离线赛
- 2017/9/2 离线赛
- HDU-寻找大富翁
- 读properties和写properties文件
- 工具
- 大、小端机器判断
- 用Scala模拟RPC通信
- 2017/7/27 离线赛
- Spark 2.0 DataFrame map操作中Unable to find encoder for type stored in a Dataset.问题的分析与解决
- 51nod 1189 阶乘分数
- 错误与调试
- 再次整理Ubuntu下多个jdk版本切换的问题
- 斐波那契数列-实现1
- 实现安卓主页面代码
- Java二叉搜索树(Binary Search Tree)实现
- 浅谈如何用try、catch、finally捕获异常