CQOI2015 解题报告
CQOI2015终于全做完了~~~,讲一下题吧
首先这套题比起其他省选还是比较水的,就是5道题比较蛋疼
T1:[CQOI2015]选数
这道题还是比较神的。
首先给个比较神的题解:popoqqq大神的blog这个莫比乌斯反演真的不会
我们记f[i]为gcd=i*k时的个数,可以得到若数都不相等的话,i一定小于1e5(辗转相减法可得),那么当数都不相等时,答案显然为(r/(k*i)-l/(k*i)+1)^n-(r/(k*i)-l/(k*i)+1)-sigma(f[i*j])然后就能愉快的推出来啦,还有就是当l=1时要特判一下
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define mod 1000000007
typedef long long ll;
int power(ll x,ll y) {
ll ans=;
for (;y;y>>=){
if (y&) (ans*=x)%=mod;
(x*=x)%=mod;
}
return ans;
}
ll n,l,k,h;
#define maxk 100000
ll f[maxk+];
int main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
ll L,H;
scanf("%lld%lld%lld%lld",&n,&k,&L,&H);
ll l=L/k,h=H/k;
if (L%k) l++;
int tmp=;
for (int i=maxk;i;i--) {
ll L=l/i,H=h/i;
if (l%i) L++;
f[i]=(power(H-L+,n)-(H-L+)+mod)%mod;
for (int j=i+i;j<=maxk;j+=i) f[i]=(f[i]-f[j]+mod)%mod;
}
if (l==) f[]++;
printf("%lld\n",f[]);
return ;
}
这不就是先求出最短路图后拆点跑个最大流么= =。直接做就行了不要考虑时间问题。。。
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
#define maxm 150000
#define maxn 1100
struct edges{
int to,next,dist;ll cap;
}edge[maxm*];
int l,next[maxn];
inline void _addedge(int x,int y,int z){
l++;
edge[l*]=(edges) {x,next[y],z,};next[y]=l*;
edge[l*+]=(edges) {y,next[x],z,};next[x]=l*+;
}
inline void addedge(int x,int y,ll z){
l++;
edge[l*]=(edges){y,next[x],,z};next[x]=l*;
edge[l*+]=(edges){x,next[y],,};next[y]=l*+;
}
ll dist[maxn];
bool b[maxn];
typedef pair<ll,int> ii;
priority_queue<ii,vector<ii>,greater<ii> > q;
#define fi first
#define se second
#define inf 0x7fffffff
#define Inf inf*1ll*inf
int n;
inline void dij(){
for (int i=;i<=n;i++) dist[i]=Inf;
dist[]=;
q.push(ii(,));
while (!q.empty()){
ii u=q.top();q.pop();
if (b[u.se]) continue;
b[u.se]=;
for (int i=next[u.se];i;i=edge[i].next)
if (dist[u.se]+edge[i].dist<dist[edge[i].to]) {
dist[edge[i].to]=dist[u.se]+edge[i].dist;
q.push(ii(dist[edge[i].to],edge[i].to));
}
}
}
int p[maxn],gap[maxn],h[maxn],s,t,N;
ll sap(int u,ll flow){
if (u==t) return flow;
ll cnt=;
for (int i=p[u];i;i=edge[i].next)
if (edge[i].cap&&h[edge[i].to]+==h[u]) {
ll cur=sap(edge[i].to,min(edge[i].cap,flow-cnt));
edge[i].cap-=cur;edge[i^].cap+=cur;
p[u]=i;
if ((cnt+=cur)==flow) return flow;
}
if (!(--gap[h[u]])) h[s]=N;
gap[++h[u]]++;
p[u]=next[u];
return cnt;
}
inline ll maxflow(){
for (int i=;i<=N;i++) p[i]=next[i];
ll flow=;
gap[]=N;
while (h[s]<N) flow+=sap(s,Inf);
return flow;
}
int main(){
freopen("network.in","r",stdin);
freopen("network.out","w",stdout);
int m;
scanf("%d%d",&n,&m);
N=n*;
for (int i=;i<=m;i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
_addedge(x,y,z);
}
dij();
memset(next,,sizeof(next));
l=;
for (int i=;i<=m*+;i+=) {
if (dist[edge[i].to]==dist[edge[i^].to]+edge[i].dist)
addedge(n+edge[i^].to,edge[i].to,Inf);
else if (dist[edge[i^].to]==dist[edge[i].to]+edge[i^].dist)
addedge(n+edge[i].to,edge[i^].to,Inf);
}
for (int i=;i<=n;i++) {
int x;
scanf("%d",&x);
addedge(i,n+i,x);
}
s=+n,t=n;
printf("%lld\n",maxflow());
return ;
}
T3:[CQOI2015]任务查询系统
描述:戳我~~~
这道题首先很明显是道裸的数据结构题啦。首先他要求在线,那么按顺序建个函数式线段树就行啦
自己太弱调了好久= =
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
#define pb push_back
#define maxn 100100
struct qnode{
int x,y,z;
}q[maxn*];
int l;
inline void add(int x,int y,int z) {q[++l]=(qnode){x,y,z};}
bool cmp(qnode x,qnode y) {return x.x<y.x;}
struct node{int lc,rc,sum;ll s;}t[maxn*];
#define mid (l+r>>1)
int cnt=;
int ins(int x,int l,int r,int y,int z){
int root=++cnt;
t[root]=t[x];
t[root].s+=y*z;
t[root].sum+=z;
if (l==r) return root;
if (y<=mid) t[root].lc=ins(t[x].lc,l,mid,y,z);
else t[root].rc=ins(t[x].rc,mid+,r,y,z);
return root;
}
ll que(int x,int l,int r,int &k){
if (t[x].sum<=k) {
k-=t[x].sum;return t[x].s;
}
if (l==r) {ll ans=l*1ll*k;k=;return ans;}
ll ans=que(t[x].lc,l,mid,k);
if (k) ans+=que(t[x].rc,mid+,r,k);
return ans;
}
vector<int> a;
int s[maxn],e[maxn],p[maxn],root[maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
a.pb();
for (int i=;i<=n;i++) {
scanf("%d%d%d",s+i,e+i,p+i);
e[i]++;
a.pb(s[i]);a.pb(e[i]);
}
sort(a.begin(),a.end());
a.resize(unique(a.begin(),a.end())-a.begin());
for (int i=;i<=n;i++) {
add(lower_bound(a.begin(),a.end(),s[i])-a.begin(),p[i],);
add(lower_bound(a.begin(),a.end(),e[i])-a.begin(),p[i],-);
}
sort(q+,q++l,cmp);
#define inf 10000000
for (int i=;i<=l;i++) root[q[i].x]=ins(root[q[i-].x],,inf,q[i].y,q[i].z);
ll pre=;
for (int i=;i<=m;i++) {
int x,ai,bi,ci;
scanf("%d%d%d%d\n",&x,&ai,&bi,&ci);
int k=1ll+(ai*1ll*(pre%ci)%ci+bi)%ci;
pre=que(root[upper_bound(a.begin(),a.end(),x)-a.begin()-],,inf,k);
printf("%lld\n",pre);
}
return ;
}
T4:[CQOI2015]多项式
描述:戳我~~~
又是高精度= =
首先我们可以换一下元,吧x-t换成x那就能得到
那么就能算5次即可啦,再考虑怎么快速算组合数
完成啦
CODE:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define maxb 4
using namespace std;
char s[];
int p[]={,,,,,,,,};
struct bignum{
int a[],n,flag;
bignum(int x){
n=;memset(a,,sizeof(a));
flag=x<?:;x=abs(x);
while (x) {a[++n]=x%p[maxb];x/=p[maxb];}
if (!n) n=;
}
bignum(){n=;memset(a,,sizeof(a));flag=;}
int read(){
scanf("%s",s);
int len=strlen(s);
n=;
if (len==&&s[]=='') {a[n=]=;return ;}
for (int i=len;i>=;i-=maxb) {
int t=;
if (i>maxb) for (int j=i-maxb+;j<=i;j++) t=t*+s[j-]-'';
else for (int j=;j<=i;j++) t=t*+s[j-]-'';
a[++n]=t;
}
return ;
}
int write(){
if (flag) printf("-");
printf("%d",a[n]);
for (int i=n-;i>=;i--) {
for (int j=;j<maxb;j++) if (a[i]<p[j]) printf("");
printf("%d",a[i]);
}
printf("\n");
return ;
}
int cmp(bignum x){
if (x.n!=n) return (x.n<n);
for (int i=n;i>=;i--)
if (x.a[i]!=a[i]) return (x.a[i]<a[i]);
return -;
}
int div(int x){
int s=;
for (int i=n;i>=;i--){
s=a[i]+s*p[maxb];
a[i]=s/x;
s%=x;
}
if (n!=&&!a[n]) n--;
return s;
}
}a,b;
bignum operator + (bignum x,bignum y){
if (x.flag^y.flag && x.cmp(y)==)swap(x,y);
if (x.flag==y.flag) {
x.n=max(x.n,y.n);
for (int i=;i<=x.n;i++) {
x.a[i]+=y.a[i];
x.a[i+]+=x.a[i]/p[maxb];
x.a[i]%=p[maxb];
}
if (x.a[x.n+]) x.n++;
return x;
}
for (int i=;i<=x.n;i++) {
x.a[i]-=y.a[i];
if (x.a[i]<) {x.a[i]+=p[maxb];x.a[i+]--;}
while (!x.a[x.n]&&x.n>) x.n--;
}
return x;
}
bignum operator * (bignum x,bignum y){
bignum ans;
if (x.n==&&x.a[]==) return ans;
if (y.n==&&y.a[]==) return ans;
ans.flag=x.flag^y.flag;
for (int i=;i<=x.n;i++)
for (int j=;j<=y.n;j++) {
ans.a[i+j-]+=x.a[i]*y.a[j];
ans.a[i+j]+=ans.a[i+j-]/p[maxb];
ans.a[i+j-]%=p[maxb];
}
int n=x.n+y.n-;
while (ans.a[n+]) {
n++;ans.a[n+]+=ans.a[n]/p[maxb];
ans.a[n]%=p[maxb];
}
ans.n=n;
return ans;
}
int sum;
int main(){
static bignum n,m;
int t;
n.read();
scanf("%d",&t);
m.read();
static int a[];
a[]=;
for (int i=;i<=;i++) a[i]=(a[i-]*+) % ;
static bignum tmp=m;
int l=tmp.div();
static bignum ans,c=bignum(),T=bignum();
int cnt=;
for (bignum i=m;i.cmp(n)!=;i=i+bignum(),cnt++) {
ans=ans+c*T*bignum(a[l]);
l=(l+)%;
c=c*(i+bignum());
c.div(cnt+);
T=T*bignum(t);
}
ans.write();
return ;
}
T5:[CQOI2015]标示设计
描述:戳我~~~
首先我们考虑轮廓线,那么每个L可能有四种状态:已经结束,还未开始,还没拐弯,已经拐弯,那么如果从上到下,从左到右做的话,可以发现最多只有3条横边被标记,那么对每个L我们可以用一维来存这个状态,在加上起始状态还有终止状态就行啦,然后已经拐弯的状态一定是在那条竖边上在讨论下就行啦
由于我是从左到右,从上到下做的,所以每一维就多了1倍的状态,所以在BZ上就光荣的TLE啦,不过在学校的oj上还是能过的。所以代码就不贴啦
CQOI2015 解题报告的更多相关文章
- 重庆市队选拔 CQOI2015 解题报告
文章链接:http://www.cnblogs.com/Asm-Definer/p/4434601.html 题目链接:http://pan.baidu.com/s/1mgxIKli 官方数据:htt ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
随机推荐
- IOS 7 Xcode 5 免IDP证书 真机调试(转载)
最近转开发了,真的很久没有更新博客了,今天有空写一篇吧. 今天带来的是 IOS 7 Xcode 5 免IDP证书的真机调试.说白了就是穷,不想给苹果交那$99的钱. 注意:虽然可以用这个方法实现真机调 ...
- A股暴跌三日市值蒸发4.2万亿 股民人均浮亏超2万
A股暴跌三日市值蒸发4.2万亿 股民人均浮亏超2万 http://finance.qq.com/a/20150508/010324.htm?pgv_ref=aio2015&ptlang=205 ...
- onethink权限管理 RBAC
查看了官网的视频,写的不错. 大致熟悉了流程.这里打算自己动手写一个权限的控制
- Java数据结构整理(一)
ava数据结构内容整理关键字: 数据结构 Collection:List.SetMap:HashMap.HashTable如何在它们之间选择一.Array , ArraysJava所有“存储及随机访问 ...
- linux mint运行docker
1,sudo apt-get install docker.io 或者sudo apt-get install docker* 2,安装好之后 sudo docker -d 启动进程提示: yimiy ...
- "SQLServer复制需要有实际的服务器名称才能连接到服务器,请指定实际的服务器名"转
"SQLServer复制需要有实际的服务器名称才能连接到服务器,请指定实际的服务器名" 2014-06-12 12:01:10 最近在学习SQL SERVER的高级复制技术的时候 ...
- js原生设计模式——4安全的工厂方法模式之Factory方法模式
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- .NET DLL 保护措施详解(非混淆加密加壳)核心思路的实现
最近有很多朋友通过BLOG找到我询问我的相关细节,其实相关的实现细节我早已把源码上传到51aspx上面了,地址是http://www.51aspx.com/code/codename/56949 也有 ...
- 随机矩阵(stochastic matrix)
最近一个月来一直在看Google排序的核心算法---PageRank排序算法[1][2],在多篇论文中涉及到图论.马尔可夫链的相关性质说明与应用[3][4][5],而最为关键,一直让我迷惑 ...
- javascript window.confirm确认 取消对话框实现代码小结
本文章讲述的三种都是基于了javascript confirm提示确认框的做法了,只是在不同的地方写哦,有需要的同学可参考一下 confirm() 方法 confirm() 方法用于显示一个带有指 ...