博主这几天在赶文化课进度,………………很忙…………所以就只发题和思路,代码以后补上(博主郑重承诺!!!)
PDF加密很严重……Nitor无法转成word,所以就委屈一下,我给你们我发的免费链接!!
http://download.csdn.net/detail/lemonoil/9687522
http://pan.baidu.com/s/1slSxJx7
第一道题是弱智模拟题(博主却错了……忘记判0……)
第二道题大神们用lca+差分或树链剖分解决了,博主zz,写了暴力;
第三题是dp+Floyd,但是我的记忆化搜索硬拼GG,还不如写dp。
综上所述,博主第一天完美GG并且第二天都救不回来了……
P.S.为什么NOIP难度上升这么快,等明年博主不还是GG?加油吧……!
toy
可惜了5分,没有判ans==0(mdzz);
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<string>
#define N 300005
#define NAME "toy"
using namespace std;
inline void readin(int &res){
static char ch;
while((ch=getchar())>'9'||ch<'0');
res=ch-48;
while((ch=getchar())<='9'&&ch>='0')
res=res*10+ch-48;
}
int n,m,ans=1;
struct data{
char njsz[100];
int flag;
};
struct que{
int flag,sum;
};
data a[N];
int main(){
freopen(NAME".in","r",stdin);
freopen(NAME".out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].flag);
scanf("%s",a[i].njsz);
}
for(int tot=1;tot<=m;tot++){
que v;
readin(v.flag);readin(v.sum);
if(a[ans].flag==v.flag){
ans-=(v.sum%n);
if(ans<=0)ans+=n;
}else{
ans+=(v.sum%n);
if(ans>n)ans-=n;
}
}
printf("%s",a[ans].njsz);
return 0;
}
running
这道题我交了个暴力(30分拿走不送)~~~
正解是lca+差分+树链剖分(听说启发式合并主席树可以险过……博主蒟蒻不懂……)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<string>
#define NAME "running"
#define N 400005
using namespace std;
int n,m,siz,cnt,tot,x,y;
int father[N],num[N],d[N],g[N][20],w[N],ans[N],root[N],size[N];
int first[N],next[N*3],to[N*3];
inline void readin(int &res){
static char ch;
while((ch=getchar())>'9'||ch<'0');
res=ch-48;
while((ch=getchar())<='9'&&ch>='0')
res=res*10+ch-48;
}
struct node{
int s,t,l;
}edge[N];
struct Tree{
int lc,rc,s;
}T[N*30];
void inser(int x,int y){
next[++siz]=first[x];
first[x]=siz;
to[siz]=y;
}
void dfs1(int x){
size[x]=1,num[x]=++cnt;
for (int k = 0;g[x][k];k++)g[x][k+1]=g[g[x][k]][k];
for (int i = first[x];i;i=next[i])
if (!father[to[i]]&&to[i]!=father[x]){
father[to[i]]=g[to[i]][0] = x;
d[to[i]]=d[x]+1;
dfs1(to[i]);
size[x] += size[to[i]];
}
}
void add(int &v,int vv,int l,int r,int x){
T[v = ++ tot]=T[vv];
if(l==r){T[v].s++;return;}
int mid=l+r>>1;
if (x<=mid)add(T[v].lc,T[vv].lc,l,mid,x);
else add(T[v].rc,T[vv].rc,mid+1,r,x);
T[v].s++;
}
int query(int v,int vv,int l,int r,int x,int y){
if(x<=l&&r<=y)return T[v].s-T[vv].s;
int mid=l+r>>1,ret=0;
if(x<=mid)ret+=query(T[v].lc,T[vv].lc,l,mid,x,y);
if(mid<y)ret+=query(T[v].rc,T[vv].rc,mid+1,r,x,y);
return ret;
}
int lca(int x,int y){
if (d[x]<d[y])swap(x,y);
for (int i=18;~i;i--)if(d[g[x][i]]>=d[y])x=g[x][i];
if (x == y)return x;
for (int i=18;~i;i--)if(g[x][i]^g[y][i])x=g[x][i],y=g[y][i];
return g[x][0];
}
bool cmp_f(const node &a,const node &b){
return d[a.s]<d[b.s]||d[a.s]==d[b.s]&&num[a.s]<num[b.s];
}
bool cmp_s(const node &a,const node &b){
int d1=d[a.s]-a.l,d2 = d[b.s]-b.l;
return d1<d2||d1==d2&&num[a.s]<num[b.s];
}
int seacher_f(int dep,int st){
int l=0,r=m+1;
while(l<r-1){
int mid=l+r>>1;
if(d[edge[mid].s]<dep||d[edge[mid].s]==dep&&num[edge[mid].s]<st)l=mid;
else r=mid;
}
return l+1;
}
int seacher_s(int dep,int en){
int l=0,r=m+1;
while(l<r-1){
int mid = l+r >> 1;
if (d[edge[mid].s]>dep||d[edge[mid].s]==dep&&num[edge[mid].s]>en)r=mid;
else l=mid;
}
return r-1;
}
int findl(int dep,int st){
int l=0,r=m+1;
while(l<r-1){
int mid=l+r>>1;
if(d[edge[mid].s]-edge[mid].l<dep||d[edge[mid].s]-edge[mid].l==dep&&num[edge[mid].s]<st)l=mid;
else r=mid;
}
return l+1;
}
int findr(int dep,int en){
int l=0,r=m+1;
while (l<r-1){
int mid=l+r>>1;
if (d[edge[mid].s]-edge[mid].l>dep||d[edge[mid].s]-edge[mid].l==dep&&num[edge[mid].s]>en)r=mid;
else l=mid;
}
return r-1;
}
int main(){
freopen(NAME".in","r",stdin);
freopen(NAME".out","w",stdout);
readin(n);readin(m);
for (int i=1;i<n;i++){
readin(x);readin(y);
inser(x,y),inser(y,x);
}
for (int i=1;i<=n;i++)readin(w[i]);
dfs1(d[1]=1);
for (int i=1;i<=m;i++){
readin(edge[i].s);readin(edge[i].t);
int z = lca(edge[i].s,edge[i].t);edge[i].l=d[edge[i].s]-d[z]+d[edge[i].t]-d[z];
if (w[z]==d[edge[i].s]-d[z])ans[z]++;
}
sort(edge+1,edge+m+1,cmp_f);
for(int i=1;i<=m;i++)
add(root[i],root[i-1],1,n,num[edge[i].t]);
for(int i=1;i<=n;i++){
int l=seacher_f(d[i]+w[i],num[i]),r=seacher_s(d[i]+w[i],num[i]+size[i]-1);
if (l<=r)ans[i]+=(num[i]>1?query(root[r],root[l-1],1,n,1,num[i]-1):0)+
(num[i]+size[i]<=n?query(root[r],root[l-1],1,n,num[i]+size[i],n):0);
}
for (int i=1;i<=n;i++)w[i]=n-w[i];
for (int i=1;i<=m;i++)swap(edge[i].s,edge[i].t);
sort(edge+1,edge+m+1,cmp_s);
for (int i=1;i<=tot;i++)T[i].lc=T[i].rc=T[i].s=0;
for (int i=1;i<=m;i++)
add(root[i],root[i-1],1,n,num[edge[i].t]);
for (int i = 1;i <= n;i ++){
int l=findl(d[i]+w[i]-n,num[i]),r=findr(d[i]+w[i]-n,num[i]+size[i]-1);
if(l<=r)ans[i]+=(num[i]>1?query(root[r],root[l-1],1,n,1,num[i]-1):0)+
(num[i]+size[i]<=n?query(root[r],root[l-1],1,n,num[i]+size[i],n):0);
}
for (int i=1;i<=n;i++)cout<<ans[i]<<' ';
return 0;
}
classroom
说好的不考数学期望的呢?
(教练说dfs+floyd写得好的可以过……)
我写完floyd后硬是没有写出dfs……………………
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N = 2500;
const int Inf = 0x7fffffff;
queue < int > Q;
int n,m,C[N],D[N]; double P[N],F[N][N][2];
int v,E,f[N],p,dis[330][330];
bool use[N];
struct Edge{
int to,from,w;
}e[200000];
inline int read(){
int ret = 0,k = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')k = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){ret = ret*10 + ch-'0'; ch = getchar();}
return ret * k;
}
inline void build(int x,int y,int w){
e[++p].to = y; e[p].from = f[x]; e[p].w = w; f[x] = p;
e[++p].to = x; e[p].from = f[y]; e[p].w = w; f[y] = p;
}
void Init(){
n = read(); m = read(); v = read(); E = read();
for(int i = 1; i <= n; ++i)C[i] = read();
for(int i = 1; i <= n; ++i)D[i] = read();
for(int i = 1; i <= n; ++i)scanf("%lf",&P[i]);
for(int i = 1; i <= E; ++i){
int x = read(),y = read(),w = read();
if(x == y)continue; build(x,y,w);
}
}
void SPFA(int x){
for(int i = 1; i <= v; ++i)dis[x][i] = Inf,use[i] = 0;
Q.push(x); use[x] = 1; dis[x][x] = 0;
while(!Q.empty()){
int u = Q.front(); Q.pop(); use[u] = 0;
for(int i = f[u]; i ; i = e[i].from){
int y = e[i].to;
if(dis[x][y] > dis[x][u] + e[i].w){
dis[x][y] = dis[x][u] + e[i].w;
if(!use[y]){use[y] = 1; Q.push(y);}
}
}
}
}
void Solve(){
for(int i = 1; i <= v; ++i)SPFA(i);
for(int i = 0; i <= n; ++i)
for(int j = 0; j <= m; ++j)F[i][j][0] = F[i][j][1] = Inf;
F[0][0][0] = 0;
for(int i = 1; i <= n; ++i){
F[i][0][0] = F[i-1][0][0] + dis[C[i-1]][C[i]];
}
C[0] = C[1]; D[0] = D[1]; F[1][1][1] = 0; F[1][1][0] = Inf;
for(int i = 2; i <= n; ++i)
for(int j = 1; j <= min(i,m); ++j){
F[i][j][0] = min(F[i][j][0],F[i-1][j][0] + dis[C[i-1]][C[i]]);
F[i][j][0] = min(F[i][j][0],F[i-1][j][1] + P[i-1]*dis[D[i-1]][C[i]] + (1-P[i-1])*dis[C[i-1]][C[i]]);
F[i][j][1] = min(F[i][j][1],F[i-1][j-1][0] + P[i]*dis[C[i-1]][D[i]] + (1-P[i])*dis[C[i-1]][C[i]]);
F[i][j][1] = min(F[i][j][1],F[i-1][j-1][1] + P[i]*P[i-1]*dis[D[i-1]][D[i]] + P[i]*(1-P[i-1])*dis[C[i-1]][D[i]]+ (1-P[i])*(P[i-1])*dis[D[i-1]][C[i]] + (1-P[i])*(1-P[i-1])*dis[C[i-1]][C[i]]);
}
double ans = Inf;
for(int i = 0; i <= m; ++i){ans = min(ans,F[n][i][0]); ans = min(ans,F[n][i][1]);}
printf("%.2f\n",ans);
}
int main(){
freopen("classroom.in","r",stdin);
freopen("classroom.out","w",stdout);
Init();
Solve();
fclose(stdin);
fclose(stdout);
return 0;
}
这次考试就GG了………………
还是自己实力的问题…………