10.16NOIP模拟赛
/* 我是一个大sb */ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define ll long long #define N 10000007 #define mod 1000000000 using namespace std; ll n,m,k,x,y,flag,ans,cnt; ll a[N],cur[N]; priority_queue<ll>q; inline ll read() { ll x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int main() { freopen("shop.in","r",stdin); freopen("shop.out","w",stdout); n=read();m=read(); x=read();y=read(); a[1]=x;q.push(-a[1]); for(int i=2;i<=n;i++) { a[i]=(y*a[i-1]+x)%mod; q.push(-a[i]); if(a[i]==0){k=i;break;} } if(!k) { for(int i=1;i<=m;i++) { ll res=q.top();q.pop(); ans-=res; } cout<<ans<<endl; return 0; } int t=n/k,tt=n-t*k;a[t*k+1]=x;cur[++cnt]=x; for(int i=2;i<=tt;i++) { a[i+t*k]=(y*a[i+t*k-1]+x)%mod; cur[++cnt]=a[i]; } sort(cur+1,cur+tt+1); if(m<=t) ans=0; else { while(!q.empty() && m) { int x=q.top();q.pop();x=-x; if(x<cur[1] || x>cur[tt]) { m-=t;ans+=x*t; } if(x>=cur[1] && x<=cur[tt]) { m-=(t+1);ans+=x*(t+1); } } } cout<<ans<<endl; fclose(stdin);fclose(stdout); return 0; }
/* 优先队列 */ #include<complex> #include<cstdio> #include<queue> using namespace std; const int mod=1e9; long long n,m,x,y,ans; priority_queue<int>q; int main() { freopen("shop.in","r",stdin); freopen("shop.out","w",stdout); scanf("%d%d%d%d",&n,&m,&x,&y); long long now=x; q.push(now); for(int i=2;i<=n;i++) { now=(now*y+x)%mod; if(i<=m)q.push(now); else if(now<q.top()) { q.pop(); q.push(now); } } while(!q.empty()) { ans+=q.top(); q.pop(); } printf("%I64d\n",ans); fclose(stdin);fclose(stdout); return 0; }
#include<iostream> #include<cstdio> #include<cstring> #define N 100007 using namespace std; int n,m,k,cnt; int a[N],b[N]; double c[N],ans; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } void dfs(int now,int sum,double p) { if(now==n+1) { ans+=double(sum)*p; return; } if(a[now]==0) { dfs(now+1,sum & b[now],p*(1.000-c[now])); dfs(now+1,sum,p*c[now]); } if(a[now]==1) { dfs(now+1,sum | b[now],p*(1.000-c[now])); dfs(now+1,sum,p*c[now]); } if(a[now]==2) { dfs(now+1,sum ^ b[now],p*(1.000-c[now])); dfs(now+1,sum,p*c[now]); } } int main() { // freopen("exp.in","r",stdin); // freopen("exp.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) b[i]=read(); for(int i=1;i<=n;i++) scanf("%lf",&c[i]); ans=0;dfs(1,0,1); printf("%.1lf\n",ans); fclose(stdin);fclose(stdout); return 0; }
/* 把每一位拆开单独考虑 f[i][0/1]表示到第i个运算,该位为0/1的概率 对于每一个运算符分情况讨论 ans = sum[ f[n][1] * (1 << k) ] */ #include<bits/stdc++.h> #define N 100007 using namespace std; int n,a[N],b[N]; double c[N], f[N][2]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } double solve(int bit) { f[0][0]=1.00; for(int i=1;i<=n;i++) { int x = b[i] >> bit & 1; if(a[i]==0) { if(x==0) f[i][0]=(f[i-1][1] + f[i-1][0]) * (1 - c[i]) + f[i-1][0] * c[i], f[i][1]=f[i-1][1] * c[i]; else f[i][0]=f[i-1][0], f[i][1]=f[i-1][1]; } if(a[i]==1) { if(x==0) f[i][0]=f[i-1][0], f[i][1]=f[i-1][1]; else f[i][0]=f[i-1][0] * c[i], f[i][1]=(f[i-1][0] + f[i-1][1]) * (1 - c[i]) + f[i-1][1] * c[i]; } if(a[i] == 2) { if(x==0) f[i][0]=f[i-1][0], f[i][1]=f[i-1][1]; else f[i][0]=f[i-1][1] * (1 - c[i]) + f[i-1][0] * c[i], f[i][1]=f[i-1][0] * (1 - c[i]) + f[i-1][1] * c[i]; } } return f[n][1]; } int main() { freopen("exp.in", "r", stdin); freopen("exp.out", "w", stdout); cin>>n; for(int i = 1;i<=n;i++) cin>>a[i]; for(int i = 1;i<=n;i++) cin>>b[i]; for(int i = 1;i<=n;i++) scanf("%lf",&c[i]); double ans = 0; for(int i = 31;i>=0;i--) ans+=(double)(1ll << i) * solve(i); printf("%.1lf",ans); return 0; }
、、
#include<bits/stdc++.h> #define N 50001 using namespace std; int n,m,T,ans,cnt,res,num; int head[N],deep[N],sum[N]; int f[N][26],tmp1[N],tmp2[N]; struct edge{ int u,v,w,net; }e[N<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v,int w) { e[++cnt].v=v;e[cnt].w=w;e[cnt].net=head[u];head[u]=cnt; } void dfs(int u,int fa,int c) { f[u][0]=fa;deep[u]=c; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(v==fa) continue; sum[v]+=e[i].w+sum[u]; dfs(v,u,c+1); } } void get() { for(int j=1;j<=25;j++) for(int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; } int lca(int a,int b) { if(deep[a]<deep[b]) swap(a,b); int t=deep[a]-deep[b]; for(int i=0;i<=25;i++) if(t&(1<<i)) a=f[a][i]; if(a==b) return a; for(int i=25;i>=0;i--) { if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; }return f[a][0]; } void solve1(int x,int L,int k) { cnt=0; while(x!=L) { tmp1[++cnt]=sum[x]-sum[f[x][0]]; x=f[x][0]; } } void solve2(int y,int L,int k) { num=0; while(y!=L) { tmp2[++num]=sum[y]-sum[f[y][0]]; y=f[y][0]; } } int main() { //freopen("data.txt", "r", stdin); //freopen("2.out", "w", stdout); freopen("maze.in","r",stdin); freopen("maze.out","w",stdout); //freopen("ly.in","r",stdin); //freopen("ly.out","w",stdout); int x,y,z; n=read(); for(int i=1;i<n;i++) { x=read();y=read();z=read(); add(x,y,z);add(y,x,z); } dfs(1,1,1);get(); m=read(); for(int i=1;i<=m;i++) { x=read();y=read();z=read(); int L=lca(x,y); memset(tmp1,0,sizeof tmp1); memset(tmp2,0,sizeof tmp2); solve1(x,L,z); solve2(y,L,z);reverse(tmp2+1,tmp2+num+1); ans=0;res=0; if(cnt) for(int i=1;i<=cnt;i++) { if(tmp1[i]<=res) res-=tmp1[i]; else res=z,res-=tmp1[i],ans++; } if(num) for(int i=1;i<=num;i++) { if(tmp2[i]<=res) res-=tmp2[i]; else res=z,res-=tmp2[i],ans++; } printf("%d\n",ans); } fclose(stdin);fclose(stdout); return 0; }
/* LCA,压位 算 LCA 是显然的, 由于两个点之间可能要走很多步, 所以我们预处理每一个点往上连续 走六步会出现的各种情况,便能控制常数,从而在 8 秒内出解。由于边权只有两种,所以一 个点往上走六步遇到的边权只有 2^6 = 64 种情况 */ #include <cstdio> #include <cstring> #define E 50010 #define F 100010 using namespace std; int n, m, head[E], to[F], next[F], value[F], cnt = 0, cost = 0, costa = 0; void Read(int &x) { char ch = getchar(); x = 0; while (ch < '0' || ch > '9') ch = getchar(); while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } } void add(int x, int y, int z) { to[++cnt] = y; value[cnt] = z; next[cnt] = head[x]; head[x] = cnt; } int fa[E][20], dep[E], dist[E][7], type[E], jky[E][300], dd[E], jump[E]; short czy[1<<8][300][300][2]; void dfs(int u, int f, int d) { fa[u][0] = f; dep[u] = d; for (int j = head[u]; j; j = next[j]) { int v = to[j]; if (v == f) continue; dist[v][0] = value[j]; dfs(v, u, d+1); } } void build() { for (int k = 1; k < 20; k++) for (int u = 1; u <= n; u++) { fa[u][k] = fa[fa[u][k-1]][k-1]; if (k <= 5) dist[u][k] = dist[u][k-1] + dist[fa[u][k-1]][k-1]; } for (int i = 1; i <= n; i++) if (dep[i] >= 6) dd[i] = dist[i][2] + dist[fa[i][2]][1]; for (int i = 1; i <= n; i++) { if (dep[i] < 6) continue; int t = 0, u = i; for (int j = 0; j < 6; j++) { if (dist[u][0] == cost) t += 1 << j; u = fa[u][0]; } jump[i] = u; type[i] = t; } for (int j = 0; j < (1<<6); j++) for (int k = cost; k <= cost * 6; k++) for (int rest = 0; rest <= k; rest++) { int path = j, step = 0, re = rest; for (int t = 1; t <= 6; t++) { int co; if (path & 1) co = cost; else co = costa; if (re < co) re = k, step++; re -= co; path >>= 1; } czy[j][k][rest][0] = step; czy[j][k][rest][1] = re; } for (int i = 1; i <= n; i++) { int u = i, rest = 0; for (int j = 0; j < dd[i]; j++) { if (dep[u] > 0 && rest >= dist[u][0]) { rest -= dist[u][0]; u = fa[u][0]; } jky[i][j] = u; rest++; } } } void swap(int& x, int& y) { int t = x; x = y; y = t; } int get(int x, int y) { if (dep[x] < dep[y]) swap(x, y); for (int k = 19; k >= 0; k--) if (dep[fa[x][k]] >= dep[y]) x = fa[x][k]; if (x == y) return x; for (int k = 19; k >= 0; k--) if (fa[x][k] != fa[y][k]) x = fa[x][k], y = fa[y][k]; if (x != y) x = fa[x][0]; return x; } struct hyd { int step, rest; }; inline hyd work(int u, int f, int k) { int step = 0, rest = 0; if (k <= cost * 6) while (dep[u] > dep[f]) { if (dep[u] - dep[f] < 6) { if (rest >= dist[u][0]) rest -= dist[u][0]; else step++, rest = k - dist[u][0]; u = fa[u][0]; continue; } step += czy[type[u]][k][rest][0]; rest = czy[type[u]][k][rest][1]; u = jump[u]; } else while (dep[u] > dep[f]) { if (rest == 0) step++, rest = k; if (dep[u] - dep[f] < 6) { if (rest >= dist[u][0]) rest -= dist[u][0]; else step++, rest = k - dist[u][0]; u = fa[u][0]; continue; } if (rest >= dd[u]) { rest -= dd[u]; u = jump[u]; continue; } u = jky[u][rest], rest = 0; } return (hyd) {step, rest}; } int main() { freopen("data.txt", "r", stdin); freopen("1.out", "w", stdout); Read(n); memset(head, 0, sizeof(head)); for (int i = 1; i < n; i++) { int x, y, z; Read(x), Read(y), Read(z); add(x, y, z); add(y, x, z); if (cost < z) cost = z; if (i == 1) costa = z; else if (costa > z) costa = z; } memset(fa, 0, sizeof(fa)); memset(dep, 0, sizeof(dep)); memset(dist, 0, sizeof(dist)); dfs(1, 0, 0); build(); Read(m); for (int i = 1; i <= m; i++) { int x, y, k; Read(x), Read(y), Read(k); int f = get(x, y); hyd ans1 = work(x, f, k), ans2 = work(y, f, k); int ans = ans1.step + ans2.step; ans -= (ans1.rest + ans2.rest) / k; printf("%d\n", ans); } fclose(stdin); fclose(stdout); return 0; }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。