Noip2017复赛游记(爆炸记)
2017-12-02 16:37
387 查看
2017.11.10,7:00。出发。
路上是很愉快的(呃。。。好吧),大家分享了一些自己关于各种算法、代码的感想与经验,然后就是唱歌时间QAQ。在高速的服务站上休息了一小小之后就又继续上路了。剩下的路程中各自说了说图论,然后就都睡着了(毕竟还是困23333)。
到了,大概11:30,报到、领证(手动滑稽)啥的都很顺利,没有拥挤也基本上没有排队,很愉快的去吃饭(路上对着美其名曰“澡票”的票子陷入了沉思),之后去宿舍。意想不到的是,女生住的是男生宿舍,而男生住的是女生宿舍哟。
下午,会见了几位大佬,又去商店浪,之后就在宿舍……学习的学习,游戏的游戏,浪的浪。。。据此生一新词名曰“王者C++”233。
晚上,开会,试机,本蒻首先要吐槽输入法,一个大屁股破电脑装那么多输入法干啥,害的本弱每次输完汉字后都要按好几次Ctrl+Shift切换,后来就懒了,也烦了,索性Ctrl+空格直接快速切回系统英文;第二吐槽一下分辨率,代码看起来是像素的真的没法说啥了;第三吐槽我那按不动的键盘,后来要求换了一套;第四吐槽堂堂一个考场为毛系统还是Xp(非个人对Xp的偏见)。试了试Compile,Run,Debug等,都还好,又搞了搞long long的I64和ll以确保正常(毕竟学校微机室里有个大佬的电脑的lld和I64d被Windows反过来用了。。。),同时低头膜拜写反过的大佬。又敲了几个模板(如需练习模板请移步洛谷https://www.luogu.org/problem/lists?name=%E6%A8%A1%E6%9D%BF),以防手生(然额事实证明并没有什么卵用)。ps:本弱第一排。
Day1。
T1小凯的疑惑(题目链接 ),这就是送一群大佬退役的小学奥数。2017你的NOIP之小学奥数,回小学重念吧(滑稽)。首先公式送上:A*B-A-B。一上来各路大仙都那个噼里啪啦一顿敲啊,然额第一排一片肃静。。。十五分钟后本蒟蒻推出一个别具一格的公式,送上:answer=max(a,b)*(min(a,b)-1)-min(a,b)。于是t1约25分钟完成。下面送上本弱另类代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a,b;
long long maxn,minn,tmp,ans;
int main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
scanf("%lld%lld",&a,&b);
maxn=max(a,b);
minn=min(a,b);
tmp=minn-1;
ans=maxn*tmp-minn;
printf("%lld",ans);
return 0;
}
大神围观勿喷,其实推导过来都是一样的,只是本蒻的用了几次比较而已,反正是AC了啦。接下来是标准的代码:
T2时间复杂度(题目链接)老师说是模拟,网络上的大佬们也有说是栈的,本弱认真地审了审题,发现满分操作对于自己完全是tan270°,果断取了30%的数据骗了三十分(其实这30分好写),送上30分的时间复杂度:
接下来是洛谷的标程(仅供参考学习用,请不要恶意抄袭):
这可能是标准答案:
T3逛公园(题目链接)好好的一个dp硬是写成克鲁斯卡尔。。。神醉啊~~~也有大佬写最短路。。。
于是0分
不知道从哪挖到的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int inf=1e9;
struct node
{ int p,w;
};
struct cmp
{ inline bool operator ()(const node &a,const node &b)
{return a.w>b.w;}
};
priority_queue<node,vector<node>,cmp>h;
int q[100005],tt,n,m,k,p,x,y,z,dis[100005],dis2[100005],mn1[100005],mn2[100005];
int bel[100005],siz[100005],low[100005],dfn[100005],cnt,ct,st[100005],tp;
int f[100005][53],tmp[100005];
bool vis[100005],ins[100005];
inline bool cmp2(int a,int b){return dis[a]==dis?dfn[a]<dfn[b]:dis[a]<dis[b];}
struct cmp3
{ inline bool operator ()(int a,int b)
{return dfn[tmp[a]]>dfn[tmp[b]];}
};
priority_queue<int,vector<int>,cmp3>d;
struct line
{ int v,w,next;
};
struct graph
{ line e[200005];
int b[100005],t;
inline void init()
{ memset(b,-1,sizeof b);
t=-1;
}
inline void build(int x,int y,int w)
{ e[++t].v=y;
e[t].w=w;
e[t].next=b[x];
b[x]=t;
}
void tarjan(int u)
{ low[u]=dfn[u]=++cnt;
vis[u]=ins[u]=true;
st[++tp]=u;
for(int o=b[u];o!=-1;o=e[o].next)
{ if(!vis[e[o].v])
{ tarjan(e[o].v);
low[u]=min(low[u],low[e[o].v]);
}else if(ins[e[o].v])low[u]=min(low[u],dfn[e[o].v]);
}
if(low[u]==dfn[u])
{ siz[++ct]=0;
int k=st[tp--];
for(;;)
{ bel[k]=ct,++
bd6f
siz[ct],ins[k]=false;
if(k==u)break;
k=st[tp--];
}
}
}
void dotarjan()
{ cnt=ct=tp=0;
memset(vis,false,sizeof vis);
memset(ins,false,sizeof ins);
for(int i=1;i<=n;i++)if(!vis[i])tarjan(i);
}
void dijkstra(int st,int *dis)
{ memset(vis,false,sizeof vis);
for(int i=1;i<=n;i++)dis[i]=inf;
dis[st]=0;
h.push((node){st,0});
while(!h.empty())
{ node a=h.top();
h.pop();
if(vis[a.p])continue;
int u=a.p;
vis[u]=true;
for(int o=b[u];o!=-1;o=e[o].next)
{ if(dis[u]+e[o].w<dis[e[o].v])
{ dis[e[o].v]=dis[u]+e[o].w;
h.push((node){e[o].v,dis[e[o].v]});
}
}
}
}
void topo()
{ memset(low,0,sizeof low);
for(int i=1;i<=n;i++)if(siz[bel[i]]==1)
for(int o=b[i];o!=-1;o=e[o].next)++low[e[o].v];
int l=1,r=0;
for(int i=1;i<=n;i++)if(low[i]==0)q[++r]=i;
while(l<=r)
{ int u=q[l++];
for(int o=b[u];o!=-1;o=e[o].next)
{ --low[e[o].v];
if(low[e[o].v]==0)q[++r]=e[o].v;
}
}
for(int i=1;i<=r;i++)dfn[q[i]]=i;
}
void dp()
{ int t=0;
for(int i=1;i<=n;i++)if(siz[bel[i]]==1)tmp[++t]=i;
sort(tmp+1,tmp+t+1,cmp2);
for(int i=1;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=0;
f[1][0]=1;
int l=1,r=1;
for(int i=0;i<=dis
+k;i++)
{ while(r<t&&dis[tmp[r+1]]==i)++r;
while(l<=r&&i-dis[tmp[l]]>k)++l;
if(l>r)
{ r=l,i=dis[tmp[l]]-1;
continue;
}
d.push(l);
for(int z=l+1;z<=r;z++)if(dis[tmp[z]]!=dis[tmp[z-1]])d.push(z);
while(!d.empty())
{ int z=d.top();
d.pop();
if(z<r&&dis[tmp[z+1]]==dis[tmp[z]])d.push(z+1);
int u=tmp[z],j=i-dis[u];
for(int o=b[u];o!=-1;o=e[o].next)
{ if(i+e[o].w<=dis[e[o].v]+k)
f[e[o].v][i+e[o].w-dis[e[o].v]]=(f[e[o].v][i+e[o].w-dis[e[o].v]]+f[u][j])%p;
}
}
}
}
void dp2()
{ int t=0;
for(int i=1;i<=n;i++)if(siz[bel[i]]==1)tmp[++t]=i;
sort(tmp+1,tmp+t+1,cmp2);
for(int i=1;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=0;
f[1][0]=1;
int l=1,r=1;
for(int i=0;i<=dis
+k;i++)
{ while(r<t&&dis[tmp[r+1]]==i)++r;
while(l<=r&&i-dis[tmp[l]]>k)++l;
if(l>r)
{ r=l,i=dis[tmp[l]]-1;
continue;
}
for(int z=l;z<=r;z++)
{ int u=tmp[z],j=i-dis[u];
for(int o=b[u];o!=-1;o=e[o].next)
{ if(i+e[o].w<=dis[e[o].v]+k)
f[e[o].v][i+e[o].w-dis[e[o].v]]=(f[e[o].v][i+e[o].w-dis[e[o].v]]+f[u][j])%p;
}
}
}
}
}aa,bb,cc;
inline int read()
{ int x=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
void work()
{ aa.init(),bb.init(),cc.init();
n=read(),m=read(),k=read(),p=read();
int zz=0;
for(int i=1;i<=m;i++)
{ x=read(),y=read(),z=read();
aa.build(x,y,z),bb.build(y,x,z);
if(z==0)++zz,cc.build(x,y,0);
}
cc.dotarjan();
aa.dijkstra(1,dis);
bb.dijkstra(n,dis2);
for(int i=1;i<=ct;i++)mn1[i]=mn2[i]=inf;
for(int i=1;i<=n;i++)mn1[bel[i]]=min(mn1[bel[i]],dis[i]),mn2[bel[i]]=min(mn2[bel[i]],dis2[i]);
for(int i=1;i<=ct;i++)if(siz[i]>1&&mn1[i]+mn2[i]<=dis
+k)
{ printf("-1\n");
return;
}
cc.topo();
if(zz)aa.dp();else aa.dp2();
int ac=0;
for(int i=0;i<=k;i++)ac=(ac+f
[i])%p;
printf("%d\n",ac);
}
int main()
{ freopen("park.in","r",stdin);
freopen("park.out","w",stdout);
tt=read();
while(tt--)work();
return 0;
}
下午。在宿舍里打牌,还没开始,老师推门而入,场面一度十分尴尬。。。
晚上,和同游大佬在操场狂欢。
Day2。
T1奶酪(题目链接)本弱的纯数学方法非for循环暴力运算竟然搞到了五分,,有的大佬说这是要用图做的。
LittleOrange(https://www.cnblogs.com/Dndlns/p/7886017.html)大佬的dfs
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
long long next,to;
} e[2000005];
struct node1
{
long long x,y,z;
} a[1005];
long long head[1005],cnt,vis[1005];
inline void insert(long long u,long long v)
{
e[++cnt].next=head[u];
head[u]=cnt;
e[cnt].to=v;
}
inline void dfs(long long now)
{
vis[now]=1;
for(long long i=head[now];i;i=e[i].next)
{
if(vis[e[i].to]) continue;
dfs(e[i].to);
}
}
int main()
{
long long t,S,T,n,m,k;
scanf("%lld",&t);
while(t--)
{
cnt=0;
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
scanf("%lld%lld%lld",&n,&m,&k);
S=n+1,T=n+2;
for(long long i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
if(a[i].z<=k)
{
insert(S,i);
insert(i,S);
}
if(a[i].z>=m-k)
{
insert(T,i);
insert(i,T);
}
}
for(long long i=1;i<=n;i++)
for(long long j=i+1;j<=n;j++)
{
if((a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+(a[j].z-a[i].z)*(a[j].z-a[i].z)<=4*k*k)
{
insert(i,j);
insert(j,i);
}
}
dfs(S);
if(vis[T])
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
return 0;
}
T2宝藏(题目链接)又觉得是个不会找深度的最小生成树。。。
CQzhangyu大佬http://www.cnblogs.com/CQzhangyu/的状压DP
T3列队(题目链接)What?啥玩意?模拟?这么大的数据范围?认真的取了小范围模拟了一下,于是第二组样例…一开始几十个数都是对的…后来就有0出现…到文件末尾只剩乱糟糟的全错了…于是又爆零
CQzhangyu大佬的离线+SBT
是啥玩意蒟蒻也没看懂
然额今年并木有考网络流。。。
华丽丽的Day1Day2双炸
[b]希望各位阅读本blog的童鞋们努力学习,争取Noip2018不辜负自己
路上是很愉快的(呃。。。好吧),大家分享了一些自己关于各种算法、代码的感想与经验,然后就是唱歌时间QAQ。在高速的服务站上休息了一小小之后就又继续上路了。剩下的路程中各自说了说图论,然后就都睡着了(毕竟还是困23333)。
到了,大概11:30,报到、领证(手动滑稽)啥的都很顺利,没有拥挤也基本上没有排队,很愉快的去吃饭(路上对着美其名曰“澡票”的票子陷入了沉思),之后去宿舍。意想不到的是,女生住的是男生宿舍,而男生住的是女生宿舍哟。
下午,会见了几位大佬,又去商店浪,之后就在宿舍……学习的学习,游戏的游戏,浪的浪。。。据此生一新词名曰“王者C++”233。
晚上,开会,试机,本蒻首先要吐槽输入法,一个大屁股破电脑装那么多输入法干啥,害的本弱每次输完汉字后都要按好几次Ctrl+Shift切换,后来就懒了,也烦了,索性Ctrl+空格直接快速切回系统英文;第二吐槽一下分辨率,代码看起来是像素的真的没法说啥了;第三吐槽我那按不动的键盘,后来要求换了一套;第四吐槽堂堂一个考场为毛系统还是Xp(非个人对Xp的偏见)。试了试Compile,Run,Debug等,都还好,又搞了搞long long的I64和ll以确保正常(毕竟学校微机室里有个大佬的电脑的lld和I64d被Windows反过来用了。。。),同时低头膜拜写反过的大佬。又敲了几个模板(如需练习模板请移步洛谷https://www.luogu.org/problem/lists?name=%E6%A8%A1%E6%9D%BF),以防手生(然额事实证明并没有什么卵用)。ps:本弱第一排。
Day1。
T1小凯的疑惑(题目链接 ),这就是送一群大佬退役的小学奥数。2017你的NOIP之小学奥数,回小学重念吧(滑稽)。首先公式送上:A*B-A-B。一上来各路大仙都那个噼里啪啦一顿敲啊,然额第一排一片肃静。。。十五分钟后本蒟蒻推出一个别具一格的公式,送上:answer=max(a,b)*(min(a,b)-1)-min(a,b)。于是t1约25分钟完成。下面送上本弱另类代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a,b;
long long maxn,minn,tmp,ans;
int main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
scanf("%lld%lld",&a,&b);
maxn=max(a,b);
minn=min(a,b);
tmp=minn-1;
ans=maxn*tmp-minn;
printf("%lld",ans);
return 0;
}
大神围观勿喷,其实推导过来都是一样的,只是本蒻的用了几次比较而已,反正是AC了啦。接下来是标准的代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long a,b; int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); scanf("%lld%lld",&a,&b); printf("%lld\n",a*b-a-b); return 0; }
T2时间复杂度(题目链接)老师说是模拟,网络上的大佬们也有说是栈的,本弱认真地审了审题,发现满分操作对于自己完全是tan270°,果断取了30%的数据骗了三十分(其实这30分好写),送上30分的时间复杂度:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int t,l,cnt=0,x,s; char start[2],ii[3],y[4],str[10]; int main() { freopen("complexity.in","r",stdin); freopen("complexity.out","w",stdout); scanf("%d",&t); while(t--) { cnt=0; scanf("%d",&l); scanf("%s",str+1); for(int i=1; i<=l/2; i++) { scanf("%s",start+1); scanf("%s",ii+1); scanf("%d",&x); scanf("%s",y+1); if(y[1]=='n') cnt++; } for(int i=l/2+1; i<=l; i++) scanf("%s",start+1); if(cnt==0) { s=1; if(s==str[3]-'0') printf("Yes\n"); else printf("No\n"); } else { if(cnt==str[5]-'0') printf("Yes\n"); else printf("No\n"); } } return 0; }
接下来是洛谷的标程(仅供参考学习用,请不要恶意抄袭):
#include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <stack> using namespace std; bool stat[26]; inline char t(const string& original) { return original[0] - 'a'; } inline bool isInt(const string& str) { return str[0] >= '0' && str[0] <= '9'; } inline int getPV(const string& str) { if(isInt(str)) return atoi(str.c_str()); else return 1000000; } struct stackContent { int complexity; char var; bool parentEntryImpossible; }; int main() { int n; cin >> n; for(int i=1; i<=n; i++) { memset(stat, 0, sizeof(stat)); int lineCnt, expectedComplexity; cin >> lineCnt; string complexity; cin >> complexity; if(complexity[2] == '1') expectedComplexity = 0; else sscanf(complexity.c_str(), "O(n^%d)", &expectedComplexity); string currentToken, last_t_A; bool validFlag = true; int currentComplexity = 0, maxComplexity = 0; bool parentEntryImpossible = false; stack<stackContent> complexityStack; for(int j=1; j<=lineCnt; j++) { cin >> currentToken; if(currentToken == "F") { string t_A, t_B, t_C; cin >> t_A >> t_B >> t_C; if(!validFlag) continue; if(stat[t(t_A)]) { validFlag = false; continue; } complexityStack.push((stackContent){currentComplexity, t_A[0], parentEntryImpossible}); if(parentEntryImpossible) parentEntryImpossible = true; else if(getPV(t_B) > getPV(t_C)) parentEntryImpossible = true; else if(t_B != "n" && t_C == "n") { currentComplexity++; maxComplexity = max(maxComplexity, currentComplexity); } stat[t(t_A)] = true; } else if(currentToken == "E") { if(!validFlag) continue; if(complexityStack.size() == 0) { validFlag = false; continue; } currentComplexity = complexityStack.top().complexity; stat[complexityStack.top().var - 'a'] = false; parentEntryImpossible = complexityStack.top().parentEntryImpossible; complexityStack.pop(); } } if(!validFlag || complexityStack.size() != 0) cout << "ERR" << endl; else { if(maxComplexity == expectedComplexity) cout << "Yes" << endl; else cout << "No" << endl; } } return 0; }
这可能是标准答案:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char s[20],q[105],nm[105]; int tt,l,x[105],y[105],st[105],mch[105],ll,v[105]; bool vis[30]; void work() { scanf("%d",&l); scanf("%s",s); int ans=0,ac=0,sum=0; if(s[2]=='1')ans=0; else for(int i=4;s[i]!=')';i++)ans=ans*10+s[i]-'0'; memset(vis,false,sizeof vis); for(int i=1;i<=l;i++) { scanf("%s",s); q[i]=s[0]; if(q[i]=='F') { scanf("%s",s); nm[i]=s[0]; scanf("%s",s); if(s[0]=='n')x[i]=-1; else { x[i]=0,ll=strlen(s); for(int j=0;j<ll;j++)x[i]=x[i]*10+s[j]-'0'; } scanf("%s",s); if(s[0]=='n')y[i]=-1; else { y[i]=0,ll=strlen(s); for(int j=0;j<ll;j++)y[i]=y[i]*10+s[j]-'0'; } } } int t=0; for(int i=1;i<=l;i++) { if(q[i]=='F')st[++t]=i; else { if(t==0) { printf("ERR\n"); return; } mch[i]=st[t],mch[st[t]]=i,--t; } } if(t) { printf("ERR\n"); return; } for(int i=1;i<=l;i++) { if(q[i]=='F') { if(vis[nm[i]-'a']) { printf("ERR\n"); return; } vis[nm[i]-'a']=true; if(x[i]==-1) { if(y[i]==-1)v[i]=0; else v[i]=-1; }else { if(y[i]==-1)v[i]=1; else v[i]=x[i]<=y[i]?0:-1; } }else vis[nm[mch[i]]-'a']=false; } for(int i=1;i<=l;i++) { if(q[i]=='F') { if(v[i]==-1)i=mch[i]; else { sum+=v[i]; ac=max(ac,sum); } }else sum-=v[mch[i]]; } if(ac==ans)printf("Yes\n"); else printf("No\n"); } int main() { freopen("complexity.in","r",stdin); freopen("complexity.out","w",stdout); scanf("%d",&tt); while(tt--)work(); return 0; }
T3逛公园(题目链接)好好的一个dp硬是写成克鲁斯卡尔。。。神醉啊~~~也有大佬写最短路。。。
于是0分
不知道从哪挖到的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int inf=1e9;
struct node
{ int p,w;
};
struct cmp
{ inline bool operator ()(const node &a,const node &b)
{return a.w>b.w;}
};
priority_queue<node,vector<node>,cmp>h;
int q[100005],tt,n,m,k,p,x,y,z,dis[100005],dis2[100005],mn1[100005],mn2[100005];
int bel[100005],siz[100005],low[100005],dfn[100005],cnt,ct,st[100005],tp;
int f[100005][53],tmp[100005];
bool vis[100005],ins[100005];
inline bool cmp2(int a,int b){return dis[a]==dis?dfn[a]<dfn[b]:dis[a]<dis[b];}
struct cmp3
{ inline bool operator ()(int a,int b)
{return dfn[tmp[a]]>dfn[tmp[b]];}
};
priority_queue<int,vector<int>,cmp3>d;
struct line
{ int v,w,next;
};
struct graph
{ line e[200005];
int b[100005],t;
inline void init()
{ memset(b,-1,sizeof b);
t=-1;
}
inline void build(int x,int y,int w)
{ e[++t].v=y;
e[t].w=w;
e[t].next=b[x];
b[x]=t;
}
void tarjan(int u)
{ low[u]=dfn[u]=++cnt;
vis[u]=ins[u]=true;
st[++tp]=u;
for(int o=b[u];o!=-1;o=e[o].next)
{ if(!vis[e[o].v])
{ tarjan(e[o].v);
low[u]=min(low[u],low[e[o].v]);
}else if(ins[e[o].v])low[u]=min(low[u],dfn[e[o].v]);
}
if(low[u]==dfn[u])
{ siz[++ct]=0;
int k=st[tp--];
for(;;)
{ bel[k]=ct,++
bd6f
siz[ct],ins[k]=false;
if(k==u)break;
k=st[tp--];
}
}
}
void dotarjan()
{ cnt=ct=tp=0;
memset(vis,false,sizeof vis);
memset(ins,false,sizeof ins);
for(int i=1;i<=n;i++)if(!vis[i])tarjan(i);
}
void dijkstra(int st,int *dis)
{ memset(vis,false,sizeof vis);
for(int i=1;i<=n;i++)dis[i]=inf;
dis[st]=0;
h.push((node){st,0});
while(!h.empty())
{ node a=h.top();
h.pop();
if(vis[a.p])continue;
int u=a.p;
vis[u]=true;
for(int o=b[u];o!=-1;o=e[o].next)
{ if(dis[u]+e[o].w<dis[e[o].v])
{ dis[e[o].v]=dis[u]+e[o].w;
h.push((node){e[o].v,dis[e[o].v]});
}
}
}
}
void topo()
{ memset(low,0,sizeof low);
for(int i=1;i<=n;i++)if(siz[bel[i]]==1)
for(int o=b[i];o!=-1;o=e[o].next)++low[e[o].v];
int l=1,r=0;
for(int i=1;i<=n;i++)if(low[i]==0)q[++r]=i;
while(l<=r)
{ int u=q[l++];
for(int o=b[u];o!=-1;o=e[o].next)
{ --low[e[o].v];
if(low[e[o].v]==0)q[++r]=e[o].v;
}
}
for(int i=1;i<=r;i++)dfn[q[i]]=i;
}
void dp()
{ int t=0;
for(int i=1;i<=n;i++)if(siz[bel[i]]==1)tmp[++t]=i;
sort(tmp+1,tmp+t+1,cmp2);
for(int i=1;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=0;
f[1][0]=1;
int l=1,r=1;
for(int i=0;i<=dis
+k;i++)
{ while(r<t&&dis[tmp[r+1]]==i)++r;
while(l<=r&&i-dis[tmp[l]]>k)++l;
if(l>r)
{ r=l,i=dis[tmp[l]]-1;
continue;
}
d.push(l);
for(int z=l+1;z<=r;z++)if(dis[tmp[z]]!=dis[tmp[z-1]])d.push(z);
while(!d.empty())
{ int z=d.top();
d.pop();
if(z<r&&dis[tmp[z+1]]==dis[tmp[z]])d.push(z+1);
int u=tmp[z],j=i-dis[u];
for(int o=b[u];o!=-1;o=e[o].next)
{ if(i+e[o].w<=dis[e[o].v]+k)
f[e[o].v][i+e[o].w-dis[e[o].v]]=(f[e[o].v][i+e[o].w-dis[e[o].v]]+f[u][j])%p;
}
}
}
}
void dp2()
{ int t=0;
for(int i=1;i<=n;i++)if(siz[bel[i]]==1)tmp[++t]=i;
sort(tmp+1,tmp+t+1,cmp2);
for(int i=1;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=0;
f[1][0]=1;
int l=1,r=1;
for(int i=0;i<=dis
+k;i++)
{ while(r<t&&dis[tmp[r+1]]==i)++r;
while(l<=r&&i-dis[tmp[l]]>k)++l;
if(l>r)
{ r=l,i=dis[tmp[l]]-1;
continue;
}
for(int z=l;z<=r;z++)
{ int u=tmp[z],j=i-dis[u];
for(int o=b[u];o!=-1;o=e[o].next)
{ if(i+e[o].w<=dis[e[o].v]+k)
f[e[o].v][i+e[o].w-dis[e[o].v]]=(f[e[o].v][i+e[o].w-dis[e[o].v]]+f[u][j])%p;
}
}
}
}
}aa,bb,cc;
inline int read()
{ int x=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
void work()
{ aa.init(),bb.init(),cc.init();
n=read(),m=read(),k=read(),p=read();
int zz=0;
for(int i=1;i<=m;i++)
{ x=read(),y=read(),z=read();
aa.build(x,y,z),bb.build(y,x,z);
if(z==0)++zz,cc.build(x,y,0);
}
cc.dotarjan();
aa.dijkstra(1,dis);
bb.dijkstra(n,dis2);
for(int i=1;i<=ct;i++)mn1[i]=mn2[i]=inf;
for(int i=1;i<=n;i++)mn1[bel[i]]=min(mn1[bel[i]],dis[i]),mn2[bel[i]]=min(mn2[bel[i]],dis2[i]);
for(int i=1;i<=ct;i++)if(siz[i]>1&&mn1[i]+mn2[i]<=dis
+k)
{ printf("-1\n");
return;
}
cc.topo();
if(zz)aa.dp();else aa.dp2();
int ac=0;
for(int i=0;i<=k;i++)ac=(ac+f
[i])%p;
printf("%d\n",ac);
}
int main()
{ freopen("park.in","r",stdin);
freopen("park.out","w",stdout);
tt=read();
while(tt--)work();
return 0;
}
下午。在宿舍里打牌,还没开始,老师推门而入,场面一度十分尴尬。。。
晚上,和同游大佬在操场狂欢。
Day2。
T1奶酪(题目链接)本弱的纯数学方法非for循环暴力运算竟然搞到了五分,,有的大佬说这是要用图做的。
LittleOrange(https://www.cnblogs.com/Dndlns/p/7886017.html)大佬的dfs
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
long long next,to;
} e[2000005];
struct node1
{
long long x,y,z;
} a[1005];
long long head[1005],cnt,vis[1005];
inline void insert(long long u,long long v)
{
e[++cnt].next=head[u];
head[u]=cnt;
e[cnt].to=v;
}
inline void dfs(long long now)
{
vis[now]=1;
for(long long i=head[now];i;i=e[i].next)
{
if(vis[e[i].to]) continue;
dfs(e[i].to);
}
}
int main()
{
long long t,S,T,n,m,k;
scanf("%lld",&t);
while(t--)
{
cnt=0;
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
scanf("%lld%lld%lld",&n,&m,&k);
S=n+1,T=n+2;
for(long long i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
if(a[i].z<=k)
{
insert(S,i);
insert(i,S);
}
if(a[i].z>=m-k)
{
insert(T,i);
insert(i,T);
}
}
for(long long i=1;i<=n;i++)
for(long long j=i+1;j<=n;j++)
{
if((a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+(a[j].z-a[i].z)*(a[j].z-a[i].z)<=4*k*k)
{
insert(i,j);
insert(j,i);
}
}
dfs(S);
if(vis[T])
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
return 0;
}
T2宝藏(题目链接)又觉得是个不会找深度的最小生成树。。。
CQzhangyu大佬http://www.cnblogs.com/CQzhangyu/的状压DP
#include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; int n,m,tot,ans; int map[110][110],dis[110][110],Log[4100]; int f[15][4100],g[4100],ref[4100],v[15],p[15]; inline int min(const int &a,const int &b) { return a<b?a:b; } int main() { //freopen("treasure.in","r",stdin); //freopen("treasure.out","w",stdout); scanf("%d%d",&n,&m); register int i,j,a,b,c,x; for(i=0;i<n;i++) for(j=0;j<n;j++) map[i][j]=60000000; for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c),a--,b--; map[a][b]=map[b][a]=min(map[a][b],c); } for(i=0;i<n;i++) Log[1<<i]=i; memset(f,0x3f,sizeof(f)); for(i=0;i<n;i++) f[0][1<<i]=0; for(i=0;i<n;i++) for(x=0;x<(1<<n);x++) { tot=0; for(a=0;a<n;a++) if(!(x&(1<<a))) { v[tot]=60000000,p[tot]=1<<a; for(j=x;j;j-=j&-j) { b=Log[j&-j]; v[tot]=min(v[tot],map[a][b]*(i+1)); } tot++; } for(j=1;j<(1<<tot);j++) { g[j]=g[j-(j&-j)]+v[Log[j&-j]]; ref[j]=ref[j-(j&-j)]|p[Log[j&-j]]; f[i+1][x|ref[j]]=min(f[i+1][x|ref[j]],f[i][x]+g[j]); } } ans=1<<30; for(i=0;i<=n;i++) ans=min(ans,f[i][(1<<n)-1]); printf("%d",ans); return 0; }
T3列队(题目链接)What?啥玩意?模拟?这么大的数据范围?认真的取了小范围模拟了一下,于是第二组样例…一开始几十个数都是对的…后来就有0出现…到文件末尾只剩乱糟糟的全错了…于是又爆零
CQzhangyu大佬的离线+SBT
是啥玩意蒟蒻也没看懂
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int maxn=300010; typedef long long ll; struct node { int ch[2],siz,val,org,tag; }s[maxn<<1]; int n,m,q,tot; int rx,ry[maxn]; //px指最右面那列,py指每一行 int bel[maxn],x[maxn],y[maxn]; ll ans[maxn]; inline int rd() { int ret=0; char gc=getchar(); while(gc<'0'||gc>'9') gc=getchar(); while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret; } inline void pushdown(int x) { if(s[x].tag) { if(s[x].ch[0]) s[s[x].ch[0]].val+=s[x].tag,s[s[x].ch[0]].tag+=s[x].tag; if(s[x].ch[1]) s[s[x].ch[1]].val+=s[x].tag,s[s[x].ch[1]].tag+=s[x].tag; s[x].tag=0; } } inline void pushup(int x) { s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1; } inline void rotate(int &x,int d) { int y=s[x].ch[d]; pushdown(x),pushdown(y); s[x].ch[d]=s[y].ch[d^1],s[y].ch[d^1]=x; pushup(x),pushup(y); x=y; } inline void maintain(int &x,int d) { if(s[s[s[x].ch[d]].ch[d]].siz>s[s[x].ch[d^1]].siz) rotate(x,d); else if(s[s[s[x].ch[d]].ch[d^1]].siz>s[s[x].ch[d^1]].siz) rotate(s[x].ch[d],d^1),rotate(x,d); else return ; maintain(s[x].ch[d],d),maintain(s[x].ch[d^1],d^1); maintain(x,d),maintain(x,d^1); } void insert(int &x,int y,int z) { if(!x) { x=++tot,s[x].siz=1,s[x].ch[0]=s[x].ch[1]=s[x].tag=0,s[x].val=y,s[x].org=z; return ; } pushdown(x); int d=(y>s[x].val); insert(s[x].ch[d],y,z),pushup(x); maintain(x,d); } void del(int &x,int y) { s[x].siz--,pushdown(x); if(s[y].val>s[x].val) del(s[x].ch[1],y); else if(s[y].val<s[x].val) del(s[x].ch[0],y); else { if(!s[x].ch[0]||!s[x].ch[1]) { x=s[x].ch[0]^s[x].ch[1]; return ; } int u=s[x].ch[1]; pushdown(u); while(s[u].ch[0]) u=s[u].ch[0],pushdown(u); s[x].org=s[u].org,s[x].val=s[u].val; del(s[x].ch[1],u); } } void updata(int x,int y) { if(!x) return ; pushdown(x); if(s[x].val>=y) { s[x].val++; if(s[x].ch[1]) s[s[x].ch[1]].val++,s[s[x].ch[1]].tag++; updata(s[x].ch[0],y); } else updata(s[x].ch[1],y); } inline int findmax(int x) { pushdown(x); while(s[x].ch[1]) x=s[x].ch[1],pushdown(x); return x; } inline ll point(int a,int b) {return ll(a-1)*m+b;} void dfs(int x,int t) { if(!x) return ; pushdown(x); if(!t) ans[s[x].org]=point(s[x].val,m); else ans[s[x].org]=point(t,s[x].val); dfs(s[x].ch[0],t),dfs(s[x].ch[1],t); } int find(int x,int y) { if(!x) return 0; pushdown(x); if(y>s[x].val) return find(s[x].ch[1],y); if(y<s[x].val) return find(s[x].ch[0],y); return x; } int main() { //freopen("phalanx.in","r",stdin); //freopen("phalanx.out","w",stdout); n=rd(),m=rd(),q=rd(); int i; for(i=1;i<=q;i++) { bel[i]=i; x[i]=rd(),y[i]=rd(); } for(i=q;i>=1;i--) { int t=findmax(rx); if(s[t].val==n) { bel[s[t].org]=i,del(rx,t); } updata(rx,x[i]); updata(ry[x[i]],y[i]); t=findmax(ry[x[i]]); if(s[t].val==m) { del(ry[x[i]],t),insert(rx,x[i],s[t].org); } if(y[i]<m) insert(ry[x[i]],y[i],i); else insert(rx,x[i],i); } dfs(rx,0); for(i=1;i<=n;i++) dfs(ry[i],i); for(i=1;i<=q;i++) printf("%lld\n",ans[i]=ans[bel[i]]); return 0;
然额今年并木有考网络流。。。
华丽丽的Day1Day2双炸
[b]希望各位阅读本blog的童鞋们努力学习,争取Noip2018不辜负自己
相关文章推荐