大体状况

300/300
?因为是真题所以稍微简单一些吗= =
题目来源 NOIP2011 Day2

T1 factor

分析

求(ax+by)k(ax+by)^k中anbma^nb^m的系数。
二项式杨辉三角展开后
((ax)+(by))k((ax)+(by))^k
=Cnk(ax)n(by)m=C_k^n(ax)^n(by)^m
=k!n!m!anbmxnym=\frac{k!}{n!m!}a^nb^mx^ny^m
所以可以直接快速幂求得。
时间复杂度O(k)O(k)
然而k≤1000k \le 1000所以暴力求也没关系吧。

代码

#include<bits/stdc++.h>
using namespace std;#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define LL long longvoid Rd(int &res){char c;res=0;while((c=getchar())<48);do res=(res<<3)+(res<<1)+(c^48);while((c=getchar())>47);
}#define M 1004
#define Mod 10007
int Fac[M];
int a,b,k,n,m;
int Pow(int x,int p){int Res=1;for(int k=x%Mod;p;p>>=1,k=k*k%Mod)if(p&1)(Res*=k)%=Mod;return Res;
}
int main(){Rd(a),Rd(b),Rd(k),Rd(n),Rd(m);Fac[0]=1;REP(i,1,k+1)Fac[i]=Fac[i-1]*i%Mod;if(k==0)puts("1");else printf("%d\n",Fac[k]*Pow(Fac[n],Mod-2)%Mod*Pow(Fac[m],Mod-2)%Mod*Pow(a,n)%Mod*Pow(b,m)%Mod);return 0;
}

T2 qc

分析

|S−Y||S-Y|是一个有谷的函数。
二分WW是必需的。
然后就要考虑如何在区间内查询wj≥Ww_j \ge W的矿石数量与价值和。
首先想到的当然是主席树(不
然后主席树维护的话是O(mlog2n)O(mlog^2n)的,感觉一定会被卡常。
发现一次查询是连续的m次,然后n与m是同阶的。
所以明明扫一遍对wj≥Ww_j \ge W的矿石做前缀和就可以了。

代码

#include<bits/stdc++.h>
using namespace std;#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define LL long longvoid Rd(int &res){char c;res=0;while((c=getchar())<48);do res=(res<<3)+(res<<1)+(c^48);while((c=getchar())>47);
}
#define M 200004
int n,m,W[M],V[M],L[M],R[M];
LL S;
struct P100{int P[M],sz;int Cnt[M];LL Sum[M];LL Y(int x){REP(i,1,n+1)Cnt[i]=Cnt[i-1]+(W[i]>=x),Sum[i]=Sum[i-1]+((W[i]>=x)*V[i]);LL Res=0;REP(i,0,m){Res+=(Sum[R[i]]-Sum[L[i]-1])*(Cnt[R[i]]-Cnt[L[i]-1]);}return Res;}void Solve(){REP(i,1,n+1)P[i]=W[i];sort(P+1,P+n+1);sz=unique(P+1,P+n+1)-P-1;REP(i,1,n+1)W[i]=lower_bound(P+1,P+sz+1,W[i])-P;int l=1,r=sz;LL Ans=S;while(l<=r){int Mid=l+r>>1;LL Tmp=Y(Mid);chkmin(Ans,abs(S-Tmp));if(Tmp>S)l=Mid+1;else r=Mid-1;}REP(x,max(1,l-2),min(sz+1,l+2))chkmin(Ans,abs(S-Y(x)));printf("%lld\n",Ans);}
}P100;
int main(){Rd(n),Rd(m),scanf("%lld",&S);REP(i,1,n+1)Rd(W[i]),Rd(V[i]);REP(i,0,m)Rd(L[i]),Rd(R[i]);P100.Solve();return 0;
}

T3 bus

分析

P60

这题贪心的思路还是比较显然的。
处理出该加速器影响的区间(即均满足Timei>MxiTime_i>Mx_i)后,
加速器之间不会互相影响。
因此满足最优性,那么直接贪心的复杂度为O(nmk)或O(n2k)O(nmk)或O(n^2k)
即枚举每个位置计算其减少量,然后使用加速器。

P100

上面的思路稍微改改就能得到O(nk)O(nk)的简单做法。
处理出区间后,显然在更左用加速器更优。
用一个指针扫过去得到每个位置的值即可。
然后这样就能过所有数据。

代码

#include<bits/stdc++.h>
using namespace std;#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define LL long longvoid Rd(int &res){char c;res=0;while((c=getchar())<48);do res=(res<<3)+(res<<1)+(c^48);while((c=getchar())>47);
}#define N 1004
#define M 10004int n,m,k,D[N],Cnt[N],Mx[N],Tim[N];
int T[M],A[M],B[M];bool Delete(){REP(i,1,n) Tim[i+1]=max(Tim[i],Mx[i])+D[i];int Pos=0,Max=-1;for(int i=1,j;i<n;i++) if(D[i]>0){j=i+1;int Res=Cnt[j];while(Tim[j]>Mx[j]) Res+=Cnt[++j];if(Res>Max) Max=Res,Pos=i;i=j-1;}if(Max==-1)return 1;D[Pos]--;return 0;
}
int main(){Rd(n),Rd(m),Rd(k);REP(i,1,n)Rd(D[i]);REP(i,0,m){int t,a,b;Rd(t),Rd(a),Rd(b);Cnt[b]++;chkmax(Mx[a],t);T[i]=t,A[i]=a,B[i]=b;}REP(i,0,k)if(Delete())break;REP(i,1,n) Tim[i+1]=max(Tim[i],Mx[i])+D[i];int Ans=0;REP(i,0,m) Ans+=Tim[B[i]]-T[i];printf("%d\n",Ans);return 0;
}

优化

注意到上面的方法进行了很多次重复的计算Time,
以及重复地查找那些可能已知的值,可以对于其采用区间更新的方法。
区间更新仍然要在所有当前可用的区间中寻找最大值。
所以可以用一个堆来存放当前所有区间。
每次提取出乘客数最大的区间,查看其是否合法并用最小的可能值更新。
然后拆成两半。
理论复杂度最差为O(n2logn)O(n^2logn),实际上非常快。

代码

#include<bits/stdc++.h>
using namespace std;#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define LL long longvoid Rd(int &res){char c;res=0;while((c=getchar())<48);do res=(res<<3)+(res<<1)+(c^48);while((c=getchar())>47);
}#define N 1004int n,m,k,D[N],Cnt[N],Mx[N],Tim[N],Ans;
struct Node{int l,r,x;bool operator <(const Node &_)const{return x<_.x;}
};
priority_queue<Node>Q;
int main(){Rd(n),Rd(m),Rd(k);REP(i,1,n)Rd(D[i]);REP(i,0,m){int t,a,b;Rd(t),Rd(a),Rd(b);Cnt[b]++;chkmax(Mx[a],t);Ans-=t;}REP(i,1,n) Tim[i+1]=max(Tim[i],Mx[i])+D[i];REP(i,1,n+1) Ans+=Cnt[i]*Tim[i];REP(i,2,n+1) Cnt[i]+=Cnt[i-1];Q.push((Node){1,n,Cnt[n]-Cnt[1]});while(!Q.empty() && k){Node T=Q.top();Q.pop();int l=T.l,r=T.r,x=T.x;int Pos=-1,Use=min(k,D[l]);REP(i,l+1,r)if(Use>Tim[i]-Mx[i])Use=Tim[i]-Mx[i],Pos=i;if(Use>0){//满足要求,可以更新D[l]-=Use;k-=Use;Ans-=x*Use;REP(i,l,r)Tim[i+1]=max(Tim[i],Mx[i])+D[i];}if(~Pos){//拆为两个区间Q.push((Node){l,Pos,Cnt[Pos]-Cnt[l]});Q.push((Node){Pos,r,Cnt[r]-Cnt[Pos]});}else if((++l)<r)Q.push((Node){l,r,Cnt[r]-Cnt[l]});}printf("%d\n",Ans);return 0;
}

另一个方法

这个贪心还可以用最小费用最大流来做。
然而比暴力还慢,
最差复杂度为O(k∗SPFA(n,n))O(k*SPFA(n,n))或O(knlogn)O(knlogn)
首先裂点ii为ii与i′i',方便限制的添加。
从每个ii向i′i'连一条容量为max(0,Timei−Mxi)max(0,Time_i-Mx_i),费用为0的边,
作为可被更新到的分界线。
从源点ss向每个i′i'连一条容量为DiD_i,费用为0的边,
表示最大加速的限制。
从每个(i−1)′(i-1)'向ii连一条容量为INFINF,费用为−Cnti-Cnt_i的边,
表示每个加速器在这个点带来的收益
从每个ii向汇点tt连一条容量为INFINF,费用为0的边,
作为加速器的结束位置。
然后套模板费用流。

代码

#include<bits/stdc++.h>
using namespace std;#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define LL long long
#define INF 0x3f3f3f3fvoid Rd(int &res){char c;res=0;while((c=getchar())<48);do res=(res<<3)+(res<<1)+(c^48);while((c=getchar())>47);
}#define M 1044struct Edge{int u,v,w,c;
}E[(M<<3)+44];
template<const int Len,const int Num>struct Linklist{int G[Len],Next[Len],Head[Num],tot;int operator [](int x){return G[x];}void pb(int u,int id){Next[++tot]=Head[u],G[Head[u]=tot]=id;}#define LREP(i,a,G) for(int i=G.Head[a];i;i=G.Next[i])
};
Linklist<(M<<3)+44,(M<<1)>G;int n,m,k,etot;
void Add_Edge(int u,int v,int w,int c){assert(etot<((M<<3)+44));E[etot]=(Edge){u,v,w,c}; G.pb(u,etot++);E[etot]=(Edge){v,u,0,-c};G.pb(v,etot++);
}
int Dis[M<<1];
bool Vis[M<<1];
int Fa[M<<1];
int s,tp,t,Ans;
queue<int>Q;
void MCF(int f){while(f>0){while(!Q.empty())Q.pop();memset(Dis,63,sizeof(Dis));Dis[s]=0,Q.push(s);while(!Q.empty()){int A=Q.front();Q.pop();Vis[A]=0;LREP(i,A,G){Edge e=E[G[i]];if(!e.w)continue;int B=e.v;if(Dis[B]>Dis[A]+e.c){Dis[B]=Dis[A]+e.c;Fa[B]=G[i];if(!Vis[B])Q.push(B),Vis[B]=1;}}}if(Dis[t]==INF)break;int x=t,Dec=f;while(x!=s){chkmin(Dec,E[Fa[x]].w);x=E[Fa[x]].u;}x=t;while(x!=s){E[Fa[x]].w-=Dec,E[Fa[x]^1].w+=Dec;Ans+=Dec*E[Fa[x]].c;x=E[Fa[x]].u;}f-=Dec;}
}
int D[M],Tim[M],Cnt[M],Mx[M];
int main(){Rd(n),Rd(m),Rd(k);REP(i,1,n)Rd(D[i]);REP(i,0,m){int t,a,b;Rd(t),Rd(a),Rd(b);Cnt[b]++;chkmax(Mx[a],t);Ans-=t;}REP(i,1,n) Tim[i+1]=max(Tim[i],Mx[i])+D[i];REP(i,1,n+1) Ans+=Cnt[i]*Tim[i];s=0,t=(n<<1)+4,tp=t-1;Add_Edge(tp,t,k,0);REP(i,1,n+1) Add_Edge(i,i+n,max(0,Tim[i]-Mx[i]),0);REP(i,2,n+1) Add_Edge(i-1+n,i,INF,-Cnt[i]);REP(i,1,n+1) Add_Edge(i,tp,INF,0);REP(i,1,n) Add_Edge(s,i+n,D[i],0);MCF(k);printf("%d\n",Ans);return 0;
}

2017-10-17离线赛相关推荐

  1. 2017.10.16离线赛总结

    draw --3787 思路:这是源自一个岛国的游戏- 思考一下画鬼脚的本质,一条竖线其实就是一次对相邻两个元素的交换操作. 所以,模拟画鬼脚的时候,只需要按照高度从高到低,依次进行所有的交换操作即可 ...

  2. 2017.10.26模拟赛day1

    -- T1为爱追寻 问题描述 历经了半年的停课之后,紫萱学姐回到了陌生又熟悉的班里,她想找到学长的位置.于是她决定采用一种高效率的寻找方法:瞎找法. 我们将学姐的班级视为一个二维平面,每个整数坐标对应 ...

  3. 2017.10.17 Codechef MARCH14 GERALD07加强版 失败总结

    以前做这个题简直是噩梦的难度 有个很神的做法就是 利用最简联通形式来统计联通块 把一个要求的区间写成一颗等价的树,,就有了统一的标准 然后考虑怎么构造这棵树,看每次加入的边,如果已经联通,则考虑把这个 ...

  4. 2017.10.17 蜘蛛难题 思考记录

    强烈建议不要做此题,此题描述差到极点!毒瘤出题人 首先有想法就是从起点往后按照出水管依次满足,但多个水域需要合起来求下一个最低出水口,所以并不是很好维护 所以最好按照时间模拟 先求出当前状态下的最低水 ...

  5. 2017.10.17 CF#441 F题 思考记录

    .果然没有题解做题感觉是不一样的. 这个F题可能是最像往常B题的题了(往常B题就是dp,还一般都不难) 首先这个是|,所以|的数越多,它一定是不降的 那么合法的一定是一个数到一个数往后的数所构成的所有 ...

  6. NOIP2017模拟赛总结(2017.10.30-2017.11.1)

    第三篇博客,放上2017.10.30-2017.11.1的题. 2017.10.30 Problem A 题目大意: 有一排nnn棵果树和一个容量为sss的果篮,从前往后摘果,如果当前果树的果子数量不 ...

  7. 2020年 第11届 蓝桥杯 Java B组 省赛真题详解及小结【第2场省赛 2020.10.17】

    蓝桥杯 Java B组 省赛真题详解及小结汇总[2013年(第4届)~2020年(第11届)] 说明:大部分题解思路及程序代码 源自 蓝桥杯 官网视频(Java B组历年真题解析) -- 郑未老师. ...

  8. CT 系统参数标定及反投影重建成像-2017数模国赛论文A298编程分析

    CT 系统参数标定及反投影重建成像-2017数模国赛论文A298编程分析 之前的同学已经讲解清楚了这篇论文建模的主要思路,我主要讲解代码对建模思路的实现. 本文提到的论文下载地址:http://dxs ...

  9. 杂记2017.10.16

    杂记2017.10.16 ---------------- 2017.4.11 1,pivot是UI的图形中心.0.5,0.5表示该UI的原点在其图形正中 0,0表示该UI的原点在其图形左上角. 2, ...

  10. 2018.10.9模拟赛

    2018.10.9模拟赛 T1 trade 正解:贪心 据说lyd讲过但并没有印象QAQ,考场上现推浪费了不少时间 其实就开个小根堆,每次把堆顶取出来看它是不是比当前的 a[i]a[i]a[i] 小, ...

最新文章

  1. 2018-3-14智能算法(文章--优化问题的智能算法及其哲学内涵)笔记一(什么是优化问题)
  2. 检测移动端内存敏感数据方法(安卓)
  3. 第十六讲 傅里叶级数拓展
  4. Linux网络安装(PXE + DHCP+TFTP+ Kickstart+ FTP)
  5. poj 3608 旋转卡壳求不相交凸包最近距离;
  6. Java循环添加文件_java – 使用jGit循环提交文件
  7. Docke--利用 commit 理解构建镜像
  8. 面向对象程序的设计模式
  9. php 类中输出所有属性,PHP基于反射获取一个类中所有属性
  10. xen服务器不能挂载iso文件,Citrix XenCenter安装VM:挂载ISO详解
  11. 计算机网络生活应用,浅谈计算机网络在生活中的应用
  12. 线性表——链表(含代码)
  13. U盘做成Mac启动盘之后怎么恢复成原来的U盘(U盘变成efi怎么恢复)
  14. 艾司博讯:拼多多怎么设置团长ID?团长权限?
  15. 有用的函数-系统采集(一)
  16. 【CTS】Ubuntu下安装CTS测试环境
  17. 湖南交通学院校友会小程序云开发解决方案
  18. 连环锁 POJ - 1832(格雷码与二进制)
  19. vue3时间戳格式转换
  20. 对象(创建对象、构造函数)

热门文章

  1. C语言图书管理系统验证码,C语言的图书管理系统
  2. Linux线程基本知识
  3. TerraSAR-X雷达遥感卫星
  4. 光伏发电与“鸭子曲线”
  5. 20个最好的在线网站 Fav 图标生成工具
  6. 复数神经网络_如果神经网络状态为复数会发生什么?
  7. CentOS编译安装Qt(Qt可使用静态编译编译器)
  8. 上海市专业计算机学校地址,上海计算机专业学校
  9. IoT学习之IFTTT(一)Hello World!
  10. 第十一章 曲面积分与曲线积分(同济高等数学A)