博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多省联测2018
阅读量:4983 次
发布时间:2019-06-12

本文共 11176 字,大约阅读时间需要 37 分钟。

感觉这套题比较像比较正常的省选题呀

就是我可以做出来一两道,有一两道根本看不懂题解,非常有区分度(成功把我这个juruo区分出来)的题

 

D1T1

原来轮廓线dp就是这个……

//Serene#include
#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define db double#define For(i,a,b) for(int i=(a);i<=(b);++i)#define Rep(i,a,b) for(int i=(a);i>=(b);--i)const int maxn=13,W=10;const ll Bs=11,INF=1e14;int n,m,f[2][maxn][maxn];ll mi[maxn],T;map
G,H;char cc; ll ff;template
void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff;}ll s(int p,ll t) { if(t==T) return 0; if(H[t]) return G[t]; ll rs=-INF,x,y; y=t%mi[1]; if(y!=m) rs=f[p][1][y+1]-s(p^1,t+1); For(i,2,n) { x=(t/mi[i-1])%mi[1]; if(x

 

D1T2

场上写了个假算法,就是建树之后,一层一层贪心,写了3个线段树上二分,还有撤销操作。然而这个是假算法不是因为有相同值的原因……

关键点在于,如果你直接去确定这个子树占哪些位置怎样都是会出现问题的。所以我们只能说,在哪一块区域,我们给这个子树预订多少位置。

所以我们把d排好序之后(假如是从小到大排的),对于每个位置i,我们用线段树维护i及其右边的可用位置,就是i~n的所有位置减去i~n中预订了的位置。

于是我又写了3个线段树上二分,然而现在都还有10分WA着呢,调不出来呀orz,先放个90分代码在这好了。

//Serene#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define db double#define For(i,a,b) for(int i=(a);i<=(b);++i)#define Rep(i,a,b) for(int i=(a);i>=(b);--i)const int maxn=2e6+7;ll n,p[maxn],ld[maxn],rd[maxn],a[maxn],f[maxn],tot,ans[maxn];db k;char cc; ll ff;template
void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff;}int fir[maxn],nxt[maxn],to[maxn],e=0;void add(int x,int y) { to[++e]=y;nxt[e]=fir[x];fir[x]=e;}int size[maxn];void s(int pos) { size[pos]=1; int y,z; for(y=fir[pos];y;y=nxt[y]) { s(z=to[y]); size[pos]+=size[z]; }}ll sum[4*maxn],minnum[4*maxn],laz[4*maxn],ql,qr,qx;void ud(int pos) { sum[pos]=sum[pos<<1]+sum[pos<<1|1]; minnum[pos]=min(minnum[pos<<1],minnum[pos<<1|1]);}void pd(int pos) { if(!laz[pos]) return; minnum[pos<<1]+=laz[pos]; minnum[pos<<1|1]+=laz[pos]; laz[pos<<1]+=laz[pos]; laz[pos<<1|1]+=laz[pos]; laz[pos]=0;}void bld(int pos,int l,int r) { if(l==r) { sum[pos]=1; minnum[pos]=n-l+1; return; } int mid=(l+r)>>1; bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r); ud(pos);}void chge(int pos,int l,int r) { if(l>=ql&&r<=qr) { minnum[pos]+=qx; laz[pos]+=qx; return; } int mid=(l+r)>>1; pd(pos); if(ql<=mid) chge(pos<<1,l,mid); if(qr>mid) chge(pos<<1|1,mid+1,r); ud(pos);}void add(int pos,int l,int r) { sum[pos]+=qx; if(l==r) return; int mid=(l+r)>>1; pd(pos); if(ql<=mid) add(pos<<1,l,mid); else add(pos<<1|1,mid+1,r);}int find1(int pos,int l,int r) { if(minnum[pos]>=qx) return 0; if(l==r) return l; int mid=(l+r)>>1,rs=0; pd(pos); if(ql<=mid) rs=find1(pos<<1,l,mid); if(!rs&&qr>mid) rs=find1(pos<<1|1,mid+1,r); return rs;}int find2(int pos,int l,int r) { if(l>=ql&&r<=qr&&sum[pos]==0) return 0; if(l==r) return l; int mid=(l+r)>>1,rs=0; pd(pos); if(qr>mid) rs=find2(pos<<1|1,mid+1,r); if(!rs&&ql<=mid) rs=find2(pos<<1,l,mid); return rs;}int find3(int pos,int l,int r) { if(l>=ql&&r<=qr&&sum[pos]==0) return 0; if(l==r) return l; int mid=(l+r)>>1,rs=0; pd(pos); if(ql<=mid) rs=find3(pos<<1,l,mid); if(!rs&&qr>mid) rs=find3(pos<<1|1,mid+1,r); return rs;} int main() { freopen("iiidx.in","r",stdin); freopen("iiidx.out","w",stdout); read(n); scanf("%lf",&k); For(i,1,n) read(a[i]); sort(a+1,a+n+1); For(i,1,n) p[i]=a[i]; tot=unique(p+1,p+n+1)-(p+1); int x=1,y; ld[1]=1; For(i,1,n) { if(a[i]!=p[x]) { rd[x]=i-1; ld[++x]=i; } a[i]=x; } rd[x]=n; For(i,1,n) f[i]=(db)i/k,add(f[i],i); s(0); bld(1,1,n); For(i,1,n) { if(f[i]&&f[i]!=f[i-1]) { ql=1; qr=ans[f[i]]; qx=size[f[i]]-1; chge(1,1,n); } ql=ans[f[i]]+1; qr=n; qx=size[i]; x=find1(1,1,n); if(x==0) x=n;else x--; qr=x; x=find2(1,1,n); ql=max(ql,ld[a[x]]); qr=x; x=find3(1,1,n); ans[i]=x; ql=1; qr=x; qx=-size[i]; chge(1,1,n); ql=qr=x; qx=-1; add(1,1,n); } For(i,1,n) printf("%lld ",p[a[ans[i]]]); printf("\n"); return 0;}

update20180506:

cstc试机题,改成了相同的在线段树上缩点,就1A了……

//Serene#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define db double#define For(i,a,b) for(int i=(a);i<=(b);++i)#define Rep(i,a,b) for(int i=(a);i>=(b);--i)const int maxn=1e6+7;ll n,a[maxn],p[maxn],c[maxn],f[maxn],size[maxn],ans[maxn],tot;db k;bool vis[maxn];char cc;ll ff;template
void read(T& aa){ aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff;}int fir[maxn],nxt[maxn],to[maxn],e=0;void add(int x,int y) { to[++e]=y;nxt[e]=fir[x];fir[x]=e;}void s(int pos) { size[pos]=1; for(int y=fir[pos];y;y=nxt[y]) { s(to[y]); size[pos]+=size[to[y]]; }}ll num[4*maxn],laz[4*maxn],ql,qr,qx;void ud(int pos) { num[pos]=min(num[pos<<1],num[pos<<1|1]);}void pd(int pos) { if(!laz[pos]) return; num[pos<<1]+=laz[pos]; num[pos<<1|1]+=laz[pos]; laz[pos<<1]+=laz[pos]; laz[pos<<1|1]+=laz[pos]; laz[pos]=0;}void bld(int pos,int l,int r){ if(l==r) { num[pos]=c[l]; return; } int mid=(l+r)>>1; bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r); ud(pos);}void chge(int pos,int l,int r) { if(l>=ql&&r<=qr) { num[pos]+=qx; laz[pos]+=qx; return; } int mid=(l+r)>>1; pd(pos); if(ql<=mid) chge(pos<<1,l,mid); if(qr>mid) chge(pos<<1|1,mid+1,r); ud(pos);}int ef(int pos,int l,int r) { if(l==r) { if(num[pos]
>1; pd(pos); if(num[pos<<1]>=qx) return ef(pos<<1|1,mid+1,r); return ef(pos<<1,l,mid);}void clear(int x) { ql=1; qr=ans[x]; qx=size[x]-1; chge(1,1,tot); vis[x]=0;}int main() { read(n); scanf("%lf",&k); For(i,1,n) read(a[i]); sort(a+1,a+n+1); ll x; For(i,1,n) p[i]=a[i]; tot=unique(p+1,p+n+1)-(p+1); For(i,1,n) { x=lower_bound(p+1,p+tot+1,a[i])-p; ++c[x]; } Rep(i,tot,1) c[i]+=c[i+1]; For(i,1,n) f[i]=floor((db)i/k),add(f[i],i); s(0); bld(1,1,tot); For(i,1,n) { if(vis[f[i]]) clear(f[i]); ql=ans[f[i]]+1; qr=tot; qx=size[i]; ans[i]=ef(1,1,tot)-1; ql=1; qr=ans[i]; qx=-size[i]; chge(1,1,tot); vis[i]=1; } For(i,1,n) printf("%lld ",p[ans[i]]); printf("\n"); return 0;}

 

D1T3

没看懂题解,但是我会暴力dp+小优化水过

//Serene#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define db double#define For(i,a,b) for(int i=(a);i<=(b);++i)#define Rep(i,a,b) for(int i=(a);i>=(b);--i)const int maxn=1700+7;const ll mod=64123;ll n,k,w,d[maxn],p[maxn],rnk[maxn],dp[maxn][maxn],ans;char cc; ll ff;template
void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff;}int fir[maxn],nxt[2*maxn],to[2*maxn],e=0;void add(int x,int y) { to[++e]=y;nxt[e]=fir[x];fir[x]=e; to[++e]=x;nxt[e]=fir[y];fir[y]=e;}bool cmp(int x,int y) { return d[x]>d[y];}ll size[maxn];void dfs(int pos,int f,int sum) { For(i,0,k) dp[pos][i]=0; if((sum+=size[pos])>k) return; if(size[pos]) dp[pos][1]=1; else dp[pos][0]=1; int y,z; for(y=fir[pos];y;y=nxt[y]) { if((z=to[y])==f) continue; dfs(z,pos,sum); Rep(i,min(size[pos],k),0) if(dp[pos][i]){ Rep(j,min(k-i,size[z]),0) dp[pos][i+j]+=dp[pos][i]*dp[z][j]%mod; } size[pos]+=size[z]; } For(i,0,min(size[pos],k)) dp[pos][i]%=mod;}int main() { freopen("coat.in","r",stdin); freopen("coat.out","w",stdout); read(n); read(k); read(w); For(i,1,n) read(d[i]),p[i]=i; sort(p+1,p+n+1,cmp); For(i,1,n) rnk[p[i]]=i; int x,y; For(i,1,n-1) { read(x); read(y); add(x,y); } For(i,1,n) if(rnk[i]>=k) { For(j,1,rnk[i]) size[p[j]]=1; For(j,rnk[i]+1,n) size[p[j]]=0; dfs(i,0,0); ans+=dp[i][k]*d[i]%mod; } printf("%lld\n",ans%mod); return 0;}

 

D2T1

题面有点冗长。

我直接EK+bitset了

场上自己做死想优化一下结果优化错了,还忘记了有大样例这个东西。

//Serene#include
#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define db double#define For(i,a,b) for(int i=(a);i<=(b);++i)#define Rep(i,a,b) for(int i=(a);i>=(b);--i)const int maxn=400+7,maxm=5000+7,INF=0x3f3f3f3f;int Td,Cd,n,m,S,T,a[maxn][maxn],now,s[maxn],ans1[maxn],ans2[maxn];bitset
G[maxn],o;char cc; ll ff;template
void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff;}struct Node{ int x,y,flow,cap; Node(){} Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;}}node[2*maxm];int fir[maxn],nxt[2*maxm],e=1;void add(int x,int y,int z) { node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e; node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;}bool vis[maxn];bool Expd(int pos) { if(vis[pos]) return 0; if(pos==T) return 1; vis[pos]=1; for(int y=fir[pos];y;y=nxt[y]) { if(node[y].flow>=node[y].cap) continue; if(Expd(node[y].y)) { ++node[y].flow; --node[y^1].flow; return 1; } } return 0;}bool dfs(int pos) { if(vis[pos]) return 0; if(pos==T) return 1; vis[pos]=1; for(int y=fir[pos];y;y=nxt[y]) { if(node[y].flow>=node[y].cap) continue; if(dfs(node[y].y)) return 1; } return 0;} void find(int p) { For(i,1,m) if(G[p][i]) { memset(vis,0,sizeof(vis)); if(dfs(i+n)) G[p+1].set(i); }}void solve() { For(i,1,n) { now=m+1; For(j,1,m) if(G[i][j]) now=min(now,a[i][j]); ans1[i]=now; if(now<=m) { add(S,i,1); For(j,1,m) if(a[i][j]==now) add(i,j+n,1); memset(vis,0,sizeof(vis)); Expd(S); } if(ans1[i]>s[i]) { o.reset(); ans2[i]=i; For(j,1,m) if(a[i][j]<=s[i]) o.set(j); Rep(j,i-1,1) if((o&G[j]).count()) { ans2[i]=i-j; break; } } find(i); } For(i,1,n) printf("%d ",ans1[i]); printf("\n"); For(i,1,n) printf("%d ",ans2[i]); printf("\n");} void clear() { e=1; For(i,1,n+1) G[i].reset(); memset(fir,0,sizeof(fir)); memset(ans2,0,sizeof(ans2));}int main() { freopen("mentor.in","r",stdin); freopen("mentor.out","w",stdout); read(Td); read(Cd); int x,y,z; while(Td--) { read(n); read(m); S=n+m+1; T=S+1; clear(); For(i,1,m) { read(x); if(x) add(i+n,T,x),G[1].set(i); } For(i,1,n) For(j,1,m) { read(a[i][j]); if(a[i][j]==0) a[i][j]=INF; } For(i,1,n) read(s[i]); solve(); } return 0;}

 

D2的T2、T3不会。

场上T2的60分做法,但是来不及打:

题目等价于在树上选k条点不相交的链,使权值和最大。

f[x][k][0/1/2]表示在x的子树中选了k条链,x的度数为0,1,2的最优方案。

T3直接放个Achen博客链接好啦:

 

这几天做题觉得有点蒙,每天总是头晕或者头痛或者困,即使中午好生回去睡觉,也怎么都调节不过来。

上周因为考了省选没食欲没胃口,几天没好好吃饭好好睡觉,现在又每天一副这种样子

效率真的好低呀……

跟Achen晚上去跑步的时候,Achen说:

我们如果去NOI,就像是拿着匕首,去参加国际大战,别人一个核弹就炸平一片,人家即使没有核弹也有大炮,没有大炮也有机关枪,而我们赤条条地拿着小匕首往上冲。

如果我们回常规了,就像是把手上唯一的小匕首给扔了,别人虽然也没什么武器,但是天天练得身强体壮,我们又去和这样一大群人肉搏。

这个画面感太强了。

我突然觉得如果当初初一没有被微机课老师骗去"体验了"一下信息竞赛,就不会勾起我的一点点兴趣,然后有这么多烦人事情了。

或者是当时初一的时候我们的班导老师没有强制我们中午不能去上乱七八糟的“中午特长班”,我会从初一学OI到现在,估计也没这么多烦人的事情了。

或者是……

可是人生又不能重来,想这些也是没有用的呀。

而且毕竟还是自己太懒太弱了,又怎么能怨天尤人呢。

我挺赞同里面那句话的:

一个人在任意一秒所作出的决定,一个是靠天性,上天注定,一个是他在这一秒之前经历过的所有事--认识的所有人,他们为人处世的方式,他们对他说过的所有话,他读过的所有书,他每一秒看到的风景,每一秒听到的声音,每一秒感受的气息--决定.

我妈曾说,现在看起来不好的决定最后不一定是不好的,现在看起来不好的事情最后不一定是不好的。

有谁能猜到最后的结果呢。

转载于:https://www.cnblogs.com/Serene-shixinyi/p/8869781.html

你可能感兴趣的文章
poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)
查看>>
洛谷P1886 滑动窗口
查看>>
Shell编程(二)Bash中调用Python
查看>>
主动与被动监控 拓扑图组合图 自定义监控
查看>>
SQL总结(一)基本查询
查看>>
PDF分割--可脱离python环境执行,可传参数,可弹窗的PC端小工具
查看>>
转:C语言申请内存时堆栈大小限制
查看>>
单例模式
查看>>
PHP初入,div知识点整理(特效&字体等元素的使用整理)
查看>>
对象和map互相转换工具类
查看>>
Android Studio 问题解决List
查看>>
Oracle将密码有效期由默认的180天修改成无限制
查看>>
iOS实现简单时钟效果
查看>>
cas-client-core单点登录排除不需要拦截的URL
查看>>
OCR技术浅探 : 文字定位和文本切割(2)
查看>>
jmeter集合点
查看>>
Java类代码块执行顺序
查看>>
克鲁斯卡尔(模板题)
查看>>
汉字转拼音
查看>>
Python中Web框架编写学习心得
查看>>