NOIP2017题解

Day1T1：小凯的疑惑

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

typedef long long LL;

int a,b;
LL ans;

int main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);

scanf("%d%d",&a,&b);
ans=(long long)a*(long long)b-(long long)a-(long long)b;
printf("%lld\n",ans);

return 0;
}

Day1T2：时间复杂度

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=110;

struct data
{
int id,lo,hi,ed;
} work[maxn];

bool vis[30];
int sak[maxn];
int tail=0;

char s[maxn];
int Max,now;
int t,l,w;

{
int x=0;
while ( '0'<=s[y] && s[y]<='9' ) x=x*10+(s[y]-'0'),y++;
return x;
}

int main()
{
freopen("complexity.in","r",stdin);
freopen("complexity.out","w",stdout);

scanf("%d",&t);
while (t--)
{
scanf("%d",&l);
getchar();
scanf("%s",&s);
if (s[2]=='1') w=0;

for (int i=1; i<=l; i++)
{
scanf("%s",&s);
while ( s[0]!='E' && s[0]!='F' ) scanf("%s",&s);
if (s[0]=='E') work[i].id=-1;
else
{
scanf("%s",&s);
work[i].id=s[0]-'a';
scanf("%s",&s);
if (s[0]=='n') work[i].lo=102;
scanf("%s",&s);
if (s[0]=='n') work[i].hi=102;
}
}

//printf("%d\n",w);
//for (int i=1; i<=l; i++) printf("%d %d %d\n",work[i].id,work[i].lo,work[i].hi);
//printf("\n");

memset(vis,false,sizeof(vis));
bool sol=true;
tail=0;
for (int i=1; i<=l; i++)
{
if (work[i].id==-1)
if (!tail)
{
sol=false;
break;
}
else
{
int x=sak[tail];
tail--;
vis[ work[x].id ]=false;
work[x].ed=i;
}
else
{
tail++;
sak[tail]=i;
if (!vis[ work[i].id ]) vis[ work[i].id ]=true;
else
{
sol=false;
break;
}
}
}
if (tail) sol=false;

if (!sol)
{
printf("ERR\n");
continue;
}

//printf("\n");

now=0,Max=0;
int Time=0;
while (Time<l)
{
Time++;
if (work[Time].id==-1)
{
int x=sak[tail];
tail--;
if ( work[x].lo<work[x].hi && work[x].hi==102 ) now--;
}
else
if (work[Time].lo>work[Time].hi) Time=work[Time].ed;
else
{
sak[++tail]=Time;
if ( work[Time].lo<work[Time].hi && work[Time].hi==102 )
now++,Max=max(Max,now);
}
}

if (Max==w) printf("Yes\n");
else printf("No\n");
}

return 0;
}

Day1T3：逛公园

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

const int maxn=100100;
const int maxm=200100;
const int maxk=55;
const int oo=1000000000;

struct edge
{
int obj,len;
edge *Next;
} e[maxm<<1];
int cur=-1;

int Heap[maxn];
int id[maxn];
int tail;

int f[maxn];
int g[maxn];

int cnt[maxn][maxk];
int vis[maxn][maxk];
int num[maxn][maxk];

int qx[maxn*maxk];
int qy[maxn*maxk];
int he,ta;

int t,n,m,k,p;

{
cur++;
e[cur].obj=y;
e[cur].len=z;
}

int Delete(int *dis)
{
int temp=Heap[1];
Heap[1]=Heap[tail];
id[ Heap[1] ]=1;
tail--;

int x=1;
while (1)
{
int y=x,Left=x<<1,Right=Left|1;
if ( Left<=tail && dis[ Heap[Left] ]<dis[ Heap[y] ] ) y=Left;
if ( Right<=tail && dis[ Heap[Right] ]<dis[ Heap[y] ] ) y=Right;
if (y==x) break;
swap(Heap[x],Heap[y]);
swap(id[ Heap[x] ],id[ Heap[y] ]);
x=y;
}

return temp;
}

void Update(int *dis,int x)
{
while (x>1)
{
int y=x>>1;
if (dis[ Heap[y] ]<dis[ Heap[x] ]) break;
swap(Heap[x],Heap[y]);
swap(id[ Heap[x] ],id[ Heap[y] ]);
x=y;
}
}

{
for (int i=1; i<=n; i++) dis[i]=oo;
dis[s]=0;

tail=1;
Heap[1]=s;
id[s]=1;
for (int i=1; i<=n; i++) if (i!=s)
Heap[++tail]=i,id[i]=tail;

for (int i=1; i<n; i++)
{
int node=Delete(dis);
{
int to=p->obj;
if (dis[to]>dis[node]+p->len)
dis[to]=dis[node]+p->len,Update(dis,id[to]);
}
}
}

bool Find(int node,int i)
{
if (f[node]+i+g[node]>f[n]+k) return true;
if (vis[node][i]==2) return true;
if (vis[node][i]==1) return false;

vis[node][i]=1;
{
int to=p->obj;
int j=f[node]+i+p->len-f[to];
if (j>k) continue;
if ( !Find(to,j) ) return false;
}
vis[node][i]=2;
return true;
}

int Mod(int x)
{
if (x>=p) x-=p;
return x;
}

void Bfs()
{
for (int i=1; i<=n; i++)
for (int j=0; j<=k; j++) cnt[i][j]=0;
cnt[1][0]=1%p;

for (int i=1; i<=n; i++)
for (int j=0; j<=k; j++)
if (vis[i][j])
{
int to=p->obj;
int x=f[i]+j+p->len-f[to];
if ( x<=k && vis[to][x] ) num[to][x]++;
}

he=0,ta=1;
qx[1]=1;
qy[1]=0;
while (he<ta)
{
he++;
int node=qx[he];
int i=qy[he];

{
int to=p->obj;
int j=f[node]+i+p->len-f[to];
if ( j>k || !vis[to][j] ) continue;

cnt[to][j]=Mod(cnt[to][j]+cnt[node][i]);
num[to][j]--;
if (!num[to][j])
{
ta++;
qx[ta]=to;
qy[ta]=j;
}
}
}
}

int main()
{
freopen("3953.in","r",stdin);
freopen("3953.out","w",stdout);

scanf("%d",&t);
while (t--)
{
scanf("%d%d%d%d",&n,&m,&k,&p);
cur=-1;
for (int i=1; i<=m; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
}

for (int i=1; i<=n; i++)
for (int j=0; j<=k; j++)
vis[i][j]=num[i][j];
bool sol=Find(1,0);

if (!sol) printf("-1\n");
else
{
Bfs();
int ans=0;
for (int i=0; i<=k; i++) ans=Mod(ans+cnt[n][i]);
printf("%d\n",ans);
}
}

return 0;
}

Day2T1：奶酪

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=1010;
typedef long long LL;

struct edge
{
int obj;
edge *Next;
} e[maxn*maxn];
int cur;

int level[maxn];
int que[maxn];
int he,ta;

int X[maxn];
int Y[maxn];
int Z[maxn];

int t,n,h,r;
LL temp;

bool Judge(LL x,LL y,LL z)
{
x*=x;
y*=y;
z*=z;
LL dis=x+y+z;
return (dis<=temp);
}

{
cur++;
e[cur].obj=y;
}

bool Bfs()
{
level[0]=1;
for (int i=1; i<=n+1; i++) level[i]=0;
he=0,ta=1;
que[1]=0;
while (he<ta)
{
int node=que[++he];
{
int to=p->obj;
if (!level[to]) level[to]=level[node]+1,que[++ta]=to;
}
}
return level[n+1];
}

int main()
{
freopen("cheese.in","r",stdin);
freopen("cheese.out","w",stdout);

scanf("%d",&t);
while (t--)
{
scanf("%d%d%d",&n,&h,&r);
for (int i=1; i<=n; i++) scanf("%d%d%d",&X[i],&Y[i],&Z[i]);

cur=-1;
temp=4LL*(long long)r*(long long)r;
for (int i=0; i<=n+1; i++) head[i]=NULL;
for (register int i=1; i<n; ++i)
for (register int j=i+1; j<=n; ++j)
if ( Judge(X[i]-X[j],Y[i]-Y[j],Z[i]-Z[j]) )

for (int i=1; i<=n; i++) if (Z[i]-r<=0) Add(0,i);
for (int i=1; i<=n; i++) if (Z[i]+r>=h) Add(i,n+1);
bool sol=Bfs();
if (sol) printf("Yes\n");
else printf("No\n");
}

return 0;
}

Day2T2：宝藏

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=15;
const int maxs=(1<<12)+100;
const int oo=1000000000;

int e[maxn][maxn];

int h[maxn][maxs];
int g[maxs][maxs];
int f[maxn][maxs];

int n,m;

int main()
{
freopen("3959.in","r",stdin);
freopen("3959.out","w",stdout);

scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) e[i][j]=oo;
for (int i=1; i<=m; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[a][b]=min(e[a][b],c);
e[b][a]=min(e[b][a],c);
}

int ms=1<<n;
for (int i=1; i<=n; i++)
for (int s=1; s<ms; s++)
{
h[i][s]=oo;
if ( !(s&(1<<(i-1))) )
for (int j=1; j<=n; j++)
if ( s&(1<<(j-1)) )
h[i][s]=min(h[i][s],e[i][j]);
}

for (int s=1; s<ms; s++)
{
int t=s&(s-1);
while (t)
{
int x=s^t;
for (int i=1; i<=n; i++)
if ( x&(1<<(i-1)) )
{
g[s][t]+=h[i][t];
if (g[s][t]>oo) g[s][t]=oo;
}
t=s&(t-1);
}
}

for (int i=1; i<=n; i++)
for (int s=0; s<ms; s++) f[i][s]=oo;
for (int i=1; i<=n; i++) f[1][1<<(i-1)]=0;
for (int i=2; i<=n; i++)
for (int s=1; s<ms; s++)
{
int t=s&(s-1);
while (t)
{
int temp;
if (g[s][t]<oo) temp=g[s][t]*(i-1);
else temp=oo;
if (f[i-1][t]<oo) f[i][s]=min(f[i][s],f[i-1][t]+temp);
t=s&(t-1);
}
}

int ans=oo;
for (int i=1; i<=n; i++) ans=min(ans,f[i][ms-1]);
printf("%d\n",ans);

return 0;
}

Day2T3：列队

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=300100;
const int Lg=22;

const long long M1=998244353;
const long long M2=1000000007;
const long long M3=1998585857;
typedef long long LL;

struct Seg
{
int sum;
Seg *Lson,*Rson;
} tree[maxn*Lg];
Seg *SRoot[maxn];
int cur=-1;

struct Tnode
{
LL val;
int Size,fix;
Tnode *lson,*rson;
int Lsize() { return (lson? lson->Size:0); }
} Treap[maxn*3];
Tnode *TRoot[maxn];
int Tcur=-1;
LL seed;

int num[maxn];
int n,m,q;

Seg *New_Seg()
{
cur++;
tree[cur].sum=0;
tree[cur].Lson=tree[cur].Rson=tree;
return tree+cur;
}

int Rand()
{
seed=(seed*M1+M2)%M3;
return seed;
}

Tnode *New_Tnode(LL v)
{
Tcur++;
Treap[Tcur].val=v;
Treap[Tcur].Size=1;
Treap[Tcur].fix=Rand();
Treap[Tcur].lson=Treap[Tcur].rson=NULL;
return Treap+Tcur;
}

void Recount(Tnode *P)
{
P->Size=P->Lsize()+(P->rson? P->rson->Size:0)+1;
}

void Left_turn(Tnode *&P)
{
Tnode *W=P->rson;
P->rson=W->lson;
W->lson=P;
P=W;
Recount(P->lson);
Recount(P);
}

void Insert(Tnode *&P,LL v)
{
if (!P) P=New_Tnode(v);
else
{
Insert(P->rson,v);
if ( P->rson->fix < P->fix ) Left_turn(P);
else Recount(P);
}
}

void Right_turn(Tnode *&P)
{
Tnode *W=P->lson;
P->lson=W->rson;
W->rson=P;
P=W;
Recount(P->rson);
Recount(P);
}

LL Delete(Tnode *&P,int Rank)
{
int Ls=P->Lsize()+1;
LL temp;     //!!!
if (Ls==Rank)
if (P->lson)
if (P->rson)
if ( P->lson->fix < P->rson->fix )
{
Right_turn(P);
temp=Delete(P->rson, P->rson->Lsize()+1 );
Recount(P);
}
else
{
Left_turn(P);
temp=Delete(P->lson, P->lson->Lsize()+1 );
Recount(P);
}
else temp=P->val,P=P->lson;
else temp=P->val,P=P->rson;
else
{
if (Rank<Ls) temp=Delete(P->lson,Rank);
else temp=Delete(P->rson,Rank-Ls);
Recount(P);
}
return temp;
}

int Query(Seg *root,int L,int R,int Rank)
{
if (L==R) return L;
int mid=(L+R)>>1,Ls=root->Lson->sum;
if (Rank<=mid-Ls) return Query(root->Lson,L,mid,Rank);
else return Query(root->Rson,mid+1,R,Rank+Ls);//没考虑清楚，+号打成了-号！！！
}

void Update(Seg *&root,int L,int R,int x)
{
if (root==tree) root=New_Seg();
if (L==R) root->sum++;
else
{
int mid=(L+R)>>1;
if (x<=mid) Update(root->Lson,L,mid,x);
else Update(root->Rson,mid+1,R,x);
root->sum=root->Lson->sum+root->Rson->sum;
}
}

/*void Print(Tnode *P)
{
if (!P) return;
Print(P->lson);
printf("%d ",P->val);
Print(P->rson);
}*/

int main()
{
freopen("3960.in","r",stdin);
freopen("3960.out","w",stdout);

scanf("%d%d%d",&n,&m,&q);

seed=q;
for (int i=0; i<=n+1; i++) TRoot[i]=NULL;
New_Seg();
for (int i=1; i<=n; i++) SRoot[i]=tree,num[i]=0;

for (int i=1; i<=n; i++) Insert(TRoot[n+1],(long long)i*(long long)m);
m--;
for (int i=1; i<=q; i++)
{
int x,y;
scanf("%d%d",&x,&y);
if (y>m)
{
LL temp=Delete(TRoot[n+1],x);
printf("%lld\n",temp);     //!!!
Insert(TRoot[n+1],temp);
}
else
{
LL ans;
if (y>m-num[x]) ans=Delete(TRoot[x],y+num[x]-m);
else
{
ans=Query(SRoot[x],1,m,y);
Update(SRoot[x],1,m,ans);
ans+=( (long long)(x-1)*(long long)(m+1) );
num[x]++;
}
Insert(TRoot[x], Delete(TRoot[n+1],x) );
Insert(TRoot[n+1],ans);
printf("%lld\n",ans);
}
//if (i==4) Print(TRoot[n+1]),printf("\n");
}

return 0;
}

//记得开long long！！！

后记：

SPFA 告诉我前途在何方
01 背包装下了忧伤

Tarjan 陪伴强连通分量

——膜你抄 WC2017

07-05 1094

12-15 8万+

09-24 576

06-12 4万+

08-19 15

11-27 68

07-25 40

05-18 60

07-28 4180

NOI2017题解合集（施工中）

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。